Index: /applications/editors/josm/plugins/build.xml
===================================================================
--- /applications/editors/josm/plugins/build.xml	(revision 14286)
+++ /applications/editors/josm/plugins/build.xml	(revision 14287)
@@ -24,4 +24,5 @@
         <ant antfile="build.xml" target="dist" dir="plastic_laf"/>
         <ant antfile="build.xml" target="dist" dir="remotecontrol"/>
+        <ant antfile="build.xml" target="dist" dir="routing"/>
         <ant antfile="build.xml" target="dist" dir="slippymap"/>
         <ant antfile="build.xml" target="dist" dir="surveyor"/>
@@ -60,4 +61,5 @@
         <ant antfile="build.xml" target="clean" dir="plastic_laf"/>
         <ant antfile="build.xml" target="clean" dir="remotecontrol"/>
+        <ant antfile="build.xml" target="clean" dir="routing"/>
         <ant antfile="build.xml" target="clean" dir="slippymap"/>
         <ant antfile="build.xml" target="clean" dir="surveyor"/>
Index: /applications/editors/josm/plugins/routing/build.xml
===================================================================
--- /applications/editors/josm/plugins/routing/build.xml	(revision 14287)
+++ /applications/editors/josm/plugins/routing/build.xml	(revision 14287)
@@ -0,0 +1,75 @@
+<project name="routing" default="dist" basedir=".">
+	<!-- Define some properties -->
+    <property name="josm"                   location="../../core/dist/josm-custom.jar"/>
+    <property name="plugin.dist.dir"        value="../../dist"/>
+    <property name="plugin.build.dir"       value="build"/>
+    <property name="plugin.jar"             value="${plugin.dist.dir}/${ant.project.name}.jar"/>
+    <property name="jgrapht"                value="lib/jgrapht-jdk1.5.jar"/>
+    <property name="log4j"                  value="lib/log4j-1.2.15.jar"/>
+    <property name="ant.build.javac.target" value="1.5"/>
+	<!-- Some initializations for several other targets -->
+    <target name="init">
+        <mkdir dir="${plugin.build.dir}"/>
+    </target>
+	<!-- Compile sources -->
+    <target name="compile" depends="init" description="Compile sources">
+        <echo message="creating ${plugin.jar}"/>
+        <javac srcdir="src" debug="true" destdir="${plugin.build.dir}">
+            <compilerarg value="-Xlint:deprecation"/>
+            <compilerarg value="-Xlint:unchecked"/>
+            <classpath>
+                <pathelement location="${josm}"/>
+                <pathelement location="${jgrapht}"/>
+                <pathelement location="${log4j}"/>
+            </classpath>
+        </javac>
+    </target>
+	<!-- Generate distribution -->
+    <target name="dist" depends="compile,revision" description="Generate distribution">
+        <unjar dest="${plugin.build.dir}" src="${jgrapht}"/>
+        <unjar dest="${plugin.build.dir}" src="${log4j}"/>
+        <copy todir="${plugin.build.dir}/">
+            <fileset dir="resources">
+                <include name="*.xml"/>
+            </fileset>
+        </copy>
+        <copy todir="${plugin.build.dir}/images">
+            <fileset dir="images"/>
+        </copy>
+        <jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
+            <manifest>
+                <attribute name="Author" value="Jose Vidal &lt;vidalfree@gmail.com&gt;, Juangui Jordán &lt;juangui@gmail.com&gt;"/>
+                <attribute name="Plugin-Class" value="com.innovant.josm.plugin.routing.RoutingPlugin"/>
+                <attribute name="Plugin-Date" value="${version.entry.commit.date}"/>
+                <attribute name="Plugin-Description" value="Provides routing capabilities."/>
+                <attribute name="Plugin-Link" value="http://wiki.openstreetmap.org/index.php/JOSM/Plugins/Routing"/>
+                <attribute name="Plugin-Mainversion" value="1510"/>
+                <attribute name="Plugin-Stage" value="50"/>
+                <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
+            </manifest>
+        </jar>
+    </target>
+    <target name="revision">
+        <exec append="false" output="REVISION" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="info"/>
+            <arg value="--xml"/>
+            <arg value="."/>
+        </exec>
+        <xmlproperty file="REVISION" prefix="version" keepRoot="false" collapseAttributes="true"/>
+        <delete file="REVISION"/>
+    </target>
+    <target name="clean">
+        <delete dir="${plugin.build.dir}"/>
+        <delete file="${plugin.jar}"/>
+    </target>
+    <target name="install" depends="dist">
+        <property environment="env"/>
+        <condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins">
+            <and>
+                <os family="windows"/>
+            </and>
+        </condition>
+        <copy file="${plugin.jar}" todir="${josm.plugins.dir}"/>
+    </target>
+</project>
Index: /applications/editors/josm/plugins/routing/resources/log4j.xml
===================================================================
--- /applications/editors/josm/plugins/routing/resources/log4j.xml	(revision 14287)
+++ /applications/editors/josm/plugins/routing/resources/log4j.xml	(revision 14287)
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ 
+<!DOCTYPE log4j:configuration SYSTEM "dtds/org/apache/log4j/xml/log4j.dtd"> 
+    
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+   
+  <appender name="console" class="org.apache.log4j.ConsoleAppender">		
+	<layout class="org.apache.log4j.PatternLayout">
+	    <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%c] %-5p - %m%n" />
+	</layout>
+	</appender> 
+   
+   <logger name="com.innovant.josm.plugin.routing.RoutingModel">
+  		<level value="trace"/> 
+	</logger>
+   
+   
+   <root>   
+     <level value="debuger"></level>
+     <appender-ref ref="console"/> 
+   </root>
+</log4j:configuration>
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/PreferencesKeys.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/PreferencesKeys.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/PreferencesKeys.java	(revision 14287)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 Innovant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, please contact:
+ *
+ *  Innovant
+ *   juangui@gmail.com
+ *   vidalfree@gmail.com
+ *
+ *  http://public.grupoinnovant.com/blog
+ *
+ */
+package com.innovant.josm.jrt.core;
+
+public enum PreferencesKeys {
+	KEY_ROUTE_COLOR ("routing.route.color"),
+	KEY_ROUTE_WIDTH ("routing.route.width"),
+	KEY_ROUTE_SELECT ("routing.route.select");
+	
+	public final String key;
+	PreferencesKeys (String key) {
+		this.key=key;
+	}
+	
+	public String getKey() {return key;};
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/RoutingGraph.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/RoutingGraph.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/RoutingGraph.java	(revision 14287)
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2008 Innovant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, please contact:
+ *
+ *  Innovant
+ *   juangui@gmail.com
+ *   vidalfree@gmail.com
+ *
+ *  http://public.grupoinnovant.com/blog
+ *
+ */
+
+package com.innovant.josm.jrt.core;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.jgrapht.Graph;
+import org.jgrapht.alg.BellmanFordShortestPath;
+import org.jgrapht.alg.DijkstraShortestPath;
+import org.jgrapht.graph.AsUndirectedGraph;
+import org.jgrapht.graph.DirectedWeightedMultigraph;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Way;
+
+import com.innovant.josm.jrt.osm.OsmEdge;
+
+/**
+ * Class utility to work with graph routers.
+ *
+ * @author Juangui
+ * @author Jose Vidal
+ */
+public class RoutingGraph {
+
+	/**
+     * Routing Profile
+     */
+    private RoutingProfile routingProfile;
+
+	/**
+	 * Diferent algorithms to apply to the graph.
+	 */
+	public enum Algorithm {
+		ROUTING_ALG_DIJKSTRA, ROUTING_ALG_BELLMANFORD
+	};
+
+	/**
+	 * Search criteria for the route.
+	 */
+	public enum RouteType {FASTEST,SHORTEST};
+
+	/**
+	 *
+	 */
+	private RouteType routeType;
+
+	/**
+	 * Logger.
+	 */
+	static Logger logger = Logger.getLogger(RoutingGraph.class);
+
+	/**
+	 * Graph state
+	 * <code>true</code> Graph in memory.
+	 * <code>false</code> Graph not created.
+	 */
+	public boolean graphState;
+
+	/**
+	 * OSM Graph.
+	 */
+//	private DirectedWeightedMultigraph<Node, OsmEdge> graph;
+//	private WeightedMultigraph<Node, OsmEdge> graph;
+	private Graph<Node, OsmEdge> graph;
+
+	/**
+	 * Speeds
+	 */
+	private Map<String,Double> waySpeeds;
+
+	/**
+	 * Default Constructor.
+	 */
+	public RoutingGraph() {
+		this.graphState = false;
+		this.graph = null;
+		routeType=RouteType.SHORTEST;
+		routingProfile=new RoutingProfile("default");
+		routingProfile.setOnewayUse(true); // Don't ignore oneways by default
+		this.setWaySpeeds(routingProfile.getWaySpeeds());
+		logger.debug("Created RoutingGraph");
+	}
+
+	/**
+	 * Create OSM graph for routing
+	 *
+	 * @return
+	 */
+	public void createGraph() {
+
+		logger.debug("Init Create Graph");
+		graph = new DirectedWeightedMultigraph<Node, OsmEdge>(OsmEdge.class);
+
+		// iterate all ways and segments for all nodes:
+		for (Way way : Main.ds.ways) {
+			if (way != null && !way.deleted && this.isvalidWay(way)) {
+				Node from = null;
+				for (Node to : way.nodes) {
+					// Ignore the node if deleted
+					if (!to.deleted) {
+						graph.addVertex(to);
+						if (from != null) {
+							addEdge(way, from, to);
+							if (!isOneWay(way)){
+								addEdge(way, to, from);}
+						}
+						from = to;
+					}
+				}
+			}
+		}
+		graph.vertexSet().size();
+		logger.debug("End Create Graph");
+		logger.debug("Vertex: "+graph.vertexSet().size());
+		logger.debug("Edges: "+graph.edgeSet().size());
+	}
+
+	/**
+	 * Compute weight and add edge to the graph
+	 * @param way
+	 * @param from
+	 * @param to
+	 */
+	private void addEdge(Way way,Node from, Node to) {
+		double length = from.coor.greatCircleDistance(to.coor);
+		// edge = new OsmEdge(way, length);
+		OsmEdge edge = new OsmEdge(way, from, to);
+		graph.addEdge(from, to, edge);
+		// weight = getWeight(way);
+		double weight = getWeight(way, length);
+		logger.debug("edge for way " + way.id
+				     + "(from node " + from.id + " to node "
+				     + to.id + ") has weight: " + weight);
+		//((GraphDelegator<Node,OsmEdge>) graph).setEdgeWeight(edge, weight);
+		((DirectedWeightedMultigraph<Node,OsmEdge>)graph).setEdgeWeight(edge, weight);
+	}
+
+	/**
+	 * Returns the weight for the given segment depending on the highway type
+	 * and the length of the segment. The higher the value, the less it is used
+	 * in routing.
+	 *
+	 * @param way
+	 *            the way.
+	 * @return
+	 */
+	private double getWeight(Way way, double length) {
+		// Default speed if no setting is found
+		double speed = 1;
+
+		switch (routeType) {
+		case SHORTEST:
+			// Same speed for all types of ways
+			if (this.waySpeeds.containsKey("residential"))
+				speed=this.waySpeeds.get("residential");
+			break;
+		case FASTEST:
+			// Each type of way may have a different speed
+			if (this.waySpeeds.containsKey(way.get("highway")))
+				speed=this.waySpeeds.get(way.get("highway"));
+			logger.debug("Speed="+speed);
+			break;
+		default:
+			break;
+		}
+		// Return the time spent to traverse the way
+		return length / speed;
+	}
+
+	/**
+	 * Check is One Way.
+	 *
+	 * @param way
+	 *            the way.
+	 * @return <code>true</code> is a one way. <code>false</code> is not a one
+	 *         way.
+	 */
+	private boolean isOneWay(Way way) {
+		// FIXME: oneway=-1 is ignored for the moment!
+		return way.get("oneway") != null
+				|| "motorway".equals(way.get("highway"));
+	}
+
+	/**
+	 * Check if a Way is correct.
+	 *
+	 * @param way
+	 *            The way.
+	 * @return <code>true</code> is valid. <code>false</code> is not valid.
+	 */
+	public boolean isvalidWay(Way way) {
+		if (!way.isTagged())
+			return false;
+
+		return way.get("highway") != null || way.get("junction") != null
+				|| way.get("service") != null;
+
+	}
+
+	public boolean isvalidNode(Node node) {
+		return true;
+	}
+
+	/**
+	 * Apply selected routing algorithm to the graph.
+	 *
+	 * @param nodes
+	 *            Nodes used to calculate path.
+	 * @param algorithm
+	 *            Algorithm used to compute the path,
+	 *            RoutingGraph.Algorithm.ROUTING_ALG_DIJKSTRA or
+	 *            RoutingGraph.Algorithm.ROUTING_ALG_BELLMANFORD
+	 * @return new path.
+	 */
+	public List<OsmEdge> applyAlgorithm(List<Node> nodes, Algorithm algorithm) {
+		List<OsmEdge> path = new ArrayList<OsmEdge>();
+		Graph<Node,OsmEdge> g;
+		double totalWeight = 0;
+
+		if (graph == null)
+			this.createGraph();
+		logger.debug("apply algorithm between nodes ");
+
+		for (Node node : nodes) {
+			logger.debug(node.id);
+		}
+		logger.debug("-----------------------------------");
+
+		// Assign the graph or an undirected view of the graph to g,
+		// depending on whether oneway tags are used or not
+		if (routingProfile.isOnewayUsed())
+			g = graph;
+		else
+			g = new AsUndirectedGraph<Node, OsmEdge>((DirectedWeightedMultigraph<Node,OsmEdge>)graph);
+
+		switch (algorithm) {
+		case ROUTING_ALG_DIJKSTRA:
+			logger.debug("Using Dijkstra algorithm");
+			DijkstraShortestPath<Node, OsmEdge> routingk = null;
+			for (int index = 1; index < nodes.size(); ++index) {
+				routingk = new DijkstraShortestPath<Node, OsmEdge>(g, nodes
+						.get(index - 1), nodes.get(index));
+				if (routingk.getPathEdgeList() == null) {
+					logger.debug("no path found!");
+					break;
+				}
+				path.addAll(routingk.getPathEdgeList());
+				totalWeight += routingk.getPathLength();
+			}
+			break;
+		case ROUTING_ALG_BELLMANFORD:
+			logger.debug("Using Bellman Ford algorithm");
+			for (int index = 1; index < nodes.size(); ++index) {
+				path = BellmanFordShortestPath.findPathBetween(g, nodes
+						.get(index - 1), nodes.get(index));
+				if (path == null) {
+					logger.debug("no path found!");
+					return null;
+				}
+			}
+			break;
+		default:
+			logger.debug("Wrong algorithm");
+			break;
+		}
+
+		logger.debug("shortest path found: " + path + "\nweight: "
+						+ totalWeight);
+		return path;
+	}
+
+	/**
+	 * Return the number of vertices.
+	 * @return the number of vertices.
+	 */
+	public int getVertexCount(){
+		int value=0;
+		if (graph!=null) value=graph.vertexSet().size();
+		return value;
+	}
+
+	/**
+	 * Return the number of edges.
+	 * @return the number of edges.
+	 */
+	public int getEdgeCount(){
+		int value=0;
+		if (graph!=null) value=graph.edgeSet().size();
+		return value;
+	}
+
+	/**
+	 * @param routeType the routeType to set
+	 */
+	public void setTypeRoute(RouteType routetype) {
+		this.routeType = routetype;
+	}
+
+	/**
+	 * @return the routeType
+	 */
+	public RouteType getTypeRoute() {
+		return routeType;
+	}
+
+	public Map<String, Double> getWaySpeeds() {
+		return waySpeeds;
+	}
+
+	public void setWaySpeeds(Map<String, Double> waySpeeds) {
+		this.waySpeeds = waySpeeds;
+	}
+
+	public void resetGraph() {
+		graph=null;
+	}
+
+	public RoutingProfile getRoutingProfile() {
+		return routingProfile;
+	}
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/RoutingGraphDelegator.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/RoutingGraphDelegator.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/RoutingGraphDelegator.java	(revision 14287)
@@ -0,0 +1,40 @@
+/**
+ * 
+ */
+package com.innovant.josm.jrt.core;
+
+import org.apache.log4j.Logger;
+import org.jgrapht.Graph;
+import org.jgrapht.graph.GraphDelegator;
+
+/**
+ * @author jose
+ *
+ */
+public class RoutingGraphDelegator<V, E> extends GraphDelegator<V, E> {
+
+	/**
+	 * Logger.
+	 */
+	static Logger logger = Logger.getLogger(RoutingGraphDelegator.class);
+	
+	public String name;
+	
+	
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	public RoutingGraphDelegator(Graph<V, E> arg0) {
+		super(arg0);
+		// TODO Auto-generated constructor stub
+	}
+	
+	@Override
+	public double getEdgeWeight(E arg0) {
+		logger.debug("call getEdgeWeight");
+		return super.getEdgeWeight(arg0);
+	}
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/RoutingProfile.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/RoutingProfile.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/RoutingProfile.java	(revision 14287)
@@ -0,0 +1,161 @@
+package com.innovant.josm.jrt.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.openstreetmap.josm.Main;
+
+
+/**
+ * This class holds information about a routing profile.
+ *
+ * A routing profile specifies the type of vehicle that will go through the route
+ * and the conditions with respect to the traversal of different types of edges
+ *
+ * For instance, a pedestrian can traverse streets in both directions, walk through
+ * pedestrian ways and almost all types of ways except motorways, climb steps, and
+ * can ignore turn restrictions, while a handicapped person would have the same profile
+ * except for climbing steps. A car can drive at the maximum allowed speed of the way,
+ * and can not use cycleways nor pedestrian ways, while a bicycle can, but its maximum
+ * speed for any type of way would be around 50km/h.
+ *
+ * When combined with public transit data, information of which types of transport modes
+ * are allowed for the vehicle can be stored in the profile. For instance, bicycles are
+ * usually allowed to travel on board of trains, trams and subways.
+ *
+ * @author juangui
+ *
+ */
+public class RoutingProfile {
+	/**
+	 * logger
+	 */
+	static Logger logger = Logger.getLogger(RoutingProfile.class);
+	/**
+	 * True if oneway is used for routing (i.e. for cars).
+	 */
+	private boolean useOneway;
+
+	/**
+	 * True if turn restrictions are used for routing (i.e. for cars).
+	 */
+	private boolean useRestrictions;
+
+	/**
+	 * True if maximum allowed speed of ways is considered for routing (i.e. for cars).
+	 */
+	private boolean useMaxAllowedSpeed;
+
+	/**
+	 * Name of the routing profile, for identification issues (i.e. "pedestrian").
+	 */
+	private String name;
+
+	/**
+	 * Holds traverse speed for each type of way, using the type as key.
+	 * A speed of zero means that this type of way cannot be traversed.
+	 */
+	private Map<String,Double> waySpeeds;
+
+
+
+	/**
+	 * Holds permission of use for each type of transport mode, using the mode as key.
+	 */
+	private Map<String,Boolean> allowedModes;
+
+	/**
+	 * Constructor
+	 * @param name The name for the routing profile. Please use a name that is
+	 * self descriptive, i.e., something that an application user would
+	 * understand (like "pedestrian", "motorbike", "bicycle", etc.)
+	 */
+	public RoutingProfile(String name) {
+		logger.debug("Init RoutingProfile with name: "+name);
+		this.name = name;
+		waySpeeds=new HashMap<String,Double>();
+		Map<String,String> prefs=Main.pref.getAllPrefix("routing.profile."+name+".speed");
+		for(String key:prefs.keySet()){
+			waySpeeds.put((key.split("\\.")[4]), Double.valueOf(prefs.get(key)));
+		}
+		for (String key:waySpeeds.keySet())
+			logger.debug(key+ "-- speed: "+waySpeeds.get(key));
+		logger.debug("End init RoutingProfile with name: "+name);
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setOnewayUse(boolean useOneway) {
+		this.useOneway = useOneway;
+	}
+
+	public boolean isOnewayUsed() {
+		return useOneway;
+	}
+
+	public void setRestrictionsUse(boolean useRestrictions) {
+		this.useRestrictions = useRestrictions;
+	}
+
+	public boolean isRestrictionsUsed() {
+		return useRestrictions;
+	}
+
+	public void setMaxAllowedSpeedUse(boolean useMaxAllowedSpeed) {
+		this.useMaxAllowedSpeed = useMaxAllowedSpeed;
+	}
+
+	public boolean isMaxAllowedSpeedUsed() {
+		return useMaxAllowedSpeed;
+	}
+
+	public void setWayTypeSpeed(String type, double speed) {
+		waySpeeds.put(type, speed);
+	}
+
+	public void setTransportModePermission(String mode, boolean permission) {
+		allowedModes.put(mode, permission);
+	}
+
+	/**
+	 * Return whether the driving profile specifies that a particular type of way
+	 * can be traversed
+	 * @param type Key for the way type
+	 * @return True if the way type can be traversed
+	 */
+	public boolean isWayTypeAllowed(String type) {
+		if (waySpeeds.get(type) != 0.0)
+			return true;
+		return false;
+	}
+
+	/**
+	 * Return whether the driving profile specifies that a particular type of transport
+	 * mode can be used
+	 * @param mode Key for the way type
+	 * @return True if the way type can be traversed
+	 */
+	public boolean isTransportModeAllowed(String mode) {
+		return allowedModes.get(mode);
+	}
+
+	public double getSpeed(String key){
+		if(!waySpeeds.containsKey(key)) return 0.0;
+		return waySpeeds.get(key);
+	}
+
+	public Map<String, Double> getWaySpeeds() {
+		return waySpeeds;
+	}
+
+	public void setWaySpeeds(Map<String, Double> waySpeeds) {
+		this.waySpeeds = waySpeeds;
+	}
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/gtfs/GTFSTransportModes.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/gtfs/GTFSTransportModes.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/gtfs/GTFSTransportModes.java	(revision 14287)
@@ -0,0 +1,57 @@
+package com.innovant.josm.jrt.gtfs;
+
+/**
+ * Constants for parsing GTFS and to use in Routing Profiles
+ * @author juangui
+ * TODO Using integers is suitable to parse gtfs feeds but
+ * Routing Profile keys should be Strings
+ */
+public class GTFSTransportModes {
+
+	/**
+	 * 0 - Tram, Streetcar, Light rail. Any light rail or street level system within
+	 *     a metropolitan area.
+	 */
+	public static final int TRAM = 0;
+	public static final int STREETCAR = 0;
+	public static final int LIGHT_RAIL = 0;
+
+	/**
+	 * 1 - Subway, Metro. Any underground rail system within a metropolitan area.
+	 */
+	public static final int SUBWAY = 1;
+	public static final int METRO = 1;
+
+    /**
+     * 2 - Rail. Used for intercity or long-distance travel.
+     */
+	public static final int RAIL = 2;
+
+    /**
+     * 3 - Bus. Used for short- and long-distance bus routes.
+     */
+	public static final int BUS = 3;
+
+    /**
+     * 4 - Ferry. Used for short- and long-distance boat service.
+     */
+	public static final int FERRY = 4;
+
+	/**
+	 * 5 - Cable car. Used for street-level cable cars where the cable runs beneath the car.
+	 */
+	public static final int CABLE_CAR = 5;
+
+	/**
+	 * 6 - Gondola, Suspended cable car. Typically used for aerial cable cars where
+	 *     the car is suspended from the cable.
+	 */
+	public static final int GONDOLA = 6;
+	public static final int SUSPENDED_CABLE_CAR = 6;
+
+    /**
+     * 7 - Funicular. Any rail system designed for steep inclines.
+     */
+	public static final int FUNICULAR = 7;
+
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/osm/OsmEdge.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/osm/OsmEdge.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/osm/OsmEdge.java	(revision 14287)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008 Innovant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, please contact:
+ *
+ *  Innovant
+ *   juangui@gmail.com
+ *   vidalfree@gmail.com
+ *
+ *  http://public.grupoinnovant.com/blog
+ *
+ */
+package com.innovant.josm.jrt.osm;
+
+import org.jgrapht.graph.DefaultWeightedEdge;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Way;
+
+public class OsmEdge extends DefaultWeightedEdge {
+ /**
+  * Serial
+  */
+  private static final long serialVersionUID = 1L;
+  private Way way;
+  private Node from, to;
+  private double length;
+
+  /**
+   * Constructor
+   * @param way
+   * @param length
+   */
+  public OsmEdge(Way way, Node from, Node to) {
+	  	super();
+	  	this.way = way;
+	  	this.from = from;
+	  	this.to = to;
+	  	this.length = from.coor.greatCircleDistance(to.coor);
+	  }
+
+  /**
+   * @return the way
+   */
+  public Way getWay() {
+      return this.way;
+  }
+
+  public EastNorth fromEastNorth() {
+      return this.from.eastNorth;
+  }
+
+  public EastNorth toEastNorth() {
+      return this.to.eastNorth;
+  }
+
+  /**
+   * Returns length of segment in meters
+   * @return length of segment in meters.
+   */
+  public double getLength() {
+  	return length;
+  }
+
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/osm/OsmWayTypes.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/osm/OsmWayTypes.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/osm/OsmWayTypes.java	(revision 14287)
@@ -0,0 +1,79 @@
+/*
+ *
+ * Copyright (C) 2008 Innovant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, please contact:
+ *
+ *  Innovant
+ *   juangui@gmail.com
+ *   vidalfree@gmail.com
+ *
+ *  http://public.grupoinnovant.com/blog
+ *
+ */
+
+package com.innovant.josm.jrt.osm;
+
+/**
+ * @author jvidal
+ *
+ */
+public enum OsmWayTypes {
+	MOTORWAY ("motorway",120),
+	MOTORWAY_LINK ("motorway_link",120),
+	TRUNK ("trunk",120),
+	TRUNK_LINK ("trunk_link",120),
+	PRIMARY  ("primary",100),
+	PRIMARY_LINK ("primary_link",100),
+	SECONDARY ("secondary",90),
+	TERTIARY ("tertiary",90),
+	UNCLASSIFIED ("unclassified",50),
+	ROAD ("road",100),
+    RESIDENTIAL ("residential",50),
+	LIVING_STREET ("living_street",30),
+	SERVICE ("service",30),
+	TRACK ("track",50),
+	PEDESTRIAN ("pedestrian",30),
+	BUS_GUIDEWAY ("bus_guideway",50),
+	PATH ("path",40),
+	CYCLEWAY ("cycleway",40),
+	FOOTWAY ("footway",20),
+	BRIDLEWAY ("bridleway",40),
+	BYWAY ("byway",50),
+	STEPS ("steps",10);
+
+	/**
+	 * Default Constructor
+	 * @param tag
+	 */
+	OsmWayTypes(String tag,int speed) {
+		this.tag = tag;
+		this.speed = speed;
+	}
+
+	/**
+	 * Tag
+	 */
+	private final String tag;
+	private final int speed;
+
+	/**
+	 * @return
+	 */
+	public String getTag() {return tag;};
+	public int getSpeed() {return speed;};
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/RoutingLayer.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/RoutingLayer.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/RoutingLayer.java	(revision 14287)
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2008 Innovant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, please contact:
+ *
+ *  Innovant
+ *   juangui@gmail.com
+ *   vidalfree@gmail.com
+ *
+ *  http://public.grupoinnovant.com/blog
+ *
+ */
+
+package com.innovant.josm.plugin.routing;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Stroke;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.swing.Icon;
+import javax.swing.JMenuItem;
+import javax.swing.JSeparator;
+
+import org.apache.log4j.Logger;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.RenameLayerAction;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
+import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.tools.ColorHelper;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+import com.innovant.josm.jrt.core.PreferencesKeys;
+import com.innovant.josm.jrt.osm.OsmEdge;
+
+
+/**
+ * A JOSM layer that encapsulates the representation of the shortest path.
+ * @author juangui
+ * @author Jose Vidal
+ */
+public class RoutingLayer extends Layer {
+
+	/**
+	 * Logger
+	 */
+	static Logger logger = Logger.getLogger(RoutingLayer.class);
+
+    /**
+     * Constant
+     */
+    private static final double ARROW_PHI = Math.toRadians(20);
+
+    /**
+     * Routing Model
+     */
+    private RoutingModel routingModel;
+
+    /**
+     * Icon Start Middle End
+     */
+    private Icon startIcon,middleIcon,endIcon;
+
+    /**
+     * Flag that manager activation layer
+     */
+    private boolean layerAdded = false;
+
+    /**
+     * Default constructor
+     * @param name Layer name.
+     */
+	public RoutingLayer(String name) {
+		super(name);
+		logger.debug("Init Routing Layer");
+        if(startIcon == null) startIcon = ImageProvider.get("routing", "startflag");
+        if(middleIcon == null) middleIcon = ImageProvider.get("routing", "middleflag");
+        if(endIcon == null) endIcon = ImageProvider.get("routing", "endflag");
+        this.routingModel = new RoutingModel();
+        logger.debug("End init Routing Layer");
+	}
+
+	/**
+	 * Getter Routing Model.
+	 * @return the routingModel
+	 */
+	public RoutingModel getRoutingModel() {
+		return this.routingModel;
+	}
+
+	/**
+	 * Check if layer is load.
+	 * @return <code>true</code> Layer load.
+	 *         <code>false</code> Layer don't load.
+	 */
+	public boolean isLayerAdded() {
+		return layerAdded;
+	}
+
+	/**
+	 * Setter layer active.
+	 */
+	public void setLayerAdded() {
+		layerAdded = true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.openstreetmap.josm.gui.layer.Layer#getIcon()
+	 */
+	@Override
+	public Icon getIcon() {
+        Icon icon = ImageProvider.get("layer", "routing_small");
+        return icon;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.openstreetmap.josm.gui.layer.Layer#getInfoComponent()
+	 */
+	@Override
+	public Object getInfoComponent() {
+		String info = "<html>"
+						+ "<body>"
+							+"Graph Vertex: "+this.routingModel.routingGraph.getVertexCount()+"<br/>"
+							+"Graph Edges: "+this.routingModel.routingGraph.getEdgeCount()+"<br/>"
+						+ "</body>"
+					+ "</html>";
+        return info;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.openstreetmap.josm.gui.layer.Layer#getMenuEntries()
+	 */
+	@Override
+	public Component[] getMenuEntries() {
+        Collection<Component> components = new ArrayList<Component>();
+        components.add(new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)));
+        components.add(new JMenuItem(new LayerListDialog.ShowHideMarkerText(this)));
+        components.add(new JMenuItem(new LayerListDialog.DeleteLayerAction(this)));
+        components.add(new JSeparator());
+        components.add(new JMenuItem(new RenameLayerAction(associatedFile, this)));
+        components.add(new JSeparator());
+        components.add(new JMenuItem(new LayerListPopup.InfoAction(this)));
+        return components.toArray(new Component[0]);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.openstreetmap.josm.gui.layer.Layer#getToolTipText()
+	 */
+	@Override
+	public String getToolTipText() {
+		if (routingModel.getRouteEdges() != null) {
+			// If there's a calculated route
+	        return "Showing calculated route. You can still add route nodes and compute a new route or delete layer to start a new route";
+		} else if (routingModel.getSelectedNodes() != null) {
+			// If there are some route nodes but not a calculated route
+	        return "Keep selecting route nodes and compute route";
+		}
+        return "Select as many route nodes as you want and compute route";
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.openstreetmap.josm.gui.layer.Layer#isMergable(org.openstreetmap.josm.gui.layer.Layer)
+	 */
+	@Override
+	public boolean isMergable(Layer other) {
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.openstreetmap.josm.gui.layer.Layer#mergeFrom(org.openstreetmap.josm.gui.layer.Layer)
+	 */
+	@Override
+	public void mergeFrom(Layer from) {
+		// This layer is not mergable, so do nothing
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.openstreetmap.josm.gui.layer.Layer#paint(java.awt.Graphics, org.openstreetmap.josm.gui.MapView)
+	 */
+	@Override
+	public void paint(Graphics g, MapView mv) {
+		// Get routing nodes (start, middle, end)
+        List<Node> nodes = routingModel.getSelectedNodes();
+        if(nodes == null || nodes.size() == 0) {
+        	logger.debug("no nodes selected");
+            return;
+        }
+
+        // Get path stroke color from preferences
+//		Main.pref.hasKey(PreferencesKeys.KEY_ROUTE_COLOR.key);
+        String colorString = Main.pref.get(PreferencesKeys.KEY_ROUTE_COLOR.key);
+        if(colorString.length() == 0) {
+            colorString = ColorHelper.color2html(Color.RED);
+            // FIXME add after good color is found: Main.pref.put(KEY_ROUTE_COLOR, colorString);
+        }
+        Color color = ColorHelper.html2color(colorString);
+
+        // Get path stroke width from preferences
+        String widthString = Main.pref.get(PreferencesKeys.KEY_ROUTE_WIDTH.key);
+        if(widthString.length() == 0) {
+            widthString = "8";
+            // FIXME add after good width is found: Main.pref.put(KEY_ROUTE_WIDTH, widthString);
+        }
+        int width = Integer.parseInt(widthString);
+
+        // Paint routing path
+        List<OsmEdge> routeEdges = routingModel.getRouteEdges();
+        if(routeEdges != null) {
+            for(OsmEdge edge : routeEdges) {
+                drawEdge(g, mv, edge, color, width, true);
+            }
+        }
+
+        // paint start icon
+        Node node = nodes.get(0);
+        Point screen = mv.getPoint(node.eastNorth);
+        startIcon.paintIcon(mv, g, screen.x - startIcon.getIconWidth()/2,
+        		screen.y - startIcon.getIconHeight());
+
+        // paint middle icons
+        for(int index = 1; index < nodes.size() - 1; ++index) {
+            node = nodes.get(index);
+            screen = mv.getPoint(node.eastNorth);
+            middleIcon.paintIcon(mv, g, screen.x - startIcon.getIconWidth()/2,
+            		screen.y - middleIcon.getIconHeight());
+        }
+        // paint end icon
+        if(nodes.size() > 1) {
+            node = nodes.get(nodes.size() - 1);
+            screen = mv.getPoint(node.eastNorth);
+            endIcon.paintIcon(mv, g, screen.x - startIcon.getIconWidth()/2,
+            		screen.y - endIcon.getIconHeight());
+        }
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.openstreetmap.josm.gui.layer.Layer#visitBoundingBox(org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor)
+	 */
+	@Override
+	public void visitBoundingBox(BoundingXYVisitor v) {
+        for (Node node : routingModel.getSelectedNodes()) {
+            v.visit(node);
+        }
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.openstreetmap.josm.gui.layer.Layer#destroy()
+	 */
+	@Override
+    public void destroy() {
+		routingModel.reset();
+		layerAdded = false;
+	}
+
+    /**
+     * Draw a line with the given color.
+     */
+    private void drawEdge(Graphics g, MapView mv, OsmEdge edge, Color col, int width,
+    		boolean showDirection) {
+        g.setColor(col);
+        Point from;
+        Point to;
+        from = mv.getPoint(edge.fromEastNorth());
+        to = mv.getPoint(edge.toEastNorth());
+
+            Graphics2D g2d = (Graphics2D)g;
+            Stroke oldStroke = g2d.getStroke();
+            g2d.setStroke(new BasicStroke(width)); // thickness
+            g.drawLine(from.x, from.y, to.x, to.y);
+            if (showDirection) {
+                double t = Math.atan2(to.y-from.y, to.x-from.x) + Math.PI;
+                g.drawLine(to.x,to.y, (int)(to.x + 10*Math.cos(t-ARROW_PHI)), (int)(to.y + 10*Math.sin(t-ARROW_PHI)));
+                g.drawLine(to.x,to.y, (int)(to.x + 10*Math.cos(t+ARROW_PHI)), (int)(to.y + 10*Math.sin(t+ARROW_PHI)));
+            }
+            g2d.setStroke(oldStroke);
+    }
+
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/RoutingModel.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/RoutingModel.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/RoutingModel.java	(revision 14287)
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2008 Innovant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, please contact:
+ *
+ *  Innovant
+ *   juangui@gmail.com
+ *   vidalfree@gmail.com
+ *
+ *  http://public.grupoinnovant.com/blog
+ *
+ */
+
+package com.innovant.josm.plugin.routing;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.openstreetmap.josm.data.osm.Node;
+
+import com.innovant.josm.jrt.core.RoutingGraph;
+import com.innovant.josm.jrt.core.RoutingGraph.Algorithm;
+import com.innovant.josm.jrt.osm.OsmEdge;
+
+
+/**
+ * This class holds all the routing data and operations
+ * @author juangui
+ * @author Jose Vidal
+ *
+ */
+public class RoutingModel {
+
+	/**
+	 * Logger
+	 */
+	static Logger logger = Logger.getLogger(RoutingModel.class);
+
+    /**
+     * Graph to calculate route
+     */
+	public RoutingGraph routingGraph;
+
+    /**
+     * List of nodes that the route has to traverse
+     */
+    private List<Node> nodes;
+
+    private List<OsmEdge> path=null;
+    /**
+     * Flag to advise about changes in the selected nodes.
+     */
+    private boolean changeNodes=false;
+    /**
+     * Default Constructor.
+     */
+	public RoutingModel() {
+        nodes = new ArrayList<Node>();
+        routingGraph = new RoutingGraph();
+	}
+
+    /**
+     * Method that returns the selected nodes to calculate route.
+     * @return the selectedNodes
+     */
+    public List<Node> getSelectedNodes() {
+        return nodes;
+    }
+
+    /**
+     * Adds a node to the route node list.
+     * @param node the node to add.
+     */
+    public void addNode(Node node) {
+        nodes.add(node);
+        this.changeNodes=true;
+    }
+
+    /**
+     * Removes a node from the route node list.
+     * @param index the index of the node to remove.
+     */
+    public void removeNode(int index) {
+    	if (nodes.size()>index)	{
+    		nodes.remove(index);
+    		this.changeNodes=true;
+    	}
+    }
+
+    /**
+     * Inserts a node in the route node list.
+     * @param index the index where the node will be inserted
+     * @param node the node to be inserted
+     */
+    public void insertNode(int index, Node node) {
+    	if (nodes.size()>=index) {
+    		nodes.add(index, node);
+    		this.changeNodes=true;
+    	}
+    }
+
+    /**
+     * Reverse list of nodes
+     */
+    public void reverseNodes() {
+    	List<Node> aux = new ArrayList<Node>();
+    	for (Node n : nodes) {
+    		aux.add(0,n);
+    	}
+    	nodes = aux;
+    	this.changeNodes=true;
+    }
+
+    /**
+     * Get the edges of the route.
+     * @return A list of edges forming the shortest path
+     */
+    public List<OsmEdge> getRouteEdges() {
+    	if (this.changeNodes || path==null)
+    	{
+    		path=this.routingGraph.applyAlgorithm(nodes, Algorithm.ROUTING_ALG_DIJKSTRA);
+    		this.changeNodes=false;
+    	}
+    	return path;
+    }
+
+    /**
+     * Marks that some node or the node order has changed so the path should be computed again
+     */
+    public void setNodesChanged() {
+    	this.changeNodes = true;
+    }
+
+    /**
+     * Resets all data.
+     */
+    public void reset() {
+        nodes.clear();
+        this.changeNodes=true;
+    }
+
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/RoutingPlugin.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/RoutingPlugin.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/RoutingPlugin.java	(revision 14287)
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2008 Innovant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, please contact:
+ *
+ *  Innovant
+ *   juangui@gmail.com
+ *   vidalfree@gmail.com
+ *
+ *  http://public.grupoinnovant.com/blog
+ *
+ */
+
+package com.innovant.josm.plugin.routing;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.xml.DOMConfigurator;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.IconToggleButton;
+import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener;
+import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
+import org.openstreetmap.josm.plugins.Plugin;
+
+import com.innovant.josm.plugin.routing.actions.AddRouteNodeAction;
+import com.innovant.josm.plugin.routing.actions.MoveRouteNodeAction;
+import com.innovant.josm.plugin.routing.actions.RemoveRouteNodeAction;
+import com.innovant.josm.plugin.routing.gui.RoutingDialog;
+import com.innovant.josm.plugin.routing.gui.RoutingMenu;
+import com.innovant.josm.plugin.routing.gui.RoutingPreferenceDialog;
+
+/**
+ * The main class of the routing plugin
+ * @author juangui
+ * @author Jose Vidal
+ *
+ * @version 0.3
+ */
+public class RoutingPlugin extends Plugin implements LayerChangeListener {
+	/**
+	 * Logger
+	 */
+	static Logger logger = Logger.getLogger(RoutingPlugin.class);
+
+	/**
+	 * Displays the layer menu when right clicking on the layer name, and manages
+	 * how to paint the layer.
+	 */
+    private RoutingLayer routingLayer;
+
+    /**
+     * The side dialog where nodes are listed
+     */
+    private RoutingDialog routingDialog;
+
+    /**
+     * Preferences Settings Dialog.
+     */
+    private PreferenceSetting preferenceSettings;
+
+    /**
+     * MapMode for adding route nodes.
+     * We use this field to enable or disable the mode automatically.
+     */
+    private AddRouteNodeAction addRouteNodeAction;
+
+    /**
+     * MapMode for removing route nodes.
+     * We use this field to enable or disable the mode automatically.
+     */
+    private RemoveRouteNodeAction removeRouteNodeAction;
+
+    /**
+     * MapMode for moving route nodes.
+     * We use this field to enable or disable the mode automatically.
+     */
+    private MoveRouteNodeAction moveRouteNodeAction;
+
+    /**
+     * IconToggleButton for adding route nodes, we use this field to show or hide the button.
+     */
+    private IconToggleButton addRouteNodeButton;
+
+    /**
+     * IconToggleButton for removing route nodes, we use this field to show or hide the button.
+     */
+    private IconToggleButton removeRouteNodeButton;
+
+    /**
+     * IconToggleButton for moving route nodes, we use this field to show or hide the button.
+     */
+    private IconToggleButton moveRouteNodeButton;
+
+    /**
+     * Reference for the plugin class (as if it were a singleton)
+     */
+    private static RoutingPlugin plugin;
+
+    /**
+     * Default Constructor
+     */
+	public RoutingPlugin() {
+		super();
+		//FIXME: maybe check if plugin already exists
+		plugin = this; // Assign reference to the plugin class
+		DOMConfigurator.configure("log4j.xml");
+		logger.debug("Loading routing plugin...");
+		preferenceSettings=new RoutingPreferenceDialog();
+		// Create side dialog
+		routingDialog = new RoutingDialog();
+        // Add routing layer
+        routingLayer = new RoutingLayer(tr("Navigation"));
+        Main.main.menu.add(new RoutingMenu(tr("Routing")));
+        // Register this class as LayerChangeListener
+        Layer.listeners.add(this);
+        logger.debug("Finished loading plugin");
+	}
+
+	/**
+	 * Provides static access to the plugin instance, to enable access to the plugin methods
+	 * @return the instance of the plugin
+	 */
+	public static RoutingPlugin getInstance() {
+		return plugin;
+	}
+
+	/**
+	 * Get the routing layer
+	 * @return The instance of the routing layer
+	 */
+	public RoutingLayer getRoutingLayer() {
+		return routingLayer;
+	}
+
+	/**
+	 * Get the routing side dialog
+	 * @return The instance of the routing side dialog
+	 */
+	public RoutingDialog getRoutingDialog() {
+		return routingDialog;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.Plugin#mapFrameInitialized(org.openstreetmap.josm.gui.MapFrame, org.openstreetmap.josm.gui.MapFrame)
+	 */
+    @Override
+    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
+        if(newFrame != null) {
+        	// Create plugin map modes
+        	addRouteNodeAction = new AddRouteNodeAction(newFrame);
+        	removeRouteNodeAction = new RemoveRouteNodeAction(newFrame);
+        	moveRouteNodeAction = new MoveRouteNodeAction(newFrame);
+        	// Create plugin buttons and add them to the tool bar
+        	addRouteNodeButton = new IconToggleButton(addRouteNodeAction);
+        	removeRouteNodeButton = new IconToggleButton(removeRouteNodeAction);
+        	moveRouteNodeButton = new IconToggleButton(moveRouteNodeAction);
+            newFrame.addMapMode(addRouteNodeButton);
+            newFrame.addMapMode(removeRouteNodeButton);
+            newFrame.addMapMode(moveRouteNodeButton);
+            newFrame.toolGroup.add(addRouteNodeButton);
+            newFrame.toolGroup.add(removeRouteNodeButton);
+            newFrame.toolGroup.add(moveRouteNodeButton);
+            // Hide them by default
+			addRouteNodeButton.setVisible(false);
+			removeRouteNodeButton.setVisible(false);
+			moveRouteNodeButton.setVisible(false);
+            newFrame.addToggleDialog(routingDialog);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener#activeLayerChange(org.openstreetmap.josm.gui.layer.Layer, org.openstreetmap.josm.gui.layer.Layer)
+     */
+	public void activeLayerChange(Layer oldLayer, Layer newLayer) {}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener#layerAdded(org.openstreetmap.josm.gui.layer.Layer)
+	 */
+	public void layerAdded(Layer newLayer) {
+		// Add button(s) to the tool bar when the routing layer is added
+		if (newLayer instanceof RoutingLayer) {
+			newLayer.name=tr("Routing")+" ["+Main.map.mapView.getActiveLayer().name+"]";
+			addRouteNodeButton.setVisible(true);
+			removeRouteNodeButton.setVisible(true);
+			moveRouteNodeButton.setVisible(true);
+			logger.debug("Added routing layer.");
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener#layerRemoved(org.openstreetmap.josm.gui.layer.Layer)
+	 */
+	public void layerRemoved(Layer oldLayer) {
+		// Remove button(s) from the tool bar when the routing layer is removed
+		if (oldLayer instanceof RoutingLayer) {
+			addRouteNodeButton.setVisible(false);
+			removeRouteNodeButton.setVisible(false);
+			moveRouteNodeButton.setVisible(false);
+    		logger.debug("Removed routing layer.");
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.Plugin#getPreferenceSetting()
+	 */
+	@Override
+	public PreferenceSetting getPreferenceSetting() {
+		return preferenceSettings;
+	}
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/actions/AddRouteNodeAction.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/actions/AddRouteNodeAction.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/actions/AddRouteNodeAction.java	(revision 14287)
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2008 Innovant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, please contact:
+ *
+ *  Innovant
+ *   juangui@gmail.com
+ *   vidalfree@gmail.com
+ *
+ *  http://public.grupoinnovant.com/blog
+ *
+ */
+
+package com.innovant.josm.plugin.routing.actions;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.MouseEvent;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.mapmode.MapMode;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.WaySegment;
+import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+import com.innovant.josm.plugin.routing.RoutingLayer;
+import com.innovant.josm.plugin.routing.RoutingModel;
+import com.innovant.josm.plugin.routing.RoutingPlugin;
+import com.innovant.josm.plugin.routing.gui.RoutingDialog;
+
+/**
+ * Accounts for the selection or unselection of the routing tool in the tool bar,
+ * and the mouse events when this tool is selected
+ * @author Juangui
+ * @author Jose Vidal
+ *
+ */
+public class AddRouteNodeAction extends MapMode {
+	/**
+	 * Serial.
+	 */
+	private static final long serialVersionUID = 1L;
+	/**
+	 * Logger.
+	 */
+	static Logger logger = Logger.getLogger(AddRouteNodeAction.class);
+    /**
+     * Routing Model.
+     */
+	private RoutingModel routingModel;
+	/**
+	 * Routing Layer.
+	 */
+    private RoutingLayer routingLayer;
+	/**
+	 * Routing Dialog.
+	 */
+    private RoutingDialog routingDialog;
+
+    /**
+     * Constructor
+     * @param mapFrame
+     */
+	public AddRouteNodeAction(MapFrame mapFrame) {
+		// TODO Use constructor with shortcut
+		super(tr("Routing"), "add",
+				tr("Click to add route nodes."),
+				mapFrame, ImageProvider.getCursor("crosshair", null));
+        this.routingLayer = RoutingPlugin.getInstance().getRoutingLayer();
+        this.routingModel = routingLayer.getRoutingModel();
+        this.routingDialog = RoutingPlugin.getInstance().getRoutingDialog();
+	}
+
+    @Override public void enterMode() {
+        super.enterMode();
+        Main.map.mapView.addMouseListener(this);
+    }
+
+    @Override public void exitMode() {
+        super.exitMode();
+        Main.map.mapView.removeMouseListener(this);
+    }
+
+    @Override public void mouseClicked(MouseEvent e) {
+        // If left button is clicked
+        if (e.getButton() == MouseEvent.BUTTON1) {
+        	// Search for nearest highway node
+        	Node node = null;
+        	List<WaySegment> wsl = Main.map.mapView.getNearestWaySegments(e.getPoint());
+        	for (WaySegment ws:wsl) {
+        		if (ws.way.get("highway")!=null) {
+        			// If waysegment belongs to a highway compare the distance from
+        			// both waysegment nodes to the point clicked and keep the nearest one
+        			Node node0 = ws.way.nodes.get(ws.lowerIndex);
+        			Node node1 = ws.way.nodes.get(ws.lowerIndex + 1);
+        			double d0 = Main.map.mapView.getPoint(node0.eastNorth).distanceSq(e.getPoint());
+        			double d1 = Main.map.mapView.getPoint(node1.eastNorth).distanceSq(e.getPoint());
+        			if (d0<d1)
+        				node = node0;
+        			else
+        				node = node1;
+        			break;
+        		}
+        	}
+            logger.debug("selected node " + node);
+            if(node == null) {
+            	logger.debug("no selected node");
+                return;
+            }
+            routingModel.addNode(node);
+            routingDialog.addNode(node.id+" ["+node.coor.toDisplayString()+"]");
+        }
+        Main.map.repaint();
+    }
+
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/actions/MoveRouteNodeAction.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/actions/MoveRouteNodeAction.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/actions/MoveRouteNodeAction.java	(revision 14287)
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2008 Innovant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, please contact:
+ *
+ *  Innovant
+ *   juangui@gmail.com
+ *   vidalfree@gmail.com
+ *
+ *  http://public.grupoinnovant.com/blog
+ *
+ */
+
+package com.innovant.josm.plugin.routing.actions;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Point;
+import java.awt.event.MouseEvent;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.mapmode.MapMode;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.WaySegment;
+import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+import com.innovant.josm.plugin.routing.RoutingLayer;
+import com.innovant.josm.plugin.routing.RoutingModel;
+import com.innovant.josm.plugin.routing.RoutingPlugin;
+import com.innovant.josm.plugin.routing.gui.RoutingDialog;
+
+/**
+ * Accounts for the selection or unselection of the routing tool in the tool bar,
+ * and the mouse events when this tool is selected
+ * @author Juangui
+ * @author Jose Vidal
+ *
+ */
+public class MoveRouteNodeAction extends MapMode {
+	/**
+	 * Serial.
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Square of the distance radius where route nodes can be selected for dragging
+	 */
+	private static final int DRAG_SQR_RADIUS = 100;
+
+	/**
+	 * Logger.
+	 */
+	static Logger logger = Logger.getLogger(RoutingLayer.class);
+
+	/**
+     * Routing Model.
+     */
+	private RoutingModel routingModel;
+
+	/**
+	 * Routing Layer.
+	 */
+    private RoutingLayer routingLayer;
+
+	/**
+	 * Routing Dialog.
+	 */
+    private RoutingDialog routingDialog;
+
+    /**
+     * Index of dragged node
+     */
+    private int index;
+
+    /**
+     * Constructor
+     * @param mapFrame
+     */
+	public MoveRouteNodeAction(MapFrame mapFrame) {
+		// TODO Use constructor with shortcut
+		super(tr("Routing"), "move",
+				tr("Click and drag to move route nodes."),
+				mapFrame, ImageProvider.getCursor("normal", "move"));
+        this.routingLayer = RoutingPlugin.getInstance().getRoutingLayer();
+        this.routingModel = routingLayer.getRoutingModel();
+        this.routingDialog = RoutingPlugin.getInstance().getRoutingDialog();
+	}
+
+    @Override public void enterMode() {
+        super.enterMode();
+        Main.map.mapView.addMouseListener(this);
+    }
+
+    @Override public void exitMode() {
+        super.exitMode();
+        Main.map.mapView.removeMouseListener(this);
+    }
+
+    @Override public void mousePressed(MouseEvent e) {
+        // If left button is pressed
+        if (e.getButton() == MouseEvent.BUTTON1) {
+        	// Search for the nearest node in the list
+        	List<Node> nl = routingModel.getSelectedNodes();
+        	index = -1;
+        	double dmax = DRAG_SQR_RADIUS; // maximum distance, in pixels
+           	for (int i=0;i<nl.size();i++) {
+           		Node node = nl.get(i);
+        		double d = Main.map.mapView.getPoint(node.eastNorth).distanceSq(e.getPoint());
+        		if (d < dmax) {
+        			dmax = d;
+        			index = i;
+        		}
+        	}
+           	if (index>=0)
+                logger.debug("Moved from node " + nl.get(index));
+        }
+    }
+
+    @Override public void mouseReleased(MouseEvent e) {
+    	// If left button is released and a route node is being dragged
+    	if ((e.getButton() == MouseEvent.BUTTON1) && (index>=0)) {
+    		searchAndReplaceNode(e.getPoint());
+        }
+    }
+
+    @Override public void mouseDragged(MouseEvent e) {
+    }
+
+    private void searchAndReplaceNode(Point point) {
+    	// Search for nearest highway node
+    	Node node = null;
+    	List<WaySegment> wsl = Main.map.mapView.getNearestWaySegments(point);
+    	for (WaySegment ws:wsl) {
+    		if (ws.way.get("highway")!=null) {
+    			// If waysegment belongs to a highway compare the distance from
+    			// both waysegment nodes to the point clicked and keep the nearest one
+    			Node node0 = ws.way.nodes.get(ws.lowerIndex);
+    			Node node1 = ws.way.nodes.get(ws.lowerIndex + 1);
+    			double d0 = Main.map.mapView.getPoint(node0.eastNorth).distanceSq(point);
+    			double d1 = Main.map.mapView.getPoint(node1.eastNorth).distanceSq(point);
+    			if (d0<d1)
+    				node = node0;
+    			else
+    				node = node1;
+    			break;
+    		}
+    	}
+        if (node == null) {
+        	logger.debug("Didn't found a close node to move to.");
+            return;
+        }
+        logger.debug("Moved to node " + node);
+        routingModel.removeNode(index);
+		routingDialog.removeNode(index);
+        routingModel.insertNode(index, node);
+		routingDialog.insertNode(index,node.id+" ["+node.coor.toDisplayString()+"]");
+        Main.map.repaint();
+    }
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/actions/RemoveRouteNodeAction.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/actions/RemoveRouteNodeAction.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/actions/RemoveRouteNodeAction.java	(revision 14287)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2008 Innovant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, please contact:
+ *
+ *  Innovant
+ *   juangui@gmail.com
+ *   vidalfree@gmail.com
+ *
+ *  http://public.grupoinnovant.com/blog
+ *
+ */
+
+package com.innovant.josm.plugin.routing.actions;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.MouseEvent;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.mapmode.MapMode;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+import com.innovant.josm.plugin.routing.RoutingLayer;
+import com.innovant.josm.plugin.routing.RoutingModel;
+import com.innovant.josm.plugin.routing.RoutingPlugin;
+import com.innovant.josm.plugin.routing.gui.RoutingDialog;
+
+/**
+ * Accounts for the selection or unselection of the remove route nodes tool in the tool bar,
+ * and the mouse events when this tool is selected
+ * @author Juangui
+ * @author Jose Vidal
+ *
+ */
+public class RemoveRouteNodeAction extends MapMode {
+	/**
+	 * Serial.
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Square of the distance radius where route nodes can be removed
+	 */
+	private static final int REMOVE_SQR_RADIUS = 100;
+
+	/**
+	 * Logger.
+	 */
+	static Logger logger = Logger.getLogger(RoutingLayer.class);
+    /**
+     * Routing Model.
+     */
+	private RoutingModel routingModel;
+	/**
+	 * Routing Layer.
+	 */
+    private RoutingLayer routingLayer;
+	/**
+	 * Routing Dialog.
+	 */
+    private RoutingDialog routingDialog;
+
+	public RemoveRouteNodeAction(MapFrame mapFrame) {
+		// TODO Use constructor with shortcut
+		super(tr("Routing"), "remove",
+				tr("Remove route nodes"),
+				mapFrame, ImageProvider.getCursor("normal", "delete"));
+        this.routingLayer = RoutingPlugin.getInstance().getRoutingLayer();
+        this.routingModel = routingLayer.getRoutingModel();
+        this.routingDialog = RoutingPlugin.getInstance().getRoutingDialog();
+	}
+
+    @Override public void enterMode() {
+        super.enterMode();
+        Main.map.mapView.addMouseListener(this);
+    }
+
+    @Override public void exitMode() {
+        super.exitMode();
+        Main.map.mapView.removeMouseListener(this);
+    }
+
+    @Override public void mouseClicked(MouseEvent e) {
+        // If left button is clicked
+        if (e.getButton() == MouseEvent.BUTTON1) {
+        	// Search for the nearest node in the list
+        	List<Node> nl = routingModel.getSelectedNodes();
+        	int index = -1;
+        	double dmax = REMOVE_SQR_RADIUS; // maximum distance, in pixels
+           	for (int i=0;i<nl.size();i++) {
+           		Node node = nl.get(i);
+        		double d = Main.map.mapView.getPoint(node.eastNorth).distanceSq(e.getPoint());
+        		if (d < dmax) {
+        			dmax = d;
+        			index = i;
+        		}
+        	}
+           	// If found a close node, remove it and recalculate route
+            if (index >= 0) {
+            	// Remove node
+            	logger.debug("Removing node " + nl.get(index));
+                routingModel.removeNode(index);
+        		routingDialog.removeNode(index);
+                Main.map.repaint();
+            } else {
+            	logger.debug("Can't find a node to remove.");
+            }
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/gui/RoutingDialog.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/gui/RoutingDialog.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/gui/RoutingDialog.java	(revision 14287)
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2008 Innovant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, please contact:
+ *
+ *  Innovant
+ *   juangui@gmail.com
+ *   vidalfree@gmail.com
+ *
+ *  http://public.grupoinnovant.com/blog
+ *
+ */
+
+package com.innovant.josm.plugin.routing.gui;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.ComponentOrientation;
+import java.awt.Font;
+import java.awt.event.KeyEvent;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.DefaultListModel;
+import javax.swing.JList;
+import javax.swing.JScrollPane;
+import javax.swing.border.EtchedBorder;
+
+import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
+import org.openstreetmap.josm.tools.Shortcut;
+
+
+/**
+ * @author jose
+ *
+ */
+public class RoutingDialog extends ToggleDialog {
+
+	private DefaultListModel model;
+	private JList jList = null;
+	private JScrollPane jScrollPane = null;
+
+	/**
+	 * Serial UID
+	 */
+	private static final long serialVersionUID = 8625615652900341987L;
+
+	public RoutingDialog() {
+		super(tr("Routing"), "routing", tr("Open a list of routing nodes"),
+				Shortcut.registerShortcut("subwindow:relations", tr("Toggle: {0}", tr("Routing")), KeyEvent.VK_R, Shortcut.GROUP_LAYER), 150);
+		model= new DefaultListModel();
+		this.setSize(456, 292);
+		this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+		this.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
+		this.setName("PrincipalDialog");
+		this.setFont(new Font("Dialog", Font.PLAIN, 12));
+		this.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
+		this.add(getJScrollPane(), null);
+
+	}
+
+	/**
+	 * This method initializes jScrollPane
+	 *
+	 * @return javax.swing.JScrollPane
+	 */
+	private JScrollPane getJScrollPane() {
+		if (jScrollPane == null) {
+			jScrollPane = new JScrollPane();
+			jScrollPane.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
+			jScrollPane.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
+			jScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+			jScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+			jScrollPane.setName("nList");
+			jScrollPane.setViewportBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
+			jScrollPane.setViewportView(getJList());
+		}
+		return jScrollPane;
+	}
+
+	/**
+	 * This method initializes jList
+	 *
+	 * @return javax.swing.JList
+	 */
+	private JList getJList() {
+		if (jList == null) {
+			jList = new JList();
+			jList.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
+			jList.setModel(model);
+		}
+		return jList;
+	}
+
+	/**
+	 * Remove item from the list of nodes
+	 * @param index
+	 */
+	public void removeNode(int index) {
+		model.remove(index);
+	}
+
+	/**
+	 * Add item to the list of nodes
+	 * @param obj
+	 */
+	public void addNode(Object txt) {
+		model.addElement(txt);
+	}
+
+	/**
+	 * Insert item to the list of nodes
+	 * @param index
+	 * @param obj
+	 */
+	public void insertNode(int index, Object txt) {
+		model.insertElementAt(txt, index);
+	}
+
+	/**
+	 * Clear list of nodes
+	 */
+	public void clearNodes() {
+		model.clear();
+	}
+
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/gui/RoutingMenu.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/gui/RoutingMenu.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/gui/RoutingMenu.java	(revision 14287)
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2008 Innovant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, please contact:
+ *
+ *  Innovant
+ *   juangui@gmail.com
+ *   vidalfree@gmail.com
+ *
+ *  http://public.grupoinnovant.com/blog
+ *
+ */
+
+package com.innovant.josm.plugin.routing.gui;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JRadioButtonMenuItem;
+
+import org.openstreetmap.josm.Main;
+
+import com.innovant.josm.jrt.core.RoutingGraph.RouteType;
+import com.innovant.josm.plugin.routing.RoutingLayer;
+import com.innovant.josm.plugin.routing.RoutingModel;
+import com.innovant.josm.plugin.routing.RoutingPlugin;
+
+/**
+ * The menu bar from this plugin
+ * @author jvidal
+ *
+ */
+public class RoutingMenu extends JMenu {
+
+	/**
+	 * Default serial version UID
+	 */
+	private static final long serialVersionUID = 3559922048225708480L;
+
+	/**
+	 * @param s
+	 */
+	public RoutingMenu(final String name) {
+		super(name);
+		final RoutingLayer routingLayer = RoutingPlugin.getInstance().getRoutingLayer();
+		final RoutingModel routingModel = routingLayer.getRoutingModel();
+
+		JMenuItem mi;
+		JMenu m;
+
+		mi = new JMenuItem(tr("Start routing"));
+		mi.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				if(!routingLayer.isLayerAdded()) {
+					routingLayer.setLayerAdded();
+					Main.main.addLayer(routingLayer);
+				}
+			}
+		});
+		this.add(mi);
+
+		this.addSeparator();
+		ButtonGroup group = new ButtonGroup();
+
+		m = new JMenu(tr("Criteria"));
+
+		JRadioButtonMenuItem rshorter = new JRadioButtonMenuItem(tr("Shortest"));
+		rshorter.setSelected(true);
+		rshorter.addItemListener(new ItemListener() {
+			public void itemStateChanged(ItemEvent e) {
+				if (e.getStateChange()==ItemEvent.SELECTED) {
+					routingModel.routingGraph.setTypeRoute(RouteType.SHORTEST);
+				} else {
+					routingModel.routingGraph.setTypeRoute(RouteType.FASTEST);
+				}
+				routingModel.routingGraph.resetGraph();
+				routingModel.routingGraph.createGraph();
+				//TODO: Change this way
+				//FIXME: do not change node but recalculate routing.
+				routingModel.setNodesChanged();
+				Main.map.repaint();
+			}
+
+		});
+
+		JRadioButtonMenuItem rfaster = new JRadioButtonMenuItem(tr("Fastest"));
+
+		group.add(rshorter);
+		group.add(rfaster);
+		m.add(rshorter);
+		m.add(rfaster);
+
+		m.addSeparator();
+		JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem("Ignore oneways");
+		cbmi.addItemListener(new ItemListener() {
+			public void itemStateChanged(ItemEvent e) {
+				if (e.getStateChange()==ItemEvent.SELECTED)
+					routingModel.routingGraph.getRoutingProfile().setOnewayUse(false);
+				else
+					routingModel.routingGraph.getRoutingProfile().setOnewayUse(true);
+				routingModel.setNodesChanged();
+				Main.map.repaint();
+			}
+		});
+		m.add(cbmi);
+		this.add(m);
+
+		this.addSeparator();
+		mi = new JMenuItem(tr("Reverse route"));
+		mi.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				routingModel.reverseNodes();
+				Main.map.repaint();
+			}
+		});
+		this.add(mi);
+
+		mi = new JMenuItem(tr("Clear route"));
+		mi.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				// Reset routing nodes and paths
+				routingModel.reset();
+				RoutingPlugin.getInstance().getRoutingDialog().clearNodes();
+				Main.map.repaint();
+			}
+		});
+		this.add(mi);
+
+	}
+
+
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/gui/RoutingPreferenceDialog.java
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/gui/RoutingPreferenceDialog.java	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/gui/RoutingPreferenceDialog.java	(revision 14287)
@@ -0,0 +1,235 @@
+/*
+ *
+ * Copyright (C) 2008 Innovant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, please contact:
+ *
+ *  Innovant
+ *   juangui@gmail.com
+ *   vidalfree@gmail.com
+ *
+ *  http://public.grupoinnovant.com/blog
+ *
+ */
+
+package com.innovant.josm.plugin.routing.gui;
+
+import java.awt.ComponentOrientation;
+import java.awt.Dimension;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.swing.Box;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.table.DefaultTableModel;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import org.apache.log4j.Logger;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.preferences.PreferenceDialog;
+import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
+import org.openstreetmap.josm.tools.GBC;
+
+import com.innovant.josm.jrt.osm.OsmWayTypes;
+import com.innovant.josm.plugin.routing.RoutingPlugin;
+
+public class RoutingPreferenceDialog implements PreferenceSetting {
+
+	/**
+	 * Logger
+	 */
+	static Logger logger = Logger.getLogger(RoutingPreferenceDialog.class);
+
+	private Map<String, String> orig;
+	private DefaultTableModel model;
+
+	/**
+	 * Constructor
+	 */
+	public RoutingPreferenceDialog() {
+		super();
+		readPreferences();
+	}
+
+	public void addGui(final PreferenceDialog gui) {
+
+		JPanel principal = gui.createPreferenceTab("routing",
+				tr("Routing Plugin Preferences"), tr("Configure routing preferences."));
+
+		JPanel p = new JPanel();
+		p.setLayout(new GridBagLayout());
+
+		model = new DefaultTableModel(new String[] { tr("Highway type"),
+				tr("Speed (Km/h)") }, 0) {
+			private static final long serialVersionUID = 4253339034781567453L;
+
+			@Override
+			public boolean isCellEditable(int row, int column) {
+				return column != 0;
+			}
+		};
+		final JTable list = new JTable(model);
+		loadSpeeds(model);
+
+		JScrollPane scroll = new JScrollPane(list);
+
+		p.add(scroll, GBC.eol().fill(GBC.BOTH));
+		scroll.setPreferredSize(new Dimension(200, 200));
+
+		JButton add = new JButton(tr("Add"));
+		p.add(Box.createHorizontalGlue(), GBC.std().fill(GBC.HORIZONTAL));
+		p.add(add, GBC.std().insets(0, 5, 0, 0));
+		add.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				JPanel p = new JPanel(new GridBagLayout());
+				p.add(new JLabel(tr("Weight")), GBC.std().insets(0, 0, 5, 0));
+				JComboBox key = new JComboBox();
+				for (OsmWayTypes pk : OsmWayTypes.values())
+					key.addItem(pk.getTag());
+				JTextField value = new JTextField(10);
+				p.add(key, GBC.eop().insets(5, 0, 0, 0).fill(GBC.HORIZONTAL));
+				p.add(new JLabel(tr("Value")), GBC.std().insets(0, 0, 5, 0));
+				p.add(value, GBC.eol().insets(5, 0, 0, 0).fill(GBC.HORIZONTAL));
+				int answer = JOptionPane.showConfirmDialog(gui, p,
+						tr("Enter weight values"),
+						JOptionPane.OK_CANCEL_OPTION);
+				if (answer == JOptionPane.OK_OPTION) {
+					model
+					.addRow(new String[] {
+							key.getSelectedItem().toString(),
+							value.getText() });
+				}
+			}
+		});
+
+		JButton delete = new JButton(tr("Delete"));
+		p.add(delete, GBC.std().insets(0, 5, 0, 0));
+		delete.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				if (list.getSelectedRow() == -1)
+					JOptionPane.showMessageDialog(gui,
+							tr("Please select the row to delete."));
+				else {
+					Integer i;
+					while ((i = list.getSelectedRow()) != -1)
+						model.removeRow(i);
+				}
+			}
+		});
+
+		JButton edit = new JButton(tr("Edit"));
+		p.add(edit, GBC.std().insets(5, 5, 5, 0));
+		edit.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				edit(gui, list);
+			}
+		});
+
+		JTabbedPane Opciones = new JTabbedPane();
+		Opciones.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
+
+		Opciones.addTab("Profile", null, p, null);
+//		Opciones.addTab("Preferences", new JPanel());
+
+		list.addMouseListener(new MouseAdapter(){
+			@Override public void mouseClicked(MouseEvent e) {
+				if (e.getClickCount() == 2)
+					edit(gui, list);
+			}
+		});
+
+		principal.add(Opciones, GBC.eol().fill(GBC.BOTH));
+
+	}
+
+	public boolean ok() {
+		for (int i = 0; i < model.getRowCount(); ++i) {
+			String value = model.getValueAt(i, 1).toString();
+			if (value.length() != 0) {
+				String key = model.getValueAt(i, 0).toString();
+				String origValue = orig.get(key);
+				if (origValue == null || !origValue.equals(value))
+					Main.pref.put(key, value);
+				orig.remove(key); // processed.
+			}
+		}
+		for (Entry<String, String> e : orig.entrySet())
+			Main.pref.put(e.getKey(), null);
+		return false;
+	}
+
+	private void edit(final PreferenceDialog gui, final JTable list) {
+		if (list.getSelectedRowCount() != 1) {
+			JOptionPane.showMessageDialog(gui,
+					tr("Please select the row to edit."));
+			return;
+		}
+		String v = JOptionPane.showInputDialog(tr("New value for {0}", model
+				.getValueAt(list.getSelectedRow(), 0)), model.getValueAt(list
+						.getSelectedRow(), 1));
+		if (v != null)
+			model.setValueAt(v, list.getSelectedRow(), 1);
+	}
+
+	private void loadSpeeds(DefaultTableModel model) {
+		// Read dialog values from preferences
+		readPreferences();
+		// Put these values in the model
+		for (String tag : orig.keySet()) {
+			model.addRow(new String[] { tag, orig.get(tag) });
+		}
+	}
+
+	private void readPreferences() {
+		orig = Main.pref.getAllPrefix("routing.profile.default.speed");
+		if (orig.size() == 0) { // defaults
+			logger.debug("Loading Default Preferences.");
+			for (OsmWayTypes owt : OsmWayTypes.values()) {
+				Main.pref.putInteger("routing.profile.default.speed."
+						+ owt.getTag(), owt.getSpeed());
+			}
+			orig = Main.pref.getAllPrefix("routing.profile.default.speed");
+		}
+		else logger.debug("Default preferences already exist.");
+	}
+
+	private String getKeyTag(String tag) {
+		return tag.split(".", 5)[4];
+	}
+
+	private String getTypeTag(String tag) {
+		return tag.split(".", 5)[3];
+	}
+
+	private String getNameTag(String tag) {
+		return tag.split(".", 5)[2];
+	}
+}
Index: /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/package.html
===================================================================
--- /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/package.html	(revision 14287)
+++ /applications/editors/josm/plugins/routing/src/com/innovant/josm/plugin/routing/package.html	(revision 14287)
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<title>Package</title>
+</head>
+<body bgcolor="white">
+Main classes of Plugin.
+</body>
+</html>
