Index: applications/editors/josm/plugins/utilsplugin2/build.xml
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/build.xml	(revision 26375)
+++ applications/editors/josm/plugins/utilsplugin2/build.xml	(revision 26393)
@@ -30,5 +30,5 @@
 <project name="utilsplugin2" default="dist" basedir=".">
     <!-- enter the SVN commit message -->
-    <property name="commit.message" value="Utilsplugin2: ExtractNode - fix image"/>
+    <property name="commit.message" value="Utilsplugin2: Symmetry tool"/>
     <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
     <property name="plugin.main.version" value="4201"/>
Index: applications/editors/josm/plugins/utilsplugin2/nbproject/project.xml
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/nbproject/project.xml	(revision 26393)
+++ applications/editors/josm/plugins/utilsplugin2/nbproject/project.xml	(revision 26393)
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.ant.freeform</type>
+    <configuration>
+        <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+            <name>utilsplugin2</name>
+        </general-data>
+        <general-data xmlns="http://www.netbeans.org/ns/freeform-project/2">
+            <!-- Не используйте диалоговое окно свойств проекта при редактировании данного файла вручную. -->
+            <name>utilsplugin2</name>
+            <properties/>
+            <folders>
+                <source-folder>
+                    <label>src</label>
+                    <type>java</type>
+                    <location>src</location>
+                    <encoding>UTF-8</encoding>
+                </source-folder>
+                <source-folder>
+                    <label>utilsplugin2</label>
+                    <location>.</location>
+                    <encoding>UTF-8</encoding>
+                </source-folder>
+            </folders>
+            <ide-actions>
+                <action name="build">
+                    <target>dist</target>
+                </action>
+                <action name="clean">
+                    <target>clean</target>
+                </action>
+                <action name="run">
+                    <target>runjosm</target>
+                </action>
+                <action name="rebuild">
+                    <target>clean</target>
+                    <target>dist</target>
+                </action>
+            </ide-actions>
+            <export>
+                <type>jar</type>
+                <location>../../dist/utilsplugin2.jar</location>
+                <build-target>dist</build-target>
+            </export>
+            <view>
+                <items>
+                    <source-folder style="packages">
+                        <label>src</label>
+                        <location>src</location>
+                    </source-folder>
+                    <source-file>
+                        <location>build.xml</location>
+                    </source-file>
+                </items>
+                <context-menu>
+                    <ide-action name="build"/>
+                    <ide-action name="rebuild"/>
+                    <ide-action name="clean"/>
+                    <ide-action name="run"/>
+                </context-menu>
+            </view>
+        </general-data>
+        <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3">
+            <compilation-unit>
+                <package-root>src</package-root>
+                <classpath mode="compile">../../core/src</classpath>
+                <built-to>../../dist/utilsplugin2.jar</built-to>
+                <source-level>1.6</source-level>
+            </compilation-unit>
+        </java-data>
+    </configuration>
+</project>
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/SymmetryAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/SymmetryAction.java	(revision 26393)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/SymmetryAction.java	(revision 26393)
@@ -0,0 +1,102 @@
+// License: GPL. Copyright 2007 by Immanuel Scholz and others
+package utilsplugin2;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.MoveCommand;
+import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.data.coor.EastNorth;
+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;
+
+/**
+ * Mirror the selected ways nodes or ways along line given by two first selected points
+ *
+ * Note: If a ways are selected, their nodes are mirrored
+ *
+ * @author Alexei Kasatkin, based on much copy&Paste from other MirrorAction :)
+ */ 
+public final class SymmetryAction extends JosmAction {
+
+    public SymmetryAction() {
+        super(tr("Symmetry"), "symmetry", tr("Mirror selected nodes and ways."),
+                Shortcut.registerShortcut("tools:symmetry", tr("Tool: {0}", tr("Symmetry")),
+                        KeyEvent.VK_S, Shortcut.GROUP_EDIT, KeyEvent.ALT_DOWN_MASK), true);
+        putValue("help", ht("/Action/Symmtry"));
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        Collection<OsmPrimitive> sel = getCurrentDataSet().getSelected();
+        HashSet<Node> nodes = new HashSet<Node>();
+        EastNorth p1=null,p2=null;
+        
+        for (OsmPrimitive osm : sel) {
+            if (osm instanceof Node) {
+                if (p1==null) p1=((Node)osm).getEastNorth(); else
+                if (p2==null) p2=((Node)osm).getEastNorth(); else
+                nodes.add((Node)osm);
+            }
+        }
+        for (OsmPrimitive osm : sel) {
+            if (osm instanceof Way) {
+                nodes.addAll(((Way)osm).getNodes());
+            }
+        }
+        
+        if (p1==null || p2==null || nodes.size() < 1) {
+            JOptionPane.showMessageDialog(
+                    Main.parent,
+                    tr("Please select at least two nodes for symmetry axis and something else to mirror."),
+                    tr("Information"),
+                    JOptionPane.INFORMATION_MESSAGE
+            );
+            return;
+        }
+
+        double ne,nn,l,e0,n0;
+        e0=p1.east();        n0=p1.north();
+        ne =  -(p2.north()-p1.north());      nn =  (p2.east()-p1.east());
+        l = Math.hypot(ne,nn);
+        ne /= l; nn /= l; // normal unit vector
+        
+        Collection<Command> cmds = new LinkedList<Command>();
+
+        for (Node n : nodes) {
+            EastNorth c = n.getEastNorth();
+            double pr = (c.east()-e0)*ne + (c.north()-n0)*nn;
+            //pr=10;
+            cmds.add(new MoveCommand(n, -2*ne*pr, -2*nn*pr ));
+        }
+
+        Main.main.undoRedo.add(new SequenceCommand(tr("Symmetry"), cmds));
+        Main.map.repaint();
+    }
+
+    @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/UtilsPlugin2.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/UtilsPlugin2.java	(revision 26375)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/UtilsPlugin2.java	(revision 26393)
@@ -17,4 +17,5 @@
 public class UtilsPlugin2 extends Plugin {
     JMenuItem unglueRelation;
+    JMenuItem symmetry;
     JMenuItem addIntersections;
     JMenuItem splitObject;
@@ -46,5 +47,5 @@
         addIntersections = MainMenu.add(toolsMenu, new AddIntersectionsAction());
         splitObject = MainMenu.add(toolsMenu, new SplitObjectAction());
-
+        
         toolsMenu.addSeparator();
         replaceGeometry = MainMenu.add(toolsMenu, new ReplaceGeometryAction());
@@ -55,4 +56,5 @@
         splitOnIntersections = MainMenu.add(toolsMenu, new SplitOnIntersectionsAction());
         extractPoint = MainMenu.add(toolsMenu, new ExtractPointAction());
+        symmetry = MainMenu.add(toolsMenu, new SymmetryAction());
 
         JMenu selectionMenu = Main.main.menu.addMenu(marktr("Selection"), KeyEvent.VK_N, Main.main.menu.defaultMenuPos, "help");
