Index: build.xml
===================================================================
--- build.xml	(revision 29270)
+++ build.xml	(working copy)
@@ -3,215 +3,21 @@
     <!-- enter the SVN commit message -->
     <property name="commit.message" value="Moar bugfixes"/>
     <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
-    <property name="plugin.main.version" value="5459"/>
-    <!--
-      ************************************************
-      ** should not be necessary to change the following properties
-     -->
-    <property name="josm" location="../../core/dist/josm-custom.jar"/>
-    <property name="plugin.build.dir" value="build"/>
-    <property name="plugin.src.dir" value="src"/>
-    <!-- this is the directory where the plugin jar is copied to -->
-    <property name="plugin.dist.dir" value="../../dist"/>
-    <property name="ant.build.javac.target" value="1.5"/>
-    <property name="plugin.dist.dir" value="../../dist"/>
-    <property name="plugin.jar" value="${plugin.dist.dir}/${ant.project.name}.jar"/>
-    <!--
-    **********************************************************
-    ** init - initializes the build
-    **********************************************************
-    -->
-    <target name="init">
-        <mkdir dir="${plugin.build.dir}"/>
-    </target>
-    <!--
-    **********************************************************
-    ** compile - complies the source tree
-    **********************************************************
-    -->
-    <target name="compile" depends="init">
-        <echo message="compiling sources for  ${plugin.jar} ... "/>
-        <javac srcdir="src" classpath="${josm}" debug="true" destdir="${plugin.build.dir}">
-            <compilerarg value="-Xlint:deprecation"/>
-            <compilerarg value="-Xlint:unchecked"/>
-        </javac>
-    </target>
-    <!--
-    **********************************************************
-    ** dist - creates the plugin jar
-    **********************************************************
-    -->
-    <target name="dist" depends="compile,revision">
-        <echo message="creating ${ant.project.name}.jar ... "/>
-        <copy todir="${plugin.build.dir}/resources">
-            <fileset dir="resources"/>
-        </copy>
-        <copy todir="${plugin.build.dir}/images">
-            <fileset dir="images"/>
-        </copy>
-        <copy todir="${plugin.build.dir}/data">
-            <fileset dir="data"/>
-        </copy>
-        <copy todir="${plugin.build.dir}">
-            <fileset dir=".">
-                <include name="README"/>
-                <include name="LICENSE"/>
-            </fileset>
-        </copy>
-        <jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
-            <!--
-        ************************************************
-        ** configure these properties. Most of them will be copied to the plugins
-        ** manifest file. Property values will also show up in the list available
-        ** plugins: http://josm.openstreetmap.de/wiki/Plugins.
-        **
-        ************************************************
+    <property name="plugin.main.version" value="5737"/>
+
+    <!-- Configure these properties (replace "..." accordingly).
+         See http://josm.openstreetmap.de/wiki/DevelopersGuide/DevelopingPlugins
     -->
-            <manifest>
-                <attribute name="Author" value="Hind"/>
-                <attribute name="Plugin-Class" value="CommandLine.CommandLine"/>
-                <attribute name="Plugin-Date" value="${version.entry.commit.date}"/>
-                <attribute name="Plugin-Description" value="Implements a command line and enables to create your commands. See link for standard commands (arc, circle etc.)"/>
-                <attribute name="ru_Plugin-Description" value="Реализует командную строку с возможностью создания своих команд. Стандартные команды можно скачать по ссылке."/>
-                <attribute name="Plugin-Icon" value="images/commandline.png"/>
-                <attribute name="Plugin-Link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/CommandLine"/>
-                <attribute name="ru_Plugin-Link" value="http://wiki.openstreetmap.org/wiki/RU:JOSM/Plugins/CommandLine"/>
-                <attribute name="Plugin-Mainversion" value="${plugin.main.version}"/>
-                <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
-            </manifest>
-        </jar>
-    </target>
-    <!--
-    **********************************************************
-    ** revision - extracts the current revision number for the
-    **    file build.number and stores it in the XML property
-    **    version.*
-    **********************************************************
-    -->
-    <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>
-    <!--
-    **********************************************************
-    ** clean - clean up the build environment
-    **********************************************************
-    -->
-    <target name="clean">
-        <delete dir="${plugin.build.dir}"/>
-        <delete file="${plugin.jar}"/>
-    </target>
-    <!--
-    **********************************************************
-    ** install - install the plugin in your local JOSM installation
-    **********************************************************
-    -->
-    <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>
-    <!--
-    ************************** Publishing the plugin *********************************** 
-    -->
-    <!--
-        ** extracts the JOSM release for the JOSM version in ../core and saves it in the 
-        ** property ${coreversion.info.entry.revision}
-        **
-        -->
-    <target name="core-info">
-        <exec append="false" output="core.info.xml" executable="svn" failifexecutionfails="false">
-            <env key="LANG" value="C"/>
-            <arg value="info"/>
-            <arg value="--xml"/>
-            <arg value="../../core"/>
-        </exec>
-        <xmlproperty file="core.info.xml" prefix="coreversion" keepRoot="true" collapseAttributes="true"/>
-        <echo>Building against core revision ${coreversion.info.entry.revision}.</echo>
-        <echo>Plugin-Mainversion is set to ${plugin.main.version}.</echo>
-        <delete file="core.info.xml"/>
-    </target>
-    <!--
-        ** commits the source tree for this plugin
-        -->
-    <target name="commit-current">
-        <echo>Commiting the plugin source with message '${commit.message}' ...</echo>
-        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
-            <env key="LANG" value="C"/>
-            <arg value="commit"/>
-            <arg value="-m '${commit.message}'"/>
-            <arg value="."/>
-        </exec>
-    </target>
-    <!--
-        ** updates (svn up) the source tree for this plugin
-        -->
-    <target name="update-current">
-        <echo>Updating plugin source ...</echo>
-        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
-            <env key="LANG" value="C"/>
-            <arg value="up"/>
-            <arg value="."/>
-        </exec>
-        <echo>Updating ${plugin.jar} ...</echo>
-        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
-            <env key="LANG" value="C"/>
-            <arg value="up"/>
-            <arg value="../dist/${plugin.jar}"/>
-        </exec>
-    </target>
-    <!--
-        ** commits the plugin.jar 
-        -->
-    <target name="commit-dist">
-        <echo>
-    ***** Properties of published ${plugin.jar} *****
-    Commit message    : '${commit.message}'                    
-    Plugin-Mainversion: ${plugin.main.version}
-    JOSM build version: ${coreversion.info.entry.revision}
-    Plugin-Version    : ${version.entry.commit.revision}
-    ***** / Properties of published ${plugin.jar} *****                    
-                        
-    Now commiting ${plugin.jar} ...
-    </echo>
-        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
-            <env key="LANG" value="C"/>
-            <arg value="-m '${commit.message}'"/>
-            <arg value="commit"/>
-            <arg value="${plugin.jar}"/>
-        </exec>
-    </target>
-    <!-- ** make sure svn is present as a command line tool ** -->
-    <target name="ensure-svn-present">
-        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false" failonerror="false" resultproperty="svn.exit.code">
-            <env key="LANG" value="C"/>
-            <arg value="--version"/>
-        </exec>
-        <fail message="Fatal: command 'svn --version' failed. Please make sure svn is installed on your system.">
-            <!-- return code not set at all? Most likely svn isn't installed -->
-            <condition>
-                <not>
-                    <isset property="svn.exit.code"/>
-                </not>
-            </condition>
-        </fail>
-        <fail message="Fatal: command 'svn --version' failed. Please make sure a working copy of svn is installed on your system.">
-            <!-- error code from SVN? Most likely svn is not what we are looking on this system -->
-            <condition>
-                <isfailure code="${svn.exit.code}"/>
-            </condition>
-        </fail>
-    </target>
-    <target name="publish" depends="ensure-svn-present,core-info,commit-current,update-current,clean,dist,commit-dist">
-    </target>
+    <property name="plugin.author" value="Hind"/>
+    <property name="plugin.class" value="CommandLine.CommandLine"/>
+    <property name="plugin.description" value="Implements a command line and enables to create your commands. See link for standard commands (arc, circle etc.)"/>
+    <property name="plugin.icon" value="images/commandline.png"/>
+    <property name="plugin.link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/CommandLine"/>
+    <!--<property name="plugin.early" value="..."/>-->
+    <!--<property name="plugin.requires" value="..."/>-->
+    <!--<property name="plugin.stage" value="..."/>-->
+
+    <!-- ** include targets that all plugins have in common ** -->
+    <import file="../build-common.xml"/>
+
 </project>
