Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/AdjacentNodesAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/AdjacentNodesAction.java	(revision 25836)
+++ 	(revision )
@@ -1,115 +1,0 @@
-// License: GPL. Copyright 2011 by Alexei Kasatkin and others
-package utilsplugin2;
-
-import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.HashSet;
-import java.util.Set;
-import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.data.osm.*;
-
-import org.openstreetmap.josm.tools.Shortcut;
-
-/**
- *    Extends current selection
- */
-class AdjacentNodesAction extends JosmAction {
-
-    public static final boolean treeMode = false;
-
-    public AdjacentNodesAction() {
-        super(tr("Adjacent nodes"), "adjnodes", tr("Select adjacent nodes"),
-                Shortcut.registerShortcut("tools:adjnodes", tr("Tool: {0}","Adjacent nodes"),
-                KeyEvent.VK_E, Shortcut.GROUP_EDIT), true);
-        putValue("help", ht("/Action/AdjacentNodes"));
-    }
-
-    private  Set<Way> activeWays = new HashSet<Way>();
-
-    public void actionPerformed(ActionEvent e) {
-        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
-        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
-
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
-        
-        // if no nodes and no ways are selected, do nothing
-        if (selectedNodes.isEmpty() && selectedWays.isEmpty()) return;
-
-        if (selectedWays.isEmpty()) {
-            // if one node is selected, used ways connected to it to extend selecteons
-            // activeWays are remembered for next extend action (!!!)
-
-            // FIXME: some strange behaviour is possible if user delete some of these way
-            // how to clear activeWays during such user actions? Do not know
-            if (selectedNodes.size() == 1) {
-                activeWays.clear();
-//                System.out.println("Cleared active ways");
-            }
-        } else {
-            // use only ways that were selected for adding nodes
-            activeWays = selectedWays;
-        }
-
-        // selecting nodes of selected ways
-        if(selectedNodes.isEmpty()) {
-            HashSet<Node> newNodes = new HashSet<Node>();
-            NodeWayUtils.addNodesConnectedToWays(selectedWays, newNodes);
-            activeWays.clear();
-            getCurrentDataSet().setSelected(newNodes);
-            return;
-        }
-
-        if (activeWays.isEmpty()) {
-                NodeWayUtils.addWaysConnectedToNodes(selectedNodes, activeWays);
-        }
-
-        Set<Node> newNodes = new HashSet <Node>();
-        for (Node node: selectedNodes) {
-            for (Way w: activeWays) {
-                NodeWayUtils.addNeighbours(w, node, newNodes);
-            }
-        }
-        
-        // select only newly found nodes
-         newNodes.removeAll(selectedNodes);
-
-//         System.out.printf("Found %d new nodes\n",newNodes.size());
-         
-         // enable branching on next call of this function
-         // if no new nodes were found, next search will include all touched ways
-         if (newNodes.isEmpty()) {
-             activeWays.clear();
-//             System.out.println("No more points found, activeways cleared");
-         }
-
-         getCurrentDataSet().addSelected(newNodes);
-         newNodes = null;
-
-    }
-
-    @Override
-    protected void updateEnabledState() {
-        if (getCurrentDataSet() == null) {
-            setEnabled(false);
-        } else {
-            updateEnabledState(getCurrentDataSet().getSelected());
-        }
-    }
-
-    @Override
-    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        if (selection == null) {
-            setEnabled(false);
-            return;
-        }
-        setEnabled(!selection.isEmpty());
-    }
-
-
-
-}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/AdjacentWaysAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/AdjacentWaysAction.java	(revision 25836)
+++ 	(revision )
@@ -1,74 +1,0 @@
-// License: GPL. Copyright 2011 by Alexei Kasatkin
-package utilsplugin2;
-
-import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.data.osm.*;
-
-import org.openstreetmap.josm.tools.Shortcut;
-
-/**
- *    Extends current selection
- */
-class AdjacentWaysAction extends JosmAction {
-
-    public static final boolean treeMode = false;
-
-    public AdjacentWaysAction() {
-        super(tr("Adjacent ways"), "adjways",
-                tr("Adjacent ways will be selected. Nodes wiil be deselected."),
-                Shortcut.registerShortcut("tools:adjways", tr("Tool: {0}","Adjacent ways"),
-                KeyEvent.VK_E, Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
-        putValue("help", ht("/Action/AdjacentWays"));
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
-        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
-
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
-
-        // select ways attached to already selected ways
-        Set<Way> newWays = new HashSet<Way>();
-        newWays.addAll(selectedWays);
-        for (Way w : selectedWays){
-            NodeWayUtils.addWaysConnectedToWay(w, newWays);
-        }
-
-        // selecting ways attached to selected nodes
-        if(!selectedNodes.isEmpty()) {
-            NodeWayUtils.addWaysConnectedToNodes(selectedNodes, newWays);
-        }
-
-//        System.out.printf("%d ways added to selection\n",newWays.size()-selectedWays.size());
-        getCurrentDataSet().setSelected(newWays);
-    }
-
-    @Override
-    protected void updateEnabledState() {
-        if (getCurrentDataSet() == null) {
-            setEnabled(false);
-        } else {
-            updateEnabledState(getCurrentDataSet().getSelected());
-        }
-    }
-
-    @Override
-    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        if (selection == null) {
-            setEnabled(false);
-            return;
-        }
-        setEnabled(!selection.isEmpty());
-    }
-
-
-
-}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/ConnectedWaysAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/ConnectedWaysAction.java	(revision 25836)
+++ 	(revision )
@@ -1,69 +1,0 @@
-// License: GPL. Copyright 2011 by Alexei Kasatkin
-package utilsplugin2;
-
-import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.data.osm.*;
-
-import org.openstreetmap.josm.tools.Shortcut;
-
-/**
- *    Extends current selection by selecting nodes on all touched ways
- */
-class ConnectedWaysAction extends JosmAction {
-
-    public ConnectedWaysAction() {
-        super(tr("All connected ways"), "adjwaysall", tr("Select all connected ways"),
-                Shortcut.registerShortcut("tools:adjwaysall", tr("Tool: {0}","All connected ways"),
-                KeyEvent.VK_E, Shortcut.GROUP_MENU, Shortcut.SHIFT_DEFAULT), true);
-        putValue("help", ht("/Action/SelectConnectedWays"));
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
-        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
-
-        Set<Way> newWays = new HashSet<Way>();
-
-        // selecting ways attached to selected nodes
-        if(!selectedNodes.isEmpty()) {
-            NodeWayUtils.addWaysConnectedToNodes(selectedNodes, newWays);
-        }
-
-        // select ways attached to already selected ways
-        newWays.addAll(selectedWays);
-        NodeWayUtils.addWaysConnectedToWaysRecursively(selectedWays, newWays);
-        
-//        System.out.printf("%d ways added to selection\n",newWays.size()-selectedWays.size());
-        getCurrentDataSet().setSelected(newWays);
-
-    }
-
-    @Override
-    protected void updateEnabledState() {
-        if (getCurrentDataSet() == null) {
-            setEnabled(false);
-        } else {
-            updateEnabledState(getCurrentDataSet().getSelected());
-        }
-    }
-
-    @Override
-    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        if (selection == null) {
-            setEnabled(false);
-            return;
-        }
-        setEnabled(!selection.isEmpty());
-    }
-
-
-}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/IntersectedWaysAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/IntersectedWaysAction.java	(revision 25836)
+++ 	(revision )
@@ -1,73 +1,0 @@
-// License: GPL. Copyright 2011 by Alexei Kasatkin
-package utilsplugin2;
-
-import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-import javax.swing.JOptionPane;
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.data.osm.*;
-
-import org.openstreetmap.josm.tools.Shortcut;
-
-/**
- *    Extends current selection by selecting nodes on all touched ways
- */
-class IntersectedWaysAction extends JosmAction {
-
-    public IntersectedWaysAction() {
-        super(tr("Intersecting ways"), "intway", tr("Select intersecting ways"),
-                Shortcut.registerShortcut("tools:intway", tr("Tool: {0}","Intersecting ways"),
-                KeyEvent.VK_I, Shortcut.GROUP_EDIT), true);
-        putValue("help", ht("/Action/SelectIntersectingWays"));
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
-        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
-        Set<Way> activeWays = new HashSet<Way>();
-
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
-
-        // select ways attached to already selected ways
-        if (!selectedWays.isEmpty()) {
-            Set<Way> newWays = new HashSet<Way>();
-            NodeWayUtils.addWaysIntersectingWays(
-                    getCurrentDataSet().getWays(),
-                    selectedWays, newWays);
-            getCurrentDataSet().addSelected(newWays);
-            return;
-        } else {
-             JOptionPane.showMessageDialog(Main.parent,
-               tr("Please select some ways to find connected and intersecting ways!"),
-               tr("Warning"), JOptionPane.WARNING_MESSAGE);
-        }
-
-    }
-
-    @Override
-    protected void updateEnabledState() {
-        if (getCurrentDataSet() == null) {
-            setEnabled(false);
-        } else {
-            updateEnabledState(getCurrentDataSet().getSelected());
-        }
-    }
-
-    @Override
-    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        if (selection == null) {
-            setEnabled(false);
-            return;
-        }
-        setEnabled(!selection.isEmpty());
-    }
-
-
-}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/IntersectedWaysRecursiveAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/IntersectedWaysRecursiveAction.java	(revision 25836)
+++ 	(revision )
@@ -1,74 +1,0 @@
-// License: GPL. Copyright 2011 by Alexei Kasatkin ond others
-package utilsplugin2;
-
-import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-import javax.swing.JOptionPane;
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.data.osm.*;
-
-import org.openstreetmap.josm.tools.Shortcut;
-
-/**
- *    Extends current selection by selecting nodes on all touched ways
- */
-class IntersectedWaysRecursiveAction extends JosmAction {
-    
-    public IntersectedWaysRecursiveAction() {
-        super(tr("All intersecting ways"), "intwayall", tr("Select all intersecting ways"),
-                Shortcut.registerShortcut("tools:intwayall", tr("Tool: {0}","All intersecting ways"),
-                KeyEvent.VK_I, Shortcut.GROUP_MENU, KeyEvent.SHIFT_DOWN_MASK|KeyEvent.CTRL_DOWN_MASK), true);
-        putValue("help", ht("/Action/SelectAllIntersectingWays"));
-
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
-        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
-        Set<Way> activeWays = new HashSet<Way>();
-
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
-
-        if (!selectedWays.isEmpty()) {
-            Set<Way> newWays = new HashSet<Way>();
-            NodeWayUtils.addWaysIntersectingWaysRecursively(
-                    getCurrentDataSet().getWays(),
-                    selectedWays, newWays);
-            getCurrentDataSet().addSelected(newWays);
-            return;
-        } else {
-             JOptionPane.showMessageDialog(Main.parent,
-               tr("Please select some ways to find all connected and intersecting ways!"),
-               tr("Warning"), JOptionPane.WARNING_MESSAGE);
-        }
-
-    }
-
-
-    @Override
-    protected void updateEnabledState() {
-        if (getCurrentDataSet() == null) {
-            setEnabled(false);
-        } else {
-            updateEnabledState(getCurrentDataSet().getSelected());
-        }
-    }
-
-    @Override
-    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        if (selection == null) {
-            setEnabled(false);
-            return;
-        }
-        setEnabled(!selection.isEmpty());
-    }
-
-
-}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/NodeWayUtils.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/NodeWayUtils.java	(revision 25836)
+++ 	(revision )
@@ -1,226 +1,0 @@
-// License: GPL. Copyright 2011 by Alexei Kasatkin
-package utilsplugin2;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.swing.JOptionPane;
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.tools.Geometry;
-import org.openstreetmap.josm.tools.Pair;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-
-/**
- * Class with some useful functions that are reused in extend selection actions
- *
- */
-public final class NodeWayUtils {
-
-    static final int maxLevel = Main.pref.getInteger("selection.maxrecursion", 5);
-    static final int maxWays = Main.pref.getInteger("selection.maxfoundways", 2000);
-    static final int maxWays1 = Main.pref.getInteger("selection.maxfoundways.intersection", 500);
-
-    /**
-     * Find the neighbours of node n on the way w and put them in given collection
-     * @param w way on which the search goes
-     * @param n node to find its neighbours
-     * @param nodes collection to place the nodes we found
-     */
-    static void addNeighbours(Way w, Node n, Collection<Node> nodes) {
-        List<Node> nodeList = w.getNodes();
-        
-        int idx = nodeList.indexOf(n);
-        if (idx == -1) return;
-
-        // add previous element
-        if (idx > 0) {
-            nodes.add(nodeList.get(idx - 1));
-        }
-        // add next element
-        if (idx < nodeList.size() - 1) {
-            nodes.add(nodeList.get(idx + 1));
-        }
-        if (w.isClosed()) {
-            // cyclic neighbours detection
-            if (idx == 0) {
-                nodes.add(nodeList.get(nodeList.size() - 2));
-            }
-            if (idx == nodeList.size() - 1) {
-                nodes.add(nodeList.get(1));
-            }
-        }
-     }
-
-    /**
-     * Adds all ways attached to way to specified collection
-     * @param w way to find attached ways
-     * @param ways  collection to place the ways we found
-     */
-    static int addWaysConnectedToWay(Way w, Set<Way> ways) {
-         int s = ways.size();
-        List<Node> nodes = w.getNodes();
-        for (Node n: nodes) {
-            ways.addAll(OsmPrimitive.getFilteredList(n.getReferrers(), Way.class));
-        }
-        return ways.size() - s;
-    }
-
-    /**
-     * Adds all ways attached to node to specified collection
-     * @param n Node to find attached ways
-     * @param ways  collection to place the ways we found
-     */
-    static int addWaysConnectedToNode(Node n, Set<Way> ways) {
-        int s = ways.size();
-        ways.addAll(OsmPrimitive.getFilteredList(n.getReferrers(), Way.class));
-        return ways.size() - s;
-    }
-
-    /**
-     * Adds all ways intersecting one way to specified set
-     * @param ways collection of ways to search
-     * @param w way to check intersections
-     * @param newWays set to place the ways we found
-     */
-    static int addWaysIntersectingWay(Collection<Way> ways, Way w, Set<Way> newWays,Set<Way> excludeWays) {
-        List<Pair<Node, Node>> nodePairs = w.getNodePairs(false);
-        int count=0;
-        for (Way anyway: ways) {
-            if (anyway == w) continue;
-            if (newWays.contains(anyway) || excludeWays.contains(anyway) ) continue;
-
-            List<Pair<Node, Node>> nodePairs2 = anyway.getNodePairs(false);
-            loop: for (Pair<Node,Node> p1 : nodePairs) {
-                for (Pair<Node,Node> p2 : nodePairs2) {
-                    if (null!=Geometry.getSegmentSegmentIntersection(
-                            p1.a.getEastNorth(),p1.b.getEastNorth(),
-                            p2.a.getEastNorth(),p2.b.getEastNorth())) {
-                            newWays.add(anyway);
-                            count++;
-                            break loop;
-                    }
-                }
-            }
-        }
-        return count;
-    }
-
-
-        static int addWaysIntersectingWay(Collection<Way> ways, Way w, Set<Way> newWays) {
-        List<Pair<Node, Node>> nodePairs = w.getNodePairs(false);
-        int count=0;
-        for (Way anyway: ways) {
-            if (anyway == w) continue;
-            if (newWays.contains(anyway)) continue;
-            List<Pair<Node, Node>> nodePairs2 = anyway.getNodePairs(false);
-            loop: for (Pair<Node,Node> p1 : nodePairs) {
-                for (Pair<Node,Node> p2 : nodePairs2) {
-                    if (null!=Geometry.getSegmentSegmentIntersection(
-                            p1.a.getEastNorth(),p1.b.getEastNorth(),
-                            p2.a.getEastNorth(),p2.b.getEastNorth())) {
-                            newWays.add(anyway);
-                            count++;
-                            break loop;
-                    }
-                }
-            }
-        }
-        return count;
-    }
-
-    /**
-     * Adds all ways from allWays intersecting initWays way to specified set newWays
-     * @param allWays collection of ways to search
-     * @param initWays ways to check intersections
-     * @param newWays set to place the ways we found
-     */
-    static int addWaysIntersectingWays(Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays) {
-        int count=0;
-        for (Way w : initWays){
-            count+=addWaysIntersectingWay(allWays, w, newWays);
-        }
-        return count;
-    }
-
-    static int addWaysConnectedToNodes(Set<Node> selectedNodes, Set<Way> newWays) {
-        int s = newWays.size();
-        for (Node node: selectedNodes) {
-            addWaysConnectedToNode(node, newWays);
-        }
-        return newWays.size() - s;
-    }
-
-    static int addNodesConnectedToWays(Set<Way> initWays, Set<Node> newNodes) {
-        int s = newNodes.size();
-        for (Way w: initWays) {
-                newNodes.addAll(w.getNodes());
-        }
-        return newNodes.size()-s;
-    }
-
-    static void addWaysIntersectingWaysRecursively
-            (Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays)
-    {
-            Set<Way> foundWays = new HashSet<Way>();
-            foundWays.addAll(initWays);
-            newWays.addAll(initWays);
-            Set<Way> newFoundWays = new HashSet<Way>();
-
-            int level=0,c;
-            do {
-                 c=0;
-                 newFoundWays = new HashSet<Way>();
-                 for (Way w : foundWays){
-                      c+=addWaysIntersectingWay(allWays, w, newFoundWays,newWays);
-                 }
-                 foundWays = newFoundWays;
-                 newWays.addAll(newFoundWays);
-                 level++;
-//                 System.out.printf("%d: %d ways added to selection intersectiong\n",level,c);
-                 if (c>maxWays1) {
-                       JOptionPane.showMessageDialog(Main.parent,
-                                tr("Too many ways are added: {0}!",c),
-                                        tr("Warning"),
-                                        JOptionPane.WARNING_MESSAGE);
-                       return;
-                 }
-            } while ( c >0 && level < maxLevel );
-            return;
-    }
-
- static void addWaysConnectedToWaysRecursively
-            (Collection<Way> initWays, Set<Way> newWays)
-    {
-            //long t = System.currentTimeMillis();
-            int level=0,c;
-            newWays.addAll(initWays);
-            do {
-                 c=0;
-                 Set<Way> foundWays = new HashSet<Way>();
-                 foundWays.addAll(newWays);
-                 for (Way w : foundWays){
-                      c+=addWaysConnectedToWay(w, newWays);
-                 }
-                 level++;
-//                 System.out.printf("%d: %d ways added to selection\n",level,c);
-                 if (c>maxWays) {
-                       JOptionPane.showMessageDialog(Main.parent,
-                                tr("Too many ways are added: {0}!",c),
-                                        tr("Warning"),
-                                        JOptionPane.WARNING_MESSAGE);
-                       return;
-                 }
-            } while ( c >0 && level < maxLevel );
-           // System.out.println("time = "+(System.currentTimeMillis()-t)+" ways = "+newWays.size());
-            return;
-    }
-
-
-
-}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/SelectWayNodesAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/SelectWayNodesAction.java	(revision 25836)
+++ 	(revision )
@@ -1,107 +1,0 @@
-// License: GPL. Copyright 2010 by Hanno Hecker
-package utilsplugin2;
-
-import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
-import static org.openstreetmap.josm.tools.I18n.tr;
-import static org.openstreetmap.josm.tools.I18n.trn;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.command.AddCommand;
-import org.openstreetmap.josm.command.ChangeCommand;
-import org.openstreetmap.josm.command.Command;
-import org.openstreetmap.josm.command.SequenceCommand;
-import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Relation;
-import org.openstreetmap.josm.data.osm.RelationMember;
-import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.gui.MapView;
-import org.openstreetmap.josm.tools.Shortcut;
-
-/**
- * Select all nodes of a selected way.
- *
- */
-
-public class SelectWayNodesAction extends JosmAction {
-
-    private Node selectedNode;
-    private ArrayList<Node> selectedNodes;
-
-    /**
-     * Create a new SelectWayNodesAction
-     */
-    public SelectWayNodesAction() {
-        super(tr("Select Way Nodes"),"selectwaynodes" , tr("Select all nodes of a selected way."),
-                Shortcut.registerShortcut("tools:selectwaynodes", tr("Tool: {0}", tr("Select Way Nodes")), KeyEvent.VK_N, Shortcut.GROUP_MENU, Shortcut.SHIFT_DEFAULT), true);
-        putValue("help", ht("/Action/SelectWayNodes"));
-    }
-
-    /**
-     * Called when the action is executed.
-     *
-     * This method does some checking on the selection and calls the matching selectWayNodes method.
-     */
-    public void actionPerformed(ActionEvent e) {
-        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
-
-        String errMsg = null;
-        for (OsmPrimitive p : selection) {
-            if (p instanceof Way) {
-                Way w = (Way) p;
-                if (!w.isUsable() || w.getNodesCount() < 1) {
-                    continue;
-                }
-                selectWayNodes(w);
-            }
-            else if (p instanceof Node) {
-                Node n = (Node) p;
-                if (selectedNodes == null) {
-                    selectedNodes = new ArrayList<Node>();
-                }
-                selectedNodes.add(n);
-            }
-        }
-            
-        getCurrentDataSet().setSelected(selectedNodes);
-        selectedNodes = null;
-    }
-
-    private void selectWayNodes(Way w) {
-        
-        for (Node n : w.getNodes()) {
-            if (selectedNodes == null) {
-                selectedNodes = new ArrayList<Node>();
-            }
-            selectedNodes.add(n);
-        }
-    }
-
-    @Override
-    protected void updateEnabledState() {
-        if (getCurrentDataSet() == null) {
-            setEnabled(false);
-        } else {
-            updateEnabledState(getCurrentDataSet().getSelected());
-        }
-    }
-
-    @Override
-    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
-    }
-}
-
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/UnselectNodesAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/UnselectNodesAction.java	(revision 25836)
+++ 	(revision )
@@ -1,53 +1,0 @@
-// License: GPL. Copyright 2011 by Alexei Kasatkin and Martin Ždila
-package utilsplugin2;
-
-import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.util.Collection;
-import java.util.Set;
-import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.data.osm.*;
-
-import org.openstreetmap.josm.tools.Shortcut;
-
-/**
- *    Unselects all nodes
- */
-class UnselectNodesAction extends JosmAction {
-
-    
-    public UnselectNodesAction() {
-        super(tr("Unselect nodes"), "unsnodes",
-                tr("Removes all nodes from selection"),
-                Shortcut.registerShortcut("tools:unsnodes", tr("Tool: {0}","Unselect nodes"),
-                KeyEvent.VK_U, Shortcut.GROUP_MNEMONIC,KeyEvent.ALT_MASK  ), true);
-        putValue("help", ht("/Action/UnselectNodes"));
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
-        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
-        getCurrentDataSet().clearSelection(selectedNodes);
-    }
-
-    @Override
-    protected void updateEnabledState() {
-        if (getCurrentDataSet() == null) {
-            setEnabled(false);
-        } else {
-            updateEnabledState(getCurrentDataSet().getSelected());
-        }
-    }
-
-    @Override
-    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        if (selection == null) {
-            setEnabled(false);
-            return;
-        }
-        setEnabled(!selection.isEmpty());
-    }
-}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/UtilsPlugin2.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/UtilsPlugin2.java	(revision 25836)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/UtilsPlugin2.java	(revision 25876)
@@ -5,4 +5,6 @@
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;
+import utilsplugin2.selection.*;
+import utilsplugin2.dumbutils.*;
 
 import org.openstreetmap.josm.Main;
