Index: /applications/editors/josm/plugins/00_plugin_dir_template/LICENSE
===================================================================
--- /applications/editors/josm/plugins/00_plugin_dir_template/LICENSE	(revision 23139)
+++ /applications/editors/josm/plugins/00_plugin_dir_template/LICENSE	(revision 23139)
@@ -0,0 +1,345 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+	51 Franklin St, 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 Library 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 St, 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 Library General
+Public License instead of this License.
Index: /applications/editors/josm/plugins/00_plugin_dir_template/README
===================================================================
--- /applications/editors/josm/plugins/00_plugin_dir_template/README	(revision 23138)
+++ /applications/editors/josm/plugins/00_plugin_dir_template/README	(revision 23139)
@@ -1,11 +1,17 @@
-README 
-======
+ImportImagePlugin:
 
-Readme for your plugin 
+This Plugin makes use of the Geotools library to provide a method to 
+import spatial referenced images into JOSM.
 
-    * Plugin author and contact email address.
-    
-    * The license for your plugin source code. If you have no special preferences, 
-      you can pick the license that is used for JOSM ("GPL v2 or later").
-      
-    * Notes for future developers, if needed.
+Basically, the plugin import function needs:
+- the image file (Supported formats: GeoTiff, Tiff, jpg, bmp, png, gif)
+- a world file (<image_name>.wld (or other extensions like ".bpw" for BMP files, ".tfw" for Tiffs))
+- a projection file (<image_name>.prj) with a WKT-representation of the source projection for this image
+
+If no world file can be found, the plugin cannot continue.
+If no projection file can be found, the plugin asks to use the DEFAULT reference system,
+which can be set either in "<APP_DATA_DIR>/JOSM/plugins/ImportImagePlugin/pluginProperties.properties" file
+or in the layer-properties dialog after a layer is created.
+
+For a more detailed documentation you may visit the WIKI-entry for the plugin.
+
Index: /applications/editors/josm/plugins/00_plugin_dir_template/build.xml
===================================================================
--- /applications/editors/josm/plugins/00_plugin_dir_template/build.xml	(revision 23138)
+++ /applications/editors/josm/plugins/00_plugin_dir_template/build.xml	(revision 23139)
@@ -28,68 +28,84 @@
 **
 -->
-<project name="myPluginName" 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="" />
-
-
-    <!--
+<project name="ImportImagePlugin" 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="" />
+
+
+	<!--
       ************************************************
       ** 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.target" value="1.5"/>
-    <property name="plugin.dist.dir"        value="../../dist"/>
-    <property name="plugin.jar"             value="${plugin.dist.dir}/${ant.project.name}.jar"/>
-
-    <!--
+	<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.target" value="1.5"/>
+	<property name="plugin.dist.dir"        value="../../dist"/>
+	<property name="plugin.jar"             value="${plugin.dist.dir}/${ant.project.name}.jar"/>
+
+	<!--
     **********************************************************
     ** init - initializes the build
     **********************************************************
     -->
-    <target name="init">
-        <mkdir dir="${plugin.build.dir}"/>
-    </target>
-
-    <!--
+	<target name="init">
+		<mkdir dir="${plugin.build.dir}"/>
+	</target>
+
+	<!--
     **********************************************************
     ** compile - complies the source tree
     **********************************************************
     -->
-    <target name="compile" depends="init">
-        <echo message="compiling sources for  ${plugin.jar} ... "/>
-        <javac srcdir="src" classpath="${josm}" debug="true" destdir="${plugin.build.dir}">
-            <compilerarg value="-Xlint:deprecation"/>
-            <compilerarg value="-Xlint:unchecked"/>
-        </javac>
-    </target>
-
-    <!--
+	<target name="compile" depends="init">
+		<echo message="compiling sources for  ${plugin.jar} ... "/>
+		<javac srcdir="src" classpath="${josm}" debug="true" destdir="${plugin.build.dir}">
+            <classpath>
+                <pathelement location="${josm}"/>
+                <fileset dir="lib">
+                    <include name="**/*.jar"/>
+                </fileset>
+            </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}/resources">
-            <fileset dir="resources"/>
-        </copy>
-        <copy todir="${plugin.build.dir}/images">
-            <fileset dir="images"/>
-        </copy>
-        <copy todir="${plugin.build.dir}">
-            <fileset dir=".">
-                <include name="README" />
-                <include name="LICENSE" />
-            </fileset>
-        </copy>
-        <jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
-            <!--
+	<target name="dist" depends="compile,revision">
+		<echo message="creating ${ant.project.name}.jar ... "/>
+		
+		<copy todir="${plugin.build.dir}/lib">
+			<fileset dir="lib">
+				  <not>
+				    <filename name="log4j-1.2.12.jar"/>
+				  </not>
+			</fileset>
+		</copy>
+        <unjar src="lib/log4j-1.2.12.jar" dest="${plugin.build.dir}"/>
+		<copy todir="${plugin.build.dir}/images">
+			<fileset dir="images"/>
+		</copy>
+		<copy todir="${plugin.build.dir}/resources">
+			<fileset dir="resources"/>
+		</copy>
+		<copy todir="${plugin.build.dir}">
+			<fileset dir=".">
+				<include name="README" />
+				<include name="LICENSE" />
+			</fileset>
+		</copy>
+        	
+		<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
+			<!--
         ************************************************
         ** configure these properties. Most of them will be copied to the plugins
@@ -99,18 +115,19 @@
         ************************************************
     -->
-            <manifest>
-                <attribute name="Author" value="..."/>
-                <attribute name="Plugin-Class" value="..."/>
+
+			<manifest>
+                <attribute name="Author" value="Christoph Beekmans, Fabian Kowitz, Anna Robaszkiewicz, Oliver Kuhn, Martin Ulitzny"/>
+                <attribute name="Plugin-Class" value="org.openstreetmap.josm.plugins.ImageImportPlugin.ImageImportPlugin"/>
                 <attribute name="Plugin-Date" value="${version.entry.commit.date}"/>
-                <attribute name="Plugin-Description" value="..."/>
-                <attribute name="Plugin-Icon" value="..."/>
-                <attribute name="Plugin-Link" value="..."/>
-                <attribute name="Plugin-Mainversion" value="${plugin.main.version}"/>
+                <attribute name="Plugin-Description" value="Plugin for importing spatial referenced images"/>
+                <attribute name="Plugin-Link" value=" -- will soon be added -- "/>
+                <attribute name="Plugin-Mainversion" value="1.0"/>
                 <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
-            </manifest>
-        </jar>
-    </target>
-
-    <!--
+				<attribute name="Class-Path" value="."/>
+			</manifest>
+		</jar>
+	</target>
+
+	<!--
     **********************************************************
     ** revision - extracts the current revision number for the
@@ -119,139 +136,160 @@
     **********************************************************
     -->
-    <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>
-
-    <!--
+	<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>
-
-    <!--
+	<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>
+	<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>
+	
+	<target name="unjar-test" >
+        <!--unjar dest="C:/Workspace_2/geotoolstest/lib/unjartest">
+            <fileset dir="lib"/>
+        </unjar-->
+        
+        		<jar destfile="C:/Workspace_2/geotoolstest/lib/unjartest/${ant.project.name}.jar" basedir="C:/Workspace_2/geotoolstest/lib/unjartest">
+
+			<manifest>
+                <attribute name="Author" value="Christoph Beekmans, Fabian Kowitz, Anna Robaszkiewicz, Oliver Kuhn, Martin Ulitzny"/>
+                <attribute name="Plugin-Class" value="org.openstreetmap.josm.plugins.CoveragePlugin.CoveragePlugin"/>
+                <attribute name="Plugin-Date" value="${version.entry.commit.date}"/>
+                <attribute name="Plugin-Description" value="Plugin for importing spatial referenced images"/>
+                <attribute name="Plugin-Link" value="..."/>
+                <attribute name="Plugin-Mainversion" value=".."/>
+                <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
+                <attribute name="Class-path" value=" . CoveragePlugin/lib/commons-beanutils-1.7.0.jar CoveragePlugin/lib/commons-pool-1.5.3.jar CoveragePlugin/lib/geoapi-2.3-M1.jar CoveragePlugin/lib/geoapi-pending-2.3-M1.jar CoveragePlugin/lib/geoapi.jar CoveragePlugin/lib/gt-api-2.6.0.jar CoveragePlugin/lib/gt-coverage-2.6.0.jar CoveragePlugin/lib/gt-epsg-extension-2.6.0.jar CoveragePlugin/lib/gt-epsg-hsql-2.6.0.jar CoveragePlugin/lib/gt-geotiff-2.6.0.jar CoveragePlugin/lib/gt-main-2.6.0.jar CoveragePlugin/lib/gt-metadata-2.6.0.jar CoveragePlugin/lib/gt-referencing-2.6.0.jar CoveragePlugin/lib/hsqldb-1.8.0.7.jar CoveragePlugin/lib/imageio-ext-tiff-1.0.4.jar CoveragePlugin/lib/imageio-ext-utilities-1.0.4.jar CoveragePlugin/lib/jai_codec-1.1.3.jar CoveragePlugin/lib/jai_core.jar CoveragePlugin/lib/jai_imageio-1.1.jar CoveragePlugin/lib/jdom-1.0.jar CoveragePlugin/lib/jsr-275-1.0-beta-2.jar CoveragePlugin/lib/jts-1.10.jar CoveragePlugin/lib/log4j-1.2.12.jar CoveragePlugin/lib/vecmath-1.3.2.jar" />
+			</manifest>
+		</jar>
+	</target>
+	
 </project>
