Index: applications/editors/josm/plugins/utilsplugin2/build.xml
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/build.xml	(revision 26646)
+++ applications/editors/josm/plugins/utilsplugin2/build.xml	(revision 26662)
@@ -30,5 +30,5 @@
 <project name="utilsplugin2" default="dist" basedir=".">
     <!-- enter the SVN commit message -->
-    <property name="commit.message" value="Utilsplugin2: select all inside (testing)"/>
+    <property name="commit.message" value="Utilsplugin2: select all inside multipolygon added"/>
     <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
     <property name="plugin.main.version" value="4395"/>
@@ -245,3 +245,13 @@
         </java>
     </target>
+    
+    
+    <target name="profilejosm" depends="install">
+        <nbprofiledirect>
+        </nbprofiledirect>
+        <java jar="${josm}" fork="true">
+            <arg line="e:/test.osm"/>
+             <jvmarg value="${profiler.info.jvmargs.agent}"/>
+        </java>
+    </target>
 </project>
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/OpenPageAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/OpenPageAction.java	(revision 26646)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/OpenPageAction.java	(revision 26662)
@@ -44,7 +44,8 @@
 
     public OpenPageAction() {
-        super(tr("Open custom URL"), "openurl", tr("Opens specified URL browser"),
-                Shortcut.registerShortcut("tools:openaddress", tr("Tool: {0}", tr("Open custom URL")),
-                        KeyEvent.VK_BACK_SLASH, Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
+        super(tr("Open custom URL"), "openurl",
+                tr("Opens specified URL browser"),
+                Shortcut.registerShortcut("tools:openurl", tr("Tool: {0}", tr("Open custom URL")),
+                KeyEvent.VK_BACK_SLASH, Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
         putValue("help", ht("/Action/OpenPage"));
     }
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/NodeWayUtils.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/NodeWayUtils.java	(revision 26646)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/NodeWayUtils.java	(revision 26662)
@@ -2,4 +2,6 @@
 package utilsplugin2.selection;
 
+import org.openstreetmap.josm.data.osm.Relation;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Collection;
@@ -7,6 +9,8 @@
 import java.util.List;
 import java.util.Set;
+
 import javax.swing.JOptionPane;
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.osm.BBox;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -266,4 +270,41 @@
 
     
+    static void addAllInsideMultipolygon(DataSet data, Relation rel, Set<Way> newWays, Set<Node> newNodes) {
+        if (!rel.isMultipolygon()) return;
+        BBox box = rel.getBBox();
+        Set<Way> usedWays = OsmPrimitive.getFilteredSet(rel.getMemberPrimitives(), Way.class);
+        List<EastNorth> polyPoints = new ArrayList<EastNorth>(10000);
+        
+        for (Way way: usedWays) {
+            List<Node> polyNodes = way.getNodes();
+            // converts all points to EastNorth
+            for (Node n: polyNodes) polyPoints.add(n.getEastNorth());  
+        }
+        
+        
+        List<Node> searchNodes = data.searchNodes(box);
+        Set<Node> newestNodes = new HashSet<Node>();
+        Set<Way> newestWays = new HashSet<Way>();
+        for (Node n : searchNodes) {
+            //if (Geometry.nodeInsidePolygon(n, polyNodes)) {
+            if (NodeWayUtils.isPointInsidePolygon(n.getEastNorth(), polyPoints)>0) {
+                newestNodes.add(n);
+            }
+        }
+        
+        List<Way> searchWays = data.searchWays(box);
+        for (Way w : searchWays) {
+            if (newestNodes.containsAll(w.getNodes())) {
+                newestWays.add(w);
+            }
+        }
+        for (Way w : newestWays) {
+            newestNodes.removeAll(w.getNodes());
+            // do not select nodes of already selected ways
+        }
+        
+        newNodes.addAll(newestNodes);
+        newWays.addAll(newestWays);
+    }
 
     static void addAllInsideWay(DataSet data, Way way, Set<Way> newWays, Set<Node> newNodes) {
@@ -271,9 +312,15 @@
         BBox box = way.getBBox();
         List<Node> polyNodes = way.getNodes();
+        List<EastNorth> polyPoints = new ArrayList<EastNorth>(polyNodes.size());
+        
+        // converts all points to EastNorth
+        for (Node n: polyNodes) polyPoints.add(n.getEastNorth());  
+        
         List<Node> searchNodes = data.searchNodes(box);
         Set<Node> newestNodes = new HashSet<Node>();
         Set<Way> newestWays = new HashSet<Way>();
         for (Node n : searchNodes) {
-            if (Geometry.nodeInsidePolygon(n, polyNodes)) {
+            //if (Geometry.nodeInsidePolygon(n, polyNodes)) {
+            if (NodeWayUtils.isPointInsidePolygon(n.getEastNorth(), polyPoints)>0) {
                 newestNodes.add(n);
             }
@@ -294,3 +341,49 @@
         newWays.addAll(newestWays);
     }
+    
+    /**
+     * @return 0 =  not inside polygon, 1 = strictly inside, 2 = near edge, 3 = near vertex
+     */
+    public static int isPointInsidePolygon(EastNorth point, List<EastNorth> polygonPoints) {
+        int n=polygonPoints.size();
+        EastNorth oldPoint = polygonPoints.get(n-1);
+        double n1,n2,n3,e1,e2,e3,d;
+        int interCount=0;
+        
+        for (EastNorth curPoint : polygonPoints) {
+            n1 = curPoint.north(); n2 = oldPoint.north();  n3 =  point.north();
+            e1 = curPoint.east(); e2 = oldPoint.east();  e3 =  point.east();
+            
+            if (Math.abs(n1-n3)<1e-5 && Math.abs(e1-e3)<1e-5) return 3; // vertex
+            if (Math.abs(n2-n3)<1e-5 && Math.abs(e2-e3)<1e-5) return 3; // vertex
+            
+            // looking at oldPoint-curPoint segment
+            if ( n1 > n2) {
+                if (n1 > n3 && n3 >= n2) {
+                    n1-=n3; n2-=n3; e1-=e3; e2-=e3;
+                    d = e1*n2 - n1*e2;
+                    if (d<-1e-5) {
+                        interCount++; // there is OX intersecthion at e = (e1n2-e2n1)/(n2-n1) >=0
+                    } else if (d<=1e-5) return 2; // boundary detected
+                }
+            } else if (n1 == n2) {
+                if (n1 == n3) {
+                    e1-=e3; e2-=e3;
+                    if ((e1 <=0 && e2 >= 0) || (e1 >=0 && e2 <= 0)) return 2;// boundary detected
+                }
+            } else {
+                if (n1 <= n3 && n3 < n2) {
+                    n1-=n3; n2-=n3; e1-=e3; e2-=e3;
+                    d = e1*n2 - n1*e2;
+                    if (d>1e-5) {
+                        interCount++; // there is OX intersecthion at e = (e1n2-e2n1)/(n2-n1) >=0
+                    } else if (d>=-1e-5) return 2; // boundary detected
+                }
+            }
+            oldPoint = curPoint;
+        }
+       // System.out.printf("Intersected intercount %d %s\n",interCount, point.toString());
+        if (interCount%2 == 1) return 1; else return 0;
+    }
+
 }
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/SelectAllInsideAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/SelectAllInsideAction.java	(revision 26646)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/SelectAllInsideAction.java	(revision 26662)
@@ -31,26 +31,35 @@
 
     public void actionPerformed(ActionEvent e) {
+        long t=System.currentTimeMillis();
         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);
+        Set<Relation> selectedRels = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Relation.class);
+        
         for (Way w: selectedWays) {
             if (!w.isClosed()) selectedWays.remove(w);
         }
+        for (Relation r: selectedRels) {
+            if (!r.isMultipolygon()) selectedRels.remove(r);
+        }
 
+        Set<Way> newWays = new HashSet<Way>();
+        Set<Node> newNodes = new HashSet<Node>();
         // select ways attached to already selected ways
         if (!selectedWays.isEmpty()) {
-            Set<Way> newWays = new HashSet<Way>();
-            Set<Node> newNodes = new HashSet<Node>();
             for (Way w: selectedWays) {
                 NodeWayUtils.addAllInsideWay(getCurrentDataSet(),w,newWays,newNodes);
             }
+        }
+        if (!selectedRels.isEmpty()) {
+            for (Relation r: selectedRels) {
+                NodeWayUtils.addAllInsideMultipolygon(getCurrentDataSet(),r,newWays,newNodes);
+            }
+        }
+        if (!newWays.isEmpty() || !newNodes.isEmpty()) {
             getCurrentDataSet().addSelected(newWays);
             getCurrentDataSet().addSelected(newNodes);
-            return;
-        } else {
-             JOptionPane.showMessageDialog(Main.parent,
-               tr("Please select some closed ways to find all primitives inside them!"),
+        } else{
+        JOptionPane.showMessageDialog(Main.parent,
+               tr("Nothing found. Please select some closed ways or multipolygons to find all primitives inside them!"),
                tr("Warning"), JOptionPane.WARNING_MESSAGE);
         }