@@ -25,20 +27,33 @@
     JMenuItem intWaysR;
 
+    JMenuItem replaceGeometry;
+    JMenuItem tagBuffer;
+    JMenuItem sourceTag;
+    JMenuItem pasteRelations;
+    JMenuItem alignWayNodes;
+
     public UtilsPlugin2(PluginInformation info) {
         super(info);
-        Main.main.menu.toolsMenu.addSeparator();
-        unglueRelation = MainMenu.add(Main.main.menu.toolsMenu, new UnGlueRelationAction());
-        addIntersections = MainMenu.add(Main.main.menu.toolsMenu, new AddIntersectionsAction());
-        splitObject = MainMenu.add(Main.main.menu.toolsMenu, new SplitObjectAction());
-        Main.main.menu.toolsMenu.addSeparator();
-        JMenu m1 = Main.main.menu.addMenu(marktr("Selection"), KeyEvent.VK_N, Main.main.menu.defaultMenuPos, "help");
 
-        selectWayNodes = MainMenu.add(m1, new SelectWayNodesAction());
-        adjNodes = MainMenu.add(m1, new AdjacentNodesAction());
-        unsNodes = MainMenu.add(m1, new UnselectNodesAction());
-        adjWays = MainMenu.add(m1, new AdjacentWaysAction());
-        adjWaysAll = MainMenu.add(m1, new ConnectedWaysAction());
-        intWays = MainMenu.add(m1, new IntersectedWaysAction());
-        intWaysR = MainMenu.add(m1, new IntersectedWaysRecursiveAction());
+        JMenu toolsMenu = Main.main.menu.addMenu(marktr("More tools"), KeyEvent.VK_M, 4, "help");
+        unglueRelation = MainMenu.add(toolsMenu, new UnGlueRelationAction());
+        addIntersections = MainMenu.add(toolsMenu, new AddIntersectionsAction());
+        splitObject = MainMenu.add(toolsMenu, new SplitObjectAction());
+
+        toolsMenu.addSeparator();
+        replaceGeometry = MainMenu.add(toolsMenu, new ReplaceGeometryAction());
+        tagBuffer = MainMenu.add(toolsMenu, new TagBufferAction());
+        sourceTag = MainMenu.add(toolsMenu, new TagSourceAction());
+        pasteRelations = MainMenu.add(toolsMenu, new PasteRelationsAction());
+        alignWayNodes = MainMenu.add(toolsMenu, new AlignWayNodesAction());
+
+        JMenu selectionMenu = Main.main.menu.addMenu(marktr("Selection"), KeyEvent.VK_N, Main.main.menu.defaultMenuPos, "help");
+        selectWayNodes = MainMenu.add(selectionMenu, new SelectWayNodesAction());
+        adjNodes = MainMenu.add(selectionMenu, new AdjacentNodesAction());
+        unsNodes = MainMenu.add(selectionMenu, new UnselectNodesAction());
+        adjWays = MainMenu.add(selectionMenu, new AdjacentWaysAction());
+        adjWaysAll = MainMenu.add(selectionMenu, new ConnectedWaysAction());
+        intWays = MainMenu.add(selectionMenu, new IntersectedWaysAction());
+        intWaysR = MainMenu.add(selectionMenu, new IntersectedWaysRecursiveAction());
     }
 
