diff --git a/src/org/openstreetmap/josm/actions/search/SearchAction.java b/src/org/openstreetmap/josm/actions/search/SearchAction.java
index ea65058..bcc01d7 100644
--- a/src/org/openstreetmap/josm/actions/search/SearchAction.java
+++ b/src/org/openstreetmap/josm/actions/search/SearchAction.java
@@ -1,11 +1,11 @@
 // License: GPL. Copyright 2007 by Immanuel Scholz and others
 package org.openstreetmap.josm.actions.search;
 
-import java.awt.Dimension;
 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.tr;
 import static org.openstreetmap.josm.tools.I18n.trc;
 
+import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
@@ -27,9 +27,9 @@ import javax.swing.JRadioButton;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.ActionParameter;
+import org.openstreetmap.josm.actions.ActionParameter.SearchSettingsActionParameter;
 import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.actions.ParameterizedAction;
-import org.openstreetmap.josm.actions.ActionParameter.SearchSettingsActionParameter;
 import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Filter;
@@ -198,10 +198,12 @@ public class SearchAction extends JosmAction implements ParameterizedAction {
                     + "<li>"+tr("<b>tags:</b>... - object with given number of tags (tags:count or tags:min-max)")+"</li>"
                     + "<li>"+tr("<b>role:</b>... - object with given role in a relation")+"</li>"
                     + "<li>"+tr("<b>timestamp:</b>... -  objects with this timestamp (<b>2009-11-12T14:51:09Z</b>, <b>2009-11-12</b> or <b>T14:51</b> ...)")+"</li>"
+                    + "<li>"+tr("<b>areaSize:</b>... - closed ways with area between MIN and MAX sqm. (areaSize:MIN-MAX or areaSize:MAX")+"</li>"
                     + "<li>"+tr("<b>modified</b> - all changed objects")+"</li>"
                     + "<li>"+tr("<b>selected</b> - all selected objects")+"</li>"
                     + "<li>"+tr("<b>incomplete</b> - all incomplete objects")+"</li>"
                     + "<li>"+tr("<b>untagged</b> - all untagged objects")+"</li>"
+                    + "<li>"+tr("<b>closed</b> - all closed ways (a node is not considered closed")+"</li>"
                     + "<li>"+tr("<b>child <i>expr</i></b> - all children of objects matching the expression")+"</li>"
                     + "<li>"+tr("<b>parent <i>expr</i></b> - all parents of objects matching the expression")+"</li>"
                     + "<li>"+tr("Use <b>|</b> or <b>OR</b> to combine with logical or")+"</li>"
diff --git a/src/org/openstreetmap/josm/actions/search/SearchCompiler.java b/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
index bfb9415..ff923fc 100644
--- a/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
+++ b/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
@@ -629,6 +629,84 @@ public class SearchCompiler {
         }
         @Override public String toString() {return "child(" + parent + ")";}
     }
+    /**
+     * Matches on the area of a closed way. (approximate(?), but should be OK for small areas)
+     * 
+     * Doesn't behave completely nice with not since it will match all nodes and non-closed ways too.
+     * (not sure if there is a good way to fix this, and it's "easy enough" to work around with '& closed')
+     * 
+     * @author Ole Jørgen Brønner
+     */
+    private static class Area extends Match {
+        private int min, max;
+
+        public Area(int min, int max) {
+            this.min = min;
+            this.max = max;
+            if (min == max) {
+                this.min = 0;
+            }
+        }
+        // taken from the measurement plugin
+        public static double calcX(Node p1){
+            double lat1, lon1, lat2, lon2;
+            double dlon, dlat;
+
+            lat1 = p1.getCoor().lat() * Math.PI / 180.0;
+            lon1 = p1.getCoor().lon() * Math.PI / 180.0;
+            lat2 = lat1;
+            lon2 = 0;
+
+            dlon = lon2 - lon1;
+            dlat = lat2 - lat1;
+
+            double a = (Math.pow(Math.sin(dlat/2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon/2), 2));
+            double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
+            return 6367000 * c;
+        }
+        // taken from the measurement plugin
+        public static double calcY(Node p1){
+            double lat1, lon1, lat2, lon2;
+            double dlon, dlat;
+
+            lat1 = p1.getCoor().lat() * Math.PI / 180.0;
+            lon1 = p1.getCoor().lon() * Math.PI / 180.0;
+            lat2 = 0;
+            lon2 = lon1;
+
+            dlon = lon2 - lon1;
+            dlat = lat2 - lat1;
+
+            double a = (Math.pow(Math.sin(dlat/2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon/2), 2));
+            double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
+            return 6367000 * c;
+        }
+
+        private static double calcClosedWayArea(Way way) {
+            //assert(way.isClosed());
+
+            //http://local.wasp.uwa.edu.au/~pbourke/geometry/polyarea/
+            double area = 0;
+            Node lastN = null;
+            for (Node n : way.getNodes()) {
+                if (lastN != null) {
+                    n.getEastNorth().getX();
+
+                    area += (calcX(n) * calcY(lastN)) - (calcY(n) * calcX(lastN));
+                }
+                lastN = n;
+            }
+            return Math.abs(area/2);
+        }
+        @Override
+        public boolean match(OsmPrimitive osm) {
+            if(!(osm instanceof Way && ((Way) osm).isClosed()))
+                return false;
+            Way way = (Way)osm;
+            double area = calcClosedWayArea(way);
+            return (min <= area && area <= max);
+        }
+    }
 
     public static class ParseError extends Exception {
         public ParseError(String msg) {
@@ -700,6 +778,9 @@ public class SearchCompiler {
                 } else if ("nodes".equals(key)) {
                     Range range = tokenizer.readRange(tr("Range of numbers expected"));
                     return new NodeCountRange((int)range.getStart(), (int)range.getEnd());
+                } else if ("areaSize".equals(key)) {
+                    Range range = tokenizer.readRange(tr("Range of numbers expected"));
+                    return new Area((int)range.getStart(), (int)range.getEnd());
                 } else if ("changeset".equals(key))
                     return new ChangesetId(tokenizer.readNumber(tr("Changeset id expected")));
                 else if ("version".equals(key))