Index: src/CommandLine/CommandLine.java
===================================================================
--- src/CommandLine/CommandLine.java	(revision 29270)
+++ src/CommandLine/CommandLine.java	(working copy)
@@ -37,7 +37,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.List;
 
 import javax.swing.JMenu;
@@ -65,564 +64,557 @@
 import org.openstreetmap.josm.io.OsmWriterFactory;
 import org.openstreetmap.josm.plugins.Plugin;
 import org.openstreetmap.josm.plugins.PluginInformation;
+import org.openstreetmap.josm.tools.SubclassFilteredCollection;
 
 public class CommandLine extends Plugin {
-	protected JTextField textField;
-	protected JTextField historyField;
-	private String prefix;
-	private Mode mode;
-	private ArrayList<Command> commands;
-	private JMenu commandMenu;
-	protected Command currentCommand;
-	protected String commandSymbol;
-	protected History history;
-	protected MapFrame currentMapFrame;
-	protected MapMode previousMode;
+    protected JTextField textField;
+    protected JTextField historyField;
+    private String prefix;
+    private Mode mode;
+    private ArrayList<Command> commands;
+    private JMenu commandMenu;
+    protected Command currentCommand;
+    protected String commandSymbol;
+    protected History history;
+    protected MapFrame currentMapFrame;
+    protected MapMode previousMode;
 
-	static final String pluginDir = Main.pref.getPluginsDirectory().getAbsolutePath() + "/CommandLine/";
+    static final String pluginDir = Main.pref.getPluginsDirectory().getAbsolutePath() + "/CommandLine/";
 
-	public CommandLine(PluginInformation info) {
-		super(info);
-		commandSymbol = ": ";
-		history = new History(100);
-		historyField = new JTextField();
-		textField = new JTextField() {
-			@Override
-			protected void processKeyEvent(KeyEvent e) {
-				if (e.getID() == KeyEvent.KEY_PRESSED) {
-					String text = textField.getText();
-					int code = e.getKeyCode();
-					if (code == KeyEvent.VK_ENTER) {
-						String commandText = textField.getText().substring(prefix.length());
-						switch (mode) {
-						case IDLE:
-							if (commandText.isEmpty()) {
-								commandText = history.getLastItem();
-							}
-							else {
-								history.addItem(commandText);
-							}
-							Command command = findCommand(commandText, true);
-							if (command != null) {
-								startCommand(command);
-							}
-							else
-								setMode(Mode.IDLE);
-							break;
-						case SELECTION:
-							if (currentMapFrame.mapMode instanceof WayAction || currentMapFrame.mapMode instanceof NodeAction || currentMapFrame.mapMode instanceof RelationAction || currentMapFrame.mapMode instanceof AnyAction) {
-								Collection<OsmPrimitive> selected = Main.main.getCurrentDataSet().getSelected();
-								if (selected.size() > 0)
-									loadParameter(selected, true);
-							}
-							else {
-								loadParameter(commandText, currentCommand.parameters.get(currentCommand.currentParameterNum).maxInstances == 1);
-							}
-							break;
-						case ADJUSTMENT:
-							break;
-						}
-						e.consume();
-					}
-					else if (code == KeyEvent.VK_UP) {
-						textField.setText(prefix + history.getPrevItem());
-						e.consume();
-					}
-					else if (code == KeyEvent.VK_DOWN) {
-						textField.setText(prefix + history.getNextItem());
-						e.consume();
-					}
-					else if (code == KeyEvent.VK_BACK_SPACE || code == KeyEvent.VK_LEFT) {
-						if (textField.getCaretPosition() <= prefix.length())
-							e.consume();
-					}
-					else if (code == KeyEvent.VK_HOME) {
-						setCaretPosition(prefix.length());
-						e.consume();
-					}
-					else if (code == KeyEvent.VK_ESCAPE) {
-						if (textField.getText().length() == prefix.length() && mode == Mode.IDLE)
-							deactivate();
-						else
-							endInput();
-						e.consume();
-					}
-					else if (code == KeyEvent.VK_DELETE || code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_END) {
-					}
-					else {
-						e.consume();
-					}
-					if (textField.getCaretPosition() < prefix.length() || (textField.getSelectionStart() < prefix.length() && textField.getSelectionStart() > 0) )
-						e.consume();
-				}
-				if (e.getID() == KeyEvent.KEY_TYPED)
-					if (textField.getCaretPosition() < prefix.length() || (textField.getSelectionStart() < prefix.length() && textField.getSelectionStart() > 0) )
-						e.consume();
-				super.processKeyEvent(e);
-				if (textField.getText().length() < prefix.length()) { // Safe
-					setMode(mode);
-				}
-				if (e.getID() == KeyEvent.KEY_TYPED) {
-					if (e.getKeyChar() > 'A' && e.getKeyChar() < 'z') {
-						Command command = findCommand(textField.getText().substring(prefix.length()), false);
-						if (command != null) {
-							int currentPos = textField.getSelectionStart() == 0 ? textField.getCaretPosition() : textField.getSelectionStart();
-							textField.setText(prefix + command.name);
-							textField.setCaretPosition(currentPos);
-							textField.select(currentPos, prefix.length() + command.name.length());
-						}
-					}
-				}
-			}
-			@Override
-			protected void processMouseEvent(MouseEvent e) {
-				super.processMouseEvent(e);
-				if (e.getButton() == MouseEvent.BUTTON1 && e.getID() == MouseEvent.MOUSE_RELEASED) {
-					if (textField.getSelectionStart() > 0 && textField.getSelectionStart() < prefix.length())
-						textField.setSelectionStart(prefix.length());
-					else if (textField.getCaretPosition() < prefix.length())
-						textField.setCaretPosition(prefix.length());
-				}
-			}
-		};
+    @SuppressWarnings("serial")
+    public CommandLine(PluginInformation info) {
+        super(info);
+        commandSymbol = ": ";
+        history = new History(100);
+        historyField = new JTextField();
+        textField = new JTextField() {
+            @Override
+            protected void processKeyEvent(KeyEvent e) {
+                if (e.getID() == KeyEvent.KEY_PRESSED) {
+                    //String text = textField.getText();
+                    int code = e.getKeyCode();
+                    if (code == KeyEvent.VK_ENTER) {
+                        String commandText = textField.getText().substring(prefix.length());
+                        switch (mode) {
+                        case IDLE:
+                            if (commandText.isEmpty()) {
+                                commandText = history.getLastItem();
+                            }
+                            else {
+                                history.addItem(commandText);
+                            }
+                            Command command = findCommand(commandText, true);
+                            if (command != null) {
+                                startCommand(command);
+                            }
+                            else
+                                setMode(Mode.IDLE);
+                            break;
+                        case SELECTION:
+                            if (currentMapFrame.mapMode instanceof WayAction || currentMapFrame.mapMode instanceof NodeAction || currentMapFrame.mapMode instanceof RelationAction || currentMapFrame.mapMode instanceof AnyAction) {
+                                Collection<OsmPrimitive> selected = Main.main.getCurrentDataSet().getSelected();
+                                if (selected.size() > 0)
+                                    loadParameter(selected, true);
+                            }
+                            else {
+                                loadParameter(commandText, currentCommand.parameters.get(currentCommand.currentParameterNum).maxInstances == 1);
+                            }
+                            break;
+                        case ADJUSTMENT:
+                            break;
+                        }
+                        e.consume();
+                    }
+                    else if (code == KeyEvent.VK_UP) {
+                        textField.setText(prefix + history.getPrevItem());
+                        e.consume();
+                    }
+                    else if (code == KeyEvent.VK_DOWN) {
+                        textField.setText(prefix + history.getNextItem());
+                        e.consume();
+                    }
+                    else if (code == KeyEvent.VK_BACK_SPACE || code == KeyEvent.VK_LEFT) {
+                        if (textField.getCaretPosition() <= prefix.length())
+                            e.consume();
+                    }
+                    else if (code == KeyEvent.VK_HOME) {
+                        setCaretPosition(prefix.length());
+                        e.consume();
+                    }
+                    else if (code == KeyEvent.VK_ESCAPE) {
+                        if (textField.getText().length() == prefix.length() && mode == Mode.IDLE)
+                            deactivate();
+                        else
+                            endInput();
+                        e.consume();
+                    }
+                    else if (code == KeyEvent.VK_DELETE || code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_END) {
+                    }
+                    else {
+                        e.consume();
+                    }
+                    if (textField.getCaretPosition() < prefix.length() || (textField.getSelectionStart() < prefix.length() && textField.getSelectionStart() > 0) )
+                        e.consume();
+                }
+                if (e.getID() == KeyEvent.KEY_TYPED)
+                    if (textField.getCaretPosition() < prefix.length() || (textField.getSelectionStart() < prefix.length() && textField.getSelectionStart() > 0) )
+                        e.consume();
+                super.processKeyEvent(e);
+                if (textField.getText().length() < prefix.length()) { // Safe
+                    setMode(mode);
+                }
+                if (e.getID() == KeyEvent.KEY_TYPED) {
+                    if (e.getKeyChar() > 'A' && e.getKeyChar() < 'z') {
+                        Command command = findCommand(textField.getText().substring(prefix.length()), false);
+                        if (command != null) {
+                            int currentPos = textField.getSelectionStart() == 0 ? textField.getCaretPosition() : textField.getSelectionStart();
+                            textField.setText(prefix + command.name);
+                            textField.setCaretPosition(currentPos);
+                            textField.select(currentPos, prefix.length() + command.name.length());
+                        }
+                    }
+                }
+            }
+            @Override
+            protected void processMouseEvent(MouseEvent e) {
+                super.processMouseEvent(e);
+                if (e.getButton() == MouseEvent.BUTTON1 && e.getID() == MouseEvent.MOUSE_RELEASED) {
+                    if (textField.getSelectionStart() > 0 && textField.getSelectionStart() < prefix.length())
+                        textField.setSelectionStart(prefix.length());
+                    else if (textField.getCaretPosition() < prefix.length())
+                        textField.setCaretPosition(prefix.length());
+                }
+            }
+        };
 
-		if ( Main.main.menu != null ) {
-			commandMenu = Main.main.menu.addMenu(marktr("Commands") , KeyEvent.VK_M, Main.main.menu.defaultMenuPos, ht("/Plugin/CommandLine"));
-			MainMenu.add(Main.main.menu.toolsMenu, new CommandLineAction(this));
-		}
-		loadCommands();
-		setMode(Mode.IDLE);
-	}
+        if ( Main.main.menu != null ) {
+            commandMenu = Main.main.menu.addMenu(marktr("Commands") , KeyEvent.VK_M, Main.main.menu.defaultMenuPos, ht("/Plugin/CommandLine"));
+            MainMenu.add(Main.main.menu.toolsMenu, new CommandLineAction(this));
+        }
+        loadCommands();
+        setMode(Mode.IDLE);
+    }
 
-	public void startCommand(String commandName) {
-		Command command = findCommand(commandName, true);
-		if (command != null) {
-			startCommand(command);
-		}
-	}
+    public void startCommand(String commandName) {
+        Command command = findCommand(commandName, true);
+        if (command != null) {
+            startCommand(command);
+        }
+    }
 
-	protected void startCommand(Command command) {
-		if (Main.map == null)
-			return;
-		DataSet ds = Main.main.getCurrentDataSet();
-		if (ds == null)
-			return;
-		currentCommand = command;
-		currentCommand.resetLoading();
-		parseSelection(ds.getSelected());
-		if (!(Main.map.mapMode instanceof AnyAction || Main.map.mapMode instanceof DummyAction || Main.map.mapMode instanceof LengthAction || Main.map.mapMode instanceof NodeAction || Main.map.mapMode instanceof PointAction || Main.map.mapMode instanceof RelationAction || Main.map.mapMode instanceof WayAction)) {
-			previousMode = Main.map.mapMode;
-		}
-		if (currentCommand.currentParameterNum < currentCommand.parameters.size())
-			setMode(Mode.SELECTION);
-		else
-			runTool();
-	}
+    protected void startCommand(Command command) {
+        if (Main.map == null)
+            return;
+        DataSet ds = Main.main.getCurrentDataSet();
+        if (ds == null)
+            return;
+        currentCommand = command;
+        currentCommand.resetLoading();
+        parseSelection(ds.getSelected());
+        if (!(Main.map.mapMode instanceof AnyAction || Main.map.mapMode instanceof DummyAction || Main.map.mapMode instanceof LengthAction || Main.map.mapMode instanceof NodeAction || Main.map.mapMode instanceof PointAction || Main.map.mapMode instanceof RelationAction || Main.map.mapMode instanceof WayAction)) {
+            previousMode = Main.map.mapMode;
+        }
+        if (currentCommand.currentParameterNum < currentCommand.parameters.size())
+            setMode(Mode.SELECTION);
+        else
+            runTool();
+    }
 
-	@Override
-	public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame)
-	{
-		currentMapFrame = newFrame;
-		if (oldFrame == null && newFrame != null) {
-			JToolBar tb = new JToolBar();
-			tb.setLayout(new BorderLayout());
-			tb.setFloatable(false);
-			tb.setOrientation(JToolBar.HORIZONTAL);
-			tb.add(historyField, BorderLayout.NORTH);
-			tb.add(textField, BorderLayout.SOUTH);
-			currentMapFrame.add(tb, BorderLayout.NORTH);
-			printHistory("Loaded CommandLine, version " + getPluginInformation().version);
-		}
-	}
+    @Override
+    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame)
+    {
+        currentMapFrame = newFrame;
+        if (oldFrame == null && newFrame != null) {
+            JToolBar tb = new JToolBar();
+            tb.setLayout(new BorderLayout());
+            tb.setFloatable(false);
+            tb.setOrientation(JToolBar.HORIZONTAL);
+            tb.add(historyField, BorderLayout.NORTH);
+            tb.add(textField, BorderLayout.SOUTH);
+            currentMapFrame.add(tb, BorderLayout.NORTH);
+            printHistory("Loaded CommandLine, version " + getPluginInformation().version);
+        }
+    }
 
