Index: /build.xml
===================================================================
--- /build.xml	(revision 150)
+++ /build.xml	(revision 151)
@@ -1,49 +1,34 @@
 <project name="openstreetmap" default="dist" basedir=".">
 
-	<property name="src" location="src" />
-	<property name="po" location="po" />
-	<property name="build" location="build" />
-	<property name="dist" location="dist" />
-	<property name="lib" location="lib" />
-	
+	<!-- All jar files necessary to run only JOSM (no tests) -->
+	<fileset id="josm_required_libs" dir="lib">
+		<include name="gettext-commons-0.9.jar"/>
+		<include name="metadata-extractor-2.3.1.jar"/>
+		<include name="MinML2.jar"/>
+	</fileset>
+
+	<!-- Java classpath addition (all jar files to compile tests with this) -->
 	<path id="classpath">
-		<fileset dir="${lib}">
+		<fileset dir="lib">
 			<include name="**/*.jar"/>
 		</fileset>
 	</path>
 
-	<path id="srcfiles">
-		<fileset dir="${src}">
-			<include name="**/*.java"/>
-		</fileset>
-	</path>
-
-	<target name="init">
-		<mkdir dir="${build}" />
-		<mkdir dir="${dist}" />
-	</target>
-
-	<target name="compile" depends="init">
-		<javac srcdir="${src}" classpathref="classpath" destdir="${build}">
-			<include name="org/openstreetmap/josm/gui/MainApplication.java"/>
-			<include name="org/openstreetmap/josm/gui/MainApplet.java"/>
-			<include name="org/openstreetmap/josm/plugins/**/*.java"/>
-		</javac>
-	</target>
-
 	<target name="dist" depends="compile">
 		<!-- jars -->
-		<unjar src="${lib}/MinML2.jar" dest="${build}" />
-		<unjar src="${lib}/gettext-commons-0.9.jar" dest="${build}" />
-		<unjar src="${lib}/metadata-extractor-2.3.1.jar" dest="${build}" />
+		<unjar dest="build">
+			<fileset refid="josm_required_libs" />
+		</unjar>
 
 		<!-- images -->
-		<copy todir="${build}/images">
+		<copy todir="build/images">
 			<fileset dir="images" />
 		</copy>
-		<copy todir="${build}/org/openstreetmap/josm">
-		        <fileset dir="${po}/org/openstreetmap/josm" />
+		<copy todir="build/org/openstreetmap/josm">
+		        <fileset dir="po/org/openstreetmap/josm" />
 		</copy>
-		<jar destfile="${dist}/josm-custom.jar" basedir="${build}">
+		
+		<!-- create josm-custom.jar -->
+		<jar destfile="dist/josm-custom.jar" basedir="build">
 			<manifest>
 				<attribute name="Main-class" value="org.openstreetmap.josm.gui.MainApplication" />
@@ -52,22 +37,16 @@
 	</target>
 
-	<target name="clean">
-		<delete dir="${build}" />
-		<delete dir="${dist}" />
-	</target>
-
-
 	<target name="gettext" depends="init">
-    	<exec executable="find" output="${build}/alljava.txt">
-    		<arg line="${src} -name '*.java'"/>
+    	<exec executable="find" output="build/alljava.txt">
+    		<arg line="src -name '*.java'"/>
     	</exec>
         <exec executable="xgettext">
-        	<arg line="-ktr -ktrn:1,2 -ktrc -kmarktr -Ljava -o${po}/keys.pot -f${build}/alljava.txt"/>
+        	<arg line="-ktr -ktrn:1,2 -ktrc -kmarktr -Ljava -opo/keys.pot -fbuild/alljava.txt"/>
         </exec>
         <apply executable="msgmerge">
         	<arg value="-U"/>
 			<srcfile/>
-        	<arg file="${po}/keys.pot"/>
-        	<fileset dir="${po}">
+        	<arg file="po/keys.pot"/>
+        	<fileset dir="po">
         		<include name="*.po"/>
         	</fileset>
@@ -76,16 +55,35 @@
     	<!-- FIXME: somehow iterate the po-directory and create the java files -->
     	<exec executable="msgfmt">
-    		<arg line="--java2 -d${po} -rorg.openstreetmap.josm.Translation -lde ${po}/de.po"/>
+    		<arg line="--java2 -dpo -rorg.openstreetmap.josm.Translation -lde po/de.po"/>
     	</exec>
     	<exec executable="msgfmt">
-    		<arg line="--java2 -d${po} -rorg.openstreetmap.josm.Translation -lfr ${po}/fr.po"/>
+    		<arg line="--java2 -dpo -rorg.openstreetmap.josm.Translation -lfr po/fr.po"/>
     	</exec>
     	<exec executable="msgfmt">
