Index: applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/OdConstants.java
===================================================================
--- applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/OdConstants.java	(revision 28143)
+++ applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/OdConstants.java	(revision 28152)
@@ -36,4 +36,5 @@
 	public static final String UTF8 = "UTF-8";
 	public static final String ISO8859_15 = "ISO-8859-15";
+	public static final String CP850 = "Cp850";
 	public static final String CP1252 = "Cp1252";
 	public static final String MAC_ROMAN = "MacRoman";
Index: applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/fr/FrenchShpHandler.java
===================================================================
--- applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/fr/FrenchShpHandler.java	(revision 28143)
+++ applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/fr/FrenchShpHandler.java	(revision 28152)
@@ -17,6 +17,10 @@
 
 import org.geotools.referencing.CRS;
+import org.geotools.referencing.operation.projection.LambertConformal2SP;
+import org.geotools.referencing.operation.projection.MapProjection.AbstractProvider;
 import org.opengis.referencing.FactoryException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.operation.MathTransform;
 import org.openstreetmap.josm.plugins.opendata.core.io.geographic.DefaultShpHandler;
@@ -34,7 +38,22 @@
 		} else if (sourceCRS.getName().getCode().equalsIgnoreCase("RGFG95_UTM_Zone_22N")) {
 			return CRS.findMathTransform(CRS.decode("EPSG:2972"), targetCRS, lenient);
-		} else {
-			return super.findMathTransform(sourceCRS, targetCRS, lenient);
+		} else if (sourceCRS.getName().getCode().equalsIgnoreCase("Lambert I Nord")) {
+			if (sourceCRS instanceof ProjectedCRS) {
+				GeodeticDatum datum = ((ProjectedCRS) sourceCRS).getDatum();
+				if (datum.getPrimeMeridian().getGreenwichLongitude() > 0.0 && ((ProjectedCRS) sourceCRS).getConversionFromBase().getMathTransform() instanceof LambertConformal2SP) {
+					LambertConformal2SP lambert = (LambertConformal2SP) ((ProjectedCRS) sourceCRS).getConversionFromBase().getMathTransform();
+					Double falseNorthing = get(lambert.getParameterValues(), AbstractProvider.FALSE_NORTHING);
+					Double centralmeridian = get(lambert.getParameterValues(), AbstractProvider.CENTRAL_MERIDIAN);
+					if (centralmeridian.equals(0.0)) {
+						if (falseNorthing.equals(200000.0)) {
+							return CRS.findMathTransform(CRS.decode("EPSG:27561"), targetCRS, lenient);
+						} else if (falseNorthing.equals(1200000.0)) {
+							return CRS.findMathTransform(CRS.decode("EPSG:27571"), targetCRS, lenient);
+						}
+					}
+				}
+			}
 		}
+		return super.findMathTransform(sourceCRS, targetCRS, lenient);
 	}
 }
Index: applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/NetworkReader.java
===================================================================
--- applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/NetworkReader.java	(revision 28143)
+++ applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/NetworkReader.java	(revision 28152)
@@ -125,11 +125,10 @@
 	public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
         InputStream in = null;