-	protected void printHistory(String text) {
-		historyField.setText(text);
-	}
+    protected void printHistory(String text) {
+        historyField.setText(text);
+    }
 
-	private void loadCommands() {
-		commands = (new Loader(getPluginDir())).load();
-		for (Command command : commands) {
-			commandMenu.add(new CommandAction(command, this));
-		}
-	}
+    private void loadCommands() {
+        commands = (new Loader(getPluginDir())).load();
+        for (Command command : commands) {
+            commandMenu.add(new CommandAction(command, this));
+        }
+    }
 
-	private Command findCommand(String text, boolean strict) {
-		for (int i = 0; i < commands.size(); i++) {
-			if (strict) {
-				if ( commands.get(i).name.equalsIgnoreCase(text) ) {
-					return commands.get(i);
-				}
-			}
-			else {
-				if ( commands.get(i).name.toLowerCase().startsWith( text.toLowerCase() ) && text.length() > 1 ) {
-					return commands.get(i);
-				}
-			}
-		}
-		return null;
-	}
+    private Command findCommand(String text, boolean strict) {
+        for (int i = 0; i < commands.size(); i++) {
+            if (strict) {
+                if ( commands.get(i).name.equalsIgnoreCase(text) ) {
+                    return commands.get(i);
+                }
+            }
+            else {
+                if ( commands.get(i).name.toLowerCase().startsWith( text.toLowerCase() ) && text.length() > 1 ) {
+                    return commands.get(i);
+                }
+            }
+        }
+        return null;
+    }
 
