var type = require("./type"),
    area = require("./area"),
    topojson = require("../../");

module.exports = function(topology, options) {
  var minimumArea = 0,
      cw = true; // force exterior rings to be clockwise?

  if (arguments.length > 1)
    "minimum-area" in options && (minimumArea = +options["minimum-area"]),
    "force-clockwise" in options && (cw = !!options["force-clockwise"]);

  var filter = type({
    Polygon: function(polygon) {
      var a = ringArea(polygon.arcs[0]);
      if (a < 0) {
        if (cw) {
          reverse(polygon.arcs[0]); // TODO reverse holes, too?
          a = Math.abs(a);
        } else {
          a = 4 * Math.PI - a;
        }
      }
      if (a <= minimumArea) {
        delete polygon.type;
        delete polygon.arcs;
      }
    },
    MultiPolygon: function(multiPolygon) {
      multiPolygon.arcs = multiPolygon.arcs.filter(function(polygon) {
        var a = ringArea(polygon[0]);
        if (a < 0) {
          if (cw) {
            reverse(polygon[0]); // TODO reverse holes, too?
            a = Math.abs(a);
          } else {
            a = 4 * Math.PI - a;
          }
        }
        return a <= minimumArea;
      });
    }
  });

  for (var key in topology.objects) {
    filter.object(topology.objects[key]);
  }

  function ringArea(ring) {
    return area(topojson.object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]);
  }
};

// TODO It might be slightly more compact to reverse the arc.
function reverse(ring) {
  var i = -1, n = ring.length;
  ring.reverse();
  while (++i < n) ring[i] = ~ring[i];
}

@@ -451,32 +451,63 @@
 on) %7B%0A      var 
+arcs = polygon.arcs,%0A          
 a = ringArea(pol
@@ -503,24 +503,16 @@
 ingArea(
-polygon.
 arcs%5B0%5D)
@@ -568,24 +568,16 @@
 reverse(
-polygon.
 arcs%5B0%5D)
@@ -581,36 +581,8 @@
 0%5D);
- // TODO reverse holes, too?
 %0A   
@@ -588,35 +588,26 @@
         a = 
-Math.abs(a)
+-a
 ;%0A        %7D 
@@ -617,32 +617,33 @@
 e %7B%0A          a 
++
 = 4 * Math.PI - 
@@ -631,36 +631,32 @@
 a += 4 * Math.PI
- - a
 ;%0A        %7D%0A    
@@ -747,16 +747,137 @@
 n.arcs;%0A
+      %7D else if (cw) for (var i = 1, n = arcs.length; i %3C n; ++i) %7B%0A        if (ringArea(arcs%5Bi%5D) %3E 0) reverse(arcs%5Bi%5D);%0A
       %7D%0A
@@ -1112,36 +1112,8 @@
 0%5D);
- // TODO reverse holes, too?
 %0A   
@@ -1129,19 +1129,10 @@
 a = 
-Math.abs(a)
+-a
 ;%0A  
@@ -1162,16 +1162,17 @@
       a 
++
 = 4 * Ma
@@ -1180,12 +1180,8 @@
 h.PI
- - a
 ;%0A  
@@ -1212,32 +1212,206 @@
     
-return a %3C= minimumArea;
+if (a %3E minimumArea) %7B%0A          if (cw) for (var i = 1, n = polygon.length; i %3C n; ++i) %7B%0A            if (ringArea(polygon%5Bi%5D) %3E 0) reverse(polygon%5Bi%5D);%0A          %7D%0A          return true;%0A        %7D
 %0A   

Fix a few topology.filter bugs and reverse holes.