-        progressMonitor.beginTask(tr("Contacting Server...", 10));
+        ProgressMonitor instance = null;
         try {
-            in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
+        	in = getInputStreamRaw(url, progressMonitor);
             if (in == null)
                 return null;
             progressMonitor.subTask(tr("Downloading data..."));
-            ProgressMonitor instance = progressMonitor.createSubTaskMonitor(1, false);
             if (readerClass == null) {
             	readerClass = findReaderByAttachment();
@@ -146,4 +145,5 @@
             	filename = url.substring(url.lastIndexOf('/')+1);
             }
+            instance = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
             if (readerClass.equals(ZipReader.class)) {
             	ZipReader zipReader = new ZipReader(in, handler);
@@ -177,4 +177,7 @@
             throw new OsmTransferException(e);
         } finally {
+        	if (instance != null) {
+        		instance.finishTask();
+        	}
             progressMonitor.finishTask();
             try {
Index: applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/ZipReader.java
===================================================================
--- applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/ZipReader.java	(revision 28143)
+++ applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/ZipReader.java	(revision 28152)
@@ -16,4 +16,6 @@
 package org.openstreetmap.josm.plugins.opendata.core.io.archive;
 
+import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.io.File;
 import java.io.FileInputStream;
@@ -89,5 +91,5 @@
 	}
 
-	public DataSet parseDoc(ProgressMonitor instance) throws IOException, XMLStreamException, FactoryConfigurationError, JAXBException  {
+	public DataSet parseDoc(ProgressMonitor progressMonitor) throws IOException, XMLStreamException, FactoryConfigurationError, JAXBException  {
 		
 	    final File temp = createTempDir();
@@ -95,4 +97,7 @@
 	    
 	    try {
+	    	if (progressMonitor != null) {
+	    		progressMonitor.beginTask(tr("Reading Zip file..."));
+	    	}
 			ZipEntry entry;
 			while ((entry = zis.getNextEntry()) != null) {
@@ -150,5 +155,5 @@
 			
 			if (candidates.size() > 1) {
-				CandidateChooser dialog = (CandidateChooser) new CandidateChooser(instance.getWindowParent(), candidates).showDialog();
+				CandidateChooser dialog = (CandidateChooser) new CandidateChooser(progressMonitor.getWindowParent(), candidates).showDialog();
 				if (dialog.getValue() != 1) {
 					return null; // User clicked Cancel
@@ -162,4 +167,8 @@
 				DataSet from = null;
 				FileInputStream in = new FileInputStream(file);
+				ProgressMonitor instance = null;
+				if (progressMonitor != null) {
+					instance = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
+				}
 				if (file.getName().toLowerCase().endsWith(CSV_EXT)) {
 					from = CsvReader.parseDataSet(in, handler, instance);
@@ -189,5 +198,8 @@
 				}
 				if (from != null) {
-					ds.mergeFrom(from);
+					if (progressMonitor != null) {
+						instance.finishTask();
+					}
+					ds = from;
 				}
 			}
@@ -196,4 +208,7 @@
 	    } finally {
 	    	deleteDir(temp);
+	    	if (progressMonitor != null) {
+	    		progressMonitor.finishTask();
+	    	}
 	    }
 		
Index: applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/DefaultShpHandler.java
===================================================================
--- applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/DefaultShpHandler.java	(revision 28143)
+++ applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/DefaultShpHandler.java	(revision 28152)
@@ -16,6 +16,8 @@
 package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
 
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 import org.geotools.referencing.CRS;
@@ -34,4 +36,6 @@
 import org.opengis.referencing.operation.MathTransform;
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.projection.AbstractProjection;
 import org.openstreetmap.josm.data.projection.Ellipsoid;
@@ -54,5 +58,5 @@
 	}
 	
-	private static final Double get(ParameterValueGroup values, ParameterDescriptor desc) {
+	protected static final Double get(ParameterValueGroup values, ParameterDescriptor desc) {
 		return (Double) values.parameter(desc.getName().getCode()).getValue();
 	}
@@ -66,6 +70,8 @@
 	}
 	
+	private boolean useNodeMap = true;
 	private boolean checkNodeProximity = false;
 	private boolean preferMultipolygonToSimpleWay = false;
+	private Charset dbfCharset = null;
 
 	@Override
@@ -151,3 +157,28 @@
 		checkNodeProximity = check;
 	}
+
+	@Override
+	public void setUseNodeMap(boolean use) {
+		useNodeMap = use;
+	}
+
+	@Override
+	public boolean useNodeMap() {
+		return useNodeMap;
+	}
+
+	@Override
+	public void notifyFeatureParsed(Object feature, DataSet result, Set<OsmPrimitive> featurePrimitives) {
+		// To be overriden by modules handlers
+	}
+
+	@Override
+	public void setDbfCharset(Charset charset) {
+		dbfCharset = charset;
+	}
+	
+	@Override
+	public Charset getDbfCharset() {
+		return dbfCharset;
+	}
 }
Index: applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpCrsException.java
===================================================================
--- applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpCrsException.java	(revision 28152)
+++ applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpCrsException.java	(revision 28152)
@@ -0,0 +1,35 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+public class ShpCrsException extends Exception {
+
+	public ShpCrsException() {
+		super();
+	}
+
+	public ShpCrsException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	public ShpCrsException(String message) {
+		super(message);
+	}
+
+	public ShpCrsException(Throwable cause) {
+		super(cause);
+	}
+}
Index: applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpHandler.java
===================================================================
--- applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpHandler.java	(revision 28143)
+++ applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpHandler.java	(revision 28152)
@@ -16,7 +16,12 @@
 package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
 
+import java.nio.charset.Charset;
+import java.util.Set;
+
 import org.opengis.referencing.FactoryException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.operation.MathTransform;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
 
 public interface ShpHandler {
@@ -31,3 +36,13 @@
 	
 	public boolean checkNodeProximity();
+	
+	public void setUseNodeMap(boolean use);
+	
+	public boolean useNodeMap();
+
+	public void notifyFeatureParsed(Object feature, DataSet result, Set<OsmPrimitive> featurePrimitives);
+
+	public void setDbfCharset(Charset charset);
+	
+	public Charset getDbfCharset();
 }
Index: applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpMathTransformException.java
===================================================================
--- applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpMathTransformException.java	(revision 28152)
+++ applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpMathTransformException.java	(revision 28152)
@@ -0,0 +1,35 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+public class ShpMathTransformException extends Exception {
+
+	public ShpMathTransformException() {
+		super();
+	}
+
+	public ShpMathTransformException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	public ShpMathTransformException(String message) {
+		super(message);
+	}
+
+	public ShpMathTransformException(Throwable cause) {
+		super(cause);
+	}
+}
Index: applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpReader.java
===================================================================
--- applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpReader.java	(revision 28143)
+++ applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpReader.java	(revision 28152)
@@ -25,6 +25,8 @@
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import javax.swing.Icon;
@@ -32,7 +34,7 @@
 import javax.swing.JOptionPane;
 
+import org.geotools.data.DataStore;
 import org.geotools.data.FeatureSource;
-import org.geotools.data.FileDataStore;
-import org.geotools.data.FileDataStoreFinder;
+import org.geotools.data.shapefile.ShapefileDataStoreFactory;
 import org.geotools.factory.Hints;
 import org.geotools.feature.FeatureCollection;
@@ -61,5 +63,5 @@
 import org.opengis.referencing.operation.TransformException;
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.corrector.UserCancelException;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -89,7 +91,8 @@
 	private final Map<String, Node> nodes;
 
-	private DataSet result;
 	private CoordinateReferenceSystem crs;
 	private MathTransform transform;
+	
+	private final Set<OsmPrimitive> featurePrimitives = new HashSet<OsmPrimitive>();
 	
 	public ShpReader(ShpHandler handler) throws NoSuchAuthorityCodeException, FactoryException {
@@ -162,12 +165,149 @@
 		return result;
 	}
+	
+	private void findCrsAndMathTransform(CoordinateReferenceSystem coordinateReferenceSystem, Component parent) throws FactoryException, UserCancelException, ShpMathTransformException {
+		crs = coordinateReferenceSystem;
+		try {
+			transform = CRS.findMathTransform(crs, wgs84);
+		} catch (OperationNotFoundException e) {
+			System.out.println(crs.getName()+": "+e.getMessage()); // Bursa wolf parameters required.
+			
+			List<CoordinateReferenceSystem> candidates = new ArrayList<CoordinateReferenceSystem>();
+			
+			// Find matching CRS with Bursa Wolf parameters in EPSG database
+			for (String code : CRS.getAuthorityFactory(false).getAuthorityCodes(ProjectedCRS.class)) {
+				CoordinateReferenceSystem candidate = CRS.decode(code);
+				if (candidate instanceof AbstractCRS && crs instanceof AbstractIdentifiedObject) {
+					
+					Hints.putSystemDefault(Hints.COMPARISON_TOLERANCE, 
+							Main.pref.getDouble(PREF_CRS_COMPARISON_TOLERANCE, DEFAULT_CRS_COMPARISON_TOLERANCE));
+					if (((AbstractCRS)candidate).equals((AbstractIdentifiedObject)crs, false)) {
+						System.out.println("Found a potential CRS: "+candidate.getName());
+						candidates.add(candidate);
+					} else if (Main.pref.getBoolean(PREF_CRS_COMPARISON_DEBUG, false)) {
+						compareDebug(crs, candidate);
+					}
+					Hints.removeSystemDefault(Hints.COMPARISON_TOLERANCE);
+				}
+			}
+			
+			if (candidates.size() > 1) {
+				System.err.println("Found several potential CRS.");//TODO: ask user which one to use
+			}
+			
+			if (candidates.size() > 0) {
+				CoordinateReferenceSystem newCRS = candidates.get(0);
+				try {
+					transform = CRS.findMathTransform(newCRS, wgs84, false);
+				} catch (OperationNotFoundException ex) {
+					System.err.println(newCRS.getName()+": "+e.getMessage());
+				}
+			}
+			
+			if (transform == null) {
+				if (handler != null) {
+					// ask handler if it can provide a math transform
+					transform = handler.findMathTransform(crs, wgs84, false);
+				}
+				if (transform == null) {
+					// ask user before trying lenient method
+					if (warnLenientMethod(parent, crs)) {
+						// User canceled
+						throw new UserCancelException();
+					}
+					System.out.println("Searching for a lenient math transform.");
+					transform = CRS.findMathTransform(crs, wgs84, true);
+				}
+			}
+		}
+		if (transform == null) {
+			throw new ShpMathTransformException("Unable to find math transform !");
+		}
+	}
+	
+	private void parseFeature(Feature feature, Component parent) 
+			throws UserCancelException, ShpMathTransformException, FactoryException, ShpCrsException, MismatchedDimensionException, TransformException {
+		featurePrimitives.clear();
+		GeometryAttribute geometry = feature.getDefaultGeometryProperty();
+		if (geometry != null) {
+
+			GeometryDescriptor desc = geometry.getDescriptor();
+			
+			if (crs == null && desc != null && desc.getCoordinateReferenceSystem() != null) {
+				findCrsAndMathTransform(desc.getCoordinateReferenceSystem(), parent);
+			} else if (crs == null) {
+				throw new ShpCrsException("Unable to detect CRS !");
+			}
+			
+			OsmPrimitive primitive = null;
+			
+			if (geometry.getValue() instanceof Point) {
+				primitive = createOrGetNode((Point) geometry.getValue());
+				
+			} else if (geometry.getValue() instanceof GeometryCollection) { // Deals with both MultiLineString and MultiPolygon
+				GeometryCollection mp = (GeometryCollection) geometry.getValue();
+				int nGeometries = mp.getNumGeometries(); 
+				if (nGeometries < 1) {
+					System.err.println("Error: empty geometry collection found");
+				} else {
+					Relation r = null;
+					Way w = null;
+					
+					for (int i=0; i<nGeometries; i++) {
+						Geometry g = mp.getGeometryN(i);
+						if (g instanceof Polygon) {
+							Polygon p = (Polygon) g;
+							// Do not create relation if there's only one polygon without interior ring
+							// except if handler prefers it
+							if (r == null && (nGeometries > 1 || p.getNumInteriorRing() > 0 || (handler != null && handler.preferMultipolygonToSimpleWay()))) {
+								r = createMultipolygon();
+							}
+							w = createWay(p.getExteriorRing());
+							if (r != null) {
+								addWayToMp(r, "outer", w);
+								for (int j=0; j<p.getNumInteriorRing(); j++) {
+									addWayToMp(r, "inner", createWay(p.getInteriorRingN(j)));
+								}
+							}
+						} else if (g instanceof LineString) {
+							w = createWay((LineString) g);
+						} else if (g instanceof Point) {
+							// Some belgian data sets hold points into collections ?!
+							readNonGeometricAttributes(feature, createOrGetNode((Point) g));
+						} else {
+							System.err.println("Error: unsupported geometry : "+g);
+						}
+					}
+					primitive = r != null ? r : w;
+				}
+			} else {
+				// Debug unknown geometry
+				System.out.println("\ttype: "+geometry.getType());
+				System.out.println("\tbounds: "+geometry.getBounds());
+				System.out.println("\tdescriptor: "+desc);
+				System.out.println("\tname: "+geometry.getName());
+				System.out.println("\tvalue: "+geometry.getValue());
+				System.out.println("\tid: "+geometry.getIdentifier());
+				System.out.println("-------------------------------------------------------------");
+			}
+			
+			if (primitive != null) {
+				// Read primitive non geometric attributes
+				readNonGeometricAttributes(feature, primitive);
+			}
+		}
+	}
 
 	public DataSet parse(File file, ProgressMonitor instance) throws IOException {
-		result = null;
 		crs = null;
 		transform = null;
 		try {
 			if (file != null) { 
-				FileDataStore dataStore = FileDataStoreFinder.getDataStore(file);
+		        Map params = new HashMap();
+		        params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
+		        if (handler != null && handler.getDbfCharset() != null) {
+		        	params.put(ShapefileDataStoreFactory.DBFCHARSET.key, handler.getDbfCharset());
+		        }
+				DataStore dataStore = new ShapefileDataStoreFactory().createDataStore(params);//FIXME
 				if (dataStore == null) {
 					throw new IOException(tr("Unable to find a data store for file {0}", file.getName()));
@@ -180,137 +320,28 @@
 				FeatureCollection<?,?> collection = featureSource.getFeatures();
 				FeatureIterator<?> iterator = collection.features();
-					
-				result = new DataSet();
+				
+				if (instance != null) {
+					instance.beginTask(tr("Loading shapefile ({0} features)", collection.size()), collection.size());
+				}
+				
+				int n = 0;
+				
+				Component parent = instance != null ? instance.getWindowParent() : Main.parent;
 				
 				try {
 					while (iterator.hasNext()) {
-						Feature feature = iterator.next();
-						GeometryAttribute geometry = feature.getDefaultGeometryProperty();
-						if (geometry != null) {
-
-							GeometryDescriptor desc = geometry.getDescriptor();
-							
-							if (crs == null && desc != null && desc.getCoordinateReferenceSystem() != null) {
-								crs = desc.getCoordinateReferenceSystem();
-								try {
-									transform = CRS.findMathTransform(crs, wgs84);
-								} catch (OperationNotFoundException e) {
-									System.out.println(crs.getName()+": "+e.getMessage()); // Bursa wolf parameters required.
-									
-									List<CoordinateReferenceSystem> candidates = new ArrayList<CoordinateReferenceSystem>();
-									
-									// Find matching CRS with Bursa Wolf parameters in EPSG database
-									for (String code : CRS.getAuthorityFactory(false).getAuthorityCodes(ProjectedCRS.class)) {
-										CoordinateReferenceSystem candidate = CRS.decode(code);
-										if (candidate instanceof AbstractCRS && crs instanceof AbstractIdentifiedObject) {
-											
-											Hints.putSystemDefault(Hints.COMPARISON_TOLERANCE, 
-													Main.pref.getDouble(PREF_CRS_COMPARISON_TOLERANCE, DEFAULT_CRS_COMPARISON_TOLERANCE));
-											if (((AbstractCRS)candidate).equals((AbstractIdentifiedObject)crs, false)) {
-												System.out.println("Found a potential CRS: "+candidate.getName());
-												candidates.add(candidate);
-											} else if (Main.pref.getBoolean(PREF_CRS_COMPARISON_DEBUG, false)) {
-												compareDebug(crs, candidate);
-											}
-											Hints.removeSystemDefault(Hints.COMPARISON_TOLERANCE);
-										}
-									}
-									
-									if (candidates.size() > 1) {
-										System.err.println("Found several potential CRS.");//TODO: ask user which one to use
-									}
-									
-									if (candidates.size() > 0) {
-										CoordinateReferenceSystem newCRS = candidates.get(0);
-										try {
-											transform = CRS.findMathTransform(newCRS, wgs84, false);
-										} catch (OperationNotFoundException ex) {
-											System.err.println(newCRS.getName()+": "+e.getMessage());
-										}
-									}
-									
-									if (transform == null) {
-										if (handler != null) {
-											// ask handler if it can provide a math transform
-											transform = handler.findMathTransform(crs, wgs84, false);
-										}
-										if (transform == null) {
-											// ask user before trying lenient method
-											if (warnLenientMethod(instance.getWindowParent(), crs)) {
-												// User canceled
-												return result;
-											}
-											System.out.println("Searching for a lenient math transform.");
-											transform = CRS.findMathTransform(crs, wgs84, true);
-										}
-									}
-								}
-								if (transform == null) {
-									System.err.println("Unable to find math transform !");
-									// TODO: something
-									return result;
-								}
-							} else if (crs == null) {
-								System.err.println("Unable to detect CRS !");
-								// TODO: ask projection
-								return result;
+						n++;
+						try {
+							Object feature = iterator.next();
+							parseFeature(iterator.next(), parent);
+							if (handler != null) {
+								handler.notifyFeatureParsed(feature, ds, featurePrimitives);
 							}
-							
-							OsmPrimitive primitive = null;
-							
-							if (geometry.getValue() instanceof Point) {
-								primitive = createOrGetNode((Point) geometry.getValue());
-								
-							} else if (geometry.getValue() instanceof GeometryCollection) { // Deals with both MultiLineString and MultiPolygon
-								GeometryCollection mp = (GeometryCollection) geometry.getValue();
-								int nGeometries = mp.getNumGeometries(); 
-								if (nGeometries < 1) {
-									System.err.println("Error: empty geometry collection found");
-								} else {
-									Relation r = null;
-									Way w = null;
-									
-									for (int i=0; i<nGeometries; i++) {
-										Geometry g = mp.getGeometryN(i);
-										if (g instanceof Polygon) {
-											Polygon p = (Polygon) g;
-											// Do not create relation if there's only one polygon without interior ring
-											// except if handler prefers it
-											if (r == null && (nGeometries > 1 || p.getNumInteriorRing() > 0 || (handler != null && handler.preferMultipolygonToSimpleWay()))) {
-												r = createMultipolygon();
-											}
-											w = createWay(p.getExteriorRing());
-											if (r != null) {
-												addWayToMp(r, "outer", w);
-												for (int j=0; j<p.getNumInteriorRing(); j++) {
-													addWayToMp(r, "inner", createWay(p.getInteriorRingN(j)));
-												}
-											}
-										} else if (g instanceof LineString) {
-											w = createWay((LineString) g);
-										} else if (g instanceof Point) {
-											// Some belgian data sets hold points into collections ?!
-											readNonGeometricAttributes(feature, createOrGetNode((Point) g));
-										} else {
-											System.err.println("Error: unsupported geometry : "+g);
-										}
-									}
-									primitive = r != null ? r : w;
-								}
-							} else {
-								// Debug unknown geometry
-								System.out.println("\ttype: "+geometry.getType());
-								System.out.println("\tbounds: "+geometry.getBounds());
-								System.out.println("\tdescriptor: "+desc);
-								System.out.println("\tname: "+geometry.getName());
-								System.out.println("\tvalue: "+geometry.getValue());
-								System.out.println("\tid: "+geometry.getIdentifier());
-								System.out.println("-------------------------------------------------------------");
-							}
-							
-							if (primitive != null) {
-								// Read primitive non geometric attributes
-								readNonGeometricAttributes(feature, primitive);
-							}
+						} catch (UserCancelException e) {
+							return ds;
+						}
+						if (instance != null) {
+							instance.worked(1);
+							instance.setCustomText(n+"/"+collection.size());
 						}
 					}
@@ -318,4 +349,7 @@
 					iterator.close();
 					nodes.clear();
+					if (instance != null) {
+						instance.setCustomText(null);
+					}
 				}
 			}
@@ -325,5 +359,5 @@
 			throw new IOException(t);
 		}
-		return result;
+		return ds;
 	}
 	
@@ -385,19 +419,20 @@
 	
 	private Node createOrGetNode(Point p) throws MismatchedDimensionException, TransformException {
-		if (transform != null) {
-			Point p2 = (Point) JTS.transform(p, transform);
-			String key = p2.getX()+"/"+p2.getY();
-			//String key = LatLon.roundToOsmPrecisionStrict(p2.getX())+"/"+LatLon.roundToOsmPrecisionStrict(p2.getY());
-			Node n = getNode(p2, key);
-			if (n == null) {
-				nodes.put(key, n = new Node(new LatLon(p2.getY(), p2.getX())));
-				result.addPrimitive(n);
-			}
-			return n;
-		} else {
-			EastNorth en = new EastNorth(p.getX(), p.getY());
-			// TODO: something to transform coordinates
-			return new Node(en);
-		}
+		Point p2 = (Point) JTS.transform(p, transform);
+		String key = p2.getX()+"/"+p2.getY();
+		//String key = LatLon.roundToOsmPrecisionStrict(p2.getX())+"/"+LatLon.roundToOsmPrecisionStrict(p2.getY());
+		Node n = getNode(p2, key);
+		if (n == null) {
+			n = new Node(new LatLon(p2.getY(), p2.getX()));
+			if (handler == null || handler.useNodeMap()) {
+				nodes.put(key, n);
+			}
+			ds.addPrimitive(n);
+		} else if (n.getDataSet() == null) {
+		    // ShpHandler may have removed the node from DataSet (see Paris public light handler for example)
+		    ds.addPrimitive(n);
+		}
+		featurePrimitives.add(n);
+		return n;
 	}
 	
@@ -413,6 +448,5 @@
 			}
 		}
-		result.addPrimitive(w);
-		return w;
+		return addOsmPrimitive(w);
 	}
 
@@ -420,6 +454,5 @@
 		Relation r = new Relation();
 		r.put("type", "multipolygon");
-		result.addPrimitive(r);
-		return r;
+		return addOsmPrimitive(r);
 	}
 
@@ -428,3 +461,9 @@
 		r.addMember(new RelationMember(role, w));
 	}
+	
+	private <T extends OsmPrimitive> T addOsmPrimitive(T p) {
+		ds.addPrimitive(p);
+		featurePrimitives.add(p);
+		return p;
+	}
 }
Index: applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/TabReader.java
===================================================================
--- applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/TabReader.java	(revision 28143)
+++ applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/TabReader.java	(revision 28152)
@@ -112,6 +112,6 @@
         try {
         	File dataFile = getDataFile(file, ".dat");
-        	ds.mergeFrom(new TabOsmReader(handler != null ? handler.getSpreadSheetHandler() : null, new TabFiles(file, dataFile)).
-        			doParse(columns.toArray(new String[0]), instance));
+        	ds = new TabOsmReader(handler != null ? handler.getSpreadSheetHandler() : null, new TabFiles(file, dataFile)).
+        			doParse(columns.toArray(new String[0]), instance);
         } catch (IOException e) {
         	System.err.println(e.getMessage());
