Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/UtilsPlugin2.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/UtilsPlugin2.java	(revision 27859)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/UtilsPlugin2.java	(revision 27936)
@@ -8,4 +8,8 @@
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
 import java.awt.event.KeyEvent;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;
@@ -15,4 +19,13 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.search.PushbackTokenizer;
+import org.openstreetmap.josm.actions.search.SearchCompiler;
+import org.openstreetmap.josm.actions.search.SearchCompiler.Match;
+import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError;
+import org.openstreetmap.josm.actions.search.SearchCompiler.UnaryMatch;
+import org.openstreetmap.josm.actions.search.SearchCompiler.UnaryMatchFactory;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.MainMenu;
 import org.openstreetmap.josm.gui.MapFrame;
@@ -94,4 +107,6 @@
 	drawArc = MainMenu.add(toolsMenu, new CurveAction());
 
+        // register search operators
+        SearchCompiler.addMatchFactory(new UtilsUnaryMatchFactory());
     }
 
@@ -133,4 +148,101 @@
         return new UtilsPluginPreferences();
     }
-
+    
+    public static class UtilsUnaryMatchFactory implements UnaryMatchFactory {
+        private static Collection<String> keywords = Arrays.asList("inside",
+                "intersecting", "allintersecting");
+        
+        @Override
+        public UnaryMatch get(String keyword, Match matchOperand, PushbackTokenizer tokenizer) throws ParseError {
+            if ("inside".equals(keyword))
+                return new InsideMatch(matchOperand);
+            else if ("intersecting".equals(keyword))
+                return new IntersectingMatch(matchOperand, false);
+            else if ("allintersecting".equals(keyword))
+                return new IntersectingMatch(matchOperand, true);
+            return null;
+        }
+
+        @Override
+        public Collection<String> getKeywords() {
+            return keywords;
+        }
+    }
+
+    /**
+     * Matches all objects contained within the match expression.
+     */
+    public static class InsideMatch extends UnaryMatch {
+        private Collection<OsmPrimitive> inside = null;
+        
+        public InsideMatch(Match match) {
+            super(match);
+            init();
+        }
+        
+        /**
+         * Find all objects inside areas which match the expression
+         */
+        private void init() {
+            Collection<OsmPrimitive> matchedAreas = new HashSet<OsmPrimitive>();
+
+            // find all ways that match the expression
+            Collection<Way> ways = Main.main.getCurrentDataSet().getWays();
+            for (Way way : ways) {
+                if (match.match(way))
+                    matchedAreas.add(way);
+            }
+            
+            // find all relations that match the expression
+            Collection<Relation> rels = Main.main.getCurrentDataSet().getRelations();
+            for (Relation rel : rels) {
+                if (match.match(rel))
+                    matchedAreas.add(rel);
+            }
+            
+            inside = NodeWayUtils.selectAllInside(matchedAreas, Main.main.getCurrentDataSet());
+        }
+
+        @Override
+        public boolean match(OsmPrimitive osm) {
+            return inside.contains(osm);
+        }
+    }
+    
+    public static class IntersectingMatch extends UnaryMatch {
+        private Collection<Way> intersecting = null;
+        
+        public IntersectingMatch(Match match, boolean all) {
+            super(match);
+            init(all);
+        }   
+        
+        /**
+         * Find (all) ways intersecting ways which match the expression.
+         */
+        private void init(boolean all) {
+            Collection<Way> matchedWays = new HashSet<Way>();
+            
+            // find all ways that match the expression
+            Collection<Way> allWays = Main.main.getCurrentDataSet().getWays();
+            for (Way way : allWays) {
+                if (match.match(way))
+                    matchedWays.add(way);
+            }
+            
+            Set<Way> newWays = new HashSet<Way>();
+            if (all)
+                NodeWayUtils.addWaysIntersectingWaysRecursively(allWays, matchedWays, newWays);
+            else
+                NodeWayUtils.addWaysIntersectingWays(allWays, matchedWays, newWays);
+            intersecting = newWays;
+        }
+        
+        @Override
+        public boolean match(OsmPrimitive osm) {
+            if (osm instanceof Way)
+                return intersecting.contains((Way)osm);
+            return false;
+        }
+    }
 }
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/NodeWayUtils.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/NodeWayUtils.java	(revision 27859)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/NodeWayUtils.java	(revision 27936)
@@ -148,5 +148,5 @@
      * @param newWays set to place the ways we found
      */
-    static int addWaysIntersectingWays(Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays) {
+    public static int addWaysIntersectingWays(Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays) {
         int count=0;
         for (Way w : initWays){
@@ -172,5 +172,5 @@
     }
 
-    static void addWaysIntersectingWaysRecursively
+    public static void addWaysIntersectingWaysRecursively
             (Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays)
     {
@@ -458,4 +458,38 @@
         if (interCount%2 == 1) return 1; else return 0;
     }
+    
+    public static Collection<OsmPrimitive> selectAllInside(Collection<OsmPrimitive> selected, DataSet dataset) {
+        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(selected, Way.class);
+        Set<Relation> selectedRels = OsmPrimitive.getFilteredSet(selected, Relation.class);
+
+        for (Iterator<Relation> it = selectedRels.iterator(); it.hasNext();) {
+            Relation r = it.next();
+            if (!r.isMultipolygon()) {
+                it.remove();
+            }
+        }
+
+        Set<Way> newWays = new HashSet<Way>();
+        Set<Node> newNodes = new HashSet<Node>();
+        // select ways attached to already selected ways
+        if (!selectedWays.isEmpty()) {
+            for (Way w: selectedWays) {
+                addAllInsideWay(dataset,w,newWays,newNodes);
+            }
+        }
+        if (!selectedRels.isEmpty()) {
+            for (Relation r: selectedRels) {
+                addAllInsideMultipolygon(dataset,r,newWays,newNodes);
+            }
+        }
+        
+        Set<OsmPrimitive> insideSelection = new HashSet<OsmPrimitive>();
+        if (!newWays.isEmpty() || !newNodes.isEmpty()) {
+            insideSelection.addAll(newWays);
+            insideSelection.addAll(newNodes);
+        }
+        return insideSelection;
+    }
+
 
 }
Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/SelectAllInsideAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/SelectAllInsideAction.java	(revision 27859)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/SelectAllInsideAction.java	(revision 27936)
@@ -15,8 +15,5 @@
 import org.openstreetmap.josm.Main;
 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.Relation;
-import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.*;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -32,30 +29,12 @@
         putValue("help", ht("/Action/SelectAllInside"));
     }
-
+    
+    @Override
     public void actionPerformed(ActionEvent e) {
         long t=System.currentTimeMillis();
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
-        Set<Relation> selectedRels = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Relation.class);
-
-        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()) {
-            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);
+        Collection<OsmPrimitive> insideSelected = NodeWayUtils.selectAllInside(getCurrentDataSet().getSelected(), getCurrentDataSet());
+        
+        if (!insideSelected.isEmpty()) {
+            getCurrentDataSet().addSelected(insideSelected);
         } else{
         JOptionPane.showMessageDialog(Main.parent,
