Index: /applications/editors/josm/plugins/opendata/build.xml
===================================================================
--- /applications/editors/josm/plugins/opendata/build.xml	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/build.xml	(revision 28044)
@@ -28,5 +28,5 @@
     <property name="commit.message" value="Commit message"/>
     <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
-    <property name="plugin.main.version" value="5056"/>
+    <property name="plugin.main.version" value="5068"/>
     <!-- should not be necessary to change the following properties -->
     <property name="josm" location="../../core/dist/josm-custom.jar"/>
Index: /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/ParisConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/ParisConstants.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/ParisConstants.java	(revision 28044)
@@ -28,5 +28,5 @@
 	 * Portal
 	 */
-	public static final String PORTAL = "http://opendata.paris.fr/opendata/jsp/site/Portal.jsp?";
+	public static final String PORTAL = "http://opendata.paris.fr/opendata/";
 
 	/**
Index: /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/datasets/ParisDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/datasets/ParisDataSetHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/datasets/ParisDataSetHandler.java	(revision 28044)
@@ -26,32 +26,31 @@
 	
 	private int documentId;
-	private int portletId;
+	private static final int portletId = 106; // FIXME
 	
-	public ParisDataSetHandler(int documentId, int portletId) {
-		init(documentId, portletId);
+	public ParisDataSetHandler(int documentId) {
+		init(documentId);
 	}
 	
-	public ParisDataSetHandler(int documentId, int portletId, String relevantTag) {
+	public ParisDataSetHandler(int documentId, String relevantTag) {
 		super(relevantTag);
-		init(documentId, portletId);
+		init(documentId);
 	}
 	
-	public ParisDataSetHandler(int documentId, int portletId, boolean relevantUnion, String ... relevantTags) {
+	public ParisDataSetHandler(int documentId, boolean relevantUnion, String ... relevantTags) {
 		super(relevantUnion, relevantTags);
-		init(documentId, portletId);
+		init(documentId);
 	}
 
-	public ParisDataSetHandler(int documentId, int portletId, String ... relevantTags) {
-		this(documentId, portletId, false, relevantTags);
+	public ParisDataSetHandler(int documentId, String ... relevantTags) {
+		this(documentId, false, relevantTags);
 	}
 
-	public ParisDataSetHandler(int documentId, int portletId, boolean relevantUnion, Tag ... relevantTags) {
+	public ParisDataSetHandler(int documentId, boolean relevantUnion, Tag ... relevantTags) {
 		super(relevantUnion, relevantTags);
-		init(documentId, portletId);
+		init(documentId);
 	}
 
-	private final void init(int documentId, int portletId) {
+	private final void init(int documentId) {
 		this.documentId = documentId;
-		this.portletId = portletId;
 	}
 
@@ -75,5 +74,22 @@
 		try {
 			if (documentId > 0) {
-				return new URL(PORTAL + "document_id="+documentId + "&portlet_id="+portletId);
+				return new URL(PORTAL + "jsp/site/Portal.jsp?document_id="+documentId + "&portlet_id="+portletId);
+			}
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+	
+	protected abstract String getDirectLink();
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getDataURL()
+	 */
+	@Override
+	public URL getDataURL() {
+		try {
+			if (documentId > 0) {
+				return new URL(PORTAL + "rating/download/?id_resource="+documentId + "&type_resource=document&url="+getDirectLink());
 			}
 		} catch (MalformedURLException e) {
Index: /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/datasets/urbanisme/SanisettesHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/datasets/urbanisme/SanisettesHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/datasets/urbanisme/SanisettesHandler.java	(revision 28044)
@@ -16,5 +16,13 @@
 package org.openstreetmap.josm.plugins.opendata.modules.fr.paris.datasets.urbanisme;
 
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.openstreetmap.josm.corrector.UserCancelException;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.WayCombiner;
 import org.openstreetmap.josm.plugins.opendata.modules.fr.paris.datasets.ParisDataSetHandler;
 
@@ -22,14 +30,97 @@
 
 	public SanisettesHandler() {
-		super(93, 106);
+		super(93);
+		setName("Sanisettes");
 	}
 
 	@Override
 	public boolean acceptsFilename(String filename) {
-		return acceptsShpFilename(filename, "sanisettes");
+		return acceptsShpFilename(filename, "sanisettes") || acceptsZipFilename(filename, "sanisettes");
+	}
+
+	private boolean wayBelongsTo(Way a, List<Way> ways) {
+		for (Way b : ways) {
+			if (a.getNode(0).equals(b.getNode(0)) || a.getNode(0).equals(b.getNode(b.getNodesCount()-1))
+			 || a.getNode(a.getNodesCount()-1).equals(b.getNode(0)) || a.getNode(a.getNodesCount()-1).equals(b.getNode(b.getNodesCount()-1))) {
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	private boolean wayProcessed(Way a, List<List<Way>> waysToCombine) {
+		for (List<Way> ways : waysToCombine) {
+			for (Way b : ways) {
+				if (a.equals(b)) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+	
+	@Override
+	public void updateDataSet(DataSet ds) {
+		
+		List<Way> sourceWays = new ArrayList<Way>(ds.getWays());
+		List<List<Way>> waysToCombine = new ArrayList<List<Way>>();
+		
+		for (Iterator<Way> it = sourceWays.iterator(); it.hasNext();) {
+			Way w = it.next();
+			it.remove();
+			if (!wayProcessed(w, waysToCombine)) {
+				List<Way> list = new ArrayList<Way>();
+				list.add(w);
+				boolean finished = false;
+				List<Way> sourceWays2 = new ArrayList<Way>(sourceWays);
+				while (!finished) {
+					int before = list.size();
+					for (Iterator<Way> it2 = sourceWays2.iterator(); it2.hasNext();) {
+						Way w2 = it2.next();
+						if (wayBelongsTo(w2, list)) {
+							list.add(w2);
+							it2.remove();
+						}
+					}
+					int after = list.size();
+					finished = (after == before);
+				}
+				if (list.size() > 1) {
+					waysToCombine.add(list);
+				}
+			}
+		}
+				
+		for (List<Way> ways : waysToCombine) {
+			try {
+				WayCombiner.combineWays(ways);
+			} catch (UserCancelException e) {
+				return;
+			}
+		}
+		
+		for (Way w : ds.getWays()) {
+			if (w.getNodesCount() <= 3) {
+				ds.removePrimitive(w);
+				for (Node n : w.getNodes()) {
+					ds.removePrimitive(n);
+				}
+			} else {
+				w.put("amenity", "toilets");
+			}
+		}
 	}
 
 	@Override
-	public void updateDataSet(DataSet ds) {
+	protected String getDirectLink() {
+		return PORTAL+"hn/sanisettes.zip";
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#checkShpNodeProximity()
+	 */
+	@Override
+	public boolean checkShpNodeProximity() {
+		return true;
 	}
 }
Index: /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/datasets/EquipementsHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/datasets/EquipementsHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/datasets/EquipementsHandler.java	(revision 28044)
@@ -15,5 +15,5 @@
 	@Override
 	public boolean acceptsFilename(String filename) {
-		return acceptsXlsFilename(filename, "gare_20......");
+		return acceptsCsvXlsFilename(filename, "gare_20......");
 	}
 
@@ -31,5 +31,5 @@
 	@Override
 	public LatLon getSpreadSheetCoor(EastNorth en, String[] fields) {
-		// Lambert II coordinates offset by 2000000 (see http://fr.wikipedia.org/wiki/Projection_conique_conforme_de_Lambert#Projections_officielles_en_France_m.C3.A9tropolitaine)
+		// Lambert II coordinates offset by 2000000 (see http://fr.wikipedia.org/wiki/Projection_conique_conforme_de_Lambert#Projections_officielles_en_France_métropolitaine)
 		return super.getSpreadSheetCoor(new EastNorth(en.getX(), en.getY()-2000000), fields);
 	}
Index: /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/datasets/SncfDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/datasets/SncfDataSetHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/datasets/SncfDataSetHandler.java	(revision 28044)
@@ -82,3 +82,16 @@
 		return null;
 	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getLicenseURL()
+	 */
+	@Override
+	public URL getLicenseURL() {
+		try {
+			return new URL("http://test.data-sncf.com/licence");
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
 }
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/ToulouseConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/ToulouseConstants.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/ToulouseConstants.java	(revision 28044)
@@ -16,4 +16,5 @@
 package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse;
 
+import org.openstreetmap.josm.plugins.opendata.core.datasets.DataSetCategory;
 import org.openstreetmap.josm.plugins.opendata.core.datasets.fr.FrenchConstants;
 
@@ -46,3 +47,17 @@
 	 */
 	public static final String TOULOUSE_NEPTUNE_XSD = "/neptune_toulouse/neptune.xsd";
+	
+	/**
+	 * Categories: TODO: icons
+	 */
+	public static final DataSetCategory CAT_ASSOCIATIONS = new DataSetCategory("Associations", "");
+	public static final DataSetCategory CAT_CITOYENNETE = new DataSetCategory("Citoyenneté", "");
+	public static final DataSetCategory CAT_CULTURE = new DataSetCategory("Culture", "");
+	public static final DataSetCategory CAT_ENFANCE = new DataSetCategory("Enfance", "");
+	public static final DataSetCategory CAT_ENVIRONNEMENT = new DataSetCategory("Environnement", "");
+	public static final DataSetCategory CAT_PATRIMOINE = new DataSetCategory("Patrimoine", "");
+	public static final DataSetCategory CAT_SPORT = new DataSetCategory("Sport", "");
+	public static final DataSetCategory CAT_TOPOGRAPHIE = new DataSetCategory("Topographie", "");
+	public static final DataSetCategory CAT_TRANSPORT = new DataSetCategory("Transport", "");
+	public static final DataSetCategory CAT_URBANISME = new DataSetCategory("Urbanisme", "");
 }
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/ToulouseDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/ToulouseDataSetHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/ToulouseDataSetHandler.java	(revision 28044)
@@ -98,4 +98,17 @@
 
 	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getDataURL()
+	 */
+	@Override
+	public URL getDataURL() {
+		try {
+			return new URL(getLocalPortalURL().toString()+"/resource/document");
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
 	 * @see org.openstreetmap.josm.plugins.fr.opendata.datasets.AbstractDataSetHandler#getWikiURL()
 	 */
@@ -113,5 +126,6 @@
 	
 	protected final void setWikiPage(String wikiPage) {
-		this.wikiPage = wikiPage;
+		this.wikiPage = wikiPage.replace(" ", "_");
+		setName(wikiPage.replace("_", " "));
 	}
 }
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/associations/Club3eAgeHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/associations/Club3eAgeHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/associations/Club3eAgeHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12587, "leisure=club", "club=elderly");
 		setWikiPage("Clubs du 3ème âge");
+		setCategory(CAT_ASSOCIATIONS);
 	}
 	
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/BureauxVoteHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/BureauxVoteHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/BureauxVoteHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12550, "polling_station");
 		setWikiPage("Bureaux de vote 2012");
+		setCategory(CAT_CITOYENNETE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/MairieAnnexeHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/MairieAnnexeHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/MairieAnnexeHandler.java	(revision 28044)
@@ -24,4 +24,5 @@
 	public MairieAnnexeHandler() {
 		super(12560, "Mairies annexes");
+		setCategory(CAT_CITOYENNETE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/MairieHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/MairieHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/MairieHandler.java	(revision 28044)
@@ -24,4 +24,5 @@
 	public MairieHandler() {
 		this(12554, "Mairies");
+		setCategory(CAT_CITOYENNETE);
 	}
 	
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/PolesTerritoriauxHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/PolesTerritoriauxHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/PolesTerritoriauxHandler.java	(revision 28044)
@@ -24,4 +24,6 @@
 	public PolesTerritoriauxHandler() {
 		super(12568);
+		setName("Pôles territoriaux ");
+		setCategory(CAT_CITOYENNETE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/QuartiersHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/QuartiersHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/QuartiersHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12574, "admin_level=11");
 		setWikiPage("Quartiers de proximité");
+		setCategory(CAT_CITOYENNETE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/SecteursHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/SecteursHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/SecteursHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12580, "admin_level=10");
 		setWikiPage("Secteurs de proximité");
+		setCategory(CAT_CITOYENNETE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/BibliothequesHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/BibliothequesHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/BibliothequesHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12402, "amenity=library");
 		setWikiPage("Médiathèques, bibliothèques et bibliobus");
+		setCategory(CAT_CULTURE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/EquipementCulturelBalmaHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/EquipementCulturelBalmaHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/EquipementCulturelBalmaHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(13997);
 		setWikiPage("Équipements Culturels");
+		setCategory(CAT_CULTURE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/LudothequeHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/LudothequeHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/LudothequeHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12420, "amenity=toy_library");
 		setWikiPage("Ludothèques");
+		setCategory(CAT_CULTURE);
 	}
 	
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/MuseeHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/MuseeHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/MuseeHandler.java	(revision 28044)
@@ -26,4 +26,5 @@
 		super(12426, "tourism=museum");
 		setWikiPage("Musées");
+		setCategory(CAT_CULTURE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/TheatreHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/TheatreHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/TheatreHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12448, "amenity=theatre");
 		setWikiPage("Théâtres");
+		setCategory(CAT_CULTURE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/CrechesHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/CrechesHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/CrechesHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12462, "amenity=kindergarten");
 		setWikiPage("Crèches");
+		setCategory(CAT_ENFANCE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleBalmaHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleBalmaHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleBalmaHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(13993, "amenity=school");
 		setWikiPage("Écoles");
+		setCategory(CAT_ENFANCE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleElementaireHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleElementaireHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleElementaireHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12474, "amenity=school");
 		setWikiPage("Écoles élémentaires publiques");
+		setCategory(CAT_ENFANCE);
 		for (String forbidden : new String[]{"maternelle","primaire","collège","lycée","secondaire"}) {
 			addForbiddenTag("school:FR="+forbidden);
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleMaternelleHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleMaternelleHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleMaternelleHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12490, "amenity=school");
 		setWikiPage("Écoles maternelles publiques");
+		setCategory(CAT_ENFANCE);
 		for (String forbidden : new String[]{"élémentaire","primaire","collège","lycée","secondaire"}) {
 			addForbiddenTag("school:FR="+forbidden);
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/PetiteEnfanceEtJeunesseBalmaHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/PetiteEnfanceEtJeunesseBalmaHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/PetiteEnfanceEtJeunesseBalmaHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(14001);
 		setWikiPage("Petite enfance et jeunesse");
+		setCategory(CAT_ENFANCE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/RecupEmballageHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/RecupEmballageHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/RecupEmballageHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12494, "amenity=recycling");
 		setWikiPage("Récup' Emballage");
+		setCategory(CAT_ENVIRONNEMENT);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/RecupVerreHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/RecupVerreHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/RecupVerreHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12496, "amenity=recycling");
 		setWikiPage("Récup' Verre");
+		setCategory(CAT_ENVIRONNEMENT);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/StationEpurationHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/StationEpurationHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/StationEpurationHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12500, "man_made=wastewater_plant");
 		setWikiPage("Stations d'épuration");
+		setCategory(CAT_ENVIRONNEMENT);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/patrimoine/Parcelles1680Handler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/patrimoine/Parcelles1680Handler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/patrimoine/Parcelles1680Handler.java	(revision 28044)
@@ -24,4 +24,6 @@
 	public Parcelles1680Handler() {
 		super(12514);
+		setName("Parcellaire de 1680");
+		setCategory(CAT_PATRIMOINE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/patrimoine/Parcelles1830Handler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/patrimoine/Parcelles1830Handler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/patrimoine/Parcelles1830Handler.java	(revision 28044)
@@ -24,4 +24,6 @@
 	public Parcelles1830Handler() {
 		super(12534);
+		setName("Parcellaire de 1830");
+		setCategory(CAT_PATRIMOINE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/sport/InstallationSportiveBalmaHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/sport/InstallationSportiveBalmaHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/sport/InstallationSportiveBalmaHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(14010);
 		setWikiPage("Installations sportives");
+		setCategory(CAT_SPORT);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/topographie/AltimetrieVoieHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/topographie/AltimetrieVoieHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/topographie/AltimetrieVoieHandler.java	(revision 28044)
@@ -24,4 +24,6 @@
 	public AltimetrieVoieHandler() {
 		super(12660, "ele");
+		setName("Altimétrie des voies");
+		setCategory(CAT_TOPOGRAPHIE);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/HorodateurHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/HorodateurHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/HorodateurHandler.java	(revision 28044)
@@ -29,4 +29,5 @@
 		super(12540, "vending=parking_tickets");
 		setWikiPage("Horodateurs");
+		setCategory(CAT_TRANSPORT);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/MetroStationHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/MetroStationHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/MetroStationHandler.java	(revision 28044)
@@ -24,4 +24,6 @@
 	public MetroStationHandler() {
 		super(12542, "subway=yes");
+		setName("Stations de métro");
+		setCategory(CAT_TRANSPORT);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/PMRHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/PMRHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/PMRHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12538, "amenity=parking_space");
 		setWikiPage("PMR");
+		setCategory(CAT_TRANSPORT);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/PistesCyclablesHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/PistesCyclablesHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/PistesCyclablesHandler.java	(revision 28044)
@@ -41,4 +41,5 @@
 	public PistesCyclablesHandler() {
 		this("Nom_voie");
+		setCategory(CAT_TRANSPORT);
 	}
 	
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/ReseauTisseoHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/ReseauTisseoHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/ReseauTisseoHandler.java	(revision 28044)
@@ -17,4 +17,5 @@
 
 import java.io.File;
+import java.net.MalformedURLException;
 import java.net.URL;
 
@@ -31,4 +32,6 @@
 		super(14022, "network=fr_tisseo");
 		NeptuneReader.registerSchema(neptuneSchemaUrl);
+		setName("Réseau Tisséo (Métro, Bus, Tram)");
+		setCategory(CAT_TRANSPORT);
 	}
 
@@ -54,4 +57,17 @@
 	}
 
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler#getWikiURL()
+	 */
+	@Override
+	public URL getWikiURL() {
+		try {
+			return new URL("http://wiki.openstreetmap.org/wiki/Toulouse/Transports_en_commun#Réseau_Tisséo");
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
 	@Override
 	public void updateDataSet(DataSet ds) {
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/TramwayStationHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/TramwayStationHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/TramwayStationHandler.java	(revision 28044)
@@ -24,4 +24,6 @@
 	public TramwayStationHandler() {
 		super(12611, "tram=yes");
+		setName("Stations de tramway");
+		setCategory(CAT_TRANSPORT);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/VeloToulouseHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/VeloToulouseHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/VeloToulouseHandler.java	(revision 28044)
@@ -26,4 +26,5 @@
 		super(12546, "amenity=bicycle_rental");
 		setWikiPage("Vélô Toulouse");
+		setCategory(CAT_TRANSPORT);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/Zone30Handler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/Zone30Handler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/Zone30Handler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12548, "Street", "maxspeed=30");
 		setWikiPage("Zones 30");
+		setCategory(CAT_TRANSPORT);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/CommuneHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/CommuneHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/CommuneHandler.java	(revision 28044)
@@ -24,4 +24,6 @@
 	public CommuneHandler() {
 		super(12582, "admin_level=8");
+		setName("Communes");
+		setCategory(CAT_URBANISME);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/NumerosRueHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/NumerosRueHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/NumerosRueHandler.java	(revision 28044)
@@ -31,4 +31,5 @@
 		super(12673, "addr:housenumber");
 		setWikiPage("Numéros de rue");
+		setCategory(CAT_URBANISME);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/SanisetteHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/SanisetteHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/SanisetteHandler.java	(revision 28044)
@@ -25,4 +25,5 @@
 		super(12584, "amenity=toilets");
 		setWikiPage("Sanisettes");
+		setCategory(CAT_URBANISME);
 	}
 
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/VoirieHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/VoirieHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/VoirieHandler.java	(revision 28044)
@@ -37,4 +37,6 @@
 	public VoirieHandler() {
 		this(12693, "lib_off", "highway");
+		setName("Filaire de voirie");
+		setCategory(CAT_URBANISME);
 	}
 	
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/OdPlugin.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/OdPlugin.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/OdPlugin.java	(revision 28044)
@@ -16,10 +16,19 @@
 package org.openstreetmap.josm.plugins.opendata;
 
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
+import static org.openstreetmap.josm.tools.I18n.marktr;
+
+import java.awt.event.KeyEvent;
 import java.io.File;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+
+import javax.swing.JMenu;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.ExtensionFileFilter;
+import org.openstreetmap.josm.gui.MainMenu;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
@@ -27,4 +36,9 @@
 import org.openstreetmap.josm.plugins.PluginInformation;
 import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.actions.DownloadDataAction;
+import org.openstreetmap.josm.plugins.opendata.core.actions.DownloadDataTask;
+import org.openstreetmap.josm.plugins.opendata.core.actions.OpenPreferencesActions;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.DataSetCategory;
 import org.openstreetmap.josm.plugins.opendata.core.gui.OdDialog;
 import org.openstreetmap.josm.plugins.opendata.core.gui.OdPreferenceSetting;
@@ -38,4 +52,5 @@
 import org.openstreetmap.josm.plugins.opendata.core.io.tabular.OdsImporter;
 import org.openstreetmap.josm.plugins.opendata.core.io.tabular.XlsImporter;
+import org.openstreetmap.josm.plugins.opendata.core.modules.Module;
 import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleHandler;
 import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleInformation;
@@ -46,4 +61,6 @@
 	
 	public final XmlImporter xmlImporter;
+	
+	private final JMenu menu;
 	
 	public OdPlugin(PluginInformation info) { // NO_UCD
@@ -65,8 +82,49 @@
         // Load modules
         loadModules();
+        // Add menu
+        menu = Main.main.menu.addMenu(marktr("Open Data"), KeyEvent.VK_O, Main.main.menu.defaultMenuPos, ht("/Plugin/OpenData"));
+        buildMenu();
+        // Add download task
+        Main.main.menu.openLocation.addDownloadTaskClass(DownloadDataTask.class);
 	}
 	
 	public static final OdPlugin getInstance() {
 		return instance;
+	}
+	
+	private void buildMenu() {
+        for (Module module : ModuleHandler.moduleList) {
+        	Map<DataSetCategory, JMenu> catMenus = new HashMap<DataSetCategory, JMenu>();
+        	JMenu moduleMenu = null;
+        	for (AbstractDataSetHandler handler: module.getHandlers()) {
+        		if (handler.getDataURL() != null) {
+        			if (moduleMenu == null) {
+        				String moduleName = module.getDisplayedName();
+        				if (moduleName == null || moduleName.isEmpty()) {
+        					moduleName = module.getModuleInformation().getName();
+        				}
+        				moduleMenu = new JMenu(moduleName);
+        				moduleMenu.setIcon(module.getModuleInformation().getScaledIcon());
+        			}
+        			DataSetCategory cat = handler.getCategory();
+        			JMenu endMenu = null;
+        			if (cat != null) {
+        				if ((endMenu = catMenus.get(cat)) == null) {
+        					catMenus.put(cat, endMenu = new JMenu(cat.getName()));
+        					moduleMenu.add(endMenu);
+        				}
+        			}
+        			if (endMenu == null) {
+        				endMenu = moduleMenu;
+        			}
+        			endMenu.add(new DownloadDataAction(handler));
+        		}
+        	}
+        	if (moduleMenu != null) {
+        		menu.add(moduleMenu);
+        	}
+        }
+        menu.addSeparator();
+        MainMenu.add(menu, new OpenPreferencesActions());
 	}
 
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/actions/DownloadDataAction.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/actions/DownloadDataAction.java	(revision 28044)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/actions/DownloadDataAction.java	(revision 28044)
@@ -0,0 +1,45 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.actions;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.Action;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+
+public class DownloadDataAction extends JosmAction {
+
+	private final AbstractDataSetHandler handler;
+	
+	public DownloadDataAction(AbstractDataSetHandler handler) {
+		CheckParameterUtil.ensureParameterNotNull(handler, "handler");
+		this.handler = handler;
+		String name = handler.getName();
+		if (name == null || name.isEmpty()) {
+			name = handler.getClass().getName();
+		}
+		putValue(Action.NAME, name);
+	}
+	
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		Main.main.menu.openLocation.openUrl(true, handler.getDataURL().toString());
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/actions/DownloadDataTask.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/actions/DownloadDataTask.java	(revision 28044)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/actions/DownloadDataTask.java	(revision 28044)
@@ -0,0 +1,86 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.actions;
+
+import java.io.File;
+import java.util.concurrent.Future;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.AbstractReader;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.DataSetUpdater;
+import org.openstreetmap.josm.plugins.opendata.core.io.NetworkReader;
+import org.openstreetmap.josm.plugins.opendata.core.layers.OdDataLayer;
+import org.openstreetmap.josm.plugins.opendata.core.modules.Module;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleHandler;
+
+public class DownloadDataTask extends DownloadOsmTask {
+
+	private AbstractDataSetHandler handler;
+	
+	@Override
+	public Future<?> download(boolean newLayer, Bounds downloadArea, ProgressMonitor progressMonitor) {
+		return null;
+	}
+
+	@Override
+	public Future<?> loadUrl(boolean newLayer, String url, ProgressMonitor progressMonitor) {
+		Class<? extends AbstractReader> readerClass = null; // TODO
+        downloadTask = new InternDownloadTasK(newLayer, new NetworkReader(url, handler, readerClass), progressMonitor);
+        currentBounds = null;
+        // Extract .osm filename from URL to set the new layer name
+        //Matcher matcher = Pattern.compile("http://.*/(.*\\.osm)").matcher(url);
+        //newLayerName = matcher.matches() ? matcher.group(1) : null;
+        return Main.worker.submit(downloadTask);
+	}
+
+	@Override
+	public boolean acceptsUrl(String url) {
+		for (Module module : ModuleHandler.moduleList) {
+			for (AbstractDataSetHandler handler : module.getHandlers()) {
+				if (handler != null && handler.getDataURL() != null && url.equals(handler.getDataURL().toString())) {
+					this.handler = handler;
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+	
+	protected class InternDownloadTasK extends DownloadTask {
+
+		public InternDownloadTasK(boolean newLayer, NetworkReader reader, ProgressMonitor progressMonitor) {
+			super(newLayer, reader, progressMonitor);
+		}
+
+		/* (non-Javadoc)
+		 * @see org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask.DownloadTask#createNewLayer(java.lang.String)
+		 */
+		@Override
+		protected OsmDataLayer createNewLayer(String layerName) {
+            File associatedFile = ((NetworkReader)reader).getReadFile();
+            if (layerName == null || layerName.isEmpty()) {
+                layerName = associatedFile == null ? OsmDataLayer.createNewName() : associatedFile.getName();
+            }
+    		DataSetUpdater.updateDataSet(dataSet, handler, associatedFile);
+    		return new OdDataLayer(dataSet, layerName, associatedFile, handler);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/actions/OpenPreferencesActions.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/actions/OpenPreferencesActions.java	(revision 28044)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/actions/OpenPreferencesActions.java	(revision 28044)
@@ -0,0 +1,42 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.actions;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.gui.preferences.PreferenceDialog;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.gui.OdPreferenceSetting;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+public class OpenPreferencesActions extends JosmAction implements OdConstants {
+	
+    public OpenPreferencesActions() {
+        putValue(NAME, tr("Preferences"));
+        putValue(SMALL_ICON, ImageProvider.get("dialogs", ICON_CORE_24));
+    }
+    
+	@Override
+	public void actionPerformed(ActionEvent e) {
+        final PreferenceDialog p = new PreferenceDialog(Main.parent);
+        p.selectPreferencesTabByClass(OdPreferenceSetting.class);
+        p.setVisible(true);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/AbstractDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/AbstractDataSetHandler.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/AbstractDataSetHandler.java	(revision 28044)
@@ -53,4 +53,5 @@
 import org.openstreetmap.josm.data.projection.proj.LambertConformalConic.Parameters2SP;
 import org.openstreetmap.josm.gui.preferences.SourceEditor.ExtendedSourceEntry;
+import org.openstreetmap.josm.io.AbstractReader;
 import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
 import org.openstreetmap.josm.plugins.opendata.core.util.NamesFrUtils;
@@ -92,4 +93,6 @@
 	}
 
+	private String name;
+	private DataSetCategory category;
 	private String sourceDate;
 	private File associatedFile;
@@ -170,8 +173,21 @@
 	public URL getWikiURL() {return null;}
 	
-	public abstract URL getLocalPortalURL();
-	public abstract URL getNationalPortalURL();
+	public URL getLocalPortalURL() {return null;}
+	
+	public URL getNationalPortalURL() {return null;}
 
 	public URL getLicenseURL() {return null;}
+
+	public URL getDataURL() {return null;}
+	
+	public AbstractReader getReaderForUrl(String url) {return null;}
+
+	public final DataSetCategory getCategory() {
+		return category;
+	}
+
+	public final void setCategory(DataSetCategory category) {
+		this.category = category;
+	}
 
 	public final Collection<String> getOsmXapiRequests(Bounds bounds) {
@@ -340,25 +356,24 @@
 	}
 
-	/**
-	 * @return the source
-	 */
 	public String getSource() {
 		return null;
 	}
 		
-	/**
-	 * @return the sourceDate
-	 */
 	public final String getSourceDate() {
 		return sourceDate;
 	}
 	
-	/**
-	 * @param sourceDate the sourceDate to set
-	 */
 	public final void setSourceDate(String sourceDate) {
 		this.sourceDate = sourceDate;
 	}
-	
+
+	public final String getName() {
+		return name;
+	}
+	
+	public final void setName(String name) {
+		this.name = name;
+	}
+
 	public String getLocalPortalIconName() {
 		return ICON_CORE_24;
@@ -503,3 +518,7 @@
 		return null;
 	}
+
+	public boolean checkShpNodeProximity() {
+		return false;
+	}
 }
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/DataSetCategory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/DataSetCategory.java	(revision 28044)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/DataSetCategory.java	(revision 28044)
@@ -0,0 +1,43 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.datasets;
+
+import javax.swing.ImageIcon;
+
+import org.openstreetmap.josm.plugins.opendata.core.util.OdUtils;
+
+public class DataSetCategory {
+
+	private final String name;
+	private final ImageIcon icon;
+	
+	public DataSetCategory(String name, ImageIcon icon) {
+		this.name = name;
+		this.icon = icon;
+	}
+	
+	public DataSetCategory(String name, String iconName) {
+		this(name, iconName != null && !iconName.isEmpty() ? OdUtils.getImageIcon(iconName) : null);
+	}
+
+	public final String getName() {
+		return name;
+	}
+
+	public final ImageIcon getIcon() {
+		return icon;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/DataSetUpdater.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/DataSetUpdater.java	(revision 28044)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/DataSetUpdater.java	(revision 28044)
@@ -0,0 +1,41 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.datasets;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+
+public abstract class DataSetUpdater implements OdConstants {
+
+	public static final void updateDataSet(DataSet dataSet, AbstractDataSetHandler handler, File associatedFile) {
+		if (dataSet != null && handler != null) {
+			if (associatedFile != null) {
+				handler.setAssociatedFile(associatedFile);
+				handler.setSourceDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date(associatedFile.lastModified())));
+			}
+			if (!Main.pref.getBoolean(PREF_RAWDATA)) {
+				handler.updateDataSet(dataSet);
+			}
+			handler.checkDataSetSource(dataSet);
+			handler.checkNames(dataSet);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/WayCombiner.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/WayCombiner.java	(revision 28044)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/WayCombiner.java	(revision 28044)
@@ -0,0 +1,180 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.datasets;
+
+import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.combineTigerTags;
+import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.completeTagCollectionForEditing;
+import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.normalizeTagCollectionBeforeEditing;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.openstreetmap.josm.actions.CombineWayAction;
+import org.openstreetmap.josm.actions.CombineWayAction.NodeGraph;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.corrector.ReverseWayTagCorrector;
+import org.openstreetmap.josm.corrector.UserCancelException;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.TagCollection;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.gui.conflict.tags.CombinePrimitiveResolverDialog;
+
+// FIXME: Try to refactor CombineWayAction instead of using this class
+public class WayCombiner {
+	
+    protected static Way getTargetWay(Collection<Way> combinedWays) {
+        // init with an arbitrary way
+        Way targetWay = combinedWays.iterator().next();
+
+        // look for the first way already existing on
+        // the server
+        for (Way w : combinedWays) {
+            targetWay = w;
+            if (!w.isNew()) {
+                break;
+            }
+        }
+        return targetWay;
+    }
+    
+    /**
+     * @param ways
+     * @throws UserCancelException
+     */
+    public static void combineWays(Collection<Way> ways) throws UserCancelException {
+
+        // prepare and clean the list of ways to combine
+        //
+        if (ways == null || ways.isEmpty())
+            return;
+        ways.remove(null); // just in case -  remove all null ways from the collection
+
+        // remove duplicates, preserving order
+        ways = new LinkedHashSet<Way>(ways);
+
+        // try to build a new way which includes all the combined
+        // ways
+        //
+        NodeGraph graph = NodeGraph.createUndirectedGraphFromNodeWays(ways);
+        List<Node> path = graph.buildSpanningPath();
+        if (path == null) {
+            return;
+        }
+        // check whether any ways have been reversed in the process
+        // and build the collection of tags used by the ways to combine
+        //
+        TagCollection wayTags = TagCollection.unionOfAllPrimitives(ways);
+
+        List<Way> reversedWays = new LinkedList<Way>();
+        List<Way> unreversedWays = new LinkedList<Way>();
+        for (Way w: ways) {
+            if ((path.indexOf(w.getNode(0)) + 1) == path.lastIndexOf(w.getNode(1))) {
+                unreversedWays.add(w);
+            } else {
+                reversedWays.add(w);
+            }
+        }
+        // reverse path if all ways have been reversed
+        if (unreversedWays.isEmpty()) {
+            Collections.reverse(path);
+            unreversedWays = reversedWays;
+            reversedWays = null;
+        }
+        if ((reversedWays != null) && !reversedWays.isEmpty()) {
+            // filter out ways that have no direction-dependent tags
+            unreversedWays = ReverseWayTagCorrector.irreversibleWays(unreversedWays);
+            reversedWays = ReverseWayTagCorrector.irreversibleWays(reversedWays);
+            // reverse path if there are more reversed than unreversed ways with direction-dependent tags
+            if (reversedWays.size() > unreversedWays.size()) {
+                Collections.reverse(path);
+                List<Way> tempWays = unreversedWays;
+                unreversedWays = reversedWays;
+                reversedWays = tempWays;
+            }
+            // if there are still reversed ways with direction-dependent tags, reverse their tags
+            if (!reversedWays.isEmpty()) {
+                List<Way> unreversedTagWays = new ArrayList<Way>(ways);
+                unreversedTagWays.removeAll(reversedWays);
+                ReverseWayTagCorrector reverseWayTagCorrector = new ReverseWayTagCorrector();
+                List<Way> reversedTagWays = new ArrayList<Way>();
+                Collection<Command> changePropertyCommands =  null;
+                for (Way w : reversedWays) {
+                    Way wnew = new Way(w);
+                    reversedTagWays.add(wnew);
+                    changePropertyCommands = reverseWayTagCorrector.execute(w, wnew);
+                }
+                if ((changePropertyCommands != null) && !changePropertyCommands.isEmpty()) {
+                    for (Command c : changePropertyCommands) {
+                        c.executeCommand();
+                    }
+                }
+                wayTags = TagCollection.unionOfAllPrimitives(reversedTagWays);
+                wayTags.add(TagCollection.unionOfAllPrimitives(unreversedTagWays));
+            }
+        }
+
+        // create the new way and apply the new node list
+        //
+        Way targetWay = getTargetWay(ways);
+        Way modifiedTargetWay = new Way(targetWay);
+        modifiedTargetWay.setNodes(path);
+
+        TagCollection completeWayTags = new TagCollection(wayTags);
+        combineTigerTags(completeWayTags);
+        normalizeTagCollectionBeforeEditing(completeWayTags, ways);
+        TagCollection tagsToEdit = new TagCollection(completeWayTags);
+        completeTagCollectionForEditing(tagsToEdit);
+
+        CombinePrimitiveResolverDialog dialog = CombinePrimitiveResolverDialog.getInstance();
+        dialog.getTagConflictResolverModel().populate(tagsToEdit, completeWayTags.getKeysWithMultipleValues());
+        dialog.setTargetPrimitive(targetWay);
+        Set<Relation> parentRelations = CombineWayAction.getParentRelations(ways);
+        dialog.getRelationMemberConflictResolverModel().populate(
+                parentRelations,
+                ways
+        );
+        dialog.prepareDefaultDecisions();
+
+        // resolve tag conflicts if necessary
+        //
+        if (!completeWayTags.isApplicableToPrimitive() || !parentRelations.isEmpty()) {
+            dialog.setVisible(true);
+            //if (dialog.isCanceled()) // FIXME
+                throw new UserCancelException();
+        }
+
+        LinkedList<Way> deletedWays = new LinkedList<Way>(ways);
+        deletedWays.remove(targetWay);
+
+        //new ChangeCommand(targetWay, modifiedTargetWay).executeCommand();
+        targetWay.cloneFrom(modifiedTargetWay);
+        /*for (Command c : dialog.buildResolutionCommands()) {
+        	c.executeCommand();//FIXME
+        }*/
+        //new DeleteCommand(deletedWays).executeCommand();
+        for (Way way: deletedWays) {
+            way.setNodes(null);
+            way.setDeleted(true);
+            way.getDataSet().removePrimitive(way);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/AbstractImporter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/AbstractImporter.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/AbstractImporter.java	(revision 28044)
@@ -18,8 +18,5 @@
 import java.io.File;
 import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.ExtensionFileFilter;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -30,4 +27,5 @@
 import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
 import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.DataSetUpdater;
 import org.openstreetmap.josm.plugins.opendata.core.layers.OdDataLayer;
 import org.openstreetmap.josm.plugins.opendata.core.modules.Module;
@@ -73,13 +71,5 @@
 	@Override
 	protected OsmDataLayer createLayer(DataSet dataSet, File associatedFile, String layerName) {
-		if (handler != null) {
-			handler.setAssociatedFile(associatedFile);
-			handler.setSourceDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date(associatedFile.lastModified())));
-			if (!Main.pref.getBoolean(PREF_RAWDATA)) {
-				handler.updateDataSet(dataSet);
-			}
-			handler.checkDataSetSource(dataSet);
-			handler.checkNames(dataSet);
-		}
+		DataSetUpdater.updateDataSet(dataSet, handler, associatedFile);
 		return new OdDataLayer(dataSet, layerName, associatedFile, handler);
 	}
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 28044)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/NetworkReader.java	(revision 28044)
@@ -0,0 +1,118 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.File;
+import java.io.InputStream;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.AbstractReader;
+import org.openstreetmap.josm.io.OsmServerReader;
+import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.core.io.archive.ZipReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.geographic.KmlReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.geographic.KmzReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.geographic.MifReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.geographic.ShpReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.geographic.TabReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.tabular.CsvReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.tabular.OdsReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.tabular.XlsReader;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+
+public class NetworkReader extends OsmServerReader {
+
+	private final String url;
+	private final AbstractDataSetHandler handler;
+	private Class<? extends AbstractReader> readerClass;
+
+	private File file;
+	
+    public NetworkReader(String url, AbstractDataSetHandler handler, Class<? extends AbstractReader> readerClass) {
+        CheckParameterUtil.ensureParameterNotNull(url, "url");
+        //CheckParameterUtil.ensureParameterNotNull(readerClass, "readerClass");
+    	this.url = url;
+        this.readerClass = readerClass;
+        this.handler = handler;
+    }
+    
+	public final File getReadFile() {
+		return file;
+	}
+
+	@Override
+	public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
+        InputStream in = null;
+        progressMonitor.beginTask(tr("Contacting Server...", 10));
+        try {
+            in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
+            if (in == null)
+                return null;
+            progressMonitor.subTask(tr("Downloading data..."));
+            ProgressMonitor instance = progressMonitor.createSubTaskMonitor(1, false);
+            if (readerClass == null) {
+            	String contentType = this.activeConnection.getContentType();
+            	if (contentType.startsWith("application/zip")) {
+            		readerClass = ZipReader.class;
+            	} else {
+            		throw new IllegalArgumentException("Unsupported content type: "+contentType);
+            	}
+            }
+            if (readerClass.equals(ZipReader.class)) {
+            	ZipReader zipReader = new ZipReader(in, handler);
+            	DataSet ds = zipReader.parseDoc(instance);
+            	file = zipReader.getReadFile();
+            	return ds;
+            } else if (readerClass.equals(KmlReader.class)) {
+            	return KmlReader.parseDataSet(in, instance);
+            } else if (readerClass.equals(KmzReader.class)) {
+            	return KmzReader.parseDataSet(in, instance);
+            } else if (readerClass.equals(MifReader.class)) {
+            	return MifReader.parseDataSet(in, null, handler, instance);
+            } else if (readerClass.equals(ShpReader.class)) {
+            	return ShpReader.parseDataSet(in, null, handler, instance);
+            } else if (readerClass.equals(TabReader.class)) {
+            	return TabReader.parseDataSet(in, null, handler, instance);
+            } else if (readerClass.equals(CsvReader.class)) {
+            	return CsvReader.parseDataSet(in, handler, instance);
+            } else if (readerClass.equals(OdsReader.class)) {
+            	return OdsReader.parseDataSet(in, handler, instance);
+            } else if (readerClass.equals(XlsReader.class)) {
+            	return XlsReader.parseDataSet(in, handler, instance);
+            } else {
+            	throw new IllegalArgumentException("Unsupported reader class: "+readerClass.getName());
+            }
+        } catch (OsmTransferException e) {
+            throw e;
+        } catch (Exception e) {
+            if (cancel)
+                return null;
+            throw new OsmTransferException(e);
+        } finally {
+            progressMonitor.finishTask();
+            try {
+                activeConnection = null;
+                if (in != null) {
+                    in.close();
+                }
+            } catch (Exception e) {/* ignore it */}
+        }
+	}
+}
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 28043)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/ZipReader.java	(revision 28044)
@@ -50,12 +50,18 @@
 	private final ZipInputStream zis;
 	private final AbstractDataSetHandler handler;
+	
+	private File file;
     
-    public ZipReader(ZipInputStream zis, AbstractDataSetHandler handler) {
-        this.zis = zis;
+    public ZipReader(InputStream in, AbstractDataSetHandler handler) {
+        this.zis = in instanceof ZipInputStream ? (ZipInputStream) in : new ZipInputStream(in);
         this.handler = handler;
     }
 
 	public static DataSet parseDataSet(InputStream in, AbstractDataSetHandler handler, ProgressMonitor instance) throws IOException, XMLStreamException, FactoryConfigurationError, JAXBException {
-		return new ZipReader(new ZipInputStream(in), handler).parseDoc(instance);
+		return new ZipReader(in, handler).parseDoc(instance);
+	}
+	
+	public final File getReadFile() {
+		return file;
 	}
 	
@@ -81,5 +87,5 @@
 	}
 
-	private DataSet parseDoc(ProgressMonitor instance) throws IOException, XMLStreamException, FactoryConfigurationError, JAXBException  {
+	public DataSet parseDoc(ProgressMonitor instance) throws IOException, XMLStreamException, FactoryConfigurationError, JAXBException  {
 		
 	    final File temp = createTempDir();
@@ -91,28 +97,36 @@
 				File file = new File(temp + File.separator + entry.getName());
 			    if (file.exists() && !file.delete()) {
-			        throw new IOException("Could not delete temp file: " + file.getAbsolutePath());
+			        throw new IOException("Could not delete temp file/dir: " + file.getAbsolutePath());
 			    }
-				if (!file.createNewFile()) {
-					throw new IOException("Could not create temp file: " + file.getAbsolutePath());
-				}
-				FileOutputStream fos = new FileOutputStream(file);
-				byte[] buffer = new byte[8192];
-				int count = 0;
-				while ((count = zis.read(buffer, 0, buffer.length)) > 0) {
-					fos.write(buffer, 0, count);
-				}
-				fos.close();
-				for (String ext : new String[] {
-						CSV_EXT, KML_EXT, KMZ_EXT, XLS_EXT, ODS_EXT, SHP_EXT, MIF_EXT, TAB_EXT, XML_EXT
-				}) {
-					if (entry.getName().toLowerCase().endsWith("."+ext)) {
-						candidates.add(file);
-						System.out.println(entry.getName());
-						break;
+			    if (!entry.isDirectory()) {
+			    	if (!file.createNewFile()) { 
+			    		throw new IOException("Could not create temp file: " + file.getAbsolutePath());
+			    	}
+					FileOutputStream fos = new FileOutputStream(file);
+					byte[] buffer = new byte[8192];
+					int count = 0;
+					while ((count = zis.read(buffer, 0, buffer.length)) > 0) {
+						fos.write(buffer, 0, count);
 					}
+					fos.close();
+					long time = entry.getTime();
+					if (time > -1) {
+						file.setLastModified(time);
+					}
+					for (String ext : new String[] {
+							CSV_EXT, KML_EXT, KMZ_EXT, XLS_EXT, ODS_EXT, SHP_EXT, MIF_EXT, TAB_EXT, XML_EXT
+					}) {
+						if (entry.getName().toLowerCase().endsWith("."+ext)) {
+							candidates.add(file);
+							System.out.println(entry.getName());
+							break;
+						}
+					}
+				} else if (!file.mkdir()) {
+					throw new IOException("Could not create temp dir: " + file.getAbsolutePath());
 				}
 			}
 			
-			File file = null;
+			file = null;
 			
 			if (candidates.size() > 1) {
@@ -159,5 +173,6 @@
 				}
 			}
-			
+	    } catch (IllegalArgumentException e) {
+	    	System.err.println(e.getMessage());
 	    } finally {
 	    	deleteDir(temp);
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 28043)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpReader.java	(revision 28044)
@@ -371,9 +371,23 @@
 	}
 	
+	private Node getNode(Point p, String key) {
+		Node n = nodes.get(key);
+		if (n == null && handler != null && handler.checkShpNodeProximity()) {
+			LatLon ll = new LatLon(p.getY(), p.getX());
+			for (Node node : nodes.values()) {
+				if (node.getCoor().equalsEpsilon(ll)) {
+					return node;
+				}
+			}
+		}
+		return n;
+	}
+	
 	private Node createOrGetNode(Point p) throws MismatchedDimensionException, TransformException {
 		if (transform != null) {
 			Point p2 = (Point) JTS.transform(p, transform);
 			String key = p2.getX()+"/"+p2.getY();
-			Node n = nodes.get(key);
+			//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())));
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/AbstractModule.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/AbstractModule.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/AbstractModule.java	(revision 28044)
@@ -55,4 +55,12 @@
 	public List<AbstractDataSetHandler> getHandlers() {
 		return handlers;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.modules.Module#getDisplayedName()
+	 */
+	@Override
+	public String getDisplayedName() {
+		return info.name;
 	}
 
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/Module.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/Module.java	(revision 28043)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/Module.java	(revision 28044)
@@ -23,4 +23,6 @@
 public interface Module {
 
+	public String getDisplayedName();
+
 	public List<AbstractDataSetHandler> getHandlers();
 	