Index: /applications/editors/josm/plugins/00_plugin_dir_template/resources/log4j.properties
===================================================================
--- /applications/editors/josm/plugins/00_plugin_dir_template/resources/log4j.properties	(revision 23139)
+++ /applications/editors/josm/plugins/00_plugin_dir_template/resources/log4j.properties	(revision 23139)
@@ -0,0 +1,5 @@
+log4j.rootLogger=ALL, MyRoFiAppender
+
+log4j.appender.MyRoFiAppender=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.MyRoFiAppender.layout=org.apache.log4j.PatternLayout
+log4j.appender.MyRoFiAppender.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c: %m%n
Index: /applications/editors/josm/plugins/00_plugin_dir_template/resources/pluginProperties.properties
===================================================================
--- /applications/editors/josm/plugins/00_plugin_dir_template/resources/pluginProperties.properties	(revision 23139)
+++ /applications/editors/josm/plugins/00_plugin_dir_template/resources/pluginProperties.properties	(revision 23139)
@@ -0,0 +1,3 @@
+default_crs_srid=EPSG\:31467
+default_crs_eastingfirst=true
+libraries=commons-beanutils-1.7.0.jar,commons-pool-1.5.3.jar,geoapi-2.3-M1.jar,geoapi-pending-2.3-M1.jar,gt-api-2.6.0.jar,gt-coverage-2.6.0.jar,gt-epsg-hsql-2.6.0.jar,gt-geotiff-2.6.0.jar,gt-main-2.6.0.jar,gt-metadata-2.6.0.jar,gt-referencing-2.6.0.jar,hsqldb-1.8.0.7.jar,imageio-ext-tiff-1.0.4.jar,imageio-ext-utilities-1.0.4.jar,jai_codec-1.1.3.jar,jai_core.jar,jai_imageio-1.1.jar,jdom-1.0.jar,jsr-275-1.0-beta-2.jar,jts-1.10.jar,vecmath-1.3.2.jar
Index: /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/ImageImportPlugin.java
===================================================================
--- /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/ImageImportPlugin.java	(revision 23139)
+++ /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/ImageImportPlugin.java	(revision 23139)
@@ -0,0 +1,291 @@
+package org.openstreetmap.josm.plugins.ImageImportPlugin;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Properties;
+
+import javax.swing.JMenu;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.plugins.Plugin;
+import org.openstreetmap.josm.plugins.PluginInformation;
+
+/**
+ * Plugin class.
+ * Provides basic routines for plugin installation and provides the plugin properties.
+ * 
+ * 
+ * @author Christoph Beekmans, Fabian Kowitz, Anna Robaszkiewicz, Oliver Kuhn, Martin Ulitzny
+ *
+ */
+public class ImageImportPlugin extends Plugin{
+	
+	private static Logger logger;
+	
+	JMenu mainmenu = null;
+	JosmAction loadFileAction = null;
+	
+	// custom Classloader
+	static ClassLoader pluginClassLoader;
+	
+	// plugin proerties
+	static Properties pluginProps;
+	
+	// path constants
+	static final String PLUGIN_DIR = Main.pref.getPluginsDirectory().getAbsolutePath() + "/ImageImportPlugin/";
+	static final String PLUGINPROPERTIES_PATH = Main.pref.getPluginsDirectory().getAbsolutePath() + "/ImageImportPlugin/pluginProperties.properties"; 
+	static final String PLUGINLIBRARIES_DIR = Main.pref.getPluginsDirectory().getAbsolutePath() + "/ImageImportPlugin/lib/"; 
+	static final String PLUGINPROPERTIES_FILENAME = "pluginProperties.properties";
+	static final String LOGGING_PROPERTIES_FILEPATH = Main.pref.getPluginsDirectory().getAbsolutePath() + "/ImageImportPlugin/log4j.properties/";
+	
+	
+	public Properties getPluginProps() {
+		return pluginProps;
+	}
+
+
+	/**
+	 * constructor
+	 * 
+	 * @param info
+	 */
+	public ImageImportPlugin(PluginInformation info){
+		super(info);
+		
+		try {
+			
+			// First create custom ClassLoader to load resources from the main JAR
+			pluginClassLoader = createPluginClassLoader();
+			
+			// Initialize logger
+			initializeLogger(pluginClassLoader);
+			
+			// Check whether plugin has already been installed. Otherwise install
+			checkInstallation();
+			
+			// If resources are available load properties from plugin directory
+			if(pluginProps == null || pluginProps.isEmpty())
+			{
+				pluginProps = new Properties();
+				pluginProps.load(new File(PLUGINPROPERTIES_PATH).toURI().toURL().openStream());
+				logger.debug("Plugin properties loaded");
+			}
+
+			/* Change class path:
+			 * Use java reflection methods to add URLs to the class-path.
+			 * Changes take effect when calling methods of other plugin classes
+			 * (new threads)
+			 * */
+			URLClassLoader sysLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
+			String[] libraryNames = pluginProps.getProperty("libraries").split(",");
+			Class<URLClassLoader> sysclass = URLClassLoader.class;
+			Method method = sysclass.getDeclaredMethod("addURL", new Class[]{URL.class});
+			method.setAccessible(true);
+			for (int i = 0; i < libraryNames.length; i++) {
+				File library = new File(PLUGINLIBRARIES_DIR + "/" + libraryNames[i]);
+				method.invoke(sysLoader, new Object[]{library.toURI().toURL()});
+			}
+	        
+	        
+			// load information about supported reference systems
+			PluginOperations.loadCRSData(pluginProps);
+			
+			// create new Action for menu entry
+			LoadImageAction loadFileAction = new LoadImageAction();
+			loadFileAction.setEnabled(true);
+			
+			// add menu entries
+			Main.main.menu.fileMenu.insert(loadFileAction, 8);
+			Main.main.menu.fileMenu.insertSeparator(9);
+			
+
+		} catch (Exception e) {
+			logger.fatal("Error while loading plugin", e);
+			try {
+				throw e;
+			} catch (Exception e1) {
+				e1.printStackTrace();
+			}
+		}
+
+		logger.info("Plugin successfully loaded.");
+		
+	}
+
+	
+	
+	/**
+	 * Checks whether plugin resources are available.
+	 * If not, start install procedure.
+	 * 
+	 * @throws IOException
+	 */
+	private void checkInstallation() throws IOException
+	{
+		
+		// check plugin resource state
+		boolean isInstalled = true;
+		if(!new File(PLUGINPROPERTIES_PATH).exists()
+				|| !new File(PLUGIN_DIR).exists()
+				|| !new File(PLUGINLIBRARIES_DIR).exists())
+			isInstalled = false;
+		
+		
+		// if properties file doesn't exist, install plugin
+		if(!isInstalled)
+		{
+			
+			/*----------- Begin installation ---------------*/
+			
+			// check if plugin directory exist
+			File pluginDir = new File(PLUGIN_DIR);
+			if(!pluginDir.exists()){
+				pluginDir.mkdir();
+			}
+			
+			// check if "lib" directory exist
+			File libDir = new File(PLUGINLIBRARIES_DIR);
+			if(!libDir.exists()){
+				libDir.mkdir();
+			}
+			
+			// create local properties file
+			if(pluginProps == null || pluginProps.isEmpty()){
+				
+				FileWriter fw = new FileWriter(new File(PLUGINPROPERTIES_PATH));
+				URL propertiesURL = pluginClassLoader.getResource("resources/" + PLUGINPROPERTIES_FILENAME);
+				pluginProps = new Properties();
+				pluginProps.load(propertiesURL.openStream());
+				pluginProps.store(fw, null);
+				fw.close();
+				logger.debug("Plugin properties loaded");
+			}
+			
+			if(!new File(LOGGING_PROPERTIES_FILEPATH).exists())
+			{
+				FileWriter fw = new FileWriter(new File(LOGGING_PROPERTIES_FILEPATH));
+				URL propertiesURL = pluginClassLoader.getResource("resources/log4j.properties");
+				Properties loggingProps = new Properties();
+				loggingProps.load(propertiesURL.openStream());
+				loggingProps.store(fw, null);
+				fw.close();
+				logger.debug("Logging properties created");
+			}
+
+			
+			// Copy all needed JAR files to $PLUGIN_DIR$/lib/  
+			String[] libStrings = pluginProps.getProperty("libraries").split(",");
+			
+			for (int i = 0; i < libStrings.length; i++) {
+				
+				URL url = pluginClassLoader.getResource("lib/" + libStrings[i]);
+				
+				FileOutputStream out = null;
+				
+				try{
+					out = new FileOutputStream(new File(libDir, libStrings[i]));
+				} catch (FileNotFoundException e) {
+					break;
+				}
+				
+				BufferedInputStream in = null;
+				try
+				{
+					in = new BufferedInputStream(url.openStream());
+
+					byte[] buffer = new byte[1024];
+					while (true)
+					{
+						int count = in.read(buffer);
+						if (count == -1)
+							break;
+						out.write(buffer, 0, count);
+					}
+				}
+				finally
+				{
+					if (in != null)
+						in.close();
+				}
+			}
+			logger.debug("Plugin successfully installed");
+		}
+	}
+
+
+	/**
+	 * Initialize logger using plugin classloader.
+	 * 
+	 * @param cl
+	 */
+	private void initializeLogger(ClassLoader cl) {
+
+		Properties props = new Properties();
+		try {
+			props.load(new File(LOGGING_PROPERTIES_FILEPATH).toURI().toURL().openStream());
+			
+			// Set file for logging here:
+			props.setProperty("log4j.appender.MyRoFiAppender.file",
+					(Main.pref.getPluginsDirectory().getAbsolutePath() + "/ImageImportPlugin/" + "log.log"));
+			
+			PropertyConfigurator.configure(props);
+
+			logger = Logger.getLogger(ImageImportPlugin.class);
+			
+			logger.info("Logger successfully initialized.");
+			
+			return;
+		
+		} catch (IOException e) {
+			System.out.println("Logging properties file not found. Using standard settings.");
+		}
+		
+		// if no log4j.properties file can be found, initialize manually:
+		
+		props.setProperty("log4j.rootLogger", "INFO, A");
+		props.setProperty("log4j.appender.A", "org.apache.log4j.FileAppender");
+
+		props.setProperty("log4j.appender.A.layout",
+				"org.apache.log4j.PatternLayout ");
+		props.setProperty("log4j.appender.A.layout.ConversionPattern",
+				"%d{ISO8601} %-5p [%t] %c: %m%n");
+
+		// Set file for logging here:
+		props.setProperty("log4j.appender.A.file",
+				(Main.pref.getPluginsDirectory().getAbsolutePath() + "/ImageImportPlugin/" + "log.log"));
+		
+		PropertyConfigurator.configure(props);
+		logger = Logger.getLogger(ImageImportPlugin.class);
+		logger.info("Logger successfully initialized with standard settings.");
+		
+	}
+	
+	/**
+	 * get a plugin-specific classloader.
+	 * 
+	 * @return
+	 * @throws MalformedURLException 
+	 */
+	private ClassLoader createPluginClassLoader() throws MalformedURLException 
+	{
+		ClassLoader loader = null;
+		loader = URLClassLoader.newInstance(
+			    new URL[] { new File(Main.pref.getPluginsDirectory().getAbsolutePath() + "/ImportImagePlugin.jar").toURI().toURL()},
+			    ImageImportPlugin.class.getClassLoader()
+				);
+		
+		return loader;
+	}
+	
+}
Index: /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/ImageLayer.java
===================================================================
--- /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/ImageLayer.java	(revision 23139)
+++ /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/ImageLayer.java	(revision 23139)
@@ -0,0 +1,343 @@
+package org.openstreetmap.josm.plugins.ImageImportPlugin;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Component;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.event.ActionEvent;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.media.jai.PlanarImage;
+import javax.swing.AbstractAction;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JSeparator;
+
+import org.apache.log4j.Logger;
+import org.geotools.coverage.grid.GridCoverage2D;
+import org.geotools.geometry.Envelope2D;
+import org.geotools.image.ImageWorker;
+import org.geotools.referencing.CRS;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.RenameLayerAction;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.ProjectionBounds;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
+import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
+import org.openstreetmap.josm.gui.layer.Layer;
+
+/**
+ * 	Layer which contains spatial referenced image data.
+ * 
+ * @author Christoph Beekmans, Fabian Kowitz, Anna Robaszkiewicz, Oliver Kuhn, Martin Ulitzny
+ *
+ */
+public class ImageLayer extends Layer {
+
+	private Logger logger = Logger.getLogger(ImageLayer.class);
+
+	private File imageFile;
+	
+	private BufferedImage image = null;
+
+	// coordinates of upper left corner
+	private EastNorth upperLeft;
+	// Angle of rotation of the image
+	private double angle = 0.0;
+
+	// current bbox
+	private Envelope2D bbox;
+	
+	// Layer icon
+	private Icon layericon = null;
+	
+	// reference system of the oringinal image
+	private CoordinateReferenceSystem sourceRefSys;
+
+
+
+	/**
+	 * Constructor
+	 * 
+	 * @param file
+	 * @throws IOException 
+	 */
+	public ImageLayer(File file) throws IOException {
+		super(file.getName());
+		
+		this.imageFile = file;
+		this.image = (BufferedImage) createImage();
+		layericon = new ImageIcon(ImageImportPlugin.pluginClassLoader.getResource("images/layericon.png"));
+		
+	}
+
+	/**
+	 * create spatial referenced image.
+	 * 
+	 * @return
+	 * @throws IOException
+	 */
+	private Image createImage() throws IOException {
+
+		// geotools type for images and value coverages
+		GridCoverage2D coverage = null;
+		try {
+			// create a grid coverage from the image
+			coverage = PluginOperations.createGridFromFile(imageFile, null);
+			this.sourceRefSys = coverage.getCoordinateReferenceSystem();
+			
+			// now reproject grid coverage
+			coverage = PluginOperations.reprojectCoverage(coverage, CRS.decode(Main.proj.toCode()));
+		
+		} catch (FactoryException e) {
+			logger.error("Error while creating GridCoverage:",e);
+			throw new IOException(e.getMessage());
+		} catch (Exception e) {
+			if(e.getMessage().contains("No projection file found"))
+			{
+				int useDefaultCRS = JOptionPane.showConfirmDialog(Main.parent, "<html>No projection file (.prj) found.<br>Use the default Coordinate Reference System instead?</html>", "Missing projection", JOptionPane.YES_NO_OPTION);
+				if (useDefaultCRS == 0)
+				{
+					try {
+						// create a grid coverage from the image
+						coverage = PluginOperations.createGridFromFile(imageFile, PluginOperations.defaultSourceCRS);
+						this.sourceRefSys = coverage.getCoordinateReferenceSystem();
+						
+						// now reproject grid coverage
+						coverage = PluginOperations.reprojectCoverage(coverage, CRS.decode(Main.proj.toCode()));
+					} catch (Exception e1) {
+						logger.error("Error while creating GridCoverage:",e1);
+						throw new IOException(e1);
+					}
+				}
+				else{
+					logger.debug("Layer creation cancled by user due to missing projection information.");
+					throw new LayerCreationCancledException();
+				}
+
+			}
+			else
+			{
+				logger.error("Error while creating GridCoverage:",e);
+				throw new IOException(e);
+			}
+
+		}
+		logger.debug("Coverage created: " + coverage);
+
+		// TODO
+		upperLeft = new EastNorth(coverage.getEnvelope2D().y, coverage
+				.getEnvelope2D().x
+				+ coverage.getEnvelope2D().width);
+		angle = 0;
+		bbox = coverage.getEnvelope2D();
+
+		// Refresh
+		// Main.map.mapView.repaint();
+//		PlanarImage image = (PlanarImage) coverage.getRenderedImage();
+//		logger.info("Color Model: " + coverage.getRenderedImage().getColorModel());
+		ImageWorker worker = new ImageWorker(coverage.getRenderedImage());
+
+		return worker.getBufferedImage();
+	}
+
+	@Override
+	public void paint(Graphics2D g2, MapView mv, Bounds bounds) {
+
+		if (image != null && g2 != null) {
+
+			// Position image at the right graphical place
+			EastNorth center = Main.map.mapView.getCenter();
+			EastNorth leftop = Main.map.mapView.getEastNorth(0, 0);
+			double pixel_per_lon_degree = (Main.map.mapView.getWidth() / 2.0)
+					/ (center.east() - leftop.east());
+			double pixel_per_lat_degree = (Main.map.mapView.getHeight() / 2.0)
+					/ (leftop.north() - center.north());
+
+			// This is now the offset in screen pixels
+			double pic_offset_x = ((upperLeft.east() - leftop.east()) * pixel_per_lon_degree);
+			double pic_offset_y = ((leftop.north() - upperLeft.north()) * pixel_per_lat_degree);
+
+			Graphics2D g = (Graphics2D) g2.create();
+
+			// Move picture by offset from upper left corner
+			g.translate(pic_offset_x, pic_offset_y);
+
+			// Rotate image by angle
+			g.rotate(angle * Math.PI / 180.0);
+			
+			// Determine scale to fit JOSM extents
+			ProjectionBounds projbounds = Main.map.mapView
+					.getProjectionBounds();
+
+			double width = projbounds.max.getX() - projbounds.min.getX();
+			double height = projbounds.max.getY() - projbounds.min.getY();
+
+			double ratio_x = (this.bbox.getMaxY() - this.bbox.getMinY())
+					/ width;
+			double ratio_y = (this.bbox.getMaxX() - this.bbox.getMinX())
+					/ height;
+
+			double pixels4bbox_width = ratio_x * Main.map.mapView.getWidth();
+			double pixels4bbox_height = ratio_y * Main.map.mapView.getHeight();
+
+			// Scale image to JOSM extents
+			double scalex = pixels4bbox_width / image.getWidth();
+			double scaley = pixels4bbox_height / image.getHeight();
+
+			g.scale(scalex, scaley);
+
+			// Draw picture
+			g.drawImage(image, 0, 0, null);
+			
+		} else {
+			logger.error("Error while dawing image: image == null or Graphics == null");
+		}
+	}
+	
+	public Envelope2D getBbox() {
+		return bbox;
+	}
+
+	@Override
+	public Icon getIcon() {
+		// TODO Auto-generated method stub
+		return this.layericon;
+	}
+
+	@Override
+	public Object getInfoComponent() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Component[] getMenuEntries() {
+        return new Component[]{
+                new JMenuItem(LayerListDialog.getInstance().createActivateLayerAction(this)),
+                new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
+                new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
+                new JSeparator(),
+                new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)),
+                new JMenuItem(new LayerPropertiesAction(this)),
+                new JSeparator(),
+                new JMenuItem(new LayerListPopup.InfoAction(this))};
+	}
+
+	@Override
+	public boolean isMergable(Layer arg0) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public void mergeFrom(Layer arg0) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	public void visitBoundingBox(BoundingXYVisitor arg0) {
+		// TODO Auto-generated method stub
+	}
+	
+
+	@Override
+	public String getToolTipText() {
+		// TODO Auto-generated method stub
+		return this.getName();
+	}
+	
+
+	public File getImageFile() {
+		return imageFile;
+	}
+
+	public BufferedImage getImage() {
+		return image;
+	}
+	
+	/**
+	 * loads the image and reprojects it using a transformation
+	 * calculated by the new reference system.
+	 * 
+	 * @param newRefSys
+	 * @throws IOException 
+	 * @throws FactoryException 
+	 * @throws NoSuchAuthorityCodeException 
+	 */
+	void resample(CoordinateReferenceSystem refSys) throws IOException, NoSuchAuthorityCodeException, FactoryException
+	{
+		
+		GridCoverage2D coverage =  PluginOperations.createGridFromFile(this.imageFile, refSys);
+		coverage = PluginOperations.reprojectCoverage(coverage, CRS.decode(Main.proj.toCode()));
+		this.bbox = coverage.getEnvelope2D();
+		this.image = ((PlanarImage)coverage.getRenderedImage()).getAsBufferedImage();
+		
+		// TODO
+		upperLeft = new EastNorth(coverage.getEnvelope2D().y, coverage
+				.getEnvelope2D().x
+				+ coverage.getEnvelope2D().width);
+		angle = 0;
+
+		// repaint and zoom to new bbox
+		Main.map.mapView.repaint();
+		LatLon min = new LatLon(bbox.getMinX(), bbox.getMinY());
+		LatLon max = new LatLon(bbox.getMaxX(), bbox.getMaxY());
+		Main.map.mapView.zoomTo(new Bounds(min, max));
+		
+		
+	}
+	
+	/**
+	 * Action that creates a dialog GUI element with properties of a layer.
+	 * 
+	 */
+	public class LayerPropertiesAction extends AbstractAction
+	{
+		public ImageLayer imageLayer;
+		
+		public LayerPropertiesAction(ImageLayer imageLayer){
+			super(tr("Layer Properties"));
+			this.imageLayer = imageLayer;
+		}
+
+		public void actionPerformed(ActionEvent arg0) {
+			
+			LayerPropertiesDialog layerProps = new LayerPropertiesDialog(imageLayer, PluginOperations.crsDescriptions);
+			layerProps.setLocation(Main.parent.getWidth() / 4 , Main.parent.getHeight() / 4);
+			layerProps.setVisible(true);
+		}
+		
+	}
+	
+	/**
+	 * Exception which represents that the layer creation has been cancled by the
+	 * user.
+	 *
+	 */
+	class LayerCreationCancledException extends IOException{
+	}
+	
+	
+	
+	public CoordinateReferenceSystem getSourceRefSys() {
+		return sourceRefSys;
+	}
+
+	public void setSourceRefSys(CoordinateReferenceSystem sourceRefSys) {
+		this.sourceRefSys = sourceRefSys;
+	}
+}
Index: /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/LayerPropertiesDialog.java
===================================================================
--- /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/LayerPropertiesDialog.java	(revision 23139)
+++ /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/LayerPropertiesDialog.java	(revision 23139)
@@ -0,0 +1,586 @@
+package org.openstreetmap.josm.plugins.ImageImportPlugin;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Rectangle;
+import java.awt.event.KeyEvent;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JFrame;
+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.SwingConstants;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import org.geotools.referencing.CRS;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+/**
+ * UI-Dialog which provides:
+ * - general and spatial information about the georeferenced image
+ * - a possiblitly to change the source reference system of the image
+ * 
+ * 
+ * @author Christoph Beekmans, Fabian Kowitz, Anna Robaszkiewicz, Oliver Kuhn, Martin Ulitzny
+ *
+ */
+public class LayerPropertiesDialog extends JFrame{
+	
+	private Vector<String> supportedCRS;
+	private ImageLayer imageLayer;
+
+	private JPanel mainPanel = null;
+	private JPanel jPanel = null;
+	private JPanel buttonPanel = null;
+	private JTabbedPane jTabbedPane = null;
+	private JPanel infoPanel = null;
+	private JPanel crsPanel = null;
+	private JButton okButton = null;
+	private JLabel layerNameLabel = null;
+	private JLabel layerNameValueLabel = null;
+	private JLabel imageFileLabel = null;
+	private JLabel imageFileValueLabel = null;
+	private JLabel sizeLabel = null;
+	private JLabel sizeValueLabel = null;
+	private JLabel crsLabel = null;
+	private JLabel crsValueLabel = null;
+	private JLabel extentLabel = null;
+	private JLabel defaultCRSDescriptorLabel = null;
+	private JLabel defaultCRSLabel = null;
+	private JTextField searchField = null;
+	private JScrollPane crsListScrollPane = null;
+	private JList crsJList = null;
+	private JButton useDefaultCRSButton = null;
+	private JButton applySelectedCRSButton = null;
+	private JButton setSelectedCRSAsDefaultButton = null;
+	private JLabel searchFieldLabel = null;
+	private JCheckBox eastingFirstCheckBox = null;
+	private JLabel eastingFirstLabel = null;
+	private JLabel tabDescriptionLabel = null;
+	private JLabel upperLeftLabel = null;
+	private JLabel lowerLeftLabel = null;
+	private JLabel upperRightLabel = null;
+	private JLabel lowerRightLabel = null;
+	private JLabel upperLeftValueLabel = null;
+	private JLabel upperRightValueLabel = null;
+	private JLabel lowerLeftValueLabel = null;
+	private JLabel lowerRightValueLabel = null;
+	private JLabel currentCRSLabel = null;
+	private JLabel currentCRSValueLabel = null;
+
+	/**
+	 * This method initializes 
+	 * 
+	 */
+	public LayerPropertiesDialog(ImageLayer imageLayer, Vector<String> supportedCRS) {
+		super(imageLayer.getName());
+		this.supportedCRS = supportedCRS;
+		this.imageLayer = imageLayer;
+		initialize();
+	}
+	
+	/**
+	 * This method initializes 
+	 * 
+	 */
+	public LayerPropertiesDialog(Vector<String> supportedCRS) {
+		super();
+		this.supportedCRS = supportedCRS;
+		initialize();
+	}
+	
+
+	/**
+	 * This method initializes this
+	 * 
+	 */
+	private void initialize() {
+        this.setMinimumSize(new Dimension(404, 485));
+        this.setContentPane(getMainPanel());
+        this.setPreferredSize(new Dimension(404, 485));
+			
+	}
+
+	/**
+	 * This method initializes mainPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */
+	private JPanel getMainPanel() {
+		if (mainPanel == null) {
+			mainPanel = new JPanel();
+			mainPanel.setLayout(null);
+			mainPanel.add(getJPanel(), null);
+			mainPanel.add(getButtonPanel(), null);
+		}
+		return mainPanel;
+	}
+
+	/**
+	 * This method initializes jPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */
+	private JPanel getJPanel() {
+		if (jPanel == null) {
+			GridBagConstraints gridBagConstraints = new GridBagConstraints();
+			gridBagConstraints.fill = GridBagConstraints.BOTH;
+			gridBagConstraints.gridy = 0;
+			gridBagConstraints.weightx = 1.0;
+			gridBagConstraints.weighty = 1.0;
+			gridBagConstraints.gridx = 0;
+			jPanel = new JPanel();
+			jPanel.setLayout(new GridBagLayout());
+			jPanel.setBounds(new Rectangle(0, 0, 391, 406));
+			jPanel.add(getJTabbedPane(), gridBagConstraints);
+		}
+		return jPanel;
+	}
+
+	/**
+	 * This method initializes buttonPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */
+	private JPanel getButtonPanel() {
+		if (buttonPanel == null) {
+			buttonPanel = new JPanel();
+			buttonPanel.setLayout(null);
+			buttonPanel.setBounds(new Rectangle(0, 405, 391, 46));
+			buttonPanel.add(getOkButton(), null);
+		}
+		return buttonPanel;
+	}
+
+	/**
+	 * This method initializes jTabbedPane	
+	 * 	
+	 * @return javax.swing.JTabbedPane	
+	 */
+	private JTabbedPane getJTabbedPane() {
+		if (jTabbedPane == null) {
+			jTabbedPane = new JTabbedPane();
+			jTabbedPane.addTab("General Information", null, getInfoPanel(), null);
+			jTabbedPane.addTab("Source Reference System", null, getCrsPanel(), null);
+		}
+		return jTabbedPane;
+	}
+
+	/**
+	 * This method initializes infoPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */
+	private JPanel getInfoPanel() {
+		if (infoPanel == null) {
+			lowerRightValueLabel = new JLabel();
+			lowerRightValueLabel.setBounds(new Rectangle(210, 315, 134, 16));
+			lowerRightValueLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+			lowerRightValueLabel.setText((float)imageLayer.getBbox().getMinX() + ", " + (float)imageLayer.getBbox().getMaxY());
+			lowerLeftValueLabel = new JLabel();
+			lowerLeftValueLabel.setBounds(new Rectangle(30, 315, 133, 16));
+			lowerLeftValueLabel.setHorizontalAlignment(SwingConstants.LEFT);
+			lowerLeftValueLabel.setText((float)imageLayer.getBbox().getMinX() + ", " + (float)imageLayer.getBbox().getMinY());
+			upperRightValueLabel = new JLabel();
+			upperRightValueLabel.setBounds(new Rectangle(210, 255, 138, 16));
+			upperRightValueLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+			upperRightValueLabel.setText((float)imageLayer.getBbox().getMaxX() + ", " + (float)imageLayer.getBbox().getMaxY());
+			upperLeftValueLabel = new JLabel();
+			upperLeftValueLabel.setBounds(new Rectangle(30, 255, 133, 16));
+			upperLeftValueLabel.setHorizontalAlignment(SwingConstants.LEFT);
+			upperLeftValueLabel.setText((float)imageLayer.getBbox().getMaxX() + ", " + (float)imageLayer.getBbox().getMinY());
+			lowerRightLabel = new JLabel();
+			lowerRightLabel.setBounds(new Rectangle(287, 344, 74, 16));
+			lowerRightLabel.setText("Lower Right");
+			upperRightLabel = new JLabel();
+			upperRightLabel.setBounds(new Rectangle(285, 225, 91, 16));
+			upperRightLabel.setText("Upper Right");
+			lowerLeftLabel = new JLabel();
+			lowerLeftLabel.setBounds(new Rectangle(15, 345, 92, 16));
+			lowerLeftLabel.setText("Lower Left");
+			upperLeftLabel = new JLabel();
+			upperLeftLabel.setBounds(new Rectangle(15, 224, 91, 16));
+			upperLeftLabel.setText("Upper Left");
+			extentLabel = new JLabel();
+			extentLabel.setBounds(new Rectangle(120, 195, 136, 16));
+			extentLabel.setEnabled(false);
+			extentLabel.setHorizontalAlignment(SwingConstants.CENTER);
+			extentLabel.setDisplayedMnemonic(KeyEvent.VK_UNDEFINED);
+			extentLabel.setText("Extent");
+			crsValueLabel = new JLabel();
+			crsValueLabel.setBounds(new Rectangle(150, 150, 226, 16));
+			
+			String crsDescription = "";
+			try {
+				crsDescription = imageLayer.getBbox().getCoordinateReferenceSystem().getIdentifiers().iterator().next().toString();
+			} catch (Exception e) {
+			}
+			crsValueLabel.setText(crsDescription + "(" + imageLayer.getBbox().getCoordinateReferenceSystem().getName().toString() + ")");
+			
+			crsLabel = new JLabel();
+			crsLabel.setBounds(new Rectangle(15, 150, 118, 16));
+			crsLabel.setText("Reference System");
+			sizeValueLabel = new JLabel();
+			sizeValueLabel.setBounds(new Rectangle(150, 105, 226, 16));
+			sizeValueLabel.setText(imageLayer.getImage().getHeight() + " x " + imageLayer.getImage().getWidth());
+			sizeLabel = new JLabel();
+			sizeLabel.setBounds(new Rectangle(15, 105, 121, 16));
+			sizeLabel.setText("Image size");
+			imageFileValueLabel = new JLabel();
+			imageFileValueLabel.setBounds(new Rectangle(150, 60, 226, 16));
+			imageFileValueLabel.setText(imageLayer.getImageFile().getAbsolutePath());
+			imageFileValueLabel.setToolTipText(imageLayer.getImageFile().getAbsolutePath());
+			imageFileLabel = new JLabel();
+			imageFileLabel.setBounds(new Rectangle(15, 60, 121, 16));
+			imageFileLabel.setText("Image file");
+			layerNameValueLabel = new JLabel();
+			layerNameValueLabel.setBounds(new Rectangle(150, 15, 226, 16));
+			layerNameValueLabel.setText(imageLayer.getName());
+			layerNameLabel = new JLabel();
+			layerNameLabel.setBounds(new Rectangle(15, 15, 121, 16));
+			layerNameLabel.setText("Layer name");
+			infoPanel = new JPanel();
+			infoPanel.setLayout(null);
+			infoPanel.setFont(new Font("Dialog", Font.BOLD, 12));
+			infoPanel.add(layerNameLabel, null);
+			infoPanel.add(layerNameValueLabel, null);
+			infoPanel.add(imageFileLabel, null);
+			infoPanel.add(imageFileValueLabel, null);
+			infoPanel.add(sizeLabel, null);
+			infoPanel.add(sizeValueLabel, null);
+			infoPanel.add(crsLabel, null);
+			infoPanel.add(crsValueLabel, null);
+			infoPanel.add(extentLabel, null);
+			infoPanel.add(upperLeftLabel, null);
+			infoPanel.add(lowerLeftLabel, null);
+			infoPanel.add(upperRightLabel, null);
+			infoPanel.add(lowerRightLabel, null);
+			infoPanel.add(upperLeftValueLabel, null);
+			infoPanel.add(upperRightValueLabel, null);
+			infoPanel.add(lowerLeftValueLabel, null);
+			infoPanel.add(lowerRightValueLabel, null);
+		}
+		return infoPanel;
+	}
+
+	/**
+	 * This method initializes crsPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */
+	private JPanel getCrsPanel() {
+		if (crsPanel == null) {
+			currentCRSValueLabel = new JLabel();
+			currentCRSValueLabel.setBounds(new Rectangle(78, 33, 297, 16));
+			String crsDescription = "unknown";
+			try {
+				crsDescription = imageLayer.getSourceRefSys().getIdentifiers().iterator().next().toString();
+			} catch (Exception e) {
+			}
+			currentCRSValueLabel.setText(crsDescription);
+			
+			currentCRSLabel = new JLabel();
+			currentCRSLabel.setBounds(new Rectangle(15, 33, 52, 16));
+			currentCRSLabel.setText("Current:");
+			tabDescriptionLabel = new JLabel();
+			tabDescriptionLabel.setBounds(new Rectangle(15, 9, 361, 16));
+			tabDescriptionLabel.setText("Set here the source reference system of the image");
+			eastingFirstLabel = new JLabel();
+			eastingFirstLabel.setBounds(new Rectangle(315, 210, 76, 46));
+			eastingFirstLabel.setHorizontalTextPosition(SwingConstants.TRAILING);
+			eastingFirstLabel.setHorizontalAlignment(SwingConstants.CENTER);
+			eastingFirstLabel.setText("<html>Easting<br>first</html>");
+			searchFieldLabel = new JLabel();
+			searchFieldLabel.setBounds(new Rectangle(298, 114, 84, 16));
+			searchFieldLabel.setDisplayedMnemonic(KeyEvent.VK_UNDEFINED);
+			searchFieldLabel.setHorizontalTextPosition(SwingConstants.TRAILING);
+			searchFieldLabel.setHorizontalAlignment(SwingConstants.CENTER);
+			searchFieldLabel.setText("Search");
+			defaultCRSLabel = new JLabel();
+			defaultCRSLabel.setBounds(new Rectangle(15, 89, 361, 16));
+			defaultCRSLabel.setText(PluginOperations.defaultSourceCRSDescription);
+			defaultCRSDescriptorLabel = new JLabel();
+			defaultCRSDescriptorLabel.setBounds(new Rectangle(15, 63, 226, 16));
+			defaultCRSDescriptorLabel.setText("Default Reference System:");
+			crsPanel = new JPanel();
+			crsPanel.setLayout(null);
+			crsPanel.add(defaultCRSDescriptorLabel, null);
+			crsPanel.add(defaultCRSLabel, null);
+			crsPanel.add(getSearchField(), null);
+			crsPanel.add(getCrsListScrollPane(), null);
+			crsPanel.add(getUseDefaultCRSButton(), null);
+			crsPanel.add(getApplySelectedCRSButton(), null);
+			crsPanel.add(getSetSelectedCRSAsDefaultButton(), null);
+			crsPanel.add(searchFieldLabel, null);
+			crsPanel.add(getEastingFirstCheckBox(), null);
+			crsPanel.add(eastingFirstLabel, null);
+			crsPanel.add(tabDescriptionLabel, null);
+			crsPanel.add(currentCRSLabel, null);
+			crsPanel.add(currentCRSValueLabel, null);
+		}
+		return crsPanel;
+	}
+
+	/**
+	 * This method initializes okButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */
+	private JButton getOkButton() {
+		if (okButton == null) {
+			okButton = new JButton();
+			okButton.setBounds(new Rectangle(134, 5, 136, 31));
+			okButton.setText("OK");
+			okButton.addActionListener(new java.awt.event.ActionListener() {
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					
+					setVisible(false);
+					dispose();
+				}
+			});
+		}
+		return okButton;
+	}
+
+	/**
+	 * This method initializes searchField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */
+	private JTextField getSearchField() {
+		if (searchField == null) {
+			searchField = new JTextField();
+			searchField.setBounds(new Rectangle(13, 111, 282, 20));
+			searchField.setToolTipText("Enter keywords or EPSG codes");
+			searchField.addKeyListener(new java.awt.event.KeyAdapter() {
+				public void keyTyped(java.awt.event.KeyEvent e) {
+					
+					for (Iterator iterator = supportedCRS.iterator(); iterator
+							.hasNext();) {
+						String type = (String) iterator.next();
+						if(type.contains(searchField.getText()))
+						{
+							crsJList.setSelectedIndex(supportedCRS.indexOf(type));
+							crsJList.ensureIndexIsVisible(supportedCRS.indexOf(type));
+							break;
+						}
+						
+					}
+				}
+			});
+		}
+		return searchField;
+	}
+
+	/**
+	 * This method initializes crsListScrollPane	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */
+	private JScrollPane getCrsListScrollPane() {
+		if (crsListScrollPane == null) {
+			crsListScrollPane = new JScrollPane();
+			crsListScrollPane.setBounds(new Rectangle(15, 135, 301, 241));
+			crsListScrollPane.setViewportView(getCrsJList());
+		}
+		return crsListScrollPane;
+	}
+
+	/**
+	 * This method initializes crsJList	
+	 * 	
+	 * @return javax.swing.JList	
+	 */
+	private JList getCrsJList() {
+		if (crsJList == null) {
+			crsJList = new JList(supportedCRS);
+			crsJList.addListSelectionListener(new ListSelectionHandler());
+		}
+		return crsJList;
+	}
+
+	/**
+	 * This method initializes useDefaultCRSButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */
+	private JButton getUseDefaultCRSButton() {
+		if (useDefaultCRSButton == null) {
+			useDefaultCRSButton = new JButton();
+			useDefaultCRSButton.setBounds(new Rectangle(253, 54, 118, 28));
+			useDefaultCRSButton.setText("Apply Default");
+			useDefaultCRSButton.addActionListener(new java.awt.event.ActionListener() {
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					
+					try {
+						
+						setCursor(new Cursor(Cursor.WAIT_CURSOR));
+						if(PluginOperations.defaultSourceCRS != null){
+							imageLayer.resample(PluginOperations.defaultSourceCRS);
+						}else
+						{
+							JOptionPane.showMessageDialog(getContentPane(), "<html>No default reference system available.<br>Please select one from the list</html>");
+						}
+						
+					} catch (NoSuchAuthorityCodeException e1) {
+						// TODO Auto-generated catch block
+						e1.printStackTrace();
+					} catch (FactoryException e1) {
+						// TODO Auto-generated catch block
+						e1.printStackTrace();
+					} catch (IOException e2) {
+						// TODO Auto-generated catch block
+						e2.printStackTrace();
+					}
+					finally{
+						setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+					}
+				}
+			});
+		}
+		return useDefaultCRSButton;
+	}
+
+	/**
+	 * This method initializes applySelectedCRSButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */
+	private JButton getApplySelectedCRSButton() {
+		if (applySelectedCRSButton == null) {
+			applySelectedCRSButton = new JButton();
+			applySelectedCRSButton.setBounds(new Rectangle(315, 135, 69, 61));
+			applySelectedCRSButton.setHorizontalAlignment(SwingConstants.CENTER);
+			applySelectedCRSButton.setHorizontalTextPosition(SwingConstants.TRAILING);
+			applySelectedCRSButton.setText("<html>Apply<br>Selection</html>");
+			applySelectedCRSButton.addActionListener(new java.awt.event.ActionListener() {
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					
+					String selection = (String) crsJList.getSelectedValue();
+					String code = selection.substring(selection.indexOf("[-") + 2, selection.indexOf("-]"));
+					
+					CoordinateReferenceSystem newRefSys = null;
+					try {
+						newRefSys = CRS.decode(code, eastingFirstCheckBox.isSelected());
+						
+						setCursor(new Cursor(Cursor.WAIT_CURSOR));
+						
+						imageLayer.resample(newRefSys);
+
+					} catch (NoSuchAuthorityCodeException e1) {
+						// TODO Auto-generated catch block
+						e1.printStackTrace();
+					} catch (FactoryException e1) {
+						// TODO Auto-generated catch block
+						e1.printStackTrace();
+					} catch (IOException e2) {
+						// TODO Auto-generated catch block
+						e2.printStackTrace();
+					}
+					finally{
+						setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+					}
+					
+					
+				}
+			});
+		}
+		return applySelectedCRSButton;
+	}
+
+	/**
+	 * This method initializes setSelectedCRSAsDefaultButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */
+	private JButton getSetSelectedCRSAsDefaultButton() {
+		if (setSelectedCRSAsDefaultButton == null) {
+			setSelectedCRSAsDefaultButton = new JButton();
+			setSelectedCRSAsDefaultButton.setBounds(new Rectangle(315, 300, 69, 61));
+			setSelectedCRSAsDefaultButton.setText("<html>Set as<br>Default</html>");
+			setSelectedCRSAsDefaultButton
+					.addActionListener(new java.awt.event.ActionListener() {
+						public void actionPerformed(java.awt.event.ActionEvent e) {
+							
+							if(crsJList.getSelectedValue() != null){
+								String selection = (String) crsJList.getSelectedValue();
+								String code = selection.substring(selection.indexOf("[-") + 2, selection.indexOf("-]"));
+								
+								try {
+									PluginOperations.defaultSourceCRS = CRS.decode(code, eastingFirstCheckBox.isSelected());
+									PluginOperations.defaultSourceCRSDescription = selection;
+									
+									ImageImportPlugin.pluginProps.setProperty("default_crs_eastingfirst", "" + eastingFirstCheckBox.isSelected());
+									ImageImportPlugin.pluginProps.setProperty("default_crs_srid", code);
+									FileWriter fileWriter = new FileWriter(new File(ImageImportPlugin.PLUGINPROPERTIES_PATH));
+									ImageImportPlugin.pluginProps.store(fileWriter, null);
+									fileWriter.close();
+									
+									defaultCRSLabel.setText(selection);
+									
+								} catch (IOException e2) {
+									// TODO Auto-generated catch block
+									e2.printStackTrace();
+								} catch (NoSuchAuthorityCodeException e3) {
+									// TODO Auto-generated catch block
+									e3.printStackTrace();
+								} catch (FactoryException e4) {
+									// TODO Auto-generated catch block
+									e4.printStackTrace();
+								}
+							}else{
+								JOptionPane.showMessageDialog(getContentPane(), "Please make a selection from the list.");
+							}
+
+							
+						}
+					});
+		}
+		return setSelectedCRSAsDefaultButton;
+	}
+	
+	/**
+	 * This method initializes eastingFirstCheckBox	
+	 * 	
+	 * @return javax.swing.JCheckBox	
+	 */
+	private JCheckBox getEastingFirstCheckBox() {
+		if (eastingFirstCheckBox == null) {
+			eastingFirstCheckBox = new JCheckBox();
+			eastingFirstCheckBox.setBounds(new Rectangle(345, 255, 21, 21));
+		}
+		return eastingFirstCheckBox;
+	}
+
+	
+	
+	/**
+	 * Listener setting text in the search field if selection has changed.
+	 *
+	 */
+    class ListSelectionHandler implements ListSelectionListener {
+        public void valueChanged(ListSelectionEvent e) {
+        	if(e.getValueIsAdjusting())
+        	{
+            	searchField.setText(supportedCRS.get(e.getLastIndex()));
+            	searchField.setEditable(true);
+        	}
+        }
+    }
+}  //  @jve:decl-index=0:visual-constraint="142,39"
Index: /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/LoadImageAction.java
===================================================================
--- /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/LoadImageAction.java	(revision 23139)
+++ /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/LoadImageAction.java	(revision 23139)
@@ -0,0 +1,70 @@
+package org.openstreetmap.josm.plugins.ImageImportPlugin;
+import java.awt.event.ActionEvent;
+import java.io.IOException;
+
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+import static org.openstreetmap.josm.tools.I18n.marktr;
+
+import org.apache.log4j.Logger;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
+import org.openstreetmap.josm.plugins.ImageImportPlugin.ImageLayer.LayerCreationCancledException;
+
+
+/**
+ * Class extends JosmAction and creates a new image layer.
+ * 
+ * @author Christoph Beekmans, Fabian Kowitz, Anna Robaszkiewicz, Oliver Kuhn, Martin Ulitzny
+ *
+ */
+public class LoadImageAction extends JosmAction {
+	
+	private Logger logger = Logger.getLogger(LoadImageAction.class);
+
+	/**
+	 * Constructor...
+	 */
+	public LoadImageAction() {
+		super(tr("Import image"), null, tr("Import georeferenced image"), null, false);
+	}
+
+	public void actionPerformed(ActionEvent arg0) {
+
+		// Choose a file
+		JFileChooser fc = new JFileChooser();
+		fc.setAcceptAllFileFilterUsed(false);
+		int result = fc.showOpenDialog(Main.parent);
+		
+		ImageLayer layer = null;
+		if (result == JFileChooser.APPROVE_OPTION) {
+			logger.info("File choosed:" + fc.getSelectedFile());
+			try {
+				layer = new ImageLayer(fc.getSelectedFile());
+			} catch (LayerCreationCancledException e) {
+				// if user decides that layer should not be created just return.
+				return;
+			}catch (Exception e) {
+				logger.error("Error while creating image layer: \n" + e.getMessage());
+				JOptionPane.showMessageDialog(null, marktr("Error while creating image layer: " + e.getCause()));
+				return;
+				
+			}
+			
+			// Add layer:
+			Main.main.addLayer(layer);
+			LatLon min = new LatLon(layer.getBbox().getMinX(), layer.getBbox().getMinY());
+			LatLon max = new LatLon(layer.getBbox().getMaxX(), layer.getBbox().getMaxY());
+			BoundingXYVisitor boundingXYVisitor = new BoundingXYVisitor();
+			boundingXYVisitor.visit(new Bounds(min, max));
+			Main.map.mapView.recalculateCenterScale(boundingXYVisitor);
+			Main.map.mapView.zoomTo(new Bounds(min, max));
+		}
+	}
+}
Index: /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/PluginOperations.java
===================================================================
--- /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/PluginOperations.java	(revision 23139)
+++ /applications/editors/josm/plugins/00_plugin_dir_template/src/org/openstreetmap/josm/plugins/ImportImagePlugin/PluginOperations.java	(revision 23139)
@@ -0,0 +1,395 @@
+package org.openstreetmap.josm.plugins.ImageImportPlugin;
+
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.imageio.ImageIO;
+
+import org.apache.log4j.Logger;
+import org.geotools.coverage.grid.GridCoverage2D;
+import org.geotools.coverage.grid.GridCoverageFactory;
+import org.geotools.coverage.processing.DefaultProcessor;
+import org.geotools.data.DataSourceException;
+import org.geotools.data.WorldFileReader;
+import org.geotools.factory.Hints;
+import org.geotools.gce.geotiff.GeoTiffReader;
+import org.geotools.geometry.Envelope2D;
+import org.geotools.image.jai.Registry;
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.crs.DefaultGeographicCRS;
+import org.opengis.metadata.content.ImageDescription;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.crs.CRSAuthorityFactory;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.util.InternationalString;
+
+
+
+/**
+ * Class provides methods for resampling operations, IO and stores important data.
+ * 
+ * @author Christoph Beekmans, Fabian Kowitz, Anna Robaszkiewicz, Oliver Kuhn, Martin Ulitzny
+ *
+ */
+public class PluginOperations {
+
+	private static final Logger logger = Logger.getLogger(PluginOperations.class);
+	
+	// contains descriptions of all available CRS
+	static Vector<String> crsDescriptions;
+
+	// the standard native CRS of user images 
+	static CoordinateReferenceSystem defaultSourceCRS;
+	// description of 'defaultSourceCRS'
+	static String defaultSourceCRSDescription;
+	
+	
+	
+	public static enum SUPPORTEDIMAGETYPES {
+		tiff, tif, jpg, jpeg, bmp, png 
+	}
+
+	public static enum POSTFIXES_WORLDFILE {
+		wld, jgw, jpgw, pgw, pngw, tfw, tifw, bpw, bmpw, 
+	};
+	
+	/**
+	 * Reprojects a GridCoverage to a given CRS.
+	 * 
+	 * @param coverage
+	 * @param targetCrs
+	 * @return destination
+	 * @throws FactoryException 
+	 * @throws NoSuchAuthorityCodeException 
+	 */
+	public static GridCoverage2D reprojectCoverage(GridCoverage2D coverage,
+			CoordinateReferenceSystem targetCrs) throws NoSuchAuthorityCodeException, FactoryException {
+
+		// TODO: add category for NO_DATA values in coverage (transparency in
+		// image)
+		
+		GridCoverage2D destination = null;
+
+		DefaultProcessor processor = new DefaultProcessor(null);
+		ParameterValueGroup resampleParams = processor.getOperation("Resample")
+				.getParameters();
+
+		// set parameters
+		resampleParams.parameter("Source").setValue(coverage);
+		resampleParams.parameter("CoordinateReferenceSystem").setValue(
+				targetCrs);
+
+		// resample coverage with given parameters
+		destination = (GridCoverage2D) processor.doOperation(resampleParams);
+
+		return destination;
+	}
+
+	/**
+	 * Creates a org.geotools.coverage.grid.GridCoverage2D from a given file. 
+	 * 
+	 * @param file
+	 * @return
+	 * @throws IOException 
+	 * @throws Exception
+	 */
+	public static GridCoverage2D createGridFromFile(File file, CoordinateReferenceSystem refSys) throws IOException{
+
+		GridCoverage2D coverage = null;
+		
+		if (!file.exists()) throw new FileNotFoundException("File not found.");
+
+		String extension = null;
+		String fileNameWithoutExt = null;
+		int dotPos = file.getAbsolutePath().lastIndexOf(".");
+		extension = file.getAbsolutePath().substring(dotPos);
+		fileNameWithoutExt = file.getAbsolutePath().substring(0, dotPos);
+
+		/*------- switch for file type -----------*/
+		if (extension.equalsIgnoreCase(".tif")
+				|| extension.equalsIgnoreCase(".tiff"))
+		{
+			
+			// try to read GeoTIFF:
+			try{
+				coverage = readGeoTiff(file, refSys);
+				return coverage;
+			}catch (DataSourceException dse) {
+				if(!dse.getMessage().contains("Coordinate Reference System is not available")){
+					dse.printStackTrace();
+				}
+			} catch (FactoryException facte) {
+				logger.fatal("Error while reading from GeoTIFF:", facte);
+				throw new IOException(facte);
+			}
+			
+			// file is no GeoTiff, searching for Worldfile and projection file: 
+			String[] postfixes = {"wld", "tfw", "tifw"};
+			// try to read Worldfile:
+			WorldFileReader tfwReader = null;
+			for (int i = 0; i < postfixes.length; i++) {
+				File prjFile = new File(fileNameWithoutExt + "." + postfixes[i]);
+				if(prjFile.exists()){
+					tfwReader = new WorldFileReader(prjFile);
+				}
+			}
+			if(tfwReader == null){
+				throw new IOException("No Worldfile found.");
+			}
+			
+			if(refSys == null){
+				// if no crs is delivered try to read projection file:
+				refSys = readPrjFile(file);
+				if(refSys == null) throw new IOException("No projection file found.");
+			}
+			
+			BufferedImage img = ImageIO.read(file);
+			
+			// create Envelope
+			double width = (double) (img.getWidth() * tfwReader.getXPixelSize());
+			double height = (double) (img.getHeight() * (-tfwReader.getYPixelSize()));
+			double lowerLeft_x = (double) tfwReader.getXULC();
+			double lowerLeft_y = (double) tfwReader.getYULC() - height;
+			Envelope2D bbox = new Envelope2D(null, new Rectangle2D.Double(lowerLeft_x, lowerLeft_y, width, height));
+			
+			coverage = createGridCoverage(img, bbox, refSys);
+			
+		}
+		// 
+		else if (extension.equalsIgnoreCase(".jpg")
+				|| extension.equalsIgnoreCase(".jpeg"))
+		{
+			String[] postfixes = {"wld", "jgw", "jpgw"};
+			// try to read Worldfile:
+			WorldFileReader tfwReader = null;
+			for (int i = 0; i < postfixes.length; i++) {
+				File prjFile = new File(fileNameWithoutExt + "." + postfixes[i]);
+				if(prjFile.exists()){
+					tfwReader = new WorldFileReader(prjFile);
+				}
+			}
+			if(tfwReader == null) throw new IOException("No Worldfile found.");
+			
+			if(refSys == null){
+				// if no crs is delivered try to read projection file:
+				refSys = readPrjFile(file);
+				if(refSys == null) throw new IOException("No projection file found.");
+			}
+			
+			BufferedImage img = ImageIO.read(file);
+			
+			// create Envelope
+			double width = (double) (img.getWidth() * tfwReader.getXPixelSize());
+			double height = (double) (img.getHeight() * (-tfwReader.getYPixelSize()));
+			double lowerLeft_x = (double) tfwReader.getXULC();
+			double lowerLeft_y = (double) tfwReader.getYULC() - height;
+			Envelope2D bbox = new Envelope2D(null, new Rectangle2D.Double(lowerLeft_x, lowerLeft_y, width, height));
+			
+			coverage = createGridCoverage(img, bbox, refSys);
+			
+		}
+		else if(extension.equalsIgnoreCase(".bmp"))
+		{
+			String[] postfixes = {"wld", "bmpw", "bpw"};
+			// try to read Worldfile:
+			WorldFileReader tfwReader = null;
+			for (int i = 0; i < postfixes.length; i++) {
+				File prjFile = new File(fileNameWithoutExt + "." + postfixes[i]);
+				if(prjFile.exists()){
+					tfwReader = new WorldFileReader(prjFile);
+				}
+			}
+			if(tfwReader == null) throw new IOException("No Worldfile found.");
+
+			if(refSys == null){
+				// if no crs is delivered try to read projection file:
+				refSys = readPrjFile(file);
+				if(refSys == null) throw new IOException("No projection file found.");
+			}
+			
+			BufferedImage img = ImageIO.read(file);
+			
+			// create Envelope
+			double width = (double) (img.getWidth() * tfwReader.getXPixelSize());
+			double height = (double) (img.getHeight() * (-tfwReader.getYPixelSize()));
+			double lowerLeft_x = (double) tfwReader.getXULC();
+			double lowerLeft_y = (double) tfwReader.getYULC() - height;
+			Envelope2D bbox = new Envelope2D(null, new Rectangle2D.Double(lowerLeft_x, lowerLeft_y, width, height));
+			
+			coverage = createGridCoverage(img, bbox, refSys);
+		}
+		else if(extension.equalsIgnoreCase(".png"))
+		{
+			
+			String[] postfixes = {"wld", "pgw", "pngw"};
+			// try to read Worldfile:
+			WorldFileReader tfwReader = null;
+			for (int i = 0; i < postfixes.length; i++) {
+				File prjFile = new File(fileNameWithoutExt + "." + postfixes[i]);
+				if(prjFile.exists()){
+					tfwReader = new WorldFileReader(prjFile);
+				}
+			}
+			if(tfwReader == null) throw new IOException("No Worldfile found.");
+			
+			if(refSys == null){
+				// if no crs is delivered try to read projection file:
+				refSys = readPrjFile(file);
+				if(refSys == null) throw new IOException("No projection file found.");
+			}
+			
+			BufferedImage img = ImageIO.read(file);
+			
+			// create Envelope
+			double width = (double) (img.getWidth() * tfwReader.getXPixelSize());
+			double height = (double) (img.getHeight() * (-tfwReader.getYPixelSize()));
+			double lowerLeft_x = (double) tfwReader.getXULC();
+			double lowerLeft_y = (double) tfwReader.getYULC() - height;
+			Envelope2D bbox = new Envelope2D(null, new Rectangle2D.Double(lowerLeft_x, lowerLeft_y, width, height));
+			
+			coverage = createGridCoverage(img, bbox, refSys);
+		}
+		else{
+			throw new IOException("Image type not supported. Supported formats are: \n" +
+					Arrays.toString(SUPPORTEDIMAGETYPES.values()));
+		}
+
+		return coverage;
+	}
+	
+	/**
+	 * Searches for a projection file (.prj) with the same name of 'file' 
+	 * tries to parse it.
+	 * 
+	 * 
+	 * @param file image file, not the real world file (will be searched)
+	 * @return 
+	 * @throws IOException 
+	 */
+	public static CoordinateReferenceSystem readPrjFile(File file) throws IOException
+	{
+		
+		CoordinateReferenceSystem refSys = null;
+		
+		String prjFilename = null;
+		int dotPos = file.getAbsolutePath().lastIndexOf(".");
+		prjFilename = file.getAbsolutePath().substring(0, dotPos) + ".prj";
+		
+		File prjFile = new File(prjFilename);
+		if(!prjFile.exists()) throw new IOException("No projection file found (.prj) for image '" + file.getName() + "'");
+		logger.debug("Loading .prj file: " + prjFile.getAbsolutePath());
+		
+		StringBuilder sb = new StringBuilder();
+		String content = null;
+		BufferedReader br = new BufferedReader(new FileReader(prjFile));
+		while((content = br.readLine()) != null)
+		{
+			sb.append(content);
+		}
+		
+		try {
+			refSys = CRS.parseWKT(sb.toString().trim());
+		} catch (FactoryException e) {
+			throw new IOException("Unable to parse prj-file: '" + prjFile.getName() + "'");
+		}
+		
+		return refSys;
+		
+	}
+	
+	
+	/**
+	 * Method for external use.
+	 * 
+	 * @param img
+	 * @param bbox
+	 * @param crs
+	 * @return
+	 */
+	public static GridCoverage2D createGridCoverage(BufferedImage img, Envelope2D bbox, CoordinateReferenceSystem crs)
+	{
+		bbox.setCoordinateReferenceSystem(crs);
+		return new GridCoverageFactory().create("", img, bbox);
+	}
+	
+	/**
+	 * Method for reading a GeoTIFF file.
+	 * 
+	 * @param file 
+	 * @param refSys if delivered, the coverage will be forced to use this crs
+	 * @return
+	 * @throws IOException
+	 * @throws FactoryException
+	 */
+	public static GridCoverage2D readGeoTiff(File file, CoordinateReferenceSystem refSys) throws IOException, FactoryException
+	{
+		GridCoverage2D coverage = null;
+		Hints hints = new Hints();
+		if(refSys != null)
+		{
+			hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, refSys);
+
+		}
+		// dont't use the EPSG-Factory because of wrong behaviour
+		hints.put(Hints.CRS_AUTHORITY_FACTORY, CRS.getAuthorityFactory(true));
+		
+		GeoTiffReader reader = new GeoTiffReader(file, hints);
+		
+		coverage = (GridCoverage2D) reader.read(null);
+		
+		return coverage;
+	}
+	
+	
+	/**
+	 * Loads CRS data from an EPSG database and creates descrptions for each one. 
+	 * 
+	 * @param pluginProps
+	 * @throws Exception
+	 */
+	public static void loadCRSData(Properties pluginProps)
+	{
+		String defaultcrsString = pluginProps.getProperty("default_crs_srid");
+		
+		crsDescriptions = new Vector<String>();
+		Set<String> supportedCodes = CRS.getSupportedCodes("EPSG");
+		CRSAuthorityFactory fac = CRS.getAuthorityFactory(false);
+		
+		for (Iterator iterator = supportedCodes.iterator(); iterator.hasNext();) {
+			String string = (String) iterator.next();
+			try {
+				InternationalString desc = fac.getDescriptionText("EPSG:" + string);
+
+				String description = desc.toString() + " [-EPSG:" + string + "-]";
+				
+				crsDescriptions.add(description);
+				
+				if(defaultcrsString != null && defaultcrsString.equalsIgnoreCase("EPSG:" + string)){
+					boolean isEastingFirst = Boolean.valueOf(pluginProps.getProperty("default_crs_eastingfirst"));
+					defaultSourceCRS = CRS.decode("EPSG:" + string, isEastingFirst);
+					defaultSourceCRSDescription = description;
+				}
+			} catch (NoSuchAuthorityCodeException e) {
+				if(!string.equalsIgnoreCase("WGS84(DD)")){
+					logger.error("Error while loading EPSG data: " + e.getMessage());
+				}
+			} catch (FactoryException e) {
+				logger.error("Error while loading EPSG data: " + e.getMessage());
+			}
+		}
+	}
+	
+}
