Index: .classpath
===================================================================
--- .classpath	(revision 34846)
+++ .classpath	(working copy)
@@ -1,7 +1,13 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/JOSM"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" output="buildtest" path="test/unit">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/JOSM"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry kind="output" path="build"/>
+</classpath>
Index: .project
===================================================================
--- .project	(revision 34846)
+++ .project	(working copy)
@@ -3,6 +3,7 @@
 	<name>JOSM-Poly</name>
 	<comment></comment>
 	<projects>
+		<project>josm</project>
 	</projects>
 	<buildSpec>
 		<buildCommand>
Index: src/poly/PolyExporter.java
===================================================================
--- src/poly/PolyExporter.java	(revision 34846)
+++ src/poly/PolyExporter.java	(working copy)
@@ -1,21 +1,19 @@
 // License: GPL. For details, see LICENSE file.
 package poly;
 
+import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
+import java.util.HashSet;
 import java.util.Locale;
-import java.util.Map;
-import java.util.TreeMap;
+import java.util.Set;
 
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.data.osm.Way;
@@ -37,36 +35,36 @@
     @Override
     public void exportData(File file, Layer layer) throws IOException {
         if (layer instanceof OsmDataLayer) {
+            if (((OsmDataLayer) layer).getDataSet().getWays().stream().anyMatch(w -> !w.isClosed())) {
+                throw new IOException(tr("Data contains unclosed ways."));
+            }
+            String fileName = file.getName();
+            if (fileName.indexOf('.') > 0) {
+                fileName = fileName.substring(0, fileName.indexOf('.'));
+            }
+            
             try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"))) {
                 DataSet ds = ((OsmDataLayer) layer).getDataSet();
-                Map<Way, Boolean> ways = new TreeMap<>();
-                String polygonName = file.getName();
-                if (polygonName.indexOf('.') > 0)
-                    polygonName = polygonName.substring(0, polygonName.indexOf('.'));
-                for (Way w : ds.getWays()) {
-                    if (w.isClosed()) {
-                        boolean outer = isOuter(w);
-                        ways.put(w, outer);
-                        if (w.hasKey("name"))
-                            polygonName = w.get("name").replace("\n", " ");
+                HashSet<Way> written = new HashSet<>();
+                boolean firstFile = true;
+                for (Relation rel : ds.getRelations()) {
+                    if (rel.isMultipolygon()) {
+                        if (!firstFile) {
+                            writer.newLine();
+                        }
+                        writeRelation(writer, fileName, rel, written);
+                        firstFile = false;
                     }
                 }
-                ways = sortOuterInner(ways);
-
+                
+                if (firstFile) {
+                    writer.write(fileName);
+                }
                 int counter = 1;
-                writer.write(polygonName);
-                writer.newLine();
-                for (Way w : ways.keySet()) {
-                    if (!ways.get(w))
-                        writer.write('!');
-                    writer.write(String.valueOf(counter++));
-                    writer.newLine();
-                    for (Node n : w.getNodes()) {
-                        writer.write(String.format(Locale.ENGLISH, "   %f   %f", n.getCoor().lon(), n.getCoor().lat()));
-                        writer.newLine();
+                for (Way w : ds.getWays()) {
+                    if (!written.contains(w)) {
+                        writeWay(writer, w, counter);
                     }
-                    writer.write("END");
-                    writer.newLine();
                 }
                 writer.write("END");
                 writer.newLine();
@@ -74,32 +72,38 @@
         }
     }
 
-    private boolean isOuter(Way w) {
-        for (OsmPrimitive p : w.getReferrers()) {
-            if (p instanceof Relation && ((Relation) p).isMultipolygon()) {
-                for (RelationMember m : ((Relation) p).getMembers()) {
-                    if (m.refersTo(w) && "inner".equals(m.getRole())) {
-                        return false;
-                    }
-                }
+    private static void writeRelation(BufferedWriter writer, String fileName, Relation rel, Set<Way> written) throws IOException {
+        String polygonName = fileName;
+        if (rel.getName() != null)
+            polygonName = rel.getName();
+        writer.write(polygonName);
+        writer.newLine();
+        int counter = 1;
+        for (RelationMember rm: rel.getMembers()) {
+            if (rm.isWay()) {
+                if ("inner".equals(rm.getRole()))
+                    writer.write('!');
+                Way w = rm.getWay();
+                counter = writeWay(writer, w, counter);
+                written.add(w);
             }
         }
-        return true;
     }
 
-    private Map<Way, Boolean> sortOuterInner(Map<Way, Boolean> ways) {
-        LinkedHashMap<Way, Boolean> result = new LinkedHashMap<>(ways.size());
-        List<Way> inner = new ArrayList<>();
-        for (Way w : ways.keySet()) {
-            Boolean outer = ways.get(w);
-            if (outer)
-                result.put(w, outer);
-            else
-                inner.add(w);
+    private static int writeWay(BufferedWriter writer, Way w, int counter) throws IOException {
+        String name = w.getName();
+        if (name == null) {
+            name = String.valueOf(counter++);
+        } 
+        writer.write(name);
+        writer.newLine();
+
+        for (Node n : w.getNodes()) {
+            writer.write(String.format(Locale.ENGLISH, "   %f   %f", n.getCoor().lon(), n.getCoor().lat()));
+            writer.newLine();
         }
-        for (Way w : inner) {
-            result.put(w, Boolean.FALSE);
-        }
-        return result;
+        writer.write("END");
+        writer.newLine();
+        return counter;
     }
 }
Index: src/poly/PolyImporter.java
===================================================================
--- src/poly/PolyImporter.java	(revision 34846)
+++ src/poly/PolyImporter.java	(working copy)
@@ -26,7 +26,6 @@
 import org.openstreetmap.josm.io.CachedFile;
 import org.openstreetmap.josm.io.IllegalDataException;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
-import org.xml.sax.SAXException;
 
 /**
  * Imports poly files.
@@ -38,8 +37,10 @@
         super(PolyType.FILE_FILTER);
     }
 
-    protected DataSet parseDataSet(final String source) throws IOException, SAXException, IllegalDataException {
-        return parseDataSet(new CachedFile(source).getInputStream(), NullProgressMonitor.INSTANCE);
+    protected DataSet parseDataSet(final String source) throws IOException, IllegalDataException {
+        try (CachedFile cf = new CachedFile(source)) {
+            return parseDataSet(cf.getInputStream(), NullProgressMonitor.INSTANCE);
+        }
     }
 
     @Override
@@ -48,8 +49,8 @@
             progressMonitor = NullProgressMonitor.INSTANCE;
         CheckParameterUtil.ensureParameterNotNull(in, "in");
 
+        progressMonitor.beginTask(tr("Reading polygon filter file..."), 3); 
         try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF8"))) {
-            progressMonitor.beginTask(tr("Reading polygon filter file..."), 2);
             progressMonitor.indeterminateSubTask(tr("Reading polygon filter file..."));
             List<Area> areas = loadPolygon(reader);
             progressMonitor.worked(1);
@@ -65,7 +66,7 @@
         }
     }
 
-    private List<Area> loadPolygon(BufferedReader reader) throws IllegalDataException, IOException {
+    private static List<Area> loadPolygon(BufferedReader reader) throws IllegalDataException, IOException {
         String name = reader.readLine();
         if (name == null || name.trim().length() == 0)
             throw new IllegalDataException(tr("The file must begin with a polygon name"));
@@ -75,48 +76,50 @@
         int fixedCoords = 0;
         while (true) {
             String line;
-            do {
-                line = reader.readLine();
-                if (line == null)
-                    throw new IllegalDataException("File ended prematurely without END record");
-                line = line.trim();
-            } while (line.length() == 0);
-
-            if (line.equals("END")) {
-                if (!parsingSection)
-                    break;
-                else {
+            line = reader.readLine();
+            if (line == null) 
+                break;
+            line = line.trim();
+            if (line.isEmpty()) {
+                // empty line is only allowed after a complete file (one or more rings belonging to one polygon)
+                if (parsingSection)
+                    throw new IllegalDataException(tr("Empty line in coordinate section"));
+                area = null;
+                parsingSection = false;
+                name = null;
+            } else if (line.equals("END")) {
+                if (!parsingSection) {
+                    area = null;
+                } else {
                     // an area has been read
                     if (area.getNodeCount() < 2)
                         throw new IllegalDataException(tr("There are less than 2 points in an area"));
                     areas.add(area);
-                    if (areas.size() == 1)
-                        areas.get(0).setPolygonName(name);
+                    area.setPolygonName(name);
                     parsingSection = false;
                 }
-            } else {
+            } else if (name == null) {
+                name = line;
+            } else if (line.length() > 0) {
                 if (!parsingSection) {
+                    if (line.indexOf(' ') >= 0) {
+                        boolean coordInsteadOfName = false;
+                        try {
+                            LatLon ll = parseCoordinate(line); 
+                            if (ll.isValid()) {
+                                coordInsteadOfName = true;
+                            }
+                        } catch (IllegalDataException e) {
+                            coordInsteadOfName = false;
+                        }
+                        if (coordInsteadOfName) {
+                            throw new IllegalDataException(tr("Found coordinates ''{0}'' instead of name", line));
+                        }
+                    }
                     area = new Area(line);
                     parsingSection = true;
                 } else {
-                    // reading area, parse coordinates
-                    String[] tokens = line.split("\\s+");
-                    double[] coords = new double[2];
-                    int tokenCount = 0;
-                    for (String token : tokens) {
-                        if (token.length() > 0) {
-                            if (tokenCount > 2)
-                                throw new IllegalDataException(tr("A polygon coordinate line must contain exactly 2 numbers"));
-                            try {
-                                coords[tokenCount++] = Double.parseDouble(token);
-                            } catch (NumberFormatException e) {
-                                throw new IllegalDataException(tr("Unable to parse {0} as a number", token));
-                            }
-                        }
-                    }
-                    if (tokenCount < 2)
-                        throw new IllegalDataException(tr("A polygon coordinate line must contain exactly 2 numbers"));
-                    LatLon coord = new LatLon(coords[1], coords[0]);
+                    LatLon coord = parseCoordinate(line);
                     if (!coord.isValid()) {
                         // fix small deviations
                         double lat = coord.lat();
@@ -125,12 +128,12 @@
                         if (lon > 180.0 && lon < 185.0) lon = 180.0;
                         if (lat < -90.0 && lat > -95.0) lat = -90.0;
                         if (lat > 90.0 && lat < 95.0) lat = 90.0;
+                        coord = new LatLon(lat, lon);
                         fixedCoords++;
-                        coord = new LatLon(lat, lon);
                         if (!coord.isValid())
                             throw new IllegalDataException(tr("Invalid coordinates were found: {0}, {1}", coord.lat(), coord.lon()));
                     }
-                    area.addNode(coord);
+                    area.addNode(parseCoordinate(line));
                 }
             }
         }
@@ -140,27 +143,70 @@
         return areas;
     }
 
-    private DataSet constructDataSet(List<Area> areas) {
+    /**
+     * Parse a line that should contain two double values which describe a latitude/longitude pair. 
+     * @param line the line to parse
+     * @return a new LatLon 
+     * @throws IllegalDataException in case of error
+     */
+    private static LatLon parseCoordinate(String line) throws IllegalDataException {
+        String[] tokens = line.split("\\s+");
+        double[] coords = new double[2];
+        int tokenCount = 0;
+        for (String token : tokens) {
+            if (token.length() > 0) {
+                if (tokenCount > 2)
+                    break;
+                try {
+                    coords[tokenCount++] = Double.parseDouble(token);
+                } catch (NumberFormatException e) {
+                    throw new IllegalDataException(tr("Unable to parse {0} as a number", token));
+                }
+            }
+        }
+        if (tokenCount != 2)
+            throw new IllegalDataException(tr("A polygon coordinate line must contain exactly 2 numbers"));
+        return new LatLon(coords[1], coords[0]);
+    }
+
+    private static DataSet constructDataSet(List<Area> areas) {
         DataSet ds = new DataSet();
         ds.setUploadPolicy(UploadPolicy.DISCOURAGED);
 
-        boolean foundInner = false;
+        
+        List<Area> curretSet = new ArrayList<>();
+        
         for (Area area : areas) {
-            if (!area.isOuter())
-                foundInner = true;
-            area.constructWay(ds);
+            if (!curretSet.isEmpty() && !area.polygonName.equals(curretSet.get(0).polygonName)) {
+                constructPrimitive(ds, curretSet);
+                curretSet.clear();
+            }
+            curretSet.add(area);
         }
+        if (!curretSet.isEmpty())
+            constructPrimitive(ds, curretSet);
 
-        if (foundInner) {
+        return ds;
+    }
+
+    private static void constructPrimitive(DataSet ds, List<Area> areas) {
+        boolean isMultipolygon = areas.size() > 1;
+        for (Area area : areas) {
+            area.constructWay(ds, isMultipolygon);
+        }
+
+        if (isMultipolygon) {
             Relation mp = new Relation();
             mp.put("type", "multipolygon");
+            Area outer = areas.get(0);
+            if (outer.polygonName != null) {
+                mp.put("name", outer.polygonName);
+            }
             for (Area area : areas) {
                 mp.addMember(new RelationMember(area.isOuter() ? "outer" : "inner", area.getWay()));
             }
             ds.addPrimitive(mp);
         }
-
-        return ds;
     }
 
     private static class Area {
@@ -177,11 +223,13 @@
                 this.name = this.name.substring(1);
             nodes = new ArrayList<>();
             way = null;
-            polygonName = null;
+            polygonName = "";
         }
 
         public void setPolygonName(String polygonName) {
-            this.polygonName = polygonName;
+            if (polygonName != null) {
+                this.polygonName = polygonName;
+            }
         }
 
         public void addNode(LatLon node) {
@@ -201,7 +249,7 @@
             return way;
         }
 
-        public void constructWay(DataSet ds) {
+        public void constructWay(DataSet ds, boolean isMultipolygon) {
             way = new Way();
             for (LatLon coord : nodes) {
                 Node node = new Node(coord);
@@ -209,8 +257,12 @@
                 way.addNode(node);
             }
             way.addNode(way.getNode(0));
-            if (polygonName != null)
-                way.put("name", polygonName);
+            if (isMultipolygon && name != null)
+                way.put("name", name);
+            else {
+                if (polygonName != null)
+                    way.put("name", polygonName);
+            }
             ds.addPrimitive(way);
         }
     }
Index: test/data/bremen-double-end.poly
===================================================================
--- test/data/bremen-double-end.poly	(nonexistent)
+++ test/data/bremen-double-end.poly	(working copy)
@@ -0,0 +1,346 @@
+none
+1
+   8.509653E+00   5.347469E+01
+   8.505762E+00   5.347047E+01
+   8.491577E+00   5.347200E+01
+   8.491656E+00   5.347549E+01
+   8.501178E+00   5.349139E+01
+   8.504218E+00   5.349441E+01
+   8.511296E+00   5.350007E+01
+   8.520366E+00   5.350472E+01
+   8.551284E+00   5.351639E+01
+   8.546220E+00   5.352130E+01
+   8.558515E+00   5.352774E+01
+   8.560064E+00   5.353183E+01
+   8.559076E+00   5.353636E+01
+   8.493468E+00   5.360245E+01
+   8.493498E+00   5.360351E+01
+   8.523178E+00   5.360744E+01
+   8.525435E+00   5.360457E+01
+   8.527368E+00   5.360641E+01
+   8.533663E+00   5.360514E+01
+   8.535422E+00   5.360772E+01
+   8.581374E+00   5.359864E+01
+   8.592972E+00   5.359386E+01
+   8.601275E+00   5.359622E+01
+   8.612262E+00   5.360352E+01
+   8.623225E+00   5.360602E+01
+   8.639793E+00   5.360518E+01
+   8.643798E+00   5.360448E+01
+   8.643166E+00   5.360603E+01
+   8.644382E+00   5.360731E+01
+   8.641847E+00   5.360889E+01
+   8.642658E+00   5.361052E+01
+   8.651924E+00   5.361063E+01
+   8.654038E+00   5.360895E+01
+   8.658592E+00   5.360983E+01
+   8.660066E+00   5.360779E+01
+   8.657775E+00   5.360268E+01
+   8.653304E+00   5.360224E+01
+   8.640072E+00   5.359466E+01
+   8.641363E+00   5.359292E+01
+   8.627218E+00   5.358420E+01
+   8.620693E+00   5.357695E+01
+   8.620204E+00   5.357422E+01
+   8.625819E+00   5.356784E+01
+   8.631574E+00   5.355619E+01
+   8.635984E+00   5.355430E+01
+   8.647419E+00   5.355588E+01
+   8.645195E+00   5.354940E+01
+   8.646030E+00   5.354024E+01
+   8.642684E+00   5.354082E+01
+   8.642332E+00   5.353640E+01
+   8.639048E+00   5.353445E+01
+   8.639099E+00   5.353337E+01
+   8.640124E+00   5.352569E+01
+   8.644103E+00   5.352311E+01
+   8.646059E+00   5.351939E+01
+   8.649762E+00   5.352007E+01
+   8.652930E+00   5.351626E+01
+   8.649244E+00   5.351386E+01
+   8.651507E+00   5.351032E+01
+   8.640633E+00   5.350679E+01
+   8.637674E+00   5.350512E+01
+   8.638345E+00   5.350340E+01
+   8.636614E+00   5.350220E+01
+   8.629345E+00   5.350097E+01
+   8.628816E+00   5.349916E+01
+   8.630505E+00   5.349675E+01
+   8.629601E+00   5.349504E+01
+   8.627630E+00   5.349518E+01
+   8.626241E+00   5.349289E+01
+   8.624468E+00   5.349323E+01
+   8.619703E+00   5.349000E+01
+   8.610639E+00   5.348680E+01
+   8.604164E+00   5.348648E+01
+   8.603295E+00   5.348379E+01
+   8.597157E+00   5.348506E+01
+   8.591864E+00   5.348421E+01
+   8.584140E+00   5.348616E+01
+   8.578344E+00   5.348486E+01
+   8.575051E+00   5.348586E+01
+   8.573728E+00   5.348781E+01
+   8.539527E+00   5.347957E+01
+   8.528859E+00   5.347938E+01
+   8.517022E+00   5.347260E+01
+   8.514411E+00   5.347464E+01
+   8.509653E+00   5.347469E+01
+END
+END
+2
+   8.615320E+00   5.319451E+01
+   8.611878E+00   5.319620E+01
+   8.613360E+00   5.319747E+01
+   8.617090E+00   5.319582E+01
+   8.616084E+00   5.319474E+01
+   8.621347E+00   5.319577E+01
+   8.621455E+00   5.319779E+01
+   8.628186E+00   5.319891E+01
+   8.631454E+00   5.319637E+01
+   8.634298E+00   5.319689E+01
+   8.640220E+00   5.319466E+01
+   8.638992E+00   5.319207E+01
+   8.643234E+00   5.319003E+01
+   8.654726E+00   5.318801E+01
+   8.656097E+00   5.318630E+01
+   8.653511E+00   5.318502E+01
+   8.658608E+00   5.318215E+01
+   8.659425E+00   5.317822E+01
+   8.662827E+00   5.317888E+01
+   8.665359E+00   5.317716E+01
+   8.669937E+00   5.317788E+01
+   8.671074E+00   5.317964E+01
+   8.674892E+00   5.317946E+01
+   8.676175E+00   5.317598E+01
+   8.678430E+00   5.317658E+01
+   8.677812E+00   5.317772E+01
+   8.679439E+00   5.317872E+01
+   8.687234E+00   5.317970E+01
+   8.691238E+00   5.318203E+01
+   8.696560E+00   5.318333E+01
+   8.699443E+00   5.318614E+01
+   8.703409E+00   5.318151E+01
+   8.701904E+00   5.317965E+01
+   8.702337E+00   5.317844E+01
+   8.705491E+00   5.317667E+01
+   8.709726E+00   5.317874E+01
+   8.709577E+00   5.318065E+01
+   8.712246E+00   5.318135E+01
+   8.714161E+00   5.318396E+01
+   8.729187E+00   5.318128E+01
+   8.732554E+00   5.317501E+01
+   8.737198E+00   5.317394E+01
+   8.739386E+00   5.317163E+01
+   8.743869E+00   5.317217E+01
+   8.744135E+00   5.317095E+01
+   8.741523E+00   5.316645E+01
+   8.741885E+00   5.316467E+01
+   8.748036E+00   5.316664E+01
+   8.755166E+00   5.316418E+01
+   8.761751E+00   5.316588E+01
+   8.771124E+00   5.316009E+01
+   8.775121E+00   5.316210E+01
+   8.782127E+00   5.316414E+01
+   8.786732E+00   5.316372E+01
+   8.790699E+00   5.316394E+01
+   8.792599E+00   5.316377E+01
+   8.797220E+00   5.316430E+01
+   8.798689E+00   5.316347E+01
+   8.814552E+00   5.316465E+01
+   8.821277E+00   5.316418E+01
+   8.829275E+00   5.316490E+01
+   8.830586E+00   5.316307E+01
+   8.831747E+00   5.316024E+01
+   8.840334E+00   5.315818E+01
+   8.845287E+00   5.314806E+01
+   8.853117E+00   5.314419E+01
+   8.858228E+00   5.314054E+01
+   8.861722E+00   5.313843E+01
+   8.862411E+00   5.313726E+01
+   8.863432E+00   5.313216E+01
+   8.874316E+00   5.313412E+01
+   8.886153E+00   5.313363E+01
+   8.897505E+00   5.313471E+01
+   8.903128E+00   5.313923E+01
+   8.907142E+00   5.313793E+01
+   8.909629E+00   5.313346E+01
+   8.912146E+00   5.313328E+01
+   8.916077E+00   5.313719E+01
+   8.915927E+00   5.313985E+01
+   8.921400E+00   5.314221E+01
+   8.920051E+00   5.314412E+01
+   8.920491E+00   5.314503E+01
+   8.930619E+00   5.314832E+01
+   8.936901E+00   5.315175E+01
+   8.939893E+00   5.315291E+01
+   8.945054E+00   5.315276E+01
+   8.956958E+00   5.314777E+01
+   8.960158E+00   5.314312E+01
+   8.971611E+00   5.313416E+01
+   8.979324E+00   5.313148E+01
+   8.983984E+00   5.312562E+01
+   8.978232E+00   5.312289E+01
+   8.966957E+00   5.312127E+01
+   8.962749E+00   5.311908E+01
+   8.948558E+00   5.311619E+01
+   8.958218E+00   5.311157E+01
+   8.961763E+00   5.310648E+01
+   8.963470E+00   5.310114E+01
+   8.969005E+00   5.310134E+01
+   8.978750E+00   5.309913E+01
+   8.982155E+00   5.309708E+01
+   8.989558E+00   5.309878E+01
+   8.991268E+00   5.309666E+01
+   8.984503E+00   5.309262E+01
+   8.965782E+00   5.308906E+01
+   8.962445E+00   5.308526E+01
+   8.966571E+00   5.308284E+01
+   8.964914E+00   5.308017E+01
+   8.965461E+00   5.307661E+01
+   8.964578E+00   5.307212E+01
+   8.965471E+00   5.307145E+01
+   8.964611E+00   5.307028E+01
+   8.966550E+00   5.306254E+01
+   8.964580E+00   5.306036E+01
+   8.966615E+00   5.305825E+01
+   8.970870E+00   5.305670E+01
+   8.973879E+00   5.305194E+01
+   8.976998E+00   5.305204E+01
+   8.980996E+00   5.304654E+01
+   8.971601E+00   5.303863E+01
+   8.966901E+00   5.303607E+01
+   8.963457E+00   5.303639E+01
+   8.952458E+00   5.303282E+01
+   8.951431E+00   5.303079E+01
+   8.946744E+00   5.303012E+01
+   8.945654E+00   5.302762E+01
+   8.947041E+00   5.302597E+01
+   8.946119E+00   5.302427E+01
+   8.938848E+00   5.302414E+01
+   8.935836E+00   5.301299E+01
+   8.929521E+00   5.301324E+01
+   8.928204E+00   5.301220E+01
+   8.922525E+00   5.301383E+01
+   8.921712E+00   5.301149E+01
+   8.917827E+00   5.301243E+01
+   8.915746E+00   5.301034E+01
+   8.896934E+00   5.301222E+01
+   8.892659E+00   5.301356E+01
+   8.883590E+00   5.302295E+01
+   8.866418E+00   5.303223E+01
+   8.865539E+00   5.302817E+01
+   8.869883E+00   5.302480E+01
+   8.867059E+00   5.302117E+01
+   8.855103E+00   5.302045E+01
+   8.852819E+00   5.301913E+01
+   8.850924E+00   5.301616E+01
+   8.848968E+00   5.301588E+01
+   8.847454E+00   5.301602E+01
+   8.846577E+00   5.301778E+01
+   8.849042E+00   5.302341E+01
+   8.844866E+00   5.302301E+01
+   8.844202E+00   5.302154E+01
+   8.840843E+00   5.302033E+01
+   8.838031E+00   5.301747E+01
+   8.830788E+00   5.302052E+01
+   8.822030E+00   5.302016E+01
+   8.817499E+00   5.302183E+01
+   8.815214E+00   5.302582E+01
+   8.810032E+00   5.302825E+01
+   8.808574E+00   5.303036E+01
+   8.785725E+00   5.303773E+01
+   8.782499E+00   5.303719E+01
+   8.777443E+00   5.303883E+01
+   8.775875E+00   5.304264E+01
+   8.772064E+00   5.304466E+01
+   8.770096E+00   5.305205E+01
+   8.762022E+00   5.304996E+01
+   8.764634E+00   5.304670E+01
+   8.758404E+00   5.304314E+01
+   8.756541E+00   5.304336E+01
+   8.756123E+00   5.304252E+01
+   8.757962E+00   5.304095E+01
+   8.756901E+00   5.303846E+01
+   8.751439E+00   5.303726E+01
+   8.743301E+00   5.303993E+01
+   8.741748E+00   5.303869E+01
+   8.740454E+00   5.303905E+01
+   8.737982E+00   5.303663E+01
+   8.733200E+00   5.303650E+01
+   8.735485E+00   5.303505E+01
+   8.734242E+00   5.303297E+01
+   8.729968E+00   5.303335E+01
+   8.709331E+00   5.304517E+01
+   8.706123E+00   5.305247E+01
+   8.709702E+00   5.306855E+01
+   8.709194E+00   5.307210E+01
+   8.705708E+00   5.307561E+01
+   8.701124E+00   5.308043E+01
+   8.686927E+00   5.308522E+01
+   8.674488E+00   5.308554E+01
+   8.665954E+00   5.309124E+01
+   8.664211E+00   5.309584E+01
+   8.669353E+00   5.310219E+01
+   8.653751E+00   5.310839E+01
+   8.652751E+00   5.311112E+01
+   8.654288E+00   5.311552E+01
+   8.651881E+00   5.311567E+01
+   8.649707E+00   5.311733E+01
+   8.650273E+00   5.312153E+01
+   8.647819E+00   5.312468E+01
+   8.634341E+00   5.313348E+01
+   8.630098E+00   5.313799E+01
+   8.625879E+00   5.314537E+01
+   8.622735E+00   5.316278E+01
+   8.619494E+00   5.316638E+01
+   8.611348E+00   5.316970E+01
+   8.582453E+00   5.317270E+01
+   8.556976E+00   5.318067E+01
+   8.533636E+00   5.318623E+01
+   8.522611E+00   5.319183E+01
+   8.515308E+00   5.319723E+01
+   8.512254E+00   5.319624E+01
+   8.505858E+00   5.319947E+01
+   8.500976E+00   5.320528E+01
+   8.495432E+00   5.320903E+01
+   8.490537E+00   5.321665E+01
+   8.482431E+00   5.322288E+01
+   8.480959E+00   5.322676E+01
+   8.488865E+00   5.322891E+01
+   8.490168E+00   5.322740E+01
+   8.503920E+00   5.322966E+01
+   8.506858E+00   5.322843E+01
+   8.517307E+00   5.322909E+01
+   8.518743E+00   5.322673E+01
+   8.521242E+00   5.322672E+01
+   8.521073E+00   5.322349E+01
+   8.523079E+00   5.322355E+01
+   8.523496E+00   5.322194E+01
+   8.526415E+00   5.322205E+01
+   8.530420E+00   5.321658E+01
+   8.537112E+00   5.321534E+01
+   8.541184E+00   5.321616E+01
+   8.543892E+00   5.321398E+01
+   8.547045E+00   5.321377E+01
+   8.554182E+00   5.320877E+01
+   8.566145E+00   5.321435E+01
+   8.572005E+00   5.321167E+01
+   8.578437E+00   5.321813E+01
+   8.599362E+00   5.321342E+01
+   8.600150E+00   5.321098E+01
+   8.597396E+00   5.320713E+01
+   8.582182E+00   5.319914E+01
+   8.585757E+00   5.319609E+01
+   8.581361E+00   5.319330E+01
+   8.581800E+00   5.319125E+01
+   8.584542E+00   5.319106E+01
+   8.584954E+00   5.319017E+01
+   8.589129E+00   5.319038E+01
+   8.593007E+00   5.318786E+01
+   8.592324E+00   5.318661E+01
+   8.593501E+00   5.318500E+01
+   8.608214E+00   5.318922E+01
+   8.608342E+00   5.319322E+01
+   8.615320E+00   5.319451E+01
+END
+END
Index: test/data/holes.poly
===================================================================
--- test/data/holes.poly	(nonexistent)
+++ test/data/holes.poly	(working copy)
@@ -0,0 +1,90 @@
+holes
+o1
+  2.285156e+00  4.126465e+01
+  2.285156e+00  4.161621e+01
+  1.757813e-01  4.161621e+01
+  1.757813e-01  4.258301e+01
+  -3.515625e-01  4.258301e+01
+  -3.515625e-01  4.267090e+01
+  -1.142578e+00  4.267090e+01
+  -1.142578e+00  4.293457e+01
+  -1.494141e+00  4.293457e+01
+  -1.494141e+00  4.302246e+01
+  -6.328125e+00  4.302246e+01
+  -6.328125e+00  4.521973e+01
+  -6.152344e+00  4.521973e+01
+  -6.152344e+00  4.671387e+01
+  -6.328125e+00  4.671387e+01
+  -6.328125e+00  5.084473e+01
+  -2.724609e+00  5.084473e+01
+  -2.724609e+00  5.075684e+01
+  -7.910156e-01  5.075684e+01
+  -7.910156e-01  5.137207e+01
+  2.988281e+00  5.137207e+01
+  2.988281e+00  5.084473e+01
+  3.251953e+00  5.084473e+01
+  3.251953e+00  5.093262e+01
+  4.394531e+00  5.093262e+01
+  4.394531e+00  5.040527e+01
+  5.449219e+00  5.040527e+01
+  5.449219e+00  4.979004e+01
+  6.591797e+00  4.979004e+01
+  6.591797e+00  4.952637e+01
+  7.382813e+00  4.952637e+01
+  7.382813e+00  4.935059e+01
+  8.349609e+00  4.935059e+01
+  8.349609e+00  4.873535e+01
+  8.437500e+00  4.873535e+01
+  8.437500e+00  4.864746e+01
+  8.085938e+00  4.864746e+01
+  8.085938e+00  4.855957e+01
+  7.998047e+00  4.855957e+01
+  7.998047e+00  4.829590e+01
+  7.822266e+00  4.829590e+01
+  7.822266e+00  4.803223e+01
+  9.843750e+00  4.803223e+01
+  9.843750e+00  4.662598e+01
+  7.382813e+00  4.662598e+01
+  7.382813e+00  4.645020e+01
+  7.207031e+00  4.645020e+01
+  7.207031e+00  4.592285e+01
+  9.843750e+00  4.592285e+01
+  9.843750e+00  4.442871e+01
+  9.404297e+00  4.442871e+01
+  9.404297e+00  4.337402e+01
+  9.843750e+00  4.337402e+01
+  9.843750e+00  4.126465e+01
+  8.261719e+00  4.126465e+01
+  8.261719e+00  4.196777e+01
+  7.910156e+00  4.196777e+01
+  7.910156e+00  4.179199e+01
+  6.064453e+00  4.179199e+01
+  6.064453e+00  4.144043e+01
+  4.833984e+00  4.144043e+01
+  4.833984e+00  4.258301e+01
+  4.570313e+00  4.258301e+01
+  4.570313e+00  4.126465e+01
+  2.285156e+00  4.126465e+01
+END
+!inner1
+  4.394531e+00  5.014160e+01
+  4.394531e+00  5.022949e+01
+  4.306641e+00  5.022949e+01
+  4.306641e+00  5.014160e+01
+  4.394531e+00  5.014160e+01
+END
+!inner2
+  -4.394531e+00  4.873535e+01
+  -4.394531e+00  4.882324e+01
+  -4.746094e+00  4.882324e+01
+  -4.746094e+00  4.873535e+01
+  -4.394531e+00  4.873535e+01
+END
+!inner3
+  -2.021484e+00  4.521973e+01
+  -2.021484e+00  4.601074e+01
+  -2.109375e+00  4.601074e+01
+  -2.109375e+00  4.521973e+01
+  -2.021484e+00  4.521973e+01
+END
+END
Index: test/data/multi-concat.poly
===================================================================
--- test/data/multi-concat.poly	(nonexistent)
+++ test/data/multi-concat.poly	(working copy)
@@ -0,0 +1,60 @@
+first
+1
+   109.116270   -19.754965
+   134.560899   -8.865515
+   155.225021   -11.445777
+   178.973341   -34.767630
+   178.819131   -47.479347
+   122.378319   -49.422367
+   103.873134   -24.186817
+   109.116270   -19.754965
+END
+END
+
+second
+1
+   -27.000000   75.000000
+   -32.733610   39.048420
+   -17.137840   31.093990
+   -9.611205   35.985870
+   -5.653329   35.894580
+   -5.393482   35.987210
+   -5.085261   36.046190
+   3.541102   37.759810
+   11.600370   37.778150
+   11.600370   34.000000
+   35.408480   33.992890
+   35.408480   35.627900
+   36.236940   35.806410
+   36.768620   36.195300
+   36.754060   36.570560
+   39.193940   36.611490
+   42.398570   37.054530
+   44.328630   36.914900
+   44.996930   37.199370
+   45.000000   75.000000
+   -27.000000   75.000000
+END
+!2
+   9.890545E+00   4.822680E+01
+   9.892534E+00   4.752921E+01
+   1.130254E+01   4.753324E+01
+   1.127072E+01   4.827977E+01
+   9.890545E+00   4.822680E+01
+END 
+END
+
+third
+1
+   -179.915000   -60.347030
+   -23.244010   -61.792990
+   -23.834280   -16.230710
+   -45.475220   10.055700
+   -74.969470   13.604260
+   -80.765080   3.298111
+   -95.342020   3.287621
+   -179.999900   -4.938220
+   -179.999900   -60.347030
+   -179.915000   -60.347030
+END
+END
Index: test/data/name-missing.poly
===================================================================
--- test/data/name-missing.poly	(nonexistent)
+++ test/data/name-missing.poly	(working copy)
@@ -0,0 +1,23 @@
+multi-1
+1
+   109.116270   -19.754965
+   134.560899   -8.865515
+   155.225021   -11.445777
+   178.973341   -34.767630
+   178.819131   -47.479347
+   122.378319   -49.422367
+   103.873134   -24.186817
+   109.116270   -19.754965
+END
+   -179.915000   -60.347030
+   -23.244010   -61.792990
+   -23.834280   -16.230710
+   -45.475220   10.055700
+   -74.969470   13.604260
+   -80.765080   3.298111
+   -95.342020   3.287621
+   -179.999900   -4.938220
+   -179.999900   -60.347030
+   -179.915000   -60.347030
+END
+END
Index: test/data/simple.poly
===================================================================
--- test/data/simple.poly	(nonexistent)
+++ test/data/simple.poly	(working copy)
@@ -0,0 +1,9 @@
+simple
+1
+   9.890545E+00   4.822680E+01
+   9.892534E+00   4.752921E+01
+   1.130254E+01   4.753324E+01
+   1.127072E+01   4.827977E+01
+   9.890545E+00   4.822680E+01
+END
+END
Index: test/data/splitter.poly
===================================================================
--- test/data/splitter.poly	(nonexistent)
+++ test/data/splitter.poly	(working copy)
@@ -0,0 +1,19 @@
+area
+1
+  7.382813  51.284180
+  7.382813  51.679688
+  6.635742  51.679688
+  6.635742  52.690430
+  6.416016  52.690430
+  6.416016  54.184570
+  8.920898  54.184570
+  8.920898  54.140625
+  10.502930  54.140625
+  10.502930  53.964844
+  11.645508  53.964844
+  11.645508  51.459961
+  10.546875  51.459961
+  10.546875  51.284180
+  7.382813  51.284180
+END
+END
Index: test/data/u.poly
===================================================================
--- test/data/u.poly	(nonexistent)
+++ test/data/u.poly	(working copy)
@@ -0,0 +1,54 @@
+second
+1
+   -27.000000   75.000000
+   -32.733610   39.048420
+   -17.137840   31.093990
+   -9.611205   35.985870
+   -5.653329   35.894580
+   -5.393482   35.987210
+   -5.085261   36.046190
+   3.541102   37.759810
+   11.600370   37.778150
+   11.600370   34.000000
+   35.408480   33.992890
+   35.408480   35.627900
+   36.236940   35.806410
+   36.768620   36.195300
+   36.754060   36.570560
+   39.193940   36.611490
+   42.398570   37.054530
+   44.328630   36.914900
+   44.996930   37.199370
+   45.000000   75.000000
+   -27.000000   75.000000
+END
+!2
+   9.890545   48.226800
+   9.892534   47.529210
+   11.302540   47.533240
+   11.270720   48.279770
+   9.890545   48.226800
+END
+third
+   -179.915000   -60.347030
+   -23.244010   -61.792990
+   -23.834280   -16.230710
+   -45.475220   10.055700
+   -74.969470   13.604260
+   -80.765080   3.298111
+   -95.342020   3.287621
+   -179.999900   -4.938220
+   -179.999900   -60.347030
+   -179.915000   -60.347030
+END
+first
+   109.116270   -19.754965
+   134.560899   -8.865515
+   155.225021   -11.445777
+   178.973341   -34.767630
+   178.819131   -47.479347
+   122.378319   -49.422367
+   103.873134   -24.186817
+   109.116270   -19.754965
+END
+END
Index: test/unit/poly/PolyImporterTest.java
===================================================================
--- test/unit/poly/PolyImporterTest.java	(nonexistent)
+++ test/unit/poly/PolyImporterTest.java	(working copy)
@@ -0,0 +1,97 @@
+// License: GPL. For details, see LICENSE file.
+package poly;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.openstreetmap.josm.TestUtils;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
+
+/**
+ * Unit tests for {@link O5mImporter}.
+ */
+public class PolyImporterTest {
+
+    /**
+     * Setup test.
+     */
+    @Rule
+    public JOSMTestRules rules = new JOSMTestRules().preferences();
+
+    /**
+     * @throws Exception if an error occurs
+     */
+    @Test
+    public void testSimple() throws Exception {
+        DataSet ds = new PolyImporter().parseDataSet(TestUtils.getTestDataRoot() + "/simple.poly");
+        assertNotNull(ds);
+        assertEquals(4, ds.getNodes().size());
+        assertEquals(1, ds.getWays().size());
+        assertEquals(0, ds.getRelations().size());
+    }
+
+    /**
+     * File with human friendly coordinate format
+     * @throws Exception if an error occurs
+     */
+    @Test
+    public void testSimple2() throws Exception {
+        DataSet ds = new PolyImporter().parseDataSet(TestUtils.getTestDataRoot() + "/splitter.poly");
+        assertNotNull(ds);
+        assertEquals(14, ds.getNodes().size());
+        assertEquals(1, ds.getWays().size());
+        assertEquals(0, ds.getRelations().size());
+    }
+
+    /**
+     * @throws Exception if an error occurs
+     */
+    @Test
+    public void testHoles() throws Exception {
+        DataSet ds = new PolyImporter().parseDataSet(TestUtils.getTestDataRoot() + "/holes.poly");
+        assertNotNull(ds);
+        assertEquals(76, ds.getNodes().size());
+        assertEquals(4, ds.getWays().size());
+        assertEquals(1, ds.getRelations().size());
+    }
+
+    /**
+     * @throws Exception if an error occurs
+     */
+    @Test
+    public void testDoubleEnd() throws Exception {
+        DataSet ds = new PolyImporter().parseDataSet(TestUtils.getTestDataRoot() + "/bremen-double-end.poly");
+        assertNotNull(ds);
+        assertEquals(337, ds.getNodes().size());
+        assertEquals(2, ds.getWays().size());
+        assertEquals(1, ds.getRelations().size());
+    }
+
+    /**
+     * @throws Exception if an error occurs
+     */
+    @Test
+    public void testMultipleFile() throws Exception {
+        DataSet ds = new PolyImporter().parseDataSet(TestUtils.getTestDataRoot() + "/multi-concat.poly");
+        assertNotNull(ds);
+        assertEquals(40, ds.getNodes().size());
+        assertEquals(4, ds.getWays().size());
+        assertEquals(1, ds.getRelations().size());
+    }
+
+    /**
+     * Should throw an IllegalDataException
+     * @throws Exception if an error occurs
+     */
+    @Test (expected = IllegalDataException.class)
+    public void testNameMissing() throws Exception {
+        DataSet ds = new PolyImporter().parseDataSet(TestUtils.getTestDataRoot() + "/name-missing.poly");
+        assertNull(ds);
+    }
+
+}