-    		<arg line="--java2 -d${po} -rorg.openstreetmap.josm.Translation -len_GB ${po}/en_GB.po"/>
+    		<arg line="--java2 -dpo -rorg.openstreetmap.josm.Translation -len_GB po/en_GB.po"/>
     	</exec>
     	<exec executable="msgfmt">
-    		<arg line="--java2 -d${po} -rorg.openstreetmap.josm.Translation -lro ${po}/ro.po"/>
+    		<arg line="--java2 -dpo -rorg.openstreetmap.josm.Translation -lro po/ro.po"/>
     	</exec>
     </target>
 
+	<target name="compile" depends="init">
+		<javac srcdir="src" classpathref="classpath" destdir="build" />
+	</target>
+
+    <target name="compile-tests" depends="compile">
+        
+    </target>
+
+
+	<target name="init">
+		<mkdir dir="build" />
+		<mkdir dir="dist" />
+	</target>
+
+	<target name="clean">
+		<delete dir="build" />
+		<delete dir="dist" />
+	</target>
+
 </project>
Index: /src/org/openstreetmap/josm/actions/mapmode/MoveAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 150)
+++ /src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 151)
@@ -5,4 +5,5 @@
 import java.awt.Cursor;
 import java.awt.Point;
+import java.awt.Rectangle;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
@@ -19,15 +20,18 @@
 import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor;
 import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.gui.SelectionManager;
+import org.openstreetmap.josm.gui.SelectionManager.SelectionEnded;
 import org.openstreetmap.josm.tools.ImageProvider;
 /**
  * Move is an action that can move all kind of OsmPrimitives (except Keys for now).
- * 
- * If any object is selected, all selected objects are moved. If no object is 
- * selected, the nearest object will be selected and moved. In this case, the
- * object will be unselected as soon as movement stopped.
+ *
+ * If an selected object is under the mouse when dragging, move all selected objects.
+ * If an unselected object is under the mouse when dragging, it becomes selected
+ * and will be moved.
+ * If no object is under the mouse, move all selected objects (if any)
  * 
  * @author imi
  */
-public class MoveAction extends MapMode {
+public class MoveAction extends MapMode implements SelectionEnded {
 	/**
 	 * The old cursor before the user pressed the mouse button.
@@ -38,9 +42,6 @@
 	 */
 	private Point mousePos;
-	/**
-	 * Non-<code>null</code>, if no object was selected before movement 
-	 * (and so the object get unselected after mouse release).
-	 */
-	private OsmPrimitive singleOsmPrimitive;
+	private SelectionManager selectionManager;
+	private boolean selectionMode = false;
 
 	/**
@@ -50,9 +51,10 @@
 	public MoveAction(MapFrame mapFrame) {
 		super(tr("Move"), 
-				"move", 
-				tr("Move selected objects around."), 
-				KeyEvent.VK_M, 
-				mapFrame, 
+				"move",
+				tr("Move around objects that are under the mouse or selected."), 
+				KeyEvent.VK_M,
+				mapFrame,
 				ImageProvider.getCursor("normal", "move"));
+		selectionManager = new SelectionManager(this, false, mapFrame.mapView);
 	}
 
@@ -69,22 +71,24 @@
 	}
 
-	
+
 	/**
 	 * If the left mouse button is pressed, move all currently selected
-	 * objects.
+	 * objects (if one of them is under the mouse) or the current one under the
+	 * mouse (which will become selected).
 	 */
 	@Override public void mouseDragged(MouseEvent e) {
 		if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0)
 			return;
+
+		if (selectionMode)
+			return;
 		
-		if (mousePos == null) {
+		if (mousePos == null)
 			mousePos = e.getPoint();
-			singleOsmPrimitive = null;
-		}
 
-		EastNorth mouseGeo = Main.map.mapView.getEastNorth(e.getX(), e.getY());
-		EastNorth mouseStartGeo = Main.map.mapView.getEastNorth(mousePos.x, mousePos.y);
-		double dx = mouseGeo.east() - mouseStartGeo.east();
-		double dy = mouseGeo.north() - mouseStartGeo.north();
+		EastNorth mouseEN = Main.map.mapView.getEastNorth(e.getX(), e.getY());
+		EastNorth mouseStartEN = Main.map.mapView.getEastNorth(mousePos.x, mousePos.y);
+		double dx = mouseEN.east() - mouseStartEN.east();
+		double dy = mouseEN.north() - mouseStartEN.north();
 		if (dx == 0 && dy == 0)
 			return;
@@ -92,5 +96,5 @@
 		Collection<OsmPrimitive> selection = Main.ds.getSelected();
 		Collection<Node> affectedNodes = AllNodesVisitor.getAllNodes(selection);
-		
+
 		// check if any coordinate would be outside the world
 		for (OsmPrimitive osm : affectedNodes) {
@@ -100,5 +104,5 @@
 			}
 		}
-		
+
 		Command c = !Main.main.editLayer().commands.isEmpty() ? Main.main.editLayer().commands.getLast() : null;
 		if (c instanceof MoveCommand && affectedNodes.equals(((MoveCommand)c).objects))
@@ -106,5 +110,5 @@
 		else
 			Main.main.editLayer().add(new MoveCommand(selection, dx, dy));
-		
+
 		Main.map.mapView.repaint();
 		mousePos = e.getPoint();
@@ -124,27 +128,35 @@
 			return;
 
-		if (Main.ds.getSelected().size() == 0) {
-			OsmPrimitive osm = Main.map.mapView.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
-			if (osm != null)
-				Main.ds.setSelected(osm);
-			singleOsmPrimitive = osm;
-			Main.map.mapView.repaint();
-		} else
-			singleOsmPrimitive = null;
-		
+		Collection<OsmPrimitive> sel = Main.ds.getSelected();
+		OsmPrimitive osm = Main.map.mapView.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
+		if (osm != null) {
+	        if (!sel.contains(osm))
+	        	Main.ds.setSelected(osm);
+	        oldCursor = Main.map.mapView.getCursor();
+	        Main.map.mapView.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
+        } else {
+        	selectionMode = true;
+			selectionManager.register(Main.map.mapView);
+        }
+
+		Main.map.mapView.repaint();
+
 		mousePos = e.getPoint();
-		oldCursor = Main.map.mapView.getCursor();
-		Main.map.mapView.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
 	}