-	protected void setMode(Mode targetMode) {
-		DataSet currentDataSet = Main.main.getCurrentDataSet();
-		if (currentDataSet != null) {
-			currentDataSet.clearSelection();
-			Main.map.mapView.repaint();
-		}
-		if (targetMode == Mode.IDLE) {
-			mode = Mode.IDLE;
-			currentCommand = null;
-			prefix = tr("Command") + commandSymbol;
-			textField.setText(prefix);
-		}
-		else if (targetMode == Mode.SELECTION) {
-			mode = Mode.SELECTION;
-			Parameter currentParameter = currentCommand.parameters.get(currentCommand.currentParameterNum);
-			prefix = tr(currentParameter.description == null ? currentParameter.name : currentParameter.description);
-			if (currentParameter.getRawValue() instanceof Relay)
-				prefix = prefix + " (" + ((Relay)(currentParameter.getRawValue())).getOptionsString() + ")";
-			prefix += commandSymbol;
-			String value = currentParameter.getValue();
-			textField.setText(prefix + value);
-			Type currentType = currentParameter.type;
-			MapMode action = null;
-			switch (currentType) {
-			case POINT:
-				action = new PointAction(currentMapFrame, this);
-				break;
-			case WAY:
-				action = new WayAction(currentMapFrame, this);
-				break;
-			case NODE:
-				action = new NodeAction(currentMapFrame, this);
-				break;
-			case RELATION:
-				action = new RelationAction(currentMapFrame, this);
-				break;
-			case ANY:
-				action = new AnyAction(currentMapFrame, this);
-				break;
-			case LENGTH:
-				action = new LengthAction(currentMapFrame, this);
-				break;
-			case USERNAME:
-				loadParameter(Main.pref.get("osm-server.username", null), true);
-				action = new DummyAction(currentMapFrame, this);
-				break;
-			case IMAGERYURL:
-				Layer layer = Main.map.mapView.getActiveLayer();
-				if (layer != null) {
-					if (layer instanceof ImageryLayer) {
-					}
-					else {
-						List<ImageryLayer> imageryLayers = Main.map.mapView.getLayersOfType(ImageryLayer.class);
-						if (imageryLayers.size() == 1) {
-							layer = imageryLayers.get(0);
-						}
-						else {
-							endInput();
-							return;
-						}
-					}
-				}
-				ImageryInfo info = ((ImageryLayer)layer).getInfo();
-				String url = info.getUrl();
-				String itype = info.getImageryType().getUrlString();
-				loadParameter((url.equals("") ? itype : url), true);
-				action = new DummyAction(currentMapFrame, this);
-				break;
-			case IMAGERYOFFSET:
-				Layer olayer = Main.map.mapView.getActiveLayer();
-				if (olayer != null) {
-					if (olayer instanceof ImageryLayer) {
-					}
-					else {
-						List<ImageryLayer> imageryLayers = Main.map.mapView.getLayersOfType(ImageryLayer.class);
-						if (imageryLayers.size() == 1) {
-							olayer = imageryLayers.get(0);
-						}
-						else {
-							endInput();
-							return;
-						}
-					}
-				}
-				loadParameter((String.valueOf(((ImageryLayer)olayer).getDx()) + "," + String.valueOf(((ImageryLayer)olayer).getDy())), true);
-				action = new DummyAction(currentMapFrame, this);
-				break;
-			default:
-				action = new DummyAction(currentMapFrame, this);
-				break;
-			}
-			currentMapFrame.selectMapMode(action);
-			activate();
-			textField.select(prefix.length(), textField.getText().length());
-		}
-		else if (targetMode == Mode.PROCESSING) {
-			mode = Mode.PROCESSING;
-			prefix = tr("Processing...");
-			textField.setText(prefix);
-			Main.map.mapView.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-		}
-	}
+    protected void setMode(Mode targetMode) {
+        DataSet currentDataSet = Main.main.getCurrentDataSet();
+        if (currentDataSet != null) {
+            currentDataSet.clearSelection();
+            Main.map.mapView.repaint();
+        }
+        if (targetMode == Mode.IDLE) {
+            mode = Mode.IDLE;
+            currentCommand = null;
+            prefix = tr("Command") + commandSymbol;
+            textField.setText(prefix);
+        }
+        else if (targetMode == Mode.SELECTION) {
+            mode = Mode.SELECTION;
+            Parameter currentParameter = currentCommand.parameters.get(currentCommand.currentParameterNum);
+            prefix = tr(currentParameter.description == null ? currentParameter.name : currentParameter.description);
+            if (currentParameter.getRawValue() instanceof Relay)
+                prefix = prefix + " (" + ((Relay)(currentParameter.getRawValue())).getOptionsString() + ")";
+            prefix += commandSymbol;
+            String value = currentParameter.getValue();
+            textField.setText(prefix + value);
+            Type currentType = currentParameter.type;
+            MapMode action = null;
+            switch (currentType) {
+            case POINT:
+                action = new PointAction(currentMapFrame, this);
+                break;
+            case WAY:
+                action = new WayAction(currentMapFrame, this);
+                break;
+            case NODE:
+                action = new NodeAction(currentMapFrame, this);
+                break;
+            case RELATION:
+                action = new RelationAction(currentMapFrame, this);
+                break;
+            case ANY:
+                action = new AnyAction(currentMapFrame, this);
+                break;
+            case LENGTH:
+                action = new LengthAction(currentMapFrame, this);
+                break;
+            case USERNAME:
+                loadParameter(Main.pref.get("osm-server.username", null), true);
+                action = new DummyAction(currentMapFrame, this);
+                break;
+            case IMAGERYURL:
+                Layer layer = Main.map.mapView.getActiveLayer();
+                if (layer != null) {
+                    if (layer instanceof ImageryLayer) {
+                    }
+                    else {
+                        List<ImageryLayer> imageryLayers = Main.map.mapView.getLayersOfType(ImageryLayer.class);
+                        if (imageryLayers.size() == 1) {
+                            layer = imageryLayers.get(0);
+                        }
+                        else {
+                            endInput();
+                            return;
+                        }
+                    }
+                }
+                ImageryInfo info = ((ImageryLayer)layer).getInfo();
+                String url = info.getUrl();
+                String itype = info.getImageryType().getUrlString();
+                loadParameter((url.equals("") ? itype : url), true);
+                action = new DummyAction(currentMapFrame, this);
+                break;
+            case IMAGERYOFFSET:
+                Layer olayer = Main.map.mapView.getActiveLayer();
+                if (olayer != null) {
+                    if (olayer instanceof ImageryLayer) {
+                    }
+                    else {
+                        List<ImageryLayer> imageryLayers = Main.map.mapView.getLayersOfType(ImageryLayer.class);
+                        if (imageryLayers.size() == 1) {
+                            olayer = imageryLayers.get(0);
+                        }
+                        else {
+                            endInput();
+                            return;
+                        }
+                    }
+                }
+                loadParameter((String.valueOf(((ImageryLayer)olayer).getDx()) + "," + String.valueOf(((ImageryLayer)olayer).getDy())), true);
+                action = new DummyAction(currentMapFrame, this);
+                break;
+            default:
+                action = new DummyAction(currentMapFrame, this);
+                break;
+            }
+            currentMapFrame.selectMapMode(action);
+            activate();
+            textField.select(prefix.length(), textField.getText().length());
+        }
+        else if (targetMode == Mode.PROCESSING) {
+            mode = Mode.PROCESSING;
+            prefix = tr("Processing...");
+            textField.setText(prefix);
+            Main.map.mapView.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+        }
+    }
 