@@ -50,4 +65,11 @@
         addIntersections.setEnabled(enabled);
         splitObject.setEnabled(enabled);
+
+        replaceGeometry.setEnabled(enabled);
+        tagBuffer.setEnabled(enabled);
+        sourceTag.setEnabled(enabled);
+        pasteRelations.setEnabled(enabled);
+        alignWayNodes.setEnabled(enabled);
+
         selectWayNodes.setEnabled(enabled);
         adjNodes.setEnabled(enabled);
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/AlignWayNodesAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/AlignWayNodesAction.java	(revision 25876)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/AlignWayNodesAction.java	(revision 25876)
@@ -0,0 +1,188 @@
+package utilsplugin2.dumbutils;
+
+import java.awt.event.KeyEvent;
+import org.openstreetmap.josm.tools.Shortcut;
+import org.openstreetmap.josm.data.osm.*;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.*;
+import java.util.*;
+import java.awt.event.ActionEvent;
+import javax.swing.JOptionPane;
+import org.openstreetmap.josm.actions.JosmAction;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+/**
+ * Pastes relation membership from objects in the paste buffer onto selected object(s).
+ *
+ * @author Zverik
+ */
+public class AlignWayNodesAction extends JosmAction {
+    private static final String TITLE = "Align Way Nodes";
+    private static final double MOVE_THRESHOLD = 1e-9;
+
+    public AlignWayNodesAction() {
+        super(tr(TITLE), "dumbutils/alignwaynodes", tr("Align nodes in a way"),
+                Shortcut.registerShortcut("tools:alignwaynodes", tr("Tool: {0}", tr(TITLE)), KeyEvent.VK_L, Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
+    }
+
+    public void actionPerformed( ActionEvent e ) {
+        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
+        Set<Node> selectedNodes = filterNodes(selection);
+        int selectedNodesCount = selectedNodes.size();
+        Set<Way> ways = findCommonWays(selectedNodes);
+        if( ways == null || ways.size() != 1 || selectedNodesCount == 0 )
+            return;
+        Way way = ways.iterator().next();
+        if( way.getNodesCount() < (way.isClosed() ? 4 : 3) ) {
+            JOptionPane.showMessageDialog(Main.parent, tr("The way with selected nodes can not be straightened."), tr(TITLE), JOptionPane.ERROR_MESSAGE);
+            return;
+        }
+
+        // Prepare a list of nodes to align
+        int firstNodePos = findFirstNode(way, selectedNodes);
+        int lastNodePos = way.isClosed() ? firstNodePos : way.getNodesCount();
+        List<Node> nodes = new ArrayList<Node>();
+        int i = firstNodePos;
+        boolean iterated = false;
+        while( !iterated || i != lastNodePos ) {
+            Node node = way.getNode(i);
+            if( selectedNodes.contains(node) ) {
+                nodes.add(node);
+                selectedNodes.remove(node);
+                if( selectedNodesCount == 1 ) {
+                    nodes.add(0, way.getNode( i > 0 ? i - 1 : way.isClosed() ? way.getNodesCount() - 2 : i + 2 ));
+                    nodes.add(way.getNode( i + 1 < way.getNodesCount() ? i + 1 : way.isClosed() ? 1 : i - 2 ));
+                }
+                if( selectedNodes.isEmpty() )
+                    break;
+            } else if( selectedNodesCount == 2 && selectedNodes.size() == 1 )
+                nodes.add(node);
+            i++;
+            if( i >= way.getNodesCount() && way.isClosed() )
+                i = 0;
+            iterated = true;
+        }
+
+        if( nodes.size() < 3 ) {
+            JOptionPane.showMessageDialog(Main.parent, "Internal error: number of nodes is " + nodes.size(),
+                    tr(TITLE), JOptionPane.ERROR_MESSAGE);
+            return;
+        }
+
+        // Now, we have an ordered list of nodes, of which idx 0 and N-1 serve as guides
+        // and 1..N-2 should be aligned with them
+        List<Command> commands = new ArrayList<Command>();
+        double ax = nodes.get(0).getEastNorth().east();
+        double ay = nodes.get(0).getEastNorth().north();
+        double bx = nodes.get(nodes.size() - 1).getEastNorth().east();
+        double by = nodes.get(nodes.size() - 1).getEastNorth().north();
+        
+        for( i = 1; i + 1 < nodes.size(); i++ ) {
+            Node n = nodes.get(i);
+            
+            // Algorithm is copied from org.openstreetmap.josm.actions.AlignInLineAction
+            double nx = n.getEastNorth().east();
+            double ny = n.getEastNorth().north();
+
+            if( ax == bx ) {
+                // Special case if AB is vertical...
+                nx = ax;
+            } else if( ay == by ) {
+                // ...or horizontal
+                ny = ay;
+            } else {
+                // Otherwise calculate position by solving y=mx+c (simplified)
+                double m1 = (by - ay) / (bx - ax);
+                double c1 = ay - (ax * m1);
+                double m2 = (-1) / m1;
+                double c2 = ny - (nx * m2);
+
+                nx = (c2 - c1) / (m1 - m2);
+                ny = (m1 * nx) + c1;
+            }
+
+            // Add the command to move the node to its new position.
+            if( Math.abs(nx - n.getEastNorth().east()) > MOVE_THRESHOLD && Math.abs(ny - n.getEastNorth().north()) > MOVE_THRESHOLD )
+                commands.add(new MoveCommand(n, nx - n.getEastNorth().east(), ny - n.getEastNorth().north()));
+        }
+
+        if( !commands.isEmpty() )
+            Main.main.undoRedo.add(new SequenceCommand(tr(TITLE), commands));
+    }
+
+    @Override
+    protected void updateEnabledState() {
+        if( getCurrentDataSet() == null ) {
+            setEnabled(false);
+        }  else
+            updateEnabledState(getCurrentDataSet().getSelected());
+    }
+
+    @Override
+    protected void updateEnabledState( Collection<? extends OsmPrimitive> selection ) {
+        Set<Node> nodes = filterNodes(selection);
+        Set<Way> ways = findCommonWays(nodes);
+        setEnabled(ways != null && ways.size() == 1 && !nodes.isEmpty());
+    }
+
+    private Set<Way> findCommonWays( Set<Node> nodes ) {
+        Set<Way> ways = null;
+        for( Node n : nodes ) {
+            List<Way> referrers = OsmPrimitive.getFilteredList(n.getReferrers(), Way.class);
+            if( ways == null )
+                ways = new HashSet<Way>(referrers);
+            else {
+                ways.retainAll(referrers);
+            }
+        }
+        return ways;
+    }
+
+    private Set<Node> filterNodes( Collection<? extends OsmPrimitive> selection ) {
+        Set<Node> result = new HashSet<Node>();
+        if( selection != null ) {
+            for( OsmPrimitive p : selection )
+                if( p instanceof Node )
+                    result.add((Node)p);
+        }
+        return result;
+    }
+
+    /**
+     * Find the largest empty span between nodes and returns the index of the node right after it.
+     *
+     * TODO: not the maximum node count, but maximum distance!
+     */
+    private int findFirstNode( Way way, Set<Node> nodes ) {
+        int pos = 0;
+        while( pos < way.getNodesCount() && !nodes.contains(way.getNode(pos)) )
+            pos++;
+        if( pos >= way.getNodesCount() )
+            return 0;
+        if( !way.isClosed() || nodes.size() <= 1 )
+            return pos;
+
+        // now, way is closed
+        boolean fullCircle = false;
+        int maxLength = 0;
+        int lastPos = 0;
+        while( !fullCircle ) {
+            int length = 0;
+            boolean skippedFirst = false;
+            while( !(skippedFirst && nodes.contains(way.getNode(pos))) ) {
+                skippedFirst = true;
+                length++;
+                pos++;
+                if( pos >= way.getNodesCount() ) {
+                    pos = 0;
+                    fullCircle = true;
+                }
+            }
+            if( length > maxLength ) {
+                maxLength = length;
+                lastPos = pos;
+            }
+        }
+        return lastPos;
+    }
+}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/PasteRelationsAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/PasteRelationsAction.java	(revision 25876)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/PasteRelationsAction.java	(revision 25876)
@@ -0,0 +1,82 @@
+package utilsplugin2.dumbutils;
+
+import org.openstreetmap.josm.data.osm.*;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.*;
+import java.util.*;
+import java.awt.event.KeyEvent;
+import org.openstreetmap.josm.tools.Shortcut;
+import java.awt.event.ActionEvent;
+import org.openstreetmap.josm.actions.JosmAction;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+/**
+ * Pastes relation membership from objects in the paste buffer onto selected object(s).
+ *
+ * @author Zverik
+ */
+public class PasteRelationsAction extends JosmAction {
+    private static final String TITLE = "Paste Relations";
+
+    public PasteRelationsAction() {
+        super(tr(TITLE), "dumbutils/pasterelations", tr("Paste relation membership from objects in the buffer onto selected object(s)"),
+                Shortcut.registerShortcut("tools:pasterelations", tr("Tool: {0}", tr(TITLE)), KeyEvent.VK_V,
+                Shortcut.GROUP_MENU, KeyEvent.ALT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK), true);
+    }
+
+    public void actionPerformed( ActionEvent e ) {
+        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
+        if( selection.isEmpty() )
+            return;
+
+        Map<Relation, String> relations = new HashMap<Relation, String>();
+        for( PrimitiveData pdata : Main.pasteBuffer.getDirectlyAdded() ) {
+            OsmPrimitive p = getCurrentDataSet().getPrimitiveById(pdata.getId(), pdata.getType());
+            for( Relation r : OsmPrimitive.getFilteredList(p.getReferrers(), Relation.class)) {
+                String role = relations.get(r);
+                for( RelationMember m : r.getMembers() ) {
+                    if( m.getMember().equals(p) ) {
+                        String newRole = m.getRole();
+                        if( newRole != null && role == null )
+                            role = newRole;
+                        else if( newRole != null ? !newRole.equals(role) : role != null ) {
+                            role = "";
+                            break;
+                        }
+                    }
+                }
+                relations.put(r, role);
+            }
+        }
+
+        List<Command> commands = new ArrayList<Command>();
+        for( Relation rel : relations.keySet() ) {
+            Relation r = new Relation(rel);
+            boolean changed = false;
+            for( OsmPrimitive p : selection ) {
+                if( !r.getMemberPrimitives().contains(p) ) {
+                    r.addMember(new RelationMember(relations.get(rel), p));
+                    changed = true;
+                }
+            }
+            if( changed )
+                commands.add(new ChangeCommand(rel, r));
+        }
+
+        if( !commands.isEmpty() )
+            Main.main.undoRedo.add(new SequenceCommand(tr(TITLE), commands));
+    }
+
+    @Override
+    protected void updateEnabledState() {
+        if( getCurrentDataSet() == null ) {
+            setEnabled(false);
+        }  else
+            updateEnabledState(getCurrentDataSet().getSelected());
+    }
+
+    @Override
+    protected void updateEnabledState( Collection<? extends OsmPrimitive> selection ) {
+        setEnabled(selection != null && !selection.isEmpty() && !Main.pasteBuffer.isEmpty() );
+    }
+}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/ReplaceGeometryAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/ReplaceGeometryAction.java	(revision 25876)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/ReplaceGeometryAction.java	(revision 25876)
@@ -0,0 +1,156 @@
+package utilsplugin2.dumbutils;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Area;
+import org.openstreetmap.josm.data.osm.Node;
+import java.util.*;
+import org.openstreetmap.josm.command.*;
+import org.openstreetmap.josm.Main;
+import javax.swing.JOptionPane;
+import org.openstreetmap.josm.data.osm.Way;
+import java.awt.event.KeyEvent;
+import org.openstreetmap.josm.tools.Shortcut;
+import java.awt.event.ActionEvent;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.DefaultNameFormatter;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+/**
+ * Replaces already existing way with the other, fresh created. Select both ways and push the button.
+ *
+ * @author Zverik
+ */
+public class ReplaceGeometryAction extends JosmAction {
+    private static final String TITLE = "Replace Geometry";
+    private static final double MAX_NODE_REPLACEMENT_DISTANCE = 3e-4;
+
+    public ReplaceGeometryAction() {
+        super(tr(TITLE), "dumbutils/replacegeometry", tr("Replace geometry of selected way with a new one"),
+                Shortcut.registerShortcut("tools:replacegeometry", tr("Tool: {0}", tr(TITLE)), KeyEvent.VK_G,
+                Shortcut.GROUP_HOTKEY, Shortcut.SHIFT_DEFAULT), true);
+    }
+
+    public void actionPerformed( ActionEvent e ) {
+        if( getCurrentDataSet() == null ) return;
+        // There must be two ways selected: one with id > 0 and one new.
+        List<Way> selection = OsmPrimitive.getFilteredList(getCurrentDataSet().getSelected(), Way.class);
+        if( selection.size() != 2 ) {
+            JOptionPane.showMessageDialog(Main.parent,
+                    tr("This tool replaces geometry of one way with another, and requires two ways to be selected."),
+                    tr(TITLE), JOptionPane.INFORMATION_MESSAGE);
+            return;
+        }
+        int idxNew = selection.get(0).isNew() ? 0 : 1;
+        Way geometry = selection.get(idxNew);
+        Way way = selection.get(1 - idxNew);
+        if( way.isNew() || !geometry.isNew() ) {
+            JOptionPane.showMessageDialog(Main.parent,
+                    tr("Please select one way that exists in the database and one new way with correct geometry."),
+                    tr(TITLE), JOptionPane.WARNING_MESSAGE);
+            return;
+        }
+
+        // Prepare a list of nodes that are not used anywhere except in the way
+        Set<Node> nodePool = new HashSet<Node>();
+        Area a = getCurrentDataSet().getDataSourceArea();
+        for( Node node : way.getNodes() ) {
+            List<OsmPrimitive> referrers = node.getReferrers();
+            if( !node.isDeleted() && referrers.size() == 1 && referrers.get(0).equals(way)
+                    && (node.isNewOrUndeleted() || a.contains(node.getCoor())) )
+                nodePool.add(node);
+        }
+
+        // And the same for geometry, list nodes that can be freely deleted
+        Set<Node> geometryPool = new HashSet<Node>();
+        for( Node node : geometry.getNodes() ) {
+            List<OsmPrimitive> referrers = node.getReferrers();
+            if( node.isNew() && !node.isDeleted() && referrers.size() == 1
+                    && referrers.get(0).equals(geometry) && !way.containsNode(node) )
+                geometryPool.add(node);
+        }
+
+        // Find new nodes that are closest to the old ones, remove matching old ones from the pool
+        Map<Node, Node> nodeAssoc = new HashMap<Node, Node>();
+        for( Node n : geometryPool ) {
+            Node nearest = findNearestNode(n, nodePool);
+            if( nearest != null ) {
+                nodeAssoc.put(n, nearest);
+                nodePool.remove(nearest);
+            }
+        }
+
+        // Now that we have replacement list, move all unused new nodes to nodePool (and delete them afterwards)
+        for( Node n : geometryPool )
+            if( nodeAssoc.containsKey(n) )
+                nodePool.add(n);
+
+        // And prepare a list of nodes with all the replacements
+        List<Node> geometryNodes = geometry.getNodes();
+        for( int i = 0; i < geometryNodes.size(); i++ )
+            if( nodeAssoc.containsKey(geometryNodes.get(i)) )
+                geometryNodes.set(i, nodeAssoc.get(geometryNodes.get(i)));
+
+        // Now do the replacement
+        List<Command> commands = new ArrayList<Command>();
+        commands.add(new ChangeNodesCommand(way, geometryNodes));
+
+        // Move old nodes to new positions
+        for( Node node : nodeAssoc.keySet() )
+            commands.add(new MoveCommand(nodeAssoc.get(node), node.getCoor()));
+
+        // Copy tags from temporary way (source etc.)
+        for( String key : geometry.keySet() )
+            commands.add(new ChangePropertyCommand(way, key, geometry.get(key)));
+
+        // Remove geometry way from selection
+        getCurrentDataSet().clearSelection(geometry);
+
+        // And delete old geometry way
+        commands.add(new DeleteCommand(geometry));
+
+        // Delete nodes that are not used anymore
+        if( !nodePool.isEmpty() )
+            commands.add(new DeleteCommand(nodePool));
+
+        // Two items in undo stack: change original way and delete geometry way
+        Main.main.undoRedo.add(new SequenceCommand(
+                tr("Replace geometry for way {0}", way.getDisplayName(DefaultNameFormatter.getInstance())),
+                commands));
+    }
+
+    /**
+     * Find node from the collection which is nearest to <tt>node</tt>. Max distance is taken in consideration.
+     * @return null if there is no such node.
+     */
+    private Node findNearestNode( Node node, Collection<Node> nodes ) {
+        if( nodes.contains(node) )
+            return node;
+        
+        Node nearest = null;
+        double distance = MAX_NODE_REPLACEMENT_DISTANCE;
+        Point2D coor = node.getCoor();
+        for( Node n : nodes ) {
+            double d = n.getCoor().distance(coor);
+            if( d < distance ) {
+                distance = d;
+                nearest = n;
+            }
+        }
+        return nearest;
+    }
+
+    @Override
+    protected void updateEnabledState() {
+        if( getCurrentDataSet() == null ) {
+            setEnabled(false);
+        }  else
+            updateEnabledState(getCurrentDataSet().getSelected());
+    }
+
+    @Override
+    protected void updateEnabledState( Collection<? extends OsmPrimitive> selection ) {
+        setEnabled(selection != null && selection.size() >= 2 );
+    }
+}
+
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/TagBufferAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/TagBufferAction.java	(revision 25876)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/TagBufferAction.java	(revision 25876)
@@ -0,0 +1,111 @@
+package utilsplugin2.dumbutils;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.*;
+import java.util.*;
+import java.awt.event.KeyEvent;
+import org.openstreetmap.josm.tools.Shortcut;
+import java.awt.event.ActionEvent;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+/**
+ * Remembers tags of selected object(s) and when clicked, pastes them onto selection.
+ *
+ * @author Zverik
+ */
+public class TagBufferAction extends JosmAction {
+    private static final String TITLE = "Copy tags from previous selection";
+    private Map<String, String> tags = new HashMap<String, String>();
+    private Map<String, String> currentTags = new HashMap<String, String>();
+    private Set<OsmPrimitive> selectionBuf = new HashSet<OsmPrimitive>();
+
+    public TagBufferAction() {
+        super(tr(TITLE), "dumbutils/tagbuffer", tr("Pastes tags of previously selected object(s)"),
+                Shortcut.registerShortcut("tools:tagbuffer", tr("Tool: {0}", tr(TITLE)), KeyEvent.VK_R,
+                Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
+    }
+
+    public void actionPerformed( ActionEvent e ) {
+        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
+        if( selection.isEmpty() )
+            return;
+
+        List<Command> commands = new ArrayList<Command>();
+        for( String key : tags.keySet() ) {
+            String value = tags.get(key);
+            boolean foundNew = false;
+            for( OsmPrimitive p : selection ) {
+                if( !p.hasKey(key) || !p.get(key).equals(value) ) {
+                    foundNew = true;
+                    break;
+                }
+            }
+            if( foundNew )
+                commands.add(new ChangePropertyCommand(selection, key, value));
+        }
+        
+        if( !commands.isEmpty() )
+            Main.main.undoRedo.add(new SequenceCommand(tr(TITLE), commands));
+    }
+
+    @Override
+    protected void updateEnabledState() {
+        if( getCurrentDataSet() == null ) {
+            setEnabled(false);
+            if( selectionBuf != null )
+                selectionBuf.clear();
+        }  else
+            updateEnabledState(getCurrentDataSet().getSelected());
+    }
+
+    @Override
+    protected void updateEnabledState( Collection<? extends OsmPrimitive> selection ) {
+        // selection changed => check if selection is completely different from before
+        boolean foundOld = false;
+        if( selection != null ) {
+            for( OsmPrimitive p : selectionBuf ) {
+                if( selection.contains(p) ) {
+                    foundOld = true;
+                    break;
+                }
+            }
+            selectionBuf.clear();
+            selectionBuf.addAll(selection);
+        } else {
+            foundOld = selectionBuf.isEmpty();
+            selectionBuf.clear();
+        }
+        if( !foundOld ) {
+            // selection has completely changed, remember tags
+            tags.clear();
+            tags.putAll(currentTags);
+        }
+        rememberSelectionTags();
+
+        setEnabled(selection != null && !selection.isEmpty() && !tags.isEmpty());
+    }
+
+    private void rememberSelectionTags() {
+        if( getCurrentDataSet() != null && !getCurrentDataSet().getSelected().isEmpty() ) {
+            currentTags.clear();
+            Set<String> bad = new HashSet<String>();
+            for( OsmPrimitive p : getCurrentDataSet().getSelected() ) {
+                if( currentTags.isEmpty() ) {
+                    for( String key : p.keySet() )
+                        currentTags.put(key, p.get(key));
+                } else {
+                    for( String key : p.keySet() )
+                        if( !currentTags.containsKey(key) || !currentTags.get(key).equals(p.get(key)) )
+                            bad.add(key);
+                    for( String key : currentTags.keySet() )
+                        if( !p.hasKey(key) )
+                            bad.add(key);
+                }
+            }
+            for( String key : bad )
+                currentTags.remove(key);
+        }
+    }
+}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/TagSourceAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/TagSourceAction.java	(revision 25876)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/TagSourceAction.java	(revision 25876)
@@ -0,0 +1,84 @@
+package utilsplugin2.dumbutils;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.*;
+import java.util.*;
+import java.awt.event.KeyEvent;
+import org.openstreetmap.josm.tools.Shortcut;
+import java.awt.event.ActionEvent;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+/**
+ * Remembers last source value and put it on selected object(s).
+ *
+ * @author Zverik
+ */
+public class TagSourceAction extends JosmAction {
+    private static final String TITLE = "Add Source Tag";
+    private String source;
+    private Set<OsmPrimitive> selectionBuf = new HashSet<OsmPrimitive>();
+    private boolean clickedTwice = false;
+
+    public TagSourceAction() {
+        super(tr(TITLE), "dumbutils/sourcetag", tr("Add remembered source tag"),
+                Shortcut.registerShortcut("tools:sourcetag", tr("Tool: {0}", tr(TITLE)), KeyEvent.VK_S,
+                Shortcut.GROUP_MENU, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK), true);
+        source = Main.pref.get("sourcetag.value");
+    }
+
+    public void actionPerformed( ActionEvent e ) {
+        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
+        if( selection.isEmpty() || source == null || source.length() == 0 )
+            return;
+
+        Main.main.undoRedo.add(new ChangePropertyCommand(selection, "source", source));
+    }
+
+    @Override
+    protected void updateEnabledState() {
+        if( getCurrentDataSet() == null ) {
+            setEnabled(false);
+            if( selectionBuf != null )
+                selectionBuf.clear();
+        }  else
+            updateEnabledState(getCurrentDataSet().getSelected());
+    }
+
+    @Override
+    protected void updateEnabledState( Collection<? extends OsmPrimitive> selection ) {
+        if( selection == null || selection.isEmpty() ) {
+            selectionBuf.clear();
+            clickedTwice = false;
+            setEnabled(false);
+            return;
+        }
+
+        if( selectionBuf.size() == selection.size() && selectionBuf.containsAll(selection) ) {
+            if( !clickedTwice )
+                clickedTwice = true;
+            else {
+                // tags may have been changed, get the source
+                String newSource = null;
+                for( OsmPrimitive p : selection ) {
+                    String value = p.get("source");
+                    if( value != null && newSource == null )
+                        newSource = value;
+                    else if( value != null ? !value.equals(newSource) : newSource != null ) {
+                        newSource = "";
+                        break;
+                    }
+                }
+                if( newSource != null && newSource.length() > 0 && !newSource.equals(source) ) {
+                    source = newSource;
+                    Main.pref.put("sourcetag.value", source);
+                }
+            }
+        } else
+            clickedTwice = false;
+        selectionBuf.clear();
+        selectionBuf.addAll(selection);
+        setEnabled(source != null && source.length() > 0);
+    }
+}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/AdjacentNodesAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/AdjacentNodesAction.java	(revision 25876)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/AdjacentNodesAction.java	(revision 25876)
@@ -0,0 +1,114 @@
+// License: GPL. Copyright 2011 by Alexei Kasatkin and others
+package utilsplugin2.selection;
+
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.osm.*;
+
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ *    Extends current selection
+ */
+public class AdjacentNodesAction extends JosmAction {
+
+    public static final boolean treeMode = false;
+
+    public AdjacentNodesAction() {
+        super(tr("Adjacent nodes"), "adjnodes", tr("Select adjacent nodes"),
+                Shortcut.registerShortcut("tools:adjnodes", tr("Tool: {0}","Adjacent nodes"),
+                KeyEvent.VK_E, Shortcut.GROUP_EDIT), true);
+        putValue("help", ht("/Action/AdjacentNodes"));
+    }
+
+    private  Set<Way> activeWays = new HashSet<Way>();
+
+    public void actionPerformed(ActionEvent e) {
+        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
+        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
+
+        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
+        
+        // if no nodes and no ways are selected, do nothing
+        if (selectedNodes.isEmpty() && selectedWays.isEmpty()) return;
+
+        if (selectedWays.isEmpty()) {
+            // if one node is selected, used ways connected to it to extend selecteons
+            // activeWays are remembered for next extend action (!!!)
+
+            // FIXME: some strange behaviour is possible if user delete some of these way
+            // how to clear activeWays during such user actions? Do not know
+            if (selectedNodes.size() == 1) {
+                activeWays.clear();
+//                System.out.println("Cleared active ways");
+            }
+        } else {
+            // use only ways that were selected for adding nodes
+            activeWays = selectedWays;
+        }
+
+        // selecting nodes of selected ways
+        if(selectedNodes.isEmpty()) {
+            HashSet<Node> newNodes = new HashSet<Node>();
+            NodeWayUtils.addNodesConnectedToWays(selectedWays, newNodes);
+            activeWays.clear();
+            getCurrentDataSet().setSelected(newNodes);
+            return;
+        }
+
+        if (activeWays.isEmpty()) {
+                NodeWayUtils.addWaysConnectedToNodes(selectedNodes, activeWays);
+        }
+
+        Set<Node> newNodes = new HashSet <Node>();
+        for (Node node: selectedNodes) {
+            for (Way w: activeWays) {
+                NodeWayUtils.addNeighbours(w, node, newNodes);
+            }
+        }
+        
+        // select only newly found nodes
+         newNodes.removeAll(selectedNodes);
+
+//         System.out.printf("Found %d new nodes\n",newNodes.size());
+         
+         // enable branching on next call of this function
+         // if no new nodes were found, next search will include all touched ways
+         if (newNodes.isEmpty()) {
+             activeWays.clear();
+//             System.out.println("No more points found, activeways cleared");
+         }
+
+         getCurrentDataSet().addSelected(newNodes);
+         newNodes = null;
+
+    }
+
+    @Override
+    protected void updateEnabledState() {
+        if (getCurrentDataSet() == null) {
+            setEnabled(false);
+        } else {
+            updateEnabledState(getCurrentDataSet().getSelected());
+        }
+    }
+
+    @Override
+    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
+        if (selection == null) {
+            setEnabled(false);
+            return;
+        }
+        setEnabled(!selection.isEmpty());
+    }
+
+
+
+}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/AdjacentWaysAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/AdjacentWaysAction.java	(revision 25876)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/AdjacentWaysAction.java	(revision 25876)
@@ -0,0 +1,74 @@
+// License: GPL. Copyright 2011 by Alexei Kasatkin
+package utilsplugin2.selection;
+
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.osm.*;
+
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ *    Extends current selection
+ */
+public class AdjacentWaysAction extends JosmAction {
+
+    public static final boolean treeMode = false;
+
+    public AdjacentWaysAction() {
+        super(tr("Adjacent ways"), "adjways",
+                tr("Adjacent ways will be selected. Nodes wiil be deselected."),
+                Shortcut.registerShortcut("tools:adjways", tr("Tool: {0}","Adjacent ways"),
+                KeyEvent.VK_E, Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
+        putValue("help", ht("/Action/AdjacentWays"));
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
+        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
+
+        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
+
+        // select ways attached to already selected ways
+        Set<Way> newWays = new HashSet<Way>();
+        newWays.addAll(selectedWays);
+        for (Way w : selectedWays){
+            NodeWayUtils.addWaysConnectedToWay(w, newWays);
+        }
+
+        // selecting ways attached to selected nodes
+        if(!selectedNodes.isEmpty()) {
+            NodeWayUtils.addWaysConnectedToNodes(selectedNodes, newWays);
+        }
+
+//        System.out.printf("%d ways added to selection\n",newWays.size()-selectedWays.size());
+        getCurrentDataSet().setSelected(newWays);
+    }
+
+    @Override
+    protected void updateEnabledState() {
+        if (getCurrentDataSet() == null) {
+            setEnabled(false);
+        } else {
+            updateEnabledState(getCurrentDataSet().getSelected());
+        }
+    }
+
+    @Override
+    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
+        if (selection == null) {
+            setEnabled(false);
+            return;
+        }
+        setEnabled(!selection.isEmpty());
+    }
+
+
+
+}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/ConnectedWaysAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/ConnectedWaysAction.java	(revision 25876)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/ConnectedWaysAction.java	(revision 25876)
@@ -0,0 +1,69 @@
+// License: GPL. Copyright 2011 by Alexei Kasatkin
+package utilsplugin2.selection;
+
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.osm.*;
+
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ *    Extends current selection by selecting nodes on all touched ways
+ */
+public class ConnectedWaysAction extends JosmAction {
+
+    public ConnectedWaysAction() {
+        super(tr("All connected ways"), "adjwaysall", tr("Select all connected ways"),
+                Shortcut.registerShortcut("tools:adjwaysall", tr("Tool: {0}","All connected ways"),
+                KeyEvent.VK_E, Shortcut.GROUP_MENU, Shortcut.SHIFT_DEFAULT), true);
+        putValue("help", ht("/Action/SelectConnectedWays"));
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
+        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
+        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
+
+        Set<Way> newWays = new HashSet<Way>();
+
+        // selecting ways attached to selected nodes
+        if(!selectedNodes.isEmpty()) {
+            NodeWayUtils.addWaysConnectedToNodes(selectedNodes, newWays);
+        }
+
+        // select ways attached to already selected ways
+        newWays.addAll(selectedWays);
+        NodeWayUtils.addWaysConnectedToWaysRecursively(selectedWays, newWays);
+        
+//        System.out.printf("%d ways added to selection\n",newWays.size()-selectedWays.size());
+        getCurrentDataSet().setSelected(newWays);
+
+    }
+
+    @Override
+    protected void updateEnabledState() {
+        if (getCurrentDataSet() == null) {
+            setEnabled(false);
+        } else {
+            updateEnabledState(getCurrentDataSet().getSelected());
+        }
+    }
+
+    @Override
+    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
+        if (selection == null) {
+            setEnabled(false);
+            return;
+        }
+        setEnabled(!selection.isEmpty());
+    }
+
+
+}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/IntersectedWaysAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/IntersectedWaysAction.java	(revision 25876)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/IntersectedWaysAction.java	(revision 25876)
@@ -0,0 +1,73 @@
+// License: GPL. Copyright 2011 by Alexei Kasatkin
+package utilsplugin2.selection;
+
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import javax.swing.JOptionPane;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.osm.*;
+
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ *    Extends current selection by selecting nodes on all touched ways
+ */
+public class IntersectedWaysAction extends JosmAction {
+
+    public IntersectedWaysAction() {
+        super(tr("Intersecting ways"), "intway", tr("Select intersecting ways"),
+                Shortcut.registerShortcut("tools:intway", tr("Tool: {0}","Intersecting ways"),
+                KeyEvent.VK_I, Shortcut.GROUP_EDIT), true);
+        putValue("help", ht("/Action/SelectIntersectingWays"));
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
+        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
+        Set<Way> activeWays = new HashSet<Way>();
+
+        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
+
+        // select ways attached to already selected ways
+        if (!selectedWays.isEmpty()) {
+            Set<Way> newWays = new HashSet<Way>();
+            NodeWayUtils.addWaysIntersectingWays(
+                    getCurrentDataSet().getWays(),
+                    selectedWays, newWays);
+            getCurrentDataSet().addSelected(newWays);
+            return;
+        } else {
+             JOptionPane.showMessageDialog(Main.parent,
+               tr("Please select some ways to find connected and intersecting ways!"),
+               tr("Warning"), JOptionPane.WARNING_MESSAGE);
+        }
+
+    }
+
+    @Override
+    protected void updateEnabledState() {
+        if (getCurrentDataSet() == null) {
+            setEnabled(false);
+        } else {
+            updateEnabledState(getCurrentDataSet().getSelected());
+        }
+    }
+
+    @Override
+    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
+        if (selection == null) {
+            setEnabled(false);
+            return;
+        }
+        setEnabled(!selection.isEmpty());
+    }
+
+
+}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/IntersectedWaysRecursiveAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/IntersectedWaysRecursiveAction.java	(revision 25876)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/IntersectedWaysRecursiveAction.java	(revision 25876)
@@ -0,0 +1,74 @@
+// License: GPL. Copyright 2011 by Alexei Kasatkin ond others
+package utilsplugin2.selection;
+
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import javax.swing.JOptionPane;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.osm.*;
+
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ *    Extends current selection by selecting nodes on all touched ways
+ */
+public class IntersectedWaysRecursiveAction extends JosmAction {
+    
+    public IntersectedWaysRecursiveAction() {
+        super(tr("All intersecting ways"), "intwayall", tr("Select all intersecting ways"),
+                Shortcut.registerShortcut("tools:intwayall", tr("Tool: {0}","All intersecting ways"),
+                KeyEvent.VK_I, Shortcut.GROUP_MENU, KeyEvent.SHIFT_DOWN_MASK|KeyEvent.CTRL_DOWN_MASK), true);
+        putValue("help", ht("/Action/SelectAllIntersectingWays"));
+
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
+        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
+        Set<Way> activeWays = new HashSet<Way>();
+
+        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
+
+        if (!selectedWays.isEmpty()) {
+            Set<Way> newWays = new HashSet<Way>();
+            NodeWayUtils.addWaysIntersectingWaysRecursively(
+                    getCurrentDataSet().getWays(),
+                    selectedWays, newWays);
+            getCurrentDataSet().addSelected(newWays);
+            return;
+        } else {
+             JOptionPane.showMessageDialog(Main.parent,
+               tr("Please select some ways to find all connected and intersecting ways!"),
+               tr("Warning"), JOptionPane.WARNING_MESSAGE);
+        }
+
+    }
+
+
+    @Override
+    protected void updateEnabledState() {
+        if (getCurrentDataSet() == null) {
+            setEnabled(false);
+        } else {
+            updateEnabledState(getCurrentDataSet().getSelected());
+        }
+    }
+
+    @Override
+    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
+        if (selection == null) {
+            setEnabled(false);
+            return;
+        }
+        setEnabled(!selection.isEmpty());
+    }
+
+
+}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/NodeWayUtils.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/NodeWayUtils.java	(revision 25876)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/NodeWayUtils.java	(revision 25876)
@@ -0,0 +1,226 @@
+// License: GPL. Copyright 2011 by Alexei Kasatkin
+package utilsplugin2.selection;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.swing.JOptionPane;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.tools.Geometry;
+import org.openstreetmap.josm.tools.Pair;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+
+/**
+ * Class with some useful functions that are reused in extend selection actions
+ *
+ */
+public final class NodeWayUtils {
+
+    static final int maxLevel = Main.pref.getInteger("selection.maxrecursion", 5);
+    static final int maxWays = Main.pref.getInteger("selection.maxfoundways", 2000);
+    static final int maxWays1 = Main.pref.getInteger("selection.maxfoundways.intersection", 500);
+
+    /**
+     * Find the neighbours of node n on the way w and put them in given collection
+     * @param w way on which the search goes
+     * @param n node to find its neighbours
+     * @param nodes collection to place the nodes we found
+     */
+    static void addNeighbours(Way w, Node n, Collection<Node> nodes) {
+        List<Node> nodeList = w.getNodes();
+        
+        int idx = nodeList.indexOf(n);
+        if (idx == -1) return;
+
+        // add previous element
+        if (idx > 0) {
+            nodes.add(nodeList.get(idx - 1));
+        }
+        // add next element
+        if (idx < nodeList.size() - 1) {
+            nodes.add(nodeList.get(idx + 1));
+        }
+        if (w.isClosed()) {
+            // cyclic neighbours detection
+            if (idx == 0) {
+                nodes.add(nodeList.get(nodeList.size() - 2));
+            }
+            if (idx == nodeList.size() - 1) {
+                nodes.add(nodeList.get(1));
+            }
+        }
+     }
+
+    /**
+     * Adds all ways attached to way to specified collection
+     * @param w way to find attached ways
+     * @param ways  collection to place the ways we found
+     */
+    static int addWaysConnectedToWay(Way w, Set<Way> ways) {
+         int s = ways.size();
+        List<Node> nodes = w.getNodes();
+        for (Node n: nodes) {
+            ways.addAll(OsmPrimitive.getFilteredList(n.getReferrers(), Way.class));
+        }
+        return ways.size() - s;
+    }
+
+    /**
+     * Adds all ways attached to node to specified collection
+     * @param n Node to find attached ways
+     * @param ways  collection to place the ways we found
+     */
+    static int addWaysConnectedToNode(Node n, Set<Way> ways) {
+        int s = ways.size();
+        ways.addAll(OsmPrimitive.getFilteredList(n.getReferrers(), Way.class));
+        return ways.size() - s;
+    }
+
+    /**
+     * Adds all ways intersecting one way to specified set
+     * @param ways collection of ways to search
+     * @param w way to check intersections
+     * @param newWays set to place the ways we found
+     */
+    static int addWaysIntersectingWay(Collection<Way> ways, Way w, Set<Way> newWays,Set<Way> excludeWays) {
+        List<Pair<Node, Node>> nodePairs = w.getNodePairs(false);
+        int count=0;
+        for (Way anyway: ways) {
+            if (anyway == w) continue;
+            if (newWays.contains(anyway) || excludeWays.contains(anyway) ) continue;
+
+            List<Pair<Node, Node>> nodePairs2 = anyway.getNodePairs(false);
+            loop: for (Pair<Node,Node> p1 : nodePairs) {
+                for (Pair<Node,Node> p2 : nodePairs2) {
+                    if (null!=Geometry.getSegmentSegmentIntersection(
+                            p1.a.getEastNorth(),p1.b.getEastNorth(),
+                            p2.a.getEastNorth(),p2.b.getEastNorth())) {
+                            newWays.add(anyway);
+                            count++;
+                            break loop;
+                    }
+                }
+            }
+        }
+        return count;
+    }
+
+
+        static int addWaysIntersectingWay(Collection<Way> ways, Way w, Set<Way> newWays) {
+        List<Pair<Node, Node>> nodePairs = w.getNodePairs(false);
+        int count=0;
+        for (Way anyway: ways) {
+            if (anyway == w) continue;
+            if (newWays.contains(anyway)) continue;
+            List<Pair<Node, Node>> nodePairs2 = anyway.getNodePairs(false);
+            loop: for (Pair<Node,Node> p1 : nodePairs) {
+                for (Pair<Node,Node> p2 : nodePairs2) {
+                    if (null!=Geometry.getSegmentSegmentIntersection(
+                            p1.a.getEastNorth(),p1.b.getEastNorth(),
+                            p2.a.getEastNorth(),p2.b.getEastNorth())) {
+                            newWays.add(anyway);
+                            count++;
+                            break loop;
+                    }
+                }
+            }
+        }
+        return count;
+    }
+
+    /**
+     * Adds all ways from allWays intersecting initWays way to specified set newWays
+     * @param allWays collection of ways to search
+     * @param initWays ways to check intersections
+     * @param newWays set to place the ways we found
+     */
+    static int addWaysIntersectingWays(Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays) {
+        int count=0;
+        for (Way w : initWays){
+            count+=addWaysIntersectingWay(allWays, w, newWays);
+        }
+        return count;
+    }
+
+    static int addWaysConnectedToNodes(Set<Node> selectedNodes, Set<Way> newWays) {
+        int s = newWays.size();
+        for (Node node: selectedNodes) {
+            addWaysConnectedToNode(node, newWays);
+        }
+        return newWays.size() - s;
+    }
+
+    static int addNodesConnectedToWays(Set<Way> initWays, Set<Node> newNodes) {
+        int s = newNodes.size();
+        for (Way w: initWays) {
+                newNodes.addAll(w.getNodes());
+        }
+        return newNodes.size()-s;
+    }
+
+    static void addWaysIntersectingWaysRecursively
+            (Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays)
+    {
+            Set<Way> foundWays = new HashSet<Way>();
+            foundWays.addAll(initWays);
+            newWays.addAll(initWays);
+            Set<Way> newFoundWays = new HashSet<Way>();
+
+            int level=0,c;
+            do {
+                 c=0;
+                 newFoundWays = new HashSet<Way>();
+                 for (Way w : foundWays){
+                      c+=addWaysIntersectingWay(allWays, w, newFoundWays,newWays);
+                 }
+                 foundWays = newFoundWays;
+                 newWays.addAll(newFoundWays);
+                 level++;
+//                 System.out.printf("%d: %d ways added to selection intersectiong\n",level,c);
+                 if (c>maxWays1) {
+                       JOptionPane.showMessageDialog(Main.parent,
+                                tr("Too many ways are added: {0}!",c),
+                                        tr("Warning"),
+                                        JOptionPane.WARNING_MESSAGE);
+                       return;
+                 }
+            } while ( c >0 && level < maxLevel );
+            return;
+    }
+
+ static void addWaysConnectedToWaysRecursively
+            (Collection<Way> initWays, Set<Way> newWays)
+    {
+            //long t = System.currentTimeMillis();
+            int level=0,c;
+            newWays.addAll(initWays);
+            do {
+                 c=0;
+                 Set<Way> foundWays = new HashSet<Way>();
+                 foundWays.addAll(newWays);
+                 for (Way w : foundWays){
+                      c+=addWaysConnectedToWay(w, newWays);
+                 }
+                 level++;
+//                 System.out.printf("%d: %d ways added to selection\n",level,c);
+                 if (c>maxWays) {
+                       JOptionPane.showMessageDialog(Main.parent,
+                                tr("Too many ways are added: {0}!",c),
+                                        tr("Warning"),
+                                        JOptionPane.WARNING_MESSAGE);
+                       return;
+                 }
+            } while ( c >0 && level < maxLevel );
+           // System.out.println("time = "+(System.currentTimeMillis()-t)+" ways = "+newWays.size());
+            return;
+    }
+
+
+
+}
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/SelectWayNodesAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/SelectWayNodesAction.java	(revision 25876)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/SelectWayNodesAction.java	(revision 25876)
@@ -0,0 +1,91 @@
+// License: GPL. Copyright 2010 by Hanno Hecker
+package utilsplugin2.selection;
+
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ * Select all nodes of a selected way.
+ *
+ */
+
+public class SelectWayNodesAction extends JosmAction {
+
+    private Node selectedNode;
+    private ArrayList<Node> selectedNodes;
+
+    /**
+     * Create a new SelectWayNodesAction
+     */
+    public SelectWayNodesAction() {
+        super(tr("Select Way Nodes"),"selectwaynodes" , tr("Select all nodes of a selected way."),
+                Shortcut.registerShortcut("tools:selectwaynodes", tr("Tool: {0}", tr("Select Way Nodes")), KeyEvent.VK_N, Shortcut.GROUP_MENU, Shortcut.SHIFT_DEFAULT), true);
+        putValue("help", ht("/Action/SelectWayNodes"));
+    }
+
+    /**
+     * Called when the action is executed.
+     *
+     * This method does some checking on the selection and calls the matching selectWayNodes method.
+     */
+    public void actionPerformed(ActionEvent e) {
+        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
+
+        String errMsg = null;
+        for (OsmPrimitive p : selection) {
+            if (p instanceof Way) {
+                Way w = (Way) p;
+                if (!w.isUsable() || w.getNodesCount() < 1) {
+                    continue;
+                }
+                selectWayNodes(w);
+            }
+            else if (p instanceof Node) {
+                Node n = (Node) p;
+                if (selectedNodes == null) {
+                    selectedNodes = new ArrayList<Node>();
+                }
+                selectedNodes.add(n);
+            }
+        }
+            
+        getCurrentDataSet().setSelected(selectedNodes);
+        selectedNodes = null;
+    }
+
+    private void selectWayNodes(Way w) {
+        
+        for (Node n : w.getNodes()) {
+            if (selectedNodes == null) {
+                selectedNodes = new ArrayList<Node>();
+            }
+            selectedNodes.add(n);
+        }
+    }
+
+    @Override
+    protected void updateEnabledState() {
+        if (getCurrentDataSet() == null) {
+            setEnabled(false);
+        } else {
+            updateEnabledState(getCurrentDataSet().getSelected());
+        }
+    }
+
+    @Override
+    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
+        setEnabled(selection != null && !selection.isEmpty());
+    }
+}
+
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/UnselectNodesAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/UnselectNodesAction.java	(revision 25876)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/UnselectNodesAction.java	(revision 25876)
@@ -0,0 +1,53 @@
+// License: GPL. Copyright 2011 by Alexei Kasatkin and Martin Ždila
+package utilsplugin2.selection;
+
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.Collection;
+import java.util.Set;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.osm.*;
+
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ *    Unselects all nodes
+ */
+public class UnselectNodesAction extends JosmAction {
+
+    
+    public UnselectNodesAction() {
+        super(tr("Unselect nodes"), "unsnodes",
+                tr("Removes all nodes from selection"),
+                Shortcut.registerShortcut("tools:unsnodes", tr("Tool: {0}","Unselect nodes"),
+                KeyEvent.VK_U, Shortcut.GROUP_MNEMONIC,KeyEvent.ALT_MASK  ), true);
+        putValue("help", ht("/Action/UnselectNodes"));
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
+        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
+        getCurrentDataSet().clearSelection(selectedNodes);
+    }
+
+    @Override
+    protected void updateEnabledState() {
+        if (getCurrentDataSet() == null) {
+            setEnabled(false);
+        } else {
+            updateEnabledState(getCurrentDataSet().getSelected());
+        }
+    }
+
+    @Override
+    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
+        if (selection == null) {
+            setEnabled(false);
+            return;
+        }
+        setEnabled(!selection.isEmpty());
+    }
+}