-	
+
 	/**
 	 * Restore the old mouse cursor.
 	 */
 	@Override public void mouseReleased(MouseEvent e) {
-		Main.map.mapView.setCursor(oldCursor);
-		if (singleOsmPrimitive != null) {
-			Main.ds.clearSelection();
-			Main.map.mapView.repaint();
-		}
+		if (selectionMode) {
+			selectionManager.unregister(Main.map.mapView);
+			selectionMode = false;
+		} else
+			Main.map.mapView.setCursor(oldCursor);
 	}
+
+	
+	public void selectionEnded(Rectangle r, boolean alt, boolean shift, boolean ctrl) {
+		SelectionAction.selectEverythingInRectangle(selectionManager, r, alt, shift, ctrl);
+    }
 }
Index: /src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 150)
+++ /src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 151)
@@ -138,5 +138,9 @@
 	 */
 	public void selectionEnded(Rectangle r, boolean alt, boolean shift, boolean ctrl) {
-		if (shift && ctrl)
+		selectEverythingInRectangle(selectionManager, r, alt, shift, ctrl);
+	}
+
+	public static void selectEverythingInRectangle(SelectionManager selectionManager, Rectangle r, boolean alt, boolean shift, boolean ctrl) {
+	    if (shift && ctrl)
 			return; // not allowed together
 
@@ -155,5 +159,5 @@
 		Main.ds.setSelected(curSel);
 		Main.map.mapView.repaint();
-	}
+    }
 
 	@Override public void mouseDragged(MouseEvent e) {
Index: /src/org/openstreetmap/josm/plugins/PluginLoader.java
===================================================================
--- /src/org/openstreetmap/josm/plugins/PluginLoader.java	(revision 150)
+++ /src/org/openstreetmap/josm/plugins/PluginLoader.java	(revision 151)
@@ -43,5 +43,5 @@
 		try {
 			ClassLoader loader = URLClassLoader.newInstance(
-					new URL[]{new URL("file:/"+pluginFile.getAbsolutePath())},
+					new URL[]{new URL("file://"+pluginFile.getAbsolutePath())},
 					getClass().getClassLoader());
 			Object plugin = Class.forName(pluginClass, true, loader).newInstance();
Index: /test/org/openstreetmap/josm/plugins/PluginLoaderTest.java
===================================================================
--- /test/org/openstreetmap/josm/plugins/PluginLoaderTest.java	(revision 150)
+++ /test/org/openstreetmap/josm/plugins/PluginLoaderTest.java	(revision 151)
@@ -2,5 +2,4 @@
 
 import java.io.File;
-import java.lang.reflect.Field;
 
 import junit.framework.TestCase;
@@ -24,7 +23,4 @@
 		PluginProxy plugin = loader.loadPlugin(getClass().getName()+"$TestPlugin", new File("foo.jar"));
 		assertTrue(plugin.plugin instanceof TestPlugin);
-		Field nameField = Plugin.class.getDeclaredField("name");
-		nameField.setAccessible(true);
-		assertEquals("foo", nameField.get(plugin.plugin));
 	}
 	