-	public void activate() {
-		textField.requestFocus();
-		textField.setCaretPosition(textField.getText().length());
-	}
+    public void activate() {
+        textField.requestFocus();
+        textField.setCaretPosition(textField.getText().length());
+    }
 
-	public void deactivate() {
-		Main.map.mapView.requestFocus();
-	}
+    public void deactivate() {
+        Main.map.mapView.requestFocus();
+    }
 
-	public void abortInput() {
-		printHistory(tr("Aborted") + ".");
-		endInput();
-	}
+    public void abortInput() {
+        printHistory(tr("Aborted") + ".");
+        endInput();
+    }
 
-	public void endInput() {
-		setMode(Mode.IDLE);
-		Main.map.selectMapMode(previousMode);
-		Main.map.mapView.repaint();
-	}
+    public void endInput() {
+        setMode(Mode.IDLE);
+        Main.map.selectMapMode(previousMode);
+        Main.map.mapView.repaint();
+    }
 
-	public void loadParameter(Object obj, boolean next) {
-		if (currentCommand.loadObject(obj)) {
-			if (currentCommand.hasNextParameter()) {
-				if (next) {
-					Parameter currentParameter = currentCommand.parameters.get(currentCommand.currentParameterNum);
-					String prefix = tr(currentParameter.description == null ? currentParameter.name : currentParameter.description);
-					prefix += commandSymbol;
-					String value = currentParameter.getValue();
-					printHistory(prefix + value);
-					currentCommand.nextParameter();
-					setMode(Mode.SELECTION);
-				}
-			}
-			else {
-				runTool();
-			}
-		}
-		else {
-			System.out.println("Invalid argument");
-			endInput();
-		}
-	}
+    public void loadParameter(Object obj, boolean next) {
+        if (currentCommand.loadObject(obj)) {
+            if (currentCommand.hasNextParameter()) {
+                if (next) {
+                    Parameter currentParameter = currentCommand.parameters.get(currentCommand.currentParameterNum);
+                    String prefix = tr(currentParameter.description == null ? currentParameter.name : currentParameter.description);
+                    prefix += commandSymbol;
+                    String value = currentParameter.getValue();
+                    printHistory(prefix + value);
+                    currentCommand.nextParameter();
+                    setMode(Mode.SELECTION);
+                }
+            }
+            else {
+                runTool();
+            }
+        }
+        else {
+            System.out.println("Invalid argument");
+            endInput();
+        }
+    }
 
-	private void parseSelection(Collection<OsmPrimitive> selection) {
-		boolean ok = false;
-		for (OsmPrimitive obj : selection) {
-			ok = currentCommand.loadObject(obj);
-			if (!ok)
-				break;
-		}
-		if (ok) {
-			currentCommand.nextParameter();
-		}
-		else {
-			currentCommand.resetLoading();
-		}
-		//System.out.println("Selected before " + String.valueOf(currentCommand.currentParameterNum) + "\n");
-	}
+    private void parseSelection(Collection<OsmPrimitive> selection) {
+        boolean ok = false;
+        for (OsmPrimitive obj : selection) {
+            ok = currentCommand.loadObject(obj);
+            if (!ok)
+                break;
+        }
+        if (ok) {
+            currentCommand.nextParameter();
+        }
+        else {
+            currentCommand.resetLoading();
+        }
+        //System.out.println("Selected before " + String.valueOf(currentCommand.currentParameterNum) + "\n");
+    }
 
-	private class ToolProcess {
-		public Process process;
-		public volatile boolean running;
-	}
+    private class ToolProcess {
+        public Process process;
+        public volatile boolean running;
+    }
 
-	// Thanks to Upliner
-	public void runTool() {
-		setMode(Mode.PROCESSING);
-		String commandToRun = currentCommand.run;
-		final boolean tracks = currentCommand.tracks;
-		final ArrayList<Parameter> parameters = currentCommand.parameters;
+    // Thanks to Upliner
+    public void runTool() {
+        setMode(Mode.PROCESSING);
+        String commandToRun = currentCommand.run;
+        final boolean tracks = currentCommand.tracks;
+        final ArrayList<Parameter> parameters = currentCommand.parameters;
 
-		for (Parameter parameter : currentCommand.parameters) {
-			commandToRun = commandToRun.replace("{" + parameter.name + "}", parameter.getValue());
-		}
-		for (Parameter parameter : currentCommand.optParameters) {
-			commandToRun = commandToRun.replace("{" + parameter.name + "}", parameter.getValue());
-		}
-		String[] listToRun = commandToRun.split(" ");
+        for (Parameter parameter : currentCommand.parameters) {
+            commandToRun = commandToRun.replace("{" + parameter.name + "}", parameter.getValue());
+        }
+        for (Parameter parameter : currentCommand.optParameters) {
+            commandToRun = commandToRun.replace("{" + parameter.name + "}", parameter.getValue());
+        }
+        String[] listToRun = commandToRun.split(" ");
 
-		// create the process
-		final Object syncObj = new Object();
+        // create the process
+        final Object syncObj = new Object();
 
-		ProcessBuilder builder;
-		builder = new ProcessBuilder(listToRun);
-		builder.directory(new File(getPluginDir()));
+        ProcessBuilder builder;
+        builder = new ProcessBuilder(listToRun);
+        builder.directory(new File(getPluginDir()));
 
-		final StringBuilder debugstr = new StringBuilder();
+        final StringBuilder debugstr = new StringBuilder();
 
-		// debug: print resulting cmdline
-		for (String s : builder.command())
-			debugstr.append(s + " ");
-		debugstr.append("\n");
-		System.out.print(debugstr.toString());
+        // debug: print resulting cmdline
+        for (String s : builder.command())
+            debugstr.append(s + " ");
+        debugstr.append("\n");
+        System.out.print(debugstr.toString());
 
-		final ToolProcess tp = new ToolProcess();
-		try {
-			tp.process = builder.start();
-		} catch (final IOException e) {
-			e.printStackTrace();
-			synchronized (debugstr) {
-				System.out.print(
-						tr("Error executing the script: ") +
-						debugstr.toString() + e.getMessage() + "\n" + e.getStackTrace());
-			}
-			return;
-		}
-		tp.running = true;
+        final ToolProcess tp = new ToolProcess();
+        try {
+            tp.process = builder.start();
+        } catch (final IOException e) {
+            e.printStackTrace();
+            synchronized (debugstr) {
+                System.out.print(
+                        tr("Error executing the script: ") +
+                        debugstr.toString() + e.getMessage() + "\n" + e.getStackTrace());
+            }
+            return;
+        }
+        tp.running = true;
 
-		// redirect child process's stderr to JOSM stderr
-		new Thread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					byte[] buffer = new byte[1024];
-					InputStream errStream = tp.process.getErrorStream();
-					int len;
-					while ((len = errStream.read(buffer)) > 0) {
-						synchronized (debugstr) {
-							debugstr.append(new String(buffer, 0, len));
-						}
-						System.err.write(buffer, 0, len);
-					}
-				} catch (IOException e) {
-				}
-			}
-		}).start();
+        // redirect child process's stderr to JOSM stderr
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    byte[] buffer = new byte[1024];
+                    InputStream errStream = tp.process.getErrorStream();
+                    int len;
+                    while ((len = errStream.read(buffer)) > 0) {
+                        synchronized (debugstr) {
+                            debugstr.append(new String(buffer, 0, len));
+                        }
+                        System.err.write(buffer, 0, len);
+                    }
+                } catch (IOException e) {
+                }
+            }
+        }).start();
 
-		// Write stdin stream
-		Thread osmWriteThread = new Thread(new Runnable() {
-			@Override
-			public void run() {
-				BBox bbox = null;
-				final OutputStream outputStream = tp.process.getOutputStream();
-				PrintWriter printWriter = null;
-				try { printWriter = new PrintWriter(new OutputStreamWriter(outputStream, "utf-8")); }
-				catch (Exception e) {e.printStackTrace();}
-				final OsmWriter osmWriter = OsmWriterFactory.createOsmWriter(printWriter, true, null);
-				Collection<OsmPrimitive> refObjects = currentCommand.getDepsObjects();
-				Collection<OsmPrimitive> pObjects;
-				osmWriter.header();
-				for (OsmPrimitive primitive : refObjects) {
-					if (primitive instanceof Node)
-						osmWriter.visit((Node)primitive);
-					else if (primitive instanceof Way)
-						osmWriter.visit((Way)primitive);
-					else if (primitive instanceof Relation)
-						osmWriter.visit((Relation)primitive);
-					if (bbox == null)
-						bbox = new BBox(primitive.getBBox());
-					else
-						bbox.addPrimitive(primitive, 0.0);
-				}
-				osmWriter.footer();
-				osmWriter.flush();
-				for (Parameter parameter : parameters) {
-					if (!parameter.isOsm())
-						continue;
-					osmWriter.header();
-					pObjects = parameter.getParameterObjects();
-					for (OsmPrimitive primitive : pObjects) {
-						if (primitive instanceof Node)
-							osmWriter.visit((Node)primitive);
-						else if (primitive instanceof Way)
-							osmWriter.visit((Way)primitive);
-						else if (primitive instanceof Relation)
-							osmWriter.visit((Relation)primitive);
-						if (bbox == null)
-							bbox = new BBox(primitive.getBBox());
-						else
-							bbox.addPrimitive(primitive, 0.0);
-					}
-					osmWriter.footer();
-					osmWriter.flush();
-				}
-				if (tracks) {
-					final GpxWriter gpxWriter = new GpxWriter(printWriter);
-					GpxFilter gpxFilter = new GpxFilter();
-					gpxFilter.initBboxFilter(bbox);
-					List<GpxLayer> gpxLayers = Main.map.mapView.getLayersOfType(GpxLayer.class);
-					for (GpxLayer gpxLayer : gpxLayers) {
-						gpxFilter.addGpxData(gpxLayer.data);
-					}
-					gpxWriter.write(gpxFilter.getGpxData());
-				}
-				osmWriter.close();
-				synchronized (syncObj) {
-					tp.running = false;
-					syncObj.notifyAll();
-				}
-			}
+        // Write stdin stream
+        Thread osmWriteThread = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                BBox bbox = null;
+                final OutputStream outputStream = tp.process.getOutputStream();
+                PrintWriter printWriter = null;
+                try { printWriter = new PrintWriter(new OutputStreamWriter(outputStream, "utf-8")); }
+                catch (Exception e) {e.printStackTrace();}
+                final OsmWriter osmWriter = OsmWriterFactory.createOsmWriter(printWriter, true, null);
+                Collection<OsmPrimitive> refObjects = currentCommand.getDepsObjects();
+                Collection<OsmPrimitive> pObjects;
+                osmWriter.header();
+                Collection<OsmPrimitive> contents = new ArrayList<OsmPrimitive>();
+                for (OsmPrimitive primitive : refObjects) {
+                    contents.add(primitive);
+                    if (bbox == null)
+                        bbox = new BBox(primitive.getBBox());
+                    else
+                        bbox.addPrimitive(primitive, 0.0);
+                }
+                for (Parameter parameter : parameters) {
+                    if (!parameter.isOsm())
+                        continue;
+                    pObjects = parameter.getParameterObjects();
+                    for (OsmPrimitive primitive : pObjects) {
+                        contents.add(primitive);
+                        if (bbox == null)
+                            bbox = new BBox(primitive.getBBox());
+                        else
+                            bbox.addPrimitive(primitive, 0.0);
+                    }
+                }
+                osmWriter.writeNodes(new SubclassFilteredCollection<OsmPrimitive, Node>(contents, OsmPrimitive.nodePredicate));
+                osmWriter.writeWays(new SubclassFilteredCollection<OsmPrimitive, Way>(contents, OsmPrimitive.wayPredicate));
+                osmWriter.writeRelations(new SubclassFilteredCollection<OsmPrimitive, Relation>(contents, OsmPrimitive.relationPredicate));
+                osmWriter.footer();
+                osmWriter.flush();
+                if (tracks) {
+                    final GpxWriter gpxWriter = new GpxWriter(printWriter);
+                    GpxFilter gpxFilter = new GpxFilter();
+                    gpxFilter.initBboxFilter(bbox);
+                    List<GpxLayer> gpxLayers = Main.map.mapView.getLayersOfType(GpxLayer.class);
+                    for (GpxLayer gpxLayer : gpxLayers) {
+                        gpxFilter.addGpxData(gpxLayer.data);
+                    }
+                    gpxWriter.write(gpxFilter.getGpxData());
+                }
+                osmWriter.close();
+                synchronized (syncObj) {
+                    tp.running = false;
+                    syncObj.notifyAll();
+                }
+            }
 
-		});
+        });
 
-		// Read stdout stream
-		final OsmToCmd osmToCmd = new OsmToCmd(this, Main.main.getCurrentDataSet());
-		Thread osmParseThread = new Thread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					String commandName = currentCommand.name;
-					HashMap<Long, Long> inexiDMap = new HashMap<Long, Long>();
-					final InputStream inputStream = tp.process.getInputStream();
-					osmToCmd.parseStream(inputStream);
-					final List<org.openstreetmap.josm.command.Command> cmdlist = osmToCmd.getCommandList();
-					if (!cmdlist.isEmpty()) {
-						SequenceCommand cmd = new SequenceCommand(commandName, cmdlist);
-						Main.main.undoRedo.add(cmd);
-					}
-				}
-				catch (Exception e) {}
-				finally {
-					synchronized (syncObj) {
-						tp.running = false;
-						syncObj.notifyAll();
-					}
-				}
-			}
+        // Read stdout stream
+        final OsmToCmd osmToCmd = new OsmToCmd(this, Main.main.getCurrentDataSet());
+        Thread osmParseThread = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    String commandName = currentCommand.name;
+                    //HashMap<Long, Long> inexiDMap = new HashMap<Long, Long>();
+                    final InputStream inputStream = tp.process.getInputStream();
+                    osmToCmd.parseStream(inputStream);
+                    final List<org.openstreetmap.josm.command.Command> cmdlist = osmToCmd.getCommandList();
+                    if (!cmdlist.isEmpty()) {
+                        SequenceCommand cmd = new SequenceCommand(commandName, cmdlist);
+                        Main.main.undoRedo.add(cmd);
+                    }
+                }
+                catch (Exception e) {}
+                finally {
+                    synchronized (syncObj) {
+                        tp.running = false;
+                        syncObj.notifyAll();
+                    }
+                }
+            }
 
-		});
+        });
 
-		osmParseThread.start();
-		osmWriteThread.start();
+        osmParseThread.start();
+        osmWriteThread.start();
 
-		synchronized (syncObj) {
-			try {
-				syncObj.wait(10000);
-			} catch (InterruptedException e) {
-			}
-		}
-		if (tp.running) {
-			new Thread(new PleaseWaitRunnable(currentCommand.name) {
-				@Override
-				protected void realRun() {
-					try {
-						progressMonitor.indeterminateSubTask(null);
-						synchronized (syncObj) {
-							if (tp.running)
-								syncObj.wait();
-						}
-					} catch (InterruptedException e) {
-					}
-				}
+        synchronized (syncObj) {
+            try {
+                syncObj.wait(10000);
+            } catch (InterruptedException e) {
+            }
+        }
+        if (tp.running) {
+            new Thread(new PleaseWaitRunnable(currentCommand.name) {
+                @Override
+                protected void realRun() {
+                    try {
+                        progressMonitor.indeterminateSubTask(null);
+                        synchronized (syncObj) {
+                            if (tp.running)
+                                syncObj.wait();
+                        }
+                    } catch (InterruptedException e) {
+                    }
+                }
 
-				@Override
-				protected void cancel() {
-					synchronized (syncObj) {
-						tp.running = false;
-						tp.process.destroy();
-						syncObj.notifyAll();
-						endInput();
-					}
-				}
+                @Override
+                protected void cancel() {
+                    synchronized (syncObj) {
+                        tp.running = false;
+                        tp.process.destroy();
+                        syncObj.notifyAll();
+                        endInput();
+                    }
+                }
 
-				@Override
-				protected void finish() {
-				}
-			}).start();
-		}
-		endInput();
-	}
+                @Override
+                protected void finish() {
+                }
+            }).start();
+        }
+        endInput();
+    }
 }
