diff --git a/src/pathops/SkAddIntersections.cpp b/src/pathops/SkAddIntersections.cpp
index c27434f..b507eb7 100644
--- a/src/pathops/SkAddIntersections.cpp
+++ b/src/pathops/SkAddIntersections.cpp
@@ -5,6 +5,7 @@
  * found in the LICENSE file.
  */
 #include "SkAddIntersections.h"
+#include "SkOpCoincidence.h"
 #include "SkPathOpsBounds.h"
 
 #if DEBUG_ADD_INTERSECTING_TS
@@ -130,20 +131,6 @@
     SkDebugf("\n");
 }
 
-static void debugShowCubicIntersection(int pts, const SkIntersectionHelper& wt,
-        const SkIntersections& i) {
-    SkASSERT(i.used() == pts);
-    if (!pts) {
-        SkDebugf("%s no self intersect " CUBIC_DEBUG_STR "\n", __FUNCTION__,
-                CUBIC_DEBUG_DATA(wt.pts()));
-        return;
-    }
-    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
-            i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
-    SkDebugf(" " T_DEBUG_STR(wtTs, 1), i[1][0]);
-    SkDebugf("\n");
-}
-
 #else
 static void debugShowLineIntersection(int , const SkIntersectionHelper& ,
         const SkIntersectionHelper& , const SkIntersections& ) {
@@ -168,13 +155,10 @@
 static void debugShowCubicIntersection(int , const SkIntersectionHelper& ,
         const SkIntersectionHelper& , const SkIntersections& ) {
 }
-
-static void debugShowCubicIntersection(int , const SkIntersectionHelper& ,
-        const SkIntersections& ) {
-}
 #endif
 
-bool AddIntersectTs(SkOpContour* test, SkOpContour* next) {
+bool AddIntersectTs(SkOpContour* test, SkOpContour* next, SkOpCoincidence* coincidence,
+        SkChunkAlloc* allocator) {
     if (test != next) {
         if (AlmostLessUlps(test->bounds().fBottom, next->bounds().fTop)) {
             return false;
@@ -186,10 +170,11 @@
     }
     SkIntersectionHelper wt;
     wt.init(test);
-    bool foundCommonContour = test == next;
     do {
         SkIntersectionHelper wn;
         wn.init(next);
+        test->debugValidate();
+        next->debugValidate();
         if (test == next && !wn.startAfter(wt)) {
             continue;
         }
@@ -306,14 +291,22 @@
                             break;
                         }
                         case SkIntersectionHelper::kQuad_Segment: {
-                            pts = ts.quadQuad(wt.pts(), wn.pts());
-                            ts.alignQuadPts(wt.pts(), wn.pts());
+                            SkDQuad quad1;
+                            quad1.set(wt.pts());
+                            SkDQuad quad2;
+                            quad2.set(wn.pts());
+                            pts = ts.intersect(quad1, quad2);
                             debugShowQuadIntersection(pts, wt, wn, ts);
                             break;
                         }
                         case SkIntersectionHelper::kCubic_Segment: {
                             swap = true;
-                            pts = ts.cubicQuad(wn.pts(), wt.pts());
+                            SkDQuad quad1;
+                            quad1.set(wt.pts());
+                            SkDCubic cubic1 = quad1.toCubic();
+                            SkDCubic cubic2;
+                            cubic2.set(wn.pts());
+                            pts = ts.intersect(cubic2, cubic1);
                             debugShowCubicQuadIntersection(pts, wn, wt, ts);
                             break;
                         }
@@ -339,12 +332,21 @@
                             break;
                         }
                         case SkIntersectionHelper::kQuad_Segment: {
-                            pts = ts.cubicQuad(wt.pts(), wn.pts());
+                            SkDCubic cubic1;
+                            cubic1.set(wt.pts());
+                            SkDQuad quad2;
+                            quad2.set(wn.pts());
+                            SkDCubic cubic2 = quad2.toCubic();
+                            pts = ts.intersect(cubic1, cubic2);
                             debugShowCubicQuadIntersection(pts, wt, wn, ts);
                             break;
                         }
                         case SkIntersectionHelper::kCubic_Segment: {
-                            pts = ts.cubicCubic(wt.pts(), wn.pts());
+                            SkDCubic cubic1;
+                            cubic1.set(wt.pts());
+                            SkDCubic cubic2;
+                            cubic2.set(wn.pts());
+                            pts = ts.intersect(cubic1, cubic2);
                             debugShowCubicIntersection(pts, wt, wn, ts);
                             break;
                         }
@@ -355,102 +357,53 @@
                 default:
                     SkASSERT(0);
             }
-            if (!foundCommonContour && pts > 0) {
-                test->addCross(next);
-                next->addCross(test);
-                foundCommonContour = true;
-            }
-            // in addition to recording T values, record matching segment
-            if (pts == 2) {
-                if (wn.segmentType() <= SkIntersectionHelper::kLine_Segment
-                        && wt.segmentType() <= SkIntersectionHelper::kLine_Segment) {
-                    if (wt.addCoincident(wn, ts, swap)) {
-                        continue;
-                    }
-                    pts = ts.cleanUpCoincidence();  // prefer (t == 0 or t == 1)
-                } else if (wn.segmentType() >= SkIntersectionHelper::kQuad_Segment
-                        && wt.segmentType() >= SkIntersectionHelper::kQuad_Segment
-                        && ts.isCoincident(0)) {
-                    SkASSERT(ts.coincidentUsed() == 2);
-                    if (wt.addCoincident(wn, ts, swap)) {
-                        continue;
-                    }
-                    pts = ts.cleanUpCoincidence();  // prefer (t == 0 or t == 1)
-                }
-            }
-            if (pts >= 2) {
-                for (int pt = 0; pt < pts - 1; ++pt) {
-                    const SkDPoint& point = ts.pt(pt);
-                    const SkDPoint& next = ts.pt(pt + 1);
-                    if (wt.isPartial(ts[swap][pt], ts[swap][pt + 1], point, next)
-                            && wn.isPartial(ts[!swap][pt], ts[!swap][pt + 1], point, next)) {
-                        if (!wt.addPartialCoincident(wn, ts, pt, swap)) {
-                            // remove extra point if two map to same float values
-                            pts = ts.cleanUpCoincidence();  // prefer (t == 0 or t == 1)
-                        }
-                    }
-                }
-            }
+            int coinIndex = -1;
+            SkOpPtT* coinPtT[2];
             for (int pt = 0; pt < pts; ++pt) {
                 SkASSERT(ts[0][pt] >= 0 && ts[0][pt] <= 1);
                 SkASSERT(ts[1][pt] >= 0 && ts[1][pt] <= 1);
-                SkPoint point = ts.pt(pt).asSkPoint();
-                wt.alignTPt(wn, swap, pt, &ts, &point);
-                int testTAt = wt.addT(wn, point, ts[swap][pt]);
-                int nextTAt = wn.addT(wt, point, ts[!swap][pt]);
-                wt.addOtherT(testTAt, ts[!swap][pt], nextTAt);
-                wn.addOtherT(nextTAt, ts[swap][pt], testTAt);
+                wt.segment()->debugValidate();
+                SkOpPtT* testTAt = wt.segment()->addT(ts[swap][pt], SkOpSegment::kAllowAlias,
+                        allocator);
+                wn.segment()->debugValidate();
+                SkOpPtT* nextTAt = wn.segment()->addT(ts[!swap][pt], SkOpSegment::kAllowAlias,
+                        allocator);
+                testTAt->addOpp(nextTAt);
+                if (testTAt->fPt != nextTAt->fPt) {
+                    testTAt->span()->unaligned();
+                    nextTAt->span()->unaligned();
+                }
+                wt.segment()->debugValidate();
+                wn.segment()->debugValidate();
+                if (!ts.isCoincident(pt)) {
+                    continue;
+                }
+                if (coinIndex < 0) {
+                    coinPtT[0] = testTAt;
+                    coinPtT[1] = nextTAt;
+                    coinIndex = pt;
+                    continue;
+                }
+                if (coinPtT[0]->span() == testTAt->span()) {
+                    coinIndex = -1;
+                    continue;
+                }
+                if (coinPtT[1]->span() == nextTAt->span()) {
+                    coinIndex = -1;  // coincidence span collapsed
+                    continue;
+                }
+                if (swap) {
+                    SkTSwap(coinPtT[0], coinPtT[1]);
+                    SkTSwap(testTAt, nextTAt);
+                }
+                SkASSERT(coinPtT[0]->span()->t() < testTAt->span()->t());
+                coincidence->add(coinPtT[0], testTAt, coinPtT[1], nextTAt, allocator);
+                wt.segment()->debugValidate();
+                wn.segment()->debugValidate();
+                coinIndex = -1;
             }
+            SkASSERT(coinIndex < 0);  // expect coincidence to be paired
         } while (wn.advance());
     } while (wt.advance());
     return true;
 }
-
-void AddSelfIntersectTs(SkOpContour* test) {
-    SkIntersectionHelper wt;
-    wt.init(test);
-    do {
-        if (wt.segmentType() != SkIntersectionHelper::kCubic_Segment) {
-            continue;
-        }
-        SkIntersections ts;
-        int pts = ts.cubic(wt.pts());
-        debugShowCubicIntersection(pts, wt, ts);
-        if (!pts) {
-            continue;
-        }
-        SkASSERT(pts == 1);
-        SkASSERT(ts[0][0] >= 0 && ts[0][0] <= 1);
-        SkASSERT(ts[1][0] >= 0 && ts[1][0] <= 1);
-        SkPoint point = ts.pt(0).asSkPoint();
-        int testTAt = wt.addSelfT(point, ts[0][0]);
-        int nextTAt = wt.addSelfT(point, ts[1][0]);
-        wt.addOtherT(testTAt, ts[1][0], nextTAt);
-        wt.addOtherT(nextTAt, ts[0][0], testTAt);
-    } while (wt.advance());
-}
-
-// resolve any coincident pairs found while intersecting, and
-// see if coincidence is formed by clipping non-concident segments
-bool CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total) {
-    int contourCount = (*contourList).count();
-    for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
-        SkOpContour* contour = (*contourList)[cIndex];
-        contour->resolveNearCoincidence();
-    }
-    for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
-        SkOpContour* contour = (*contourList)[cIndex];
-        contour->addCoincidentPoints();
-    }
-    for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
-        SkOpContour* contour = (*contourList)[cIndex];
-        if (!contour->calcCoincidentWinding()) {
-            return false;
-        }
-    }
-    for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
-        SkOpContour* contour = (*contourList)[cIndex];
-        contour->calcPartialCoincidentWinding();
-    }
-    return true;
-}
diff --git a/src/pathops/SkAddIntersections.h b/src/pathops/SkAddIntersections.h
index 4c1947b..23654e5 100644
--- a/src/pathops/SkAddIntersections.h
+++ b/src/pathops/SkAddIntersections.h
@@ -9,10 +9,10 @@
 
 #include "SkIntersectionHelper.h"
 #include "SkIntersections.h"
-#include "SkTArray.h"
 
-bool AddIntersectTs(SkOpContour* test, SkOpContour* next);
-void AddSelfIntersectTs(SkOpContour* test);
-bool CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total);
+class SkOpCoincidence;
+
+bool AddIntersectTs(SkOpContour* test, SkOpContour* next, SkOpCoincidence* coincidence,
+        SkChunkAlloc* allocator);
 
 #endif
diff --git a/src/pathops/SkDCubicIntersection.cpp b/src/pathops/SkDCubicIntersection.cpp
deleted file mode 100644
index 2fb35e1..0000000
--- a/src/pathops/SkDCubicIntersection.cpp
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkIntersections.h"
-#include "SkPathOpsCubic.h"
-#include "SkPathOpsLine.h"
-#include "SkPathOpsPoint.h"
-#include "SkPathOpsQuad.h"
-#include "SkPathOpsRect.h"
-#include "SkReduceOrder.h"
-#include "SkTSort.h"
-
-#if ONE_OFF_DEBUG
-static const double tLimits1[2][2] = {{0.3, 0.4}, {0.8, 0.9}};
-static const double tLimits2[2][2] = {{-0.8, -0.9}, {-0.8, -0.9}};
-#endif
-
-#define DEBUG_QUAD_PART ONE_OFF_DEBUG && 1
-#define DEBUG_QUAD_PART_SHOW_SIMPLE DEBUG_QUAD_PART && 0
-#define SWAP_TOP_DEBUG 0
-
-static const int kCubicToQuadSubdivisionDepth = 8; // slots reserved for cubic to quads subdivision
-
-static int quadPart(const SkDCubic& cubic, double tStart, double tEnd, SkReduceOrder* reducer) {
-    SkDCubic part = cubic.subDivide(tStart, tEnd);
-    SkDQuad quad = part.toQuad();
-    // FIXME: should reduceOrder be looser in this use case if quartic is going to blow up on an
-    // extremely shallow quadratic?
-    int order = reducer->reduce(quad);
-#if DEBUG_QUAD_PART
-    SkDebugf("%s cubic=(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)"
-            " t=(%1.9g,%1.9g)\n", __FUNCTION__, cubic[0].fX, cubic[0].fY,
-            cubic[1].fX, cubic[1].fY, cubic[2].fX, cubic[2].fY,
-            cubic[3].fX, cubic[3].fY, tStart, tEnd);
-    SkDebugf("  {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n"
-             "  {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n",
-            part[0].fX, part[0].fY, part[1].fX, part[1].fY, part[2].fX, part[2].fY,
-            part[3].fX, part[3].fY, quad[0].fX, quad[0].fY,
-            quad[1].fX, quad[1].fY, quad[2].fX, quad[2].fY);
-#if DEBUG_QUAD_PART_SHOW_SIMPLE
-    SkDebugf("%s simple=(%1.9g,%1.9g", __FUNCTION__, reducer->fQuad[0].fX, reducer->fQuad[0].fY);
-    if (order > 1) {
-        SkDebugf(" %1.9g,%1.9g", reducer->fQuad[1].fX, reducer->fQuad[1].fY);
-    }
-    if (order > 2) {
-        SkDebugf(" %1.9g,%1.9g", reducer->fQuad[2].fX, reducer->fQuad[2].fY);
-    }
-    SkDebugf(")\n");
-    SkASSERT(order < 4 && order > 0);
-#endif
-#endif
-    return order;
-}
-
-static void intersectWithOrder(const SkDQuad& simple1, int order1, const SkDQuad& simple2,
-        int order2, SkIntersections& i) {
-    if (order1 == 3 && order2 == 3) {
-        i.intersect(simple1, simple2);
-    } else if (order1 <= 2 && order2 <= 2) {
-        i.intersect((const SkDLine&) simple1, (const SkDLine&) simple2);
-    } else if (order1 == 3 && order2 <= 2) {
-        i.intersect(simple1, (const SkDLine&) simple2);
-    } else {
-        SkASSERT(order1 <= 2 && order2 == 3);
-        i.intersect(simple2, (const SkDLine&) simple1);
-        i.swapPts();
-    }
-}
-
-// this flavor centers potential intersections recursively. In contrast, '2' may inadvertently
-// chase intersections near quadratic ends, requiring odd hacks to find them.
-static void intersect(const SkDCubic& cubic1, double t1s, double t1e, const SkDCubic& cubic2,
-        double t2s, double t2e, double precisionScale, SkIntersections& i) {
-    i.upDepth();
-    SkDCubic c1 = cubic1.subDivide(t1s, t1e);
-    SkDCubic c2 = cubic2.subDivide(t2s, t2e);
-    SkSTArray<kCubicToQuadSubdivisionDepth, double, true> ts1;
-    // OPTIMIZE: if c1 == c2, call once (happens when detecting self-intersection)
-    c1.toQuadraticTs(c1.calcPrecision() * precisionScale, &ts1);
-    SkSTArray<kCubicToQuadSubdivisionDepth, double, true> ts2;
-    c2.toQuadraticTs(c2.calcPrecision() * precisionScale, &ts2);
-    double t1Start = t1s;
-    int ts1Count = ts1.count();
-    for (int i1 = 0; i1 <= ts1Count; ++i1) {
-        const double tEnd1 = i1 < ts1Count ? ts1[i1] : 1;
-        const double t1 = t1s + (t1e - t1s) * tEnd1;
-        SkReduceOrder s1;
-        int o1 = quadPart(cubic1, t1Start, t1, &s1);
-        double t2Start = t2s;
-        int ts2Count = ts2.count();
-        for (int i2 = 0; i2 <= ts2Count; ++i2) {
-            const double tEnd2 = i2 < ts2Count ? ts2[i2] : 1;
-            const double t2 = t2s + (t2e - t2s) * tEnd2;
-            if (&cubic1 == &cubic2 && t1Start >= t2Start) {
-                t2Start = t2;
-                continue;
-            }
-            SkReduceOrder s2;
-            int o2 = quadPart(cubic2, t2Start, t2, &s2);
-        #if ONE_OFF_DEBUG
-            char tab[] = "                  ";
-            if (tLimits1[0][0] >= t1Start && tLimits1[0][1] <= t1
-                    && tLimits1[1][0] >= t2Start && tLimits1[1][1] <= t2) {
-                SkDebugf("%.*s %s t1=(%1.9g,%1.9g) t2=(%1.9g,%1.9g)", i.depth()*2, tab,
-                        __FUNCTION__, t1Start, t1, t2Start, t2);
-                SkIntersections xlocals;
-                xlocals.allowNear(false);
-                xlocals.allowFlatMeasure(true);
-                intersectWithOrder(s1.fQuad, o1, s2.fQuad, o2, xlocals);
-                SkDebugf(" xlocals.fUsed=%d\n", xlocals.used());
-            }
-        #endif
-            SkIntersections locals;
-            locals.allowNear(false);
-            locals.allowFlatMeasure(true);
-            intersectWithOrder(s1.fQuad, o1, s2.fQuad, o2, locals);
-            int tCount = locals.used();
-            for (int tIdx = 0; tIdx < tCount; ++tIdx) {
-                double to1 = t1Start + (t1 - t1Start) * locals[0][tIdx];
-                double to2 = t2Start + (t2 - t2Start) * locals[1][tIdx];
-    // if the computed t is not sufficiently precise, iterate
-                SkDPoint p1 = cubic1.ptAtT(to1);
-                SkDPoint p2 = cubic2.ptAtT(to2);
-                if (p1.approximatelyEqual(p2)) {
-    // FIXME: local edge may be coincident -- experiment with not propagating coincidence to caller
-//                    SkASSERT(!locals.isCoincident(tIdx));
-                    if (&cubic1 != &cubic2 || !approximately_equal(to1, to2)) {
-                        if (i.swapped()) {  //  FIXME: insert should respect swap
-                            i.insert(to2, to1, p1);
-                        } else {
-                            i.insert(to1, to2, p1);
-                        }
-                    }
-                } else {
-/*for random cubics, 16 below catches 99.997% of the intersections. To test for the remaining 0.003%
-  look for nearly coincident curves. and check each 1/16th section.
-*/
-                    double offset = precisionScale / 16;  // FIXME: const is arbitrary: test, refine
-                    double c1Bottom = tIdx == 0 ? 0 :
-                            (t1Start + (t1 - t1Start) * locals[0][tIdx - 1] + to1) / 2;
-                    double c1Min = SkTMax(c1Bottom, to1 - offset);
-                    double c1Top = tIdx == tCount - 1 ? 1 :
-                            (t1Start + (t1 - t1Start) * locals[0][tIdx + 1] + to1) / 2;
-                    double c1Max = SkTMin(c1Top, to1 + offset);
-                    double c2Min = SkTMax(0., to2 - offset);
-                    double c2Max = SkTMin(1., to2 + offset);
-                #if ONE_OFF_DEBUG
-                    SkDebugf("%.*s %s 1 contains1=%d/%d contains2=%d/%d\n", i.depth()*2, tab,
-                            __FUNCTION__,
-                            c1Min <= tLimits1[0][1] && tLimits1[0][0] <= c1Max
-                         && c2Min <= tLimits1[1][1] && tLimits1[1][0] <= c2Max,
-                            to1 - offset <= tLimits1[0][1] && tLimits1[0][0] <= to1 + offset
-                         && to2 - offset <= tLimits1[1][1] && tLimits1[1][0] <= to2 + offset,
-                            c1Min <= tLimits2[0][1] && tLimits2[0][0] <= c1Max
-                         && c2Min <= tLimits2[1][1] && tLimits2[1][0] <= c2Max,
-                            to1 - offset <= tLimits2[0][1] && tLimits2[0][0] <= to1 + offset
-                         && to2 - offset <= tLimits2[1][1] && tLimits2[1][0] <= to2 + offset);
-                    SkDebugf("%.*s %s 1 c1Bottom=%1.9g c1Top=%1.9g c2Bottom=%1.9g c2Top=%1.9g"
-                            " 1-o=%1.9g 1+o=%1.9g 2-o=%1.9g 2+o=%1.9g offset=%1.9g\n",
-                            i.depth()*2, tab, __FUNCTION__, c1Bottom, c1Top, 0., 1.,
-                            to1 - offset, to1 + offset, to2 - offset, to2 + offset, offset);
-                    SkDebugf("%.*s %s 1 to1=%1.9g to2=%1.9g c1Min=%1.9g c1Max=%1.9g c2Min=%1.9g"
-                            " c2Max=%1.9g\n", i.depth()*2, tab, __FUNCTION__, to1, to2, c1Min,
-                            c1Max, c2Min, c2Max);
-                #endif
-                    intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, offset, i);
-                #if ONE_OFF_DEBUG
-                    SkDebugf("%.*s %s 1 i.used=%d t=%1.9g\n", i.depth()*2, tab, __FUNCTION__,
-                            i.used(), i.used() > 0 ? i[0][i.used() - 1] : -1);
-                #endif
-                    if (tCount > 1) {
-                        c1Min = SkTMax(0., to1 - offset);
-                        c1Max = SkTMin(1., to1 + offset);
-                        double c2Bottom = tIdx == 0 ? to2 :
-                                (t2Start + (t2 - t2Start) * locals[1][tIdx - 1] + to2) / 2;
-                        double c2Top = tIdx == tCount - 1 ? to2 :
-                                (t2Start + (t2 - t2Start) * locals[1][tIdx + 1] + to2) / 2;
-                        if (c2Bottom > c2Top) {
-                            SkTSwap(c2Bottom, c2Top);
-                        }
-                        if (c2Bottom == to2) {
-                            c2Bottom = 0;
-                        }
-                        if (c2Top == to2) {
-                            c2Top = 1;
-                        }
-                        c2Min = SkTMax(c2Bottom, to2 - offset);
-                        c2Max = SkTMin(c2Top, to2 + offset);
-                    #if ONE_OFF_DEBUG
-                        SkDebugf("%.*s %s 2 contains1=%d/%d contains2=%d/%d\n", i.depth()*2, tab,
-                            __FUNCTION__,
-                            c1Min <= tLimits1[0][1] && tLimits1[0][0] <= c1Max
-                         && c2Min <= tLimits1[1][1] && tLimits1[1][0] <= c2Max,
-                            to1 - offset <= tLimits1[0][1] && tLimits1[0][0] <= to1 + offset
-                         && to2 - offset <= tLimits1[1][1] && tLimits1[1][0] <= to2 + offset,
-                            c1Min <= tLimits2[0][1] && tLimits2[0][0] <= c1Max
-                         && c2Min <= tLimits2[1][1] && tLimits2[1][0] <= c2Max,
-                            to1 - offset <= tLimits2[0][1] && tLimits2[0][0] <= to1 + offset
-                         && to2 - offset <= tLimits2[1][1] && tLimits2[1][0] <= to2 + offset);
-                        SkDebugf("%.*s %s 2 c1Bottom=%1.9g c1Top=%1.9g c2Bottom=%1.9g c2Top=%1.9g"
-                                " 1-o=%1.9g 1+o=%1.9g 2-o=%1.9g 2+o=%1.9g offset=%1.9g\n",
-                                i.depth()*2, tab, __FUNCTION__, 0., 1., c2Bottom, c2Top,
-                                to1 - offset, to1 + offset, to2 - offset, to2 + offset, offset);
-                        SkDebugf("%.*s %s 2 to1=%1.9g to2=%1.9g c1Min=%1.9g c1Max=%1.9g c2Min=%1.9g"
-                                " c2Max=%1.9g\n", i.depth()*2, tab, __FUNCTION__, to1, to2, c1Min,
-                                c1Max, c2Min, c2Max);
-                    #endif
-                        intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, offset, i);
-                #if ONE_OFF_DEBUG
-                    SkDebugf("%.*s %s 2 i.used=%d t=%1.9g\n", i.depth()*2, tab, __FUNCTION__,
-                            i.used(), i.used() > 0 ? i[0][i.used() - 1] : -1);
-                #endif
-                        c1Min = SkTMax(c1Bottom, to1 - offset);
-                        c1Max = SkTMin(c1Top, to1 + offset);
-                    #if ONE_OFF_DEBUG
-                        SkDebugf("%.*s %s 3 contains1=%d/%d contains2=%d/%d\n", i.depth()*2, tab,
-                        __FUNCTION__,
-                            c1Min <= tLimits1[0][1] && tLimits1[0][0] <= c1Max
-                         && c2Min <= tLimits1[1][1] && tLimits1[1][0] <= c2Max,
-                            to1 - offset <= tLimits1[0][1] && tLimits1[0][0] <= to1 + offset
-                         && to2 - offset <= tLimits1[1][1] && tLimits1[1][0] <= to2 + offset,
-                            c1Min <= tLimits2[0][1] && tLimits2[0][0] <= c1Max
-                         && c2Min <= tLimits2[1][1] && tLimits2[1][0] <= c2Max,
-                            to1 - offset <= tLimits2[0][1] && tLimits2[0][0] <= to1 + offset
-                         && to2 - offset <= tLimits2[1][1] && tLimits2[1][0] <= to2 + offset);
-                        SkDebugf("%.*s %s 3 c1Bottom=%1.9g c1Top=%1.9g c2Bottom=%1.9g c2Top=%1.9g"
-                                " 1-o=%1.9g 1+o=%1.9g 2-o=%1.9g 2+o=%1.9g offset=%1.9g\n",
-                                i.depth()*2, tab, __FUNCTION__, 0., 1., c2Bottom, c2Top,
-                                to1 - offset, to1 + offset, to2 - offset, to2 + offset, offset);
-                        SkDebugf("%.*s %s 3 to1=%1.9g to2=%1.9g c1Min=%1.9g c1Max=%1.9g c2Min=%1.9g"
-                                " c2Max=%1.9g\n", i.depth()*2, tab, __FUNCTION__, to1, to2, c1Min,
-                                c1Max, c2Min, c2Max);
-                    #endif
-                        intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, offset, i);
-                #if ONE_OFF_DEBUG
-                    SkDebugf("%.*s %s 3 i.used=%d t=%1.9g\n", i.depth()*2, tab, __FUNCTION__,
-                            i.used(), i.used() > 0 ? i[0][i.used() - 1] : -1);
-                #endif
-                    }
-          //          intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, offset, i);
-                    // FIXME: if no intersection is found, either quadratics intersected where
-                    // cubics did not, or the intersection was missed. In the former case, expect
-                    // the quadratics to be nearly parallel at the point of intersection, and check
-                    // for that.
-                }
-            }
-            t2Start = t2;
-        }
-        t1Start = t1;
-    }
-    i.downDepth();
-}
-
-    // if two ends intersect, check middle for coincidence
-bool SkIntersections::cubicCheckCoincidence(const SkDCubic& c1, const SkDCubic& c2) {
-    if (fUsed < 2) {
-        return false;
-    }
-    int last = fUsed - 1;
-    double tRange1 = fT[0][last] - fT[0][0];
-    double tRange2 = fT[1][last] - fT[1][0];
-    for (int index = 1; index < 5; ++index) {
-        double testT1 = fT[0][0] + tRange1 * index / 5;
-        double testT2 = fT[1][0] + tRange2 * index / 5;
-        SkDPoint testPt1 = c1.ptAtT(testT1);
-        SkDPoint testPt2 = c2.ptAtT(testT2);
-        if (!testPt1.approximatelyEqual(testPt2)) {
-            return false;
-        }
-    }
-    if (fUsed > 2) {
-        fPt[1] = fPt[last];
-        fT[0][1] = fT[0][last];
-        fT[1][1] = fT[1][last];
-        fUsed = 2;
-    }
-    fIsCoincident[0] = fIsCoincident[1] = 0x03;
-    return true;
-}
-
-#define LINE_FRACTION 0.1
-
-// intersect the end of the cubic with the other. Try lines from the end to control and opposite
-// end to determine range of t on opposite cubic.
-bool SkIntersections::cubicExactEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2) {
-    int t1Index = start ? 0 : 3;
-    double testT = (double) !start;
-    bool swap = swapped();
-    // quad/quad at this point checks to see if exact matches have already been found
-    // cubic/cubic can't reject so easily since cubics can intersect same point more than once
-    SkDLine tmpLine;
-    tmpLine[0] = tmpLine[1] = cubic2[t1Index];
-    tmpLine[1].fX += cubic2[2 - start].fY - cubic2[t1Index].fY;
-    tmpLine[1].fY -= cubic2[2 - start].fX - cubic2[t1Index].fX;
-    SkIntersections impTs;
-    impTs.allowNear(false);
-    impTs.allowFlatMeasure(true);
-    impTs.intersectRay(cubic1, tmpLine);
-    for (int index = 0; index < impTs.used(); ++index) {
-        SkDPoint realPt = impTs.pt(index);
-        if (!tmpLine[0].approximatelyEqual(realPt)) {
-            continue;
-        }
-        if (swap) {
-            cubicInsert(testT, impTs[0][index], tmpLine[0], cubic2, cubic1);
-        } else {
-            cubicInsert(impTs[0][index], testT, tmpLine[0], cubic1, cubic2);
-        }
-        return true;
-    }
-    return false;
-}
-
-
-void SkIntersections::cubicInsert(double one, double two, const SkDPoint& pt,
-        const SkDCubic& cubic1, const SkDCubic& cubic2) {
-    for (int index = 0; index < fUsed; ++index) {
-        if (fT[0][index] == one) {
-            double oldTwo = fT[1][index];
-            if (oldTwo == two) {
-                return;
-            }
-            SkDPoint mid = cubic2.ptAtT((oldTwo + two) / 2);
-            if (mid.approximatelyEqual(fPt[index])) {
-                return;
-            }
-        }
-        if (fT[1][index] == two) {
-            SkDPoint mid = cubic1.ptAtT((fT[0][index] + two) / 2);
-            if (mid.approximatelyEqual(fPt[index])) {
-                return;
-            }
-        }
-    }
-    insert(one, two, pt);
-}
-
-void SkIntersections::cubicNearEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2,
-                         const SkDRect& bounds2) {
-    SkDLine line;
-    int t1Index = start ? 0 : 3;
-    double testT = (double) !start;
-   // don't bother if the two cubics are connnected
-    static const int kPointsInCubic = 4; // FIXME: move to DCubic, replace '4' with this
-    static const int kMaxLineCubicIntersections = 3;
-    SkSTArray<(kMaxLineCubicIntersections - 1) * kMaxLineCubicIntersections, double, true> tVals;
-    line[0] = cubic1[t1Index];
-    // this variant looks for intersections with the end point and lines parallel to other points
-    for (int index = 0; index < kPointsInCubic; ++index) {
-        if (index == t1Index) {
-            continue;
-        }
-        SkDVector dxy1 = cubic1[index] - line[0];
-        dxy1 /= SkDCubic::gPrecisionUnit;
-        line[1] = line[0] + dxy1;
-        SkDRect lineBounds;
-        lineBounds.setBounds(line);
-        if (!bounds2.intersects(&lineBounds)) {
-            continue;
-        }
-        SkIntersections local;
-        if (!local.intersect(cubic2, line)) {
-            continue;
-        }
-        for (int idx2 = 0; idx2 < local.used(); ++idx2) {
-            double foundT = local[0][idx2];
-            if (approximately_less_than_zero(foundT)
-                    || approximately_greater_than_one(foundT)) {
-                continue;
-            }
-            if (local.pt(idx2).approximatelyEqual(line[0])) {
-                if (swapped()) {  // FIXME: insert should respect swap
-                    insert(foundT, testT, line[0]);
-                } else {
-                    insert(testT, foundT, line[0]);
-                }
-            } else {
-                tVals.push_back(foundT);
-            }
-        }
-    }
-    if (tVals.count() == 0) {
-        return;
-    }
-    SkTQSort<double>(tVals.begin(), tVals.end() - 1);
-    double tMin1 = start ? 0 : 1 - LINE_FRACTION;
-    double tMax1 = start ? LINE_FRACTION : 1;
-    int tIdx = 0;
-    do {
-        int tLast = tIdx;
-        while (tLast + 1 < tVals.count() && roughly_equal(tVals[tLast + 1], tVals[tIdx])) {
-            ++tLast;
-        }
-        double tMin2 = SkTMax(tVals[tIdx] - LINE_FRACTION, 0.0);
-        double tMax2 = SkTMin(tVals[tLast] + LINE_FRACTION, 1.0);
-        int lastUsed = used();
-        if (start ? tMax1 < tMin2 : tMax2 < tMin1) {
-            ::intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, *this);
-        }
-        if (lastUsed == used()) {
-            tMin2 = SkTMax(tVals[tIdx] - (1.0 / SkDCubic::gPrecisionUnit), 0.0);
-            tMax2 = SkTMin(tVals[tLast] + (1.0 / SkDCubic::gPrecisionUnit), 1.0);
-            if (start ? tMax1 < tMin2 : tMax2 < tMin1) {
-                ::intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, *this);
-            }
-        }
-        tIdx = tLast + 1;
-    } while (tIdx < tVals.count());
-    return;
-}
-
-const double CLOSE_ENOUGH = 0.001;
-
-static bool closeStart(const SkDCubic& cubic, int cubicIndex, SkIntersections& i, SkDPoint& pt) {
-    if (i[cubicIndex][0] != 0 || i[cubicIndex][1] > CLOSE_ENOUGH) {
-        return false;
-    }
-    pt = cubic.ptAtT((i[cubicIndex][0] + i[cubicIndex][1]) / 2);
-    return true;
-}
-
-static bool closeEnd(const SkDCubic& cubic, int cubicIndex, SkIntersections& i, SkDPoint& pt) {
-    int last = i.used() - 1;
-    if (i[cubicIndex][last] != 1 || i[cubicIndex][last - 1] < 1 - CLOSE_ENOUGH) {
-        return false;
-    }
-    pt = cubic.ptAtT((i[cubicIndex][last] + i[cubicIndex][last - 1]) / 2);
-    return true;
-}
-
-static bool only_end_pts_in_common(const SkDCubic& c1, const SkDCubic& c2) {
-// the idea here is to see at minimum do a quick reject by rotating all points
-// to either side of the line formed by connecting the endpoints
-// if the opposite curves points are on the line or on the other side, the
-// curves at most intersect at the endpoints
-    for (int oddMan = 0; oddMan < 4; ++oddMan) {
-        const SkDPoint* endPt[3];
-        for (int opp = 1; opp < 4; ++opp) {
-            int end = oddMan ^ opp;  // choose a value not equal to oddMan
-            endPt[opp - 1] = &c1[end];
-        }
-        for (int triTest = 0; triTest < 3; ++triTest) {
-            double origX = endPt[triTest]->fX;
-            double origY = endPt[triTest]->fY;
-            int oppTest = triTest + 1;
-            if (3 == oppTest) {
-                oppTest = 0;
-            }
-            double adj = endPt[oppTest]->fX - origX;
-            double opp = endPt[oppTest]->fY - origY;
-            if (adj == 0 && opp == 0) {  // if the other point equals the test point, ignore it
-                continue;
-            }
-            double sign = (c1[oddMan].fY - origY) * adj - (c1[oddMan].fX - origX) * opp;
-            if (approximately_zero(sign)) {
-                goto tryNextHalfPlane;
-            }
-            for (int n = 0; n < 4; ++n) {
-                double test = (c2[n].fY - origY) * adj - (c2[n].fX - origX) * opp;
-                if (test * sign > 0 && !precisely_zero(test)) {
-                    goto tryNextHalfPlane;
-                }
-            }
-        }
-        return true;
-tryNextHalfPlane:
-        ;
-    }
-    return false;
-}
-
-int SkIntersections::intersect(const SkDCubic& c1, const SkDCubic& c2) {
-    if (fMax == 0) {
-        fMax = 9;
-    }
-    bool selfIntersect = &c1 == &c2;
-    if (selfIntersect) {
-        if (c1[0].approximatelyEqual(c1[3])) {
-            insert(0, 1, c1[0]);
-            return fUsed;
-        }
-    } else {
-        // OPTIMIZATION: set exact end bits here to avoid cubic exact end later
-        for (int i1 = 0; i1 < 4; i1 += 3) {
-            for (int i2 = 0; i2 < 4; i2 += 3) {
-                if (c1[i1].approximatelyEqual(c2[i2])) {
-                    insert(i1 >> 1, i2 >> 1, c1[i1]);
-                }
-            }
-        }
-    }
-    SkASSERT(fUsed < 4);
-    if (!selfIntersect) {
-        if (only_end_pts_in_common(c1, c2)) {
-            return fUsed;
-        }
-        if (only_end_pts_in_common(c2, c1)) {
-            return fUsed;
-        }
-    }
-    // quad/quad does linear test here -- cubic does not
-    // cubics which are really lines should have been detected in reduce step earlier
-    int exactEndBits = 0;
-    if (selfIntersect) {
-        if (fUsed) {
-            return fUsed;
-        }
-    } else {
-        exactEndBits |= cubicExactEnd(c1, false, c2) << 0;
-        exactEndBits |= cubicExactEnd(c1, true, c2) << 1;
-        swap();
-        exactEndBits |= cubicExactEnd(c2, false, c1) << 2;
-        exactEndBits |= cubicExactEnd(c2, true, c1) << 3;
-        swap();
-    }
-    if (cubicCheckCoincidence(c1, c2)) {
-        SkASSERT(!selfIntersect);
-        return fUsed;
-    }
-    // FIXME: pass in cached bounds from caller
-    SkDRect c2Bounds;
-    c2Bounds.setBounds(c2);
-    if (!(exactEndBits & 4)) {
-        cubicNearEnd(c1, false, c2, c2Bounds);
-    }
-    if (!(exactEndBits & 8)) {
-        if (selfIntersect && fUsed) {
-            return fUsed;
-        }
-        cubicNearEnd(c1, true, c2, c2Bounds);
-        if (selfIntersect && fUsed && ((approximately_less_than_zero(fT[0][0])
-                    && approximately_less_than_zero(fT[1][0]))
-                    || (approximately_greater_than_one(fT[0][0])
-                    && approximately_greater_than_one(fT[1][0])))) {
-            SkASSERT(fUsed == 1);
-            fUsed = 0;
-            return fUsed;
-        }
-    }
-    if (!selfIntersect) {
-        SkDRect c1Bounds;
-        c1Bounds.setBounds(c1);  // OPTIMIZE use setRawBounds ?
-        swap();
-        if (!(exactEndBits & 1)) {
-            cubicNearEnd(c2, false, c1, c1Bounds);
-        }
-        if (!(exactEndBits & 2)) {
-            cubicNearEnd(c2, true, c1, c1Bounds);
-        }
-        swap();
-    }
-    if (cubicCheckCoincidence(c1, c2)) {
-        SkASSERT(!selfIntersect);
-        return fUsed;
-    }
-    SkIntersections i;
-    i.fAllowNear = false;
-    i.fFlatMeasure = true;
-    i.fMax = 9;
-    ::intersect(c1, 0, 1, c2, 0, 1, 1, i);
-    int compCount = i.used();
-    if (compCount) {
-        int exactCount = used();
-        if (exactCount == 0) {
-            *this = i;
-        } else {
-            // at least one is exact or near, and at least one was computed. Eliminate duplicates
-            for (int exIdx = 0; exIdx < exactCount; ++exIdx) {
-                for (int cpIdx = 0; cpIdx < compCount; ) {
-                    if (fT[0][0] == i[0][0] && fT[1][0] == i[1][0]) {
-                        i.removeOne(cpIdx);
-                        --compCount;
-                        continue;
-                    }
-                    double tAvg = (fT[0][exIdx] + i[0][cpIdx]) / 2;
-                    SkDPoint pt = c1.ptAtT(tAvg);
-                    if (!pt.approximatelyEqual(fPt[exIdx])) {
-                        ++cpIdx;
-                        continue;
-                    }
-                    tAvg = (fT[1][exIdx] + i[1][cpIdx]) / 2;
-                    pt = c2.ptAtT(tAvg);
-                    if (!pt.approximatelyEqual(fPt[exIdx])) {
-                        ++cpIdx;
-                        continue;
-                    }
-                    i.removeOne(cpIdx);
-                    --compCount;
-                }
-            }
-            // if mid t evaluates to nearly the same point, skip the t
-            for (int cpIdx = 0; cpIdx < compCount - 1; ) {
-                double tAvg = (fT[0][cpIdx] + i[0][cpIdx + 1]) / 2;
-                SkDPoint pt = c1.ptAtT(tAvg);
-                if (!pt.approximatelyEqual(fPt[cpIdx])) {
-                    ++cpIdx;
-                    continue;
-                }
-                tAvg = (fT[1][cpIdx] + i[1][cpIdx + 1]) / 2;
-                pt = c2.ptAtT(tAvg);
-                if (!pt.approximatelyEqual(fPt[cpIdx])) {
-                    ++cpIdx;
-                    continue;
-                }
-                i.removeOne(cpIdx);
-                --compCount;
-            }
-            // in addition to adding below missing function, think about how to say
-            append(i);
-        }
-    }
-    // If an end point and a second point very close to the end is returned, the second
-    // point may have been detected because the approximate quads
-    // intersected at the end and close to it. Verify that the second point is valid.
-    if (fUsed <= 1) {
-        return fUsed;
-    }
-    SkDPoint pt[2];
-    if (closeStart(c1, 0, *this, pt[0]) && closeStart(c2, 1, *this, pt[1])
-            && pt[0].approximatelyEqual(pt[1])) {
-        removeOne(1);
-    }
-    if (closeEnd(c1, 0, *this, pt[0]) && closeEnd(c2, 1, *this, pt[1])
-            && pt[0].approximatelyEqual(pt[1])) {
-        removeOne(used() - 2);
-    }
-    // vet the pairs of t values to see if the mid value is also on the curve. If so, mark
-    // the span as coincident
-    if (fUsed >= 2 && !coincidentUsed()) {
-        int last = fUsed - 1;
-        int match = 0;
-        for (int index = 0; index < last; ++index) {
-            double mid1 = (fT[0][index] + fT[0][index + 1]) / 2;
-            double mid2 = (fT[1][index] + fT[1][index + 1]) / 2;
-            pt[0] = c1.ptAtT(mid1);
-            pt[1] = c2.ptAtT(mid2);
-            if (pt[0].approximatelyEqual(pt[1])) {
-                match |= 1 << index;
-            }
-        }
-        if (match) {
-#if DEBUG_CONCIDENT
-            if (((match + 1) & match) != 0) {
-                SkDebugf("%s coincident hole\n", __FUNCTION__);
-            }
-#endif
-            // for now, assume that everything from start to finish is coincident
-            if (fUsed > 2) {
-                  fPt[1] = fPt[last];
-                  fT[0][1] = fT[0][last];
-                  fT[1][1] = fT[1][last];
-                  fIsCoincident[0] = 0x03;
-                  fIsCoincident[1] = 0x03;
-                  fUsed = 2;
-            }
-        }
-    }
-    return fUsed;
-}
-
-// Up promote the quad to a cubic.
-// OPTIMIZATION If this is a common use case, optimize by duplicating
-// the intersect 3 loop to avoid the promotion  / demotion code
-int SkIntersections::intersect(const SkDCubic& cubic, const SkDQuad& quad) {
-    fMax = 7;
-    SkDCubic up = quad.toCubic();
-    (void) intersect(cubic, up);
-    return used();
-}
-
-/* http://www.ag.jku.at/compass/compasssample.pdf
-( Self-Intersection Problems and Approximate Implicitization by Jan B. Thomassen
-Centre of Mathematics for Applications, University of Oslo http://www.cma.uio.no janbth@math.uio.no
-SINTEF Applied Mathematics http://www.sintef.no )
-describes a method to find the self intersection of a cubic by taking the gradient of the implicit
-form dotted with the normal, and solving for the roots. My math foo is too poor to implement this.*/
-
-int SkIntersections::intersect(const SkDCubic& c) {
-    fMax = 1;
-    // check to see if x or y end points are the extrema. Are other quick rejects possible?
-    if (c.endsAreExtremaInXOrY()) {
-        return false;
-    }
-    // OPTIMIZATION: could quick reject if neither end point tangent ray intersected the line
-    // segment formed by the opposite end point to the control point
-    (void) intersect(c, c);
-    if (used() > 1) {
-        fUsed = 0;
-    } else if (used() > 0) {
-        if (approximately_equal_double(fT[0][0], fT[1][0])) {
-            fUsed = 0;
-        } else {
-            SkASSERT(used() == 1);
-            if (fT[0][0] > fT[1][0]) {
-                swapPts();
-            }
-        }
-    }
-    return used();
-}
diff --git a/src/pathops/SkDCubicLineIntersection.cpp b/src/pathops/SkDCubicLineIntersection.cpp
index 696c42e..f5fe015 100644
--- a/src/pathops/SkDCubicLineIntersection.cpp
+++ b/src/pathops/SkDCubicLineIntersection.cpp
@@ -93,6 +93,29 @@
         fAllowNear = allow;
     }
 
+    void checkCoincident() {
+        int last = fIntersections->used() - 1;
+        for (int index = 0; index < last; ) {
+            double cubicMidT = ((*fIntersections)[0][index] + (*fIntersections)[0][index + 1]) / 2;
+            SkDPoint cubicMidPt = fCubic.ptAtT(cubicMidT);
+            double t = fLine.nearPoint(cubicMidPt, NULL);
+            if (t < 0) {
+                ++index;
+                continue;
+            }
+            if (fIntersections->isCoincident(index)) {
+                fIntersections->removeOne(index);
+                --last;
+            } else if (fIntersections->isCoincident(index + 1)) {
+                fIntersections->removeOne(index + 1);
+                --last;
+            } else {
+                fIntersections->setCoincident(index++);
+            }
+            fIntersections->setCoincident(index);
+        }
+    }
+
     // see parallel routine in line quadratic intersections
     int intersectRay(double roots[3]) {
         double adj = fLine[1].fX - fLine[0].fX;
@@ -131,32 +154,11 @@
             double cubicT = rootVals[index];
             double lineT = findLineT(cubicT);
             SkDPoint pt;
-            if (pinTs(&cubicT, &lineT, &pt, kPointUninitialized)) {
-    #if ONE_OFF_DEBUG
-                SkDPoint cPt = fCubic.ptAtT(cubicT);
-                SkDebugf("%s pt=(%1.9g,%1.9g) cPt=(%1.9g,%1.9g)\n", __FUNCTION__, pt.fX, pt.fY,
-                        cPt.fX, cPt.fY);
-    #endif
-                for (int inner = 0; inner < fIntersections->used(); ++inner) {
-                    if (fIntersections->pt(inner) != pt) {
-                        continue;
-                    }
-                    double existingCubicT = (*fIntersections)[0][inner];
-                    if (cubicT == existingCubicT) {
-                        goto skipInsert;
-                    }
-                    // check if midway on cubic is also same point. If so, discard this
-                    double cubicMidT = (existingCubicT + cubicT) / 2;
-                    SkDPoint cubicMidPt = fCubic.ptAtT(cubicMidT);
-                    if (cubicMidPt.approximatelyEqual(pt)) {
-                        goto skipInsert;
-                    }
-                }
+            if (pinTs(&cubicT, &lineT, &pt, kPointUninitialized) && uniqueAnswer(cubicT, pt)) {
                 fIntersections->insert(cubicT, lineT, pt);
-        skipInsert:
-                ;
             }
         }
+        checkCoincident();
         return fIntersections->used();
     }
 
@@ -186,20 +188,43 @@
         int count = HorizontalIntersect(fCubic, axisIntercept, roots);
         for (int index = 0; index < count; ++index) {
             double cubicT = roots[index];
-            SkDPoint pt;
-            pt.fX = fCubic.ptAtT(cubicT).fX;
-            pt.fY = axisIntercept;
+            SkDPoint pt = { fCubic.ptAtT(cubicT).fX,  axisIntercept };
             double lineT = (pt.fX - left) / (right - left);
-            if (pinTs(&cubicT, &lineT, &pt, kPointInitialized)) {
+            if (pinTs(&cubicT, &lineT, &pt, kPointInitialized) && uniqueAnswer(cubicT, pt)) {
                 fIntersections->insert(cubicT, lineT, pt);
             }
         }
         if (flipped) {
             fIntersections->flip();
         }
+        checkCoincident();
         return fIntersections->used();
     }
 
+        bool uniqueAnswer(double cubicT, const SkDPoint& pt) {
+            for (int inner = 0; inner < fIntersections->used(); ++inner) {
+                if (fIntersections->pt(inner) != pt) {
+                    continue;
+                }
+                double existingCubicT = (*fIntersections)[0][inner];
+                if (cubicT == existingCubicT) {
+                    return false;
+                }
+                // check if midway on cubic is also same point. If so, discard this
+                double cubicMidT = (existingCubicT + cubicT) / 2;
+                SkDPoint cubicMidPt = fCubic.ptAtT(cubicMidT);
+                if (cubicMidPt.approximatelyEqual(pt)) {
+                    return false;
+                }
+            }
+#if ONE_OFF_DEBUG
+            SkDPoint cPt = fCubic.ptAtT(cubicT);
+            SkDebugf("%s pt=(%1.9g,%1.9g) cPt=(%1.9g,%1.9g)\n", __FUNCTION__, pt.fX, pt.fY,
+                    cPt.fX, cPt.fY);
+#endif
+            return true;
+        }
+
     static int VerticalIntersect(const SkDCubic& c, double axisIntercept, double roots[3]) {
         double A, B, C, D;
         SkDCubic::Coefficients(&c[0].fX, &A, &B, &C, &D);
@@ -226,17 +251,16 @@
         int count = VerticalIntersect(fCubic, axisIntercept, roots);
         for (int index = 0; index < count; ++index) {
             double cubicT = roots[index];
-            SkDPoint pt;
-            pt.fX = axisIntercept;
-            pt.fY = fCubic.ptAtT(cubicT).fY;
+            SkDPoint pt = { axisIntercept, fCubic.ptAtT(cubicT).fY };
             double lineT = (pt.fY - top) / (bottom - top);
-            if (pinTs(&cubicT, &lineT, &pt, kPointInitialized)) {
+            if (pinTs(&cubicT, &lineT, &pt, kPointInitialized) && uniqueAnswer(cubicT, pt)) {
                 fIntersections->insert(cubicT, lineT, pt);
             }
         }
         if (flipped) {
             fIntersections->flip();
         }
+        checkCoincident();
         return fIntersections->used();
     }
 
@@ -342,7 +366,7 @@
         double lT = *lineT = SkPinT(*lineT);
         SkDPoint lPt = fLine.ptAtT(lT);
         SkDPoint cPt = fCubic.ptAtT(cT);
-        if (!lPt.moreRoughlyEqual(cPt)) {
+        if (!lPt.roughlyEqual(cPt)) {
             return false;
         }
         // FIXME: if points are roughly equal but not approximately equal, need to do
diff --git a/src/pathops/SkDCubicToQuads.cpp b/src/pathops/SkDCubicToQuads.cpp
index a28564d..2d034b6 100644
--- a/src/pathops/SkDCubicToQuads.cpp
+++ b/src/pathops/SkDCubicToQuads.cpp
@@ -19,62 +19,10 @@
  it's likely not, your best bet is to average them. So,
 
 P1 = -1/4 Q0 + 3/4 Q1 + 3/4 Q2 - 1/4 Q3
-
-SkDCubic defined by: P1/2 - anchor points, C1/C2 control points
-|x| is the euclidean norm of x
-mid-point approx of cubic: a quad that shares the same anchors with the cubic and has the
- control point at C = (3·C2 - P2 + 3·C1 - P1)/4
-
-Algorithm
-
-pick an absolute precision (prec)
-Compute the Tdiv as the root of (cubic) equation
-sqrt(3)/18 · |P2 - 3·C2 + 3·C1 - P1|/2 · Tdiv ^ 3 = prec
-if Tdiv < 0.5 divide the cubic at Tdiv. First segment [0..Tdiv] can be approximated with by a
- quadratic, with a defect less than prec, by the mid-point approximation.
- Repeat from step 2 with the second resulted segment (corresponding to 1-Tdiv)
-0.5<=Tdiv<1 - simply divide the cubic in two. The two halves can be approximated by the mid-point
- approximation
-Tdiv>=1 - the entire cubic can be approximated by the mid-point approximation
-
-confirmed by (maybe stolen from)
-http://www.caffeineowl.com/graphics/2d/vectorial/cubic2quad01.html
-// maybe in turn derived from  http://www.cccg.ca/proceedings/2004/36.pdf
-// also stored at http://www.cis.usouthal.edu/~hain/general/Publications/Bezier/bezier%20cccg04%20paper.pdf
-
 */
 
 #include "SkPathOpsCubic.h"
-#include "SkPathOpsLine.h"
 #include "SkPathOpsQuad.h"
-#include "SkReduceOrder.h"
-#include "SkTArray.h"
-#include "SkTSort.h"
-
-#define USE_CUBIC_END_POINTS 1
-
-static double calc_t_div(const SkDCubic& cubic, double precision, double start) {
-    const double adjust = sqrt(3.) / 36;
-    SkDCubic sub;
-    const SkDCubic* cPtr;
-    if (start == 0) {
-        cPtr = &cubic;
-    } else {
-        // OPTIMIZE: special-case half-split ?
-        sub = cubic.subDivide(start, 1);
-        cPtr = &sub;
-    }
-    const SkDCubic& c = *cPtr;
-    double dx = c[3].fX - 3 * (c[2].fX - c[1].fX) - c[0].fX;
-    double dy = c[3].fY - 3 * (c[2].fY - c[1].fY) - c[0].fY;
-    double dist = sqrt(dx * dx + dy * dy);
-    double tDiv3 = precision / (adjust * dist);
-    double t = SkDCubeRoot(tDiv3);
-    if (start > 0) {
-        t = start + (1 - start) * t;
-    }
-    return t;
-}
 
 SkDQuad SkDCubic::toQuad() const {
     SkDQuad quad;
@@ -86,101 +34,3 @@
     quad[2] = fPts[3];
     return quad;
 }
-
-static bool add_simple_ts(const SkDCubic& cubic, double precision, SkTArray<double, true>* ts) {
-    double tDiv = calc_t_div(cubic, precision, 0);
-    if (tDiv >= 1) {
-        return true;
-    }
-    if (tDiv >= 0.5) {
-        ts->push_back(0.5);
-        return true;
-    }
-    return false;
-}
-
-static void addTs(const SkDCubic& cubic, double precision, double start, double end,
-        SkTArray<double, true>* ts) {
-    double tDiv = calc_t_div(cubic, precision, 0);
-    double parts = ceil(1.0 / tDiv);
-    for (double index = 0; index < parts; ++index) {
-        double newT = start + (index / parts) * (end - start);
-        if (newT > 0 && newT < 1) {
-            ts->push_back(newT);
-        }
-    }
-}
-
-// flavor that returns T values only, deferring computing the quads until they are needed
-// FIXME: when called from recursive intersect 2, this could take the original cubic
-// and do a more precise job when calling chop at and sub divide by computing the fractional ts.
-// it would still take the prechopped cubic for reduce order and find cubic inflections
-void SkDCubic::toQuadraticTs(double precision, SkTArray<double, true>* ts) const {
-    SkReduceOrder reducer;
-    int order = reducer.reduce(*this, SkReduceOrder::kAllow_Quadratics);
-    if (order < 3) {
-        return;
-    }
-    double inflectT[5];
-    int inflections = findInflections(inflectT);
-    SkASSERT(inflections <= 2);
-    if (!endsAreExtremaInXOrY()) {
-        inflections += findMaxCurvature(&inflectT[inflections]);
-        SkASSERT(inflections <= 5);
-    }
-    SkTQSort<double>(inflectT, &inflectT[inflections - 1]);
-    // OPTIMIZATION: is this filtering common enough that it needs to be pulled out into its
-    // own subroutine?
-    while (inflections && approximately_less_than_zero(inflectT[0])) {
-        memmove(inflectT, &inflectT[1], sizeof(inflectT[0]) * --inflections);
-    }
-    int start = 0;
-    int next = 1;
-    while (next < inflections) {
-        if (!approximately_equal(inflectT[start], inflectT[next])) {
-            ++start;
-        ++next;
-            continue;
-        }
-        memmove(&inflectT[start], &inflectT[next], sizeof(inflectT[0]) * (--inflections - start));
-    }
-
-    while (inflections && approximately_greater_than_one(inflectT[inflections - 1])) {
-        --inflections;
-    }
-    SkDCubicPair pair;
-    if (inflections == 1) {
-        pair = chopAt(inflectT[0]);
-        int orderP1 = reducer.reduce(pair.first(), SkReduceOrder::kNo_Quadratics);
-        if (orderP1 < 2) {
-            --inflections;
-        } else {
-            int orderP2 = reducer.reduce(pair.second(), SkReduceOrder::kNo_Quadratics);
-            if (orderP2 < 2) {
-                --inflections;
-            }
-        }
-    }
-    if (inflections == 0 && add_simple_ts(*this, precision, ts)) {
-        return;
-    }
-    if (inflections == 1) {
-        pair = chopAt(inflectT[0]);
-        addTs(pair.first(), precision, 0, inflectT[0], ts);
-        addTs(pair.second(), precision, inflectT[0], 1, ts);
-        return;
-    }
-    if (inflections > 1) {
-        SkDCubic part = subDivide(0, inflectT[0]);
-        addTs(part, precision, 0, inflectT[0], ts);
-        int last = inflections - 1;
-        for (int idx = 0; idx < last; ++idx) {
-            part = subDivide(inflectT[idx], inflectT[idx + 1]);
-            addTs(part, precision, inflectT[idx], inflectT[idx + 1], ts);
-        }
-        part = subDivide(inflectT[last], 1);
-        addTs(part, precision, inflectT[last], 1, ts);
-        return;
-    }
-    addTs(*this, precision, 0, 1, ts);
-}
diff --git a/src/pathops/SkDLineIntersection.cpp b/src/pathops/SkDLineIntersection.cpp
index 8fc673f..ed96b9c 100644
--- a/src/pathops/SkDLineIntersection.cpp
+++ b/src/pathops/SkDLineIntersection.cpp
@@ -7,45 +7,6 @@
 #include "SkIntersections.h"
 #include "SkPathOpsLine.h"
 
-/* Determine the intersection point of two lines. This assumes the lines are not parallel,
-   and that that the lines are infinite.
-   From http://en.wikipedia.org/wiki/Line-line_intersection
- */
-SkDPoint SkIntersections::Line(const SkDLine& a, const SkDLine& b) {
-    double axLen = a[1].fX - a[0].fX;
-    double ayLen = a[1].fY - a[0].fY;
-    double bxLen = b[1].fX - b[0].fX;
-    double byLen = b[1].fY - b[0].fY;
-    double denom = byLen * axLen - ayLen * bxLen;
-    SkASSERT(denom);
-    double term1 = a[1].fX * a[0].fY - a[1].fY * a[0].fX;
-    double term2 = b[1].fX * b[0].fY - b[1].fY * b[0].fX;
-    SkDPoint p;
-    p.fX = (term1 * bxLen - axLen * term2) / denom;
-    p.fY = (term1 * byLen - ayLen * term2) / denom;
-    return p;
-}
-
-int SkIntersections::cleanUpCoincidence() {
-    do {
-        int last = fUsed - 1;
-        for (int index = 0; index < last; ++index) {
-            if (fT[0][index] == fT[0][index + 1]) {
-                removeOne(index + (int) (fT[1][index] == 0 || fT[1][index] == 1));
-                goto tryAgain;
-            }
-        }
-        for (int index = 0; index < last; ++index) {
-            if (fT[1][index] == fT[1][index + 1]) {
-                removeOne(index + (int) (fT[0][index] == 0 || fT[0][index] == 1));
-                goto tryAgain;
-            }
-        }
-        return fUsed;
-tryAgain: ;
-    } while (true);
-}
-
 void SkIntersections::cleanUpParallelLines(bool parallel) {
     while (fUsed > 2) {
         removeOne(1);
@@ -58,6 +19,9 @@
             removeOne(endMatch);
         }
     }
+    if (fUsed == 2) {
+        fIsCoincident[0] = fIsCoincident[1] = 0x03;
+    }
 }
 
 void SkIntersections::computePoints(const SkDLine& line, int used) {
@@ -81,12 +45,6 @@
     SkDVector ab0 = a[0] - b[0];
     double numerA = ab0.fY * bLen.fX - bLen.fY * ab0.fX;
     double numerB = ab0.fY * aLen.fX - aLen.fY * ab0.fX;
-#if 0
-    if (!between(0, numerA, denom) || !between(0, numerB, denom)) {
-        fUsed = 0;
-        return 0;
-    }
-#endif
     numerA /= denom;
     numerB /= denom;
     int used;
@@ -190,7 +148,6 @@
                     }
                     SkASSERT(a[iA] != b[nearer]);
                     SkASSERT(iA == (bNearA[nearer] > 0.5));
-                    fNearlySame[iA] = true;
                     insertNear(iA, nearer, a[iA], b[nearer]);
                     aNearB[iA] = -1;
                     bNearA[nearer] = -1;
@@ -235,18 +192,6 @@
      return SkPinT((y - line[0].fY) / (line[1].fY - line[0].fY));
 }
 
-int SkIntersections::horizontal(const SkDLine& line, double y) {
-    fMax = 2;
-    int horizontalType = horizontal_coincident(line, y);
-    if (horizontalType == 1) {
-        fT[0][0] = horizontal_intercept(line, y);
-    } else if (horizontalType == 2) {
-        fT[0][0] = 0;
-        fT[0][1] = 1;
-    }
-    return fUsed = horizontalType;
-}
-
 int SkIntersections::horizontal(const SkDLine& line, double left, double right,
                                 double y, bool flipped) {
     fMax = 3;  // clean up parallel at the end will limit the result to 2 at the most
@@ -323,18 +268,6 @@
     return SkPinT((x - line[0].fX) / (line[1].fX - line[0].fX));
 }
 
-int SkIntersections::vertical(const SkDLine& line, double x) {
-    fMax = 2;
-    int verticalType = vertical_coincident(line, x);
-    if (verticalType == 1) {
-        fT[0][0] = vertical_intercept(line, x);
-    } else if (verticalType == 2) {
-        fT[0][0] = 0;
-        fT[0][1] = 1;
-    }
-    return fUsed = verticalType;
-}
-
 int SkIntersections::vertical(const SkDLine& line, double top, double bottom,
                               double x, bool flipped) {
     fMax = 3;  // cleanup parallel lines will bring this back line
@@ -393,14 +326,3 @@
     return fUsed;
 }
 
-// from http://www.bryceboe.com/wordpress/wp-content/uploads/2006/10/intersect.py
-// 4 subs, 2 muls, 1 cmp
-static bool ccw(const SkDPoint& A, const SkDPoint& B, const SkDPoint& C) {
-    return (C.fY - A.fY) * (B.fX - A.fX) > (B.fY - A.fY) * (C.fX - A.fX);
-}
-
-// 16 subs, 8 muls, 6 cmps
-bool SkIntersections::Test(const SkDLine& a, const SkDLine& b) {
-    return ccw(a[0], b[0], b[1]) != ccw(a[1], b[0], b[1])
-            && ccw(a[0], a[1], b[0]) != ccw(a[0], a[1], b[1]);
-}
diff --git a/src/pathops/SkDQuadImplicit.cpp b/src/pathops/SkDQuadImplicit.cpp
deleted file mode 100644
index f0f66d1..0000000
--- a/src/pathops/SkDQuadImplicit.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SkDQuadImplicit.h"
-
-/* from http://tom.cs.byu.edu/~tom/papers/cvgip84.pdf 4.1
- *
- * This paper proves that Syvester's method can compute the implicit form of
- * the quadratic from the parameterized form.
- *
- * Given x = a*t*t + b*t + c  (the parameterized form)
- *       y = d*t*t + e*t + f
- *
- * we want to find an equation of the implicit form:
- *
- * A*x*x + B*x*y + C*y*y + D*x + E*y + F = 0
- *
- * The implicit form can be expressed as a 4x4 determinant, as shown.
- *
- * The resultant obtained by Syvester's method is
- *
- * |   a   b   (c - x)     0     |
- * |   0   a      b     (c - x)  |
- * |   d   e   (f - y)     0     |
- * |   0   d      e     (f - y)  |
- *
- * which expands to
- *
- * d*d*x*x + -2*a*d*x*y + a*a*y*y
- *         + (-2*c*d*d + b*e*d - a*e*e + 2*a*f*d)*x
- *         + (-2*f*a*a + e*b*a - d*b*b + 2*d*c*a)*y
- *         +
- * |   a   b   c   0   |
- * |   0   a   b   c   | == 0.
- * |   d   e   f   0   |
- * |   0   d   e   f   |
- *
- * Expanding the constant determinant results in
- *
- *   | a b c |     | b c 0 |
- * a*| e f 0 | + d*| a b c | ==
- *   | d e f |     | d e f |
- *
- * a*(a*f*f + c*e*e - c*f*d - b*e*f) + d*(b*b*f + c*c*d - c*a*f - c*e*b)
- *
- */
-
-// use the tricky arithmetic path, but leave the original to compare just in case
-static bool straight_forward = false;
-
-SkDQuadImplicit::SkDQuadImplicit(const SkDQuad& q) {
-    double a, b, c;
-    SkDQuad::SetABC(&q[0].fX, &a, &b, &c);
-    double d, e, f;
-    SkDQuad::SetABC(&q[0].fY, &d, &e, &f);
-    // compute the implicit coefficients
-    if (straight_forward) {  // 42 muls, 13 adds
-        fP[kXx_Coeff] = d * d;
-        fP[kXy_Coeff] = -2 * a * d;
-        fP[kYy_Coeff] = a * a;
-        fP[kX_Coeff] = -2*c*d*d + b*e*d - a*e*e + 2*a*f*d;
-        fP[kY_Coeff] = -2*f*a*a + e*b*a - d*b*b + 2*d*c*a;
-        fP[kC_Coeff] = a*(a*f*f + c*e*e - c*f*d - b*e*f)
-                   + d*(b*b*f + c*c*d - c*a*f - c*e*b);
-    } else {  // 26 muls, 11 adds
-        double aa = a * a;
-        double ad = a * d;
-        double dd = d * d;
-        fP[kXx_Coeff] = dd;
-        fP[kXy_Coeff] = -2 * ad;
-        fP[kYy_Coeff] = aa;
-        double be = b * e;
-        double bde = be * d;
-        double cdd = c * dd;
-        double ee = e * e;
-        fP[kX_Coeff] =  -2*cdd + bde - a*ee + 2*ad*f;
-        double aaf = aa * f;
-        double abe = a * be;
-        double ac = a * c;
-        double bb_2ac = b*b - 2*ac;
-        fP[kY_Coeff] = -2*aaf + abe - d*bb_2ac;
-        fP[kC_Coeff] = aaf*f + ac*ee + d*f*bb_2ac - abe*f + c*cdd - c*bde;
-    }
-}
-
- /* Given a pair of quadratics, determine their parametric coefficients.
-  * If the scaled coefficients are nearly equal, then the part of the quadratics
-  * may be coincident.
-  * OPTIMIZATION -- since comparison short-circuits on no match,
-  * lazily compute the coefficients, comparing the easiest to compute first.
-  * xx and yy first; then xy; and so on.
-  */
-bool SkDQuadImplicit::match(const SkDQuadImplicit& p2) const {
-    int first = 0;
-    for (int index = 0; index <= kC_Coeff; ++index) {
-        if (approximately_zero(fP[index]) && approximately_zero(p2.fP[index])) {
-            first += first == index;
-            continue;
-        }
-        if (first == index) {
-            continue;
-        }
-        if (!AlmostDequalUlps(fP[index] * p2.fP[first], fP[first] * p2.fP[index])) {
-            return false;
-        }
-    }
-    return true;
-}
-
-bool SkDQuadImplicit::Match(const SkDQuad& quad1, const SkDQuad& quad2) {
-    SkDQuadImplicit i1(quad1);  // a'xx , b'xy , c'yy , d'x , e'y , f
-    SkDQuadImplicit i2(quad2);
-    return i1.match(i2);
-}
diff --git a/src/pathops/SkDQuadImplicit.h b/src/pathops/SkDQuadImplicit.h
deleted file mode 100644
index 24f1aac..0000000
--- a/src/pathops/SkDQuadImplicit.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef SkDQuadImplicit_DEFINED
-#define SkDQuadImplicit_DEFINED
-
-#include "SkPathOpsQuad.h"
-
-class SkDQuadImplicit {
-public:
-    explicit SkDQuadImplicit(const SkDQuad& q);
-
-    bool match(const SkDQuadImplicit& two) const;
-    static bool Match(const SkDQuad& quad1, const SkDQuad& quad2);
-
-    double x2() const { return fP[kXx_Coeff]; }
-    double xy() const { return fP[kXy_Coeff]; }
-    double y2() const { return fP[kYy_Coeff]; }
-    double x() const { return fP[kX_Coeff]; }
-    double y() const { return fP[kY_Coeff]; }
-    double c() const { return fP[kC_Coeff]; }
-
-private:
-    enum Coeffs {
-        kXx_Coeff,
-        kXy_Coeff,
-        kYy_Coeff,
-        kX_Coeff,
-        kY_Coeff,
-        kC_Coeff,
-    };
-
-    double fP[kC_Coeff + 1];
-};
-
-#endif
diff --git a/src/pathops/SkDQuadIntersection.cpp b/src/pathops/SkDQuadIntersection.cpp
deleted file mode 100644
index fcb9171..0000000
--- a/src/pathops/SkDQuadIntersection.cpp
+++ /dev/null
@@ -1,617 +0,0 @@
-// Another approach is to start with the implicit form of one curve and solve
-// (seek implicit coefficients in QuadraticParameter.cpp
-// by substituting in the parametric form of the other.
-// The downside of this approach is that early rejects are difficult to come by.
-// http://planetmath.org/encyclopedia/GaloisTheoreticDerivationOfTheQuarticFormula.html#step
-
-#include "SkDQuadImplicit.h"
-#include "SkIntersections.h"
-#include "SkPathOpsLine.h"
-#include "SkQuarticRoot.h"
-#include "SkTArray.h"
-#include "SkTSort.h"
-
-/* given the implicit form 0 = Ax^2 + Bxy + Cy^2 + Dx + Ey + F
- * and given x = at^2 + bt + c  (the parameterized form)
- *           y = dt^2 + et + f
- * then
- * 0 = A(at^2+bt+c)(at^2+bt+c)+B(at^2+bt+c)(dt^2+et+f)+C(dt^2+et+f)(dt^2+et+f)+D(at^2+bt+c)+E(dt^2+et+f)+F
- */
-
-static int findRoots(const SkDQuadImplicit& i, const SkDQuad& quad, double roots[4],
-        bool oneHint, bool flip, int firstCubicRoot) {
-    SkDQuad flipped;
-    const SkDQuad& q = flip ? (flipped = quad.flip()) : quad;
-    double a, b, c;
-    SkDQuad::SetABC(&q[0].fX, &a, &b, &c);
-    double d, e, f;
-    SkDQuad::SetABC(&q[0].fY, &d, &e, &f);
-    const double t4 =     i.x2() *  a * a
-                    +     i.xy() *  a * d
-                    +     i.y2() *  d * d;
-    const double t3 = 2 * i.x2() *  a * b
-                    +     i.xy() * (a * e +     b * d)
-                    + 2 * i.y2() *  d * e;
-    const double t2 =     i.x2() * (b * b + 2 * a * c)
-                    +     i.xy() * (c * d +     b * e + a * f)
-                    +     i.y2() * (e * e + 2 * d * f)
-                    +     i.x()  *  a
-                    +     i.y()  *  d;
-    const double t1 = 2 * i.x2() *  b * c
-                    +     i.xy() * (c * e + b * f)
-                    + 2 * i.y2() *  e * f
-                    +     i.x()  *  b
-                    +     i.y()  *  e;
-    const double t0 =     i.x2() *  c * c
-                    +     i.xy() *  c * f
-                    +     i.y2() *  f * f
-                    +     i.x()  *  c
-                    +     i.y()  *  f
-                    +     i.c();
-    int rootCount = SkReducedQuarticRoots(t4, t3, t2, t1, t0, oneHint, roots);
-    if (rootCount < 0) {
-        rootCount = SkQuarticRootsReal(firstCubicRoot, t4, t3, t2, t1, t0, roots);
-    }
-    if (flip) {
-        for (int index = 0; index < rootCount; ++index) {
-            roots[index] = 1 - roots[index];
-        }
-    }
-    return rootCount;
-}
-
-static int addValidRoots(const double roots[4], const int count, double valid[4]) {
-    int result = 0;
-    int index;
-    for (index = 0; index < count; ++index) {
-        if (!approximately_zero_or_more(roots[index]) || !approximately_one_or_less(roots[index])) {
-            continue;
-        }
-        double t = 1 - roots[index];
-        if (approximately_less_than_zero(t)) {
-            t = 0;
-        } else if (approximately_greater_than_one(t)) {
-            t = 1;
-        }
-        SkASSERT(t >= 0 && t <= 1);
-        valid[result++] = t;
-    }
-    return result;
-}
-
-static bool only_end_pts_in_common(const SkDQuad& q1, const SkDQuad& q2) {
-// the idea here is to see at minimum do a quick reject by rotating all points
-// to either side of the line formed by connecting the endpoints
-// if the opposite curves points are on the line or on the other side, the
-// curves at most intersect at the endpoints
-    for (int oddMan = 0; oddMan < 3; ++oddMan) {
-        const SkDPoint* endPt[2];
-        for (int opp = 1; opp < 3; ++opp) {
-            int end = oddMan ^ opp;  // choose a value not equal to oddMan
-            if (3 == end) {  // and correct so that largest value is 1 or 2
-                end = opp;
-            }
-            endPt[opp - 1] = &q1[end];
-        }
-        double origX = endPt[0]->fX;
-        double origY = endPt[0]->fY;
-        double adj = endPt[1]->fX - origX;
-        double opp = endPt[1]->fY - origY;
-        double sign = (q1[oddMan].fY - origY) * adj - (q1[oddMan].fX - origX) * opp;
-        if (approximately_zero(sign)) {
-            goto tryNextHalfPlane;
-        }
-        for (int n = 0; n < 3; ++n) {
-            double test = (q2[n].fY - origY) * adj - (q2[n].fX - origX) * opp;
-            if (test * sign > 0 && !precisely_zero(test)) {
-                goto tryNextHalfPlane;
-            }
-        }
-        return true;
-tryNextHalfPlane:
-        ;
-    }
-    return false;
-}
-
-// returns false if there's more than one intercept or the intercept doesn't match the point
-// returns true if the intercept was successfully added or if the
-// original quads need to be subdivided
-static bool add_intercept(const SkDQuad& q1, const SkDQuad& q2, double tMin, double tMax,
-                          SkIntersections* i, bool* subDivide) {
-    double tMid = (tMin + tMax) / 2;
-    SkDPoint mid = q2.ptAtT(tMid);
-    SkDLine line;
-    line[0] = line[1] = mid;
-    SkDVector dxdy = q2.dxdyAtT(tMid);
-    line[0] -= dxdy;
-    line[1] += dxdy;
-    SkIntersections rootTs;
-    rootTs.allowNear(false);
-    int roots = rootTs.intersect(q1, line);
-    if (roots == 0) {
-        if (subDivide) {
-            *subDivide = true;
-        }
-        return true;
-    }
-    if (roots == 2) {
-        return false;
-    }
-    SkDPoint pt2 = q1.ptAtT(rootTs[0][0]);
-    if (!pt2.approximatelyEqual(mid)) {
-        return false;
-    }
-    i->insertSwap(rootTs[0][0], tMid, pt2);
-    return true;
-}
-
-static bool is_linear_inner(const SkDQuad& q1, double t1s, double t1e, const SkDQuad& q2,
-                            double t2s, double t2e, SkIntersections* i, bool* subDivide) {
-    SkDQuad hull = q1.subDivide(t1s, t1e);
-    SkDLine line = {{hull[2], hull[0]}};
-    const SkDLine* testLines[] = { &line, (const SkDLine*) &hull[0], (const SkDLine*) &hull[1] };
-    const size_t kTestCount = SK_ARRAY_COUNT(testLines);
-    SkSTArray<kTestCount * 2, double, true> tsFound;
-    for (size_t index = 0; index < kTestCount; ++index) {
-        SkIntersections rootTs;
-        rootTs.allowNear(false);
-        int roots = rootTs.intersect(q2, *testLines[index]);
-        for (int idx2 = 0; idx2 < roots; ++idx2) {
-            double t = rootTs[0][idx2];
-#if 0 // def SK_DEBUG   // FIXME : accurate for error = 16, error of 17.5 seen
-// {{{136.08723965397621, 1648.2814535211637}, {593.49031197259478, 1190.8784277439891}, {593.49031197259478, 544.0128173828125}}}
-// {{{-968.181396484375, 544.0128173828125}, {592.2825927734375, 870.552490234375}, {593.435302734375, 557.8828125}}}
-
-            SkDPoint qPt = q2.ptAtT(t);
-            SkDPoint lPt = testLines[index]->ptAtT(rootTs[1][idx2]);
-            SkASSERT(qPt.approximatelyDEqual(lPt));
-#endif
-            if (approximately_negative(t - t2s) || approximately_positive(t - t2e)) {
-                continue;
-            }
-            tsFound.push_back(rootTs[0][idx2]);
-        }
-    }
-    int tCount = tsFound.count();
-    if (tCount <= 0) {
-        return true;
-    }
-    double tMin, tMax;
-    if (tCount == 1) {
-        tMin = tMax = tsFound[0];
-    } else {
-        SkASSERT(tCount > 1);
-        SkTQSort<double>(tsFound.begin(), tsFound.end() - 1);
-        tMin = tsFound[0];
-        tMax = tsFound[tsFound.count() - 1];
-    }
-    SkDPoint end = q2.ptAtT(t2s);
-    bool startInTriangle = hull.pointInHull(end);
-    if (startInTriangle) {
-        tMin = t2s;
-    }
-    end = q2.ptAtT(t2e);
-    bool endInTriangle = hull.pointInHull(end);
-    if (endInTriangle) {
-        tMax = t2e;
-    }
-    int split = 0;
-    SkDVector dxy1, dxy2;
-    if (tMin != tMax || tCount > 2) {
-        dxy2 = q2.dxdyAtT(tMin);
-        for (int index = 1; index < tCount; ++index) {
-            dxy1 = dxy2;
-            dxy2 = q2.dxdyAtT(tsFound[index]);
-            double dot = dxy1.dot(dxy2);
-            if (dot < 0) {
-                split = index - 1;
-                break;
-            }
-        }
-    }
-    if (split == 0) {  // there's one point
-        if (add_intercept(q1, q2, tMin, tMax, i, subDivide)) {
-            return true;
-        }
-        i->swap();
-        return is_linear_inner(q2, tMin, tMax, q1, t1s, t1e, i, subDivide);
-    }
-    // At this point, we have two ranges of t values -- treat each separately at the split
-    bool result;
-    if (add_intercept(q1, q2, tMin, tsFound[split - 1], i, subDivide)) {
-        result = true;
-    } else {
-        i->swap();
-        result = is_linear_inner(q2, tMin, tsFound[split - 1], q1, t1s, t1e, i, subDivide);
-    }
-    if (add_intercept(q1, q2, tsFound[split], tMax, i, subDivide)) {
-        result = true;
-    } else {
-        i->swap();
-        result |= is_linear_inner(q2, tsFound[split], tMax, q1, t1s, t1e, i, subDivide);
-    }
-    return result;
-}
-
-static double flat_measure(const SkDQuad& q) {
-    SkDVector mid = q[1] - q[0];
-    SkDVector dxy = q[2] - q[0];
-    double length = dxy.length();  // OPTIMIZE: get rid of sqrt
-    return fabs(mid.cross(dxy) / length);
-}
-
-// FIXME ? should this measure both and then use the quad that is the flattest as the line?
-static bool is_linear(const SkDQuad& q1, const SkDQuad& q2, SkIntersections* i) {
-    if (i->flatMeasure()) {
-        // for backward compatibility, use the old method when called from cubics
-        // FIXME: figure out how to fix cubics when it calls the new path
-        double measure = flat_measure(q1);
-        // OPTIMIZE: (get rid of sqrt) use approximately_zero
-        if (!approximately_zero_sqrt(measure)) {  // approximately_zero_sqrt
-            return false;
-        }
-     } else {
-        if (!q1.isLinear(0, 2)) {
-            return false;
-        }
-    }
-    return is_linear_inner(q1, 0, 1, q2, 0, 1, i, NULL);
-}
-
-// FIXME: if flat measure is sufficiently large, then probably the quartic solution failed
-// avoid imprecision incurred with chopAt
-static void relaxed_is_linear(const SkDQuad* q1, double s1, double e1, const SkDQuad* q2,
-        double s2, double e2, SkIntersections* i) {
-    double m1 = flat_measure(*q1);
-    double m2 = flat_measure(*q2);
-    i->reset();
-    const SkDQuad* rounder, *flatter;
-    double sf, midf, ef, sr, er;
-    if (m2 < m1) {
-        rounder = q1;
-        sr = s1;
-        er = e1;
-        flatter = q2;
-        sf = s2;
-        midf = (s2 + e2) / 2;
-        ef = e2;
-    } else {
-        rounder = q2;
-        sr = s2;
-        er = e2;
-        flatter = q1;
-        sf = s1;
-        midf = (s1 + e1) / 2;
-        ef = e1;
-    }
-    bool subDivide = false;
-    is_linear_inner(*flatter, sf, ef, *rounder, sr, er, i, &subDivide);
-    if (subDivide) {
-        relaxed_is_linear(flatter, sf, midf, rounder, sr, er, i);
-        relaxed_is_linear(flatter, midf, ef, rounder, sr, er, i);
-    }
-    if (m2 < m1) {
-        i->swapPts();
-    }
-}
-
-// each time through the loop, this computes values it had from the last loop
-// if i == j == 1, the center values are still good
-// otherwise, for i != 1 or j != 1, four of the values are still good
-// and if i == 1 ^ j == 1, an additional value is good
-static bool binary_search(const SkDQuad& quad1, const SkDQuad& quad2, double* t1Seed,
-                          double* t2Seed, SkDPoint* pt) {
-    double tStep = ROUGH_EPSILON;
-    SkDPoint t1[3], t2[3];
-    int calcMask = ~0;
-    do {
-        if (calcMask & (1 << 1)) t1[1] = quad1.ptAtT(*t1Seed);
-        if (calcMask & (1 << 4)) t2[1] = quad2.ptAtT(*t2Seed);
-        if (t1[1].approximatelyEqual(t2[1])) {
-            *pt = t1[1];
-    #if ONE_OFF_DEBUG
-            SkDebugf("%s t1=%1.9g t2=%1.9g (%1.9g,%1.9g) == (%1.9g,%1.9g)\n", __FUNCTION__,
-                    t1Seed, t2Seed, t1[1].fX, t1[1].fY, t2[1].fX, t2[1].fY);
-    #endif
-            if (*t1Seed < 0) {
-                *t1Seed = 0;
-            } else if (*t1Seed > 1) {
-                *t1Seed = 1;
-            }
-            if (*t2Seed < 0) {
-                *t2Seed = 0;
-            } else if (*t2Seed > 1) {
-                *t2Seed = 1;
-            }
-            return true;
-        }
-        if (calcMask & (1 << 0)) t1[0] = quad1.ptAtT(SkTMax(0., *t1Seed - tStep));
-        if (calcMask & (1 << 2)) t1[2] = quad1.ptAtT(SkTMin(1., *t1Seed + tStep));
-        if (calcMask & (1 << 3)) t2[0] = quad2.ptAtT(SkTMax(0., *t2Seed - tStep));
-        if (calcMask & (1 << 5)) t2[2] = quad2.ptAtT(SkTMin(1., *t2Seed + tStep));
-        double dist[3][3];
-        // OPTIMIZE: using calcMask value permits skipping some distance calcuations
-        //   if prior loop's results are moved to correct slot for reuse
-        dist[1][1] = t1[1].distanceSquared(t2[1]);
-        int best_i = 1, best_j = 1;
-        for (int i = 0; i < 3; ++i) {
-            for (int j = 0; j < 3; ++j) {
-                if (i == 1 && j == 1) {
-                    continue;
-                }
-                dist[i][j] = t1[i].distanceSquared(t2[j]);
-                if (dist[best_i][best_j] > dist[i][j]) {
-                    best_i = i;
-                    best_j = j;
-                }
-            }
-        }
-        if (best_i == 1 && best_j == 1) {
-            tStep /= 2;
-            if (tStep < FLT_EPSILON_HALF) {
-                break;
-            }
-            calcMask = (1 << 0) | (1 << 2) | (1 << 3) | (1 << 5);
-            continue;
-        }
-        if (best_i == 0) {
-            *t1Seed -= tStep;
-            t1[2] = t1[1];
-            t1[1] = t1[0];
-            calcMask = 1 << 0;
-        } else if (best_i == 2) {
-            *t1Seed += tStep;
-            t1[0] = t1[1];
-            t1[1] = t1[2];
-            calcMask = 1 << 2;
-        } else {
-            calcMask = 0;
-        }
-        if (best_j == 0) {
-            *t2Seed -= tStep;
-            t2[2] = t2[1];
-            t2[1] = t2[0];
-            calcMask |= 1 << 3;
-        } else if (best_j == 2) {
-            *t2Seed += tStep;
-            t2[0] = t2[1];
-            t2[1] = t2[2];
-            calcMask |= 1 << 5;
-        }
-    } while (true);
-#if ONE_OFF_DEBUG
-    SkDebugf("%s t1=%1.9g t2=%1.9g (%1.9g,%1.9g) != (%1.9g,%1.9g) %s\n", __FUNCTION__,
-        t1Seed, t2Seed, t1[1].fX, t1[1].fY, t1[2].fX, t1[2].fY);
-#endif
-    return false;
-}
-
-static void lookNearEnd(const SkDQuad& q1, const SkDQuad& q2, int testT,
-        const SkIntersections& orig, bool swap, SkIntersections* i) {
-    if (orig.used() == 1 && orig[!swap][0] == testT) {
-        return;
-    }
-    if (orig.used() == 2 && orig[!swap][1] == testT) {
-        return;
-    }
-    SkDLine tmpLine;
-    int testTIndex = testT << 1;
-    tmpLine[0] = tmpLine[1] = q2[testTIndex];
-    tmpLine[1].fX += q2[1].fY - q2[testTIndex].fY;
-    tmpLine[1].fY -= q2[1].fX - q2[testTIndex].fX;
-    SkIntersections impTs;
-    impTs.intersectRay(q1, tmpLine);
-    for (int index = 0; index < impTs.used(); ++index) {
-        SkDPoint realPt = impTs.pt(index);
-        if (!tmpLine[0].approximatelyPEqual(realPt)) {
-            continue;
-        }
-        if (swap) {
-            i->insert(testT, impTs[0][index], tmpLine[0]);
-        } else {
-            i->insert(impTs[0][index], testT, tmpLine[0]);
-        }
-    }
-}
-
-int SkIntersections::intersect(const SkDQuad& q1, const SkDQuad& q2) {
-    fMax = 4;
-    bool exactMatch = false;
-    // if the quads share an end point, check to see if they overlap
-    for (int i1 = 0; i1 < 3; i1 += 2) {
-        for (int i2 = 0; i2 < 3; i2 += 2) {
-            if (q1[i1].asSkPoint() == q2[i2].asSkPoint()) {
-                insert(i1 >> 1, i2 >> 1, q1[i1]);
-                exactMatch = true;
-            }
-        }
-    }
-    SkASSERT(fUsed < 3);
-    if (only_end_pts_in_common(q1, q2)) {
-        return fUsed;
-    }
-    if (only_end_pts_in_common(q2, q1)) {
-        return fUsed;
-    }
-    // see if either quad is really a line
-    // FIXME: figure out why reduce step didn't find this earlier
-    if (is_linear(q1, q2, this)) {
-        return fUsed;
-    }
-    SkIntersections swapped;
-    swapped.setMax(fMax);
-    if (is_linear(q2, q1, &swapped)) {
-        swapped.swapPts();
-        *this = swapped;
-        return fUsed;
-    }
-    SkIntersections copyI(*this);
-    lookNearEnd(q1, q2, 0, *this, false, &copyI);
-    lookNearEnd(q1, q2, 1, *this, false, &copyI);
-    lookNearEnd(q2, q1, 0, *this, true, &copyI);
-    lookNearEnd(q2, q1, 1, *this, true, &copyI);
-    int innerEqual = 0;
-    if (copyI.fUsed >= 2) {
-        SkASSERT(copyI.fUsed <= 4);
-        double width = copyI[0][1] - copyI[0][0];
-        int midEnd = 1;
-        for (int index = 2; index < copyI.fUsed; ++index) {
-            double testWidth = copyI[0][index] - copyI[0][index - 1];
-            if (testWidth <= width) {
-                continue;
-            }
-            midEnd = index;
-        }
-        for (int index = 0; index < 2; ++index) {
-            double testT = (copyI[0][midEnd] * (index + 1)
-                    + copyI[0][midEnd - 1] * (2 - index)) / 3;
-            SkDPoint testPt1 = q1.ptAtT(testT);
-            testT = (copyI[1][midEnd] * (index + 1) + copyI[1][midEnd - 1] * (2 - index)) / 3;
-            SkDPoint testPt2 = q2.ptAtT(testT);
-            innerEqual += testPt1.approximatelyEqual(testPt2);
-        }
-    }
-    bool expectCoincident = copyI.fUsed >= 2 && innerEqual == 2;
-    if (expectCoincident) {
-        reset();
-        insertCoincident(copyI[0][0], copyI[1][0], copyI.fPt[0]);
-        int last = copyI.fUsed - 1;
-        insertCoincident(copyI[0][last], copyI[1][last], copyI.fPt[last]);
-        return fUsed;
-    }
-    SkDQuadImplicit i1(q1);
-    SkDQuadImplicit i2(q2);
-    int index;
-    bool flip1 = q1[2] == q2[0];
-    bool flip2 = q1[0] == q2[2];
-    bool useCubic = q1[0] == q2[0];
-    double roots1[4];
-    int rootCount = findRoots(i2, q1, roots1, useCubic, flip1, 0);
-    // OPTIMIZATION: could short circuit here if all roots are < 0 or > 1
-    double roots1Copy[4];
-    SkDEBUGCODE(sk_bzero(roots1Copy, sizeof(roots1Copy)));
-    int r1Count = addValidRoots(roots1, rootCount, roots1Copy);
-    SkDPoint pts1[4];
-    for (index = 0; index < r1Count; ++index) {
-        pts1[index] = q1.ptAtT(roots1Copy[index]);
-    }
-    double roots2[4];
-    int rootCount2 = findRoots(i1, q2, roots2, useCubic, flip2, 0);
-    double roots2Copy[4];
-    int r2Count = addValidRoots(roots2, rootCount2, roots2Copy);
-    SkDPoint pts2[4];
-    for (index = 0; index < r2Count; ++index) {
-        pts2[index] = q2.ptAtT(roots2Copy[index]);
-    }
-    bool triedBinary = false;
-    if (r1Count == r2Count && r1Count <= 1) {
-        if (r1Count == 1 && used() == 0) {
-            if (pts1[0].approximatelyEqual(pts2[0])) {
-                insert(roots1Copy[0], roots2Copy[0], pts1[0]);
-            } else {
-                // find intersection by chasing t
-                triedBinary = true;
-                if (binary_search(q1, q2, roots1Copy, roots2Copy, pts1)) {
-                    insert(roots1Copy[0], roots2Copy[0], pts1[0]);
-                }
-            }
-        }
-        return fUsed;
-    }
-    int closest[4];
-    double dist[4];
-    bool foundSomething = false;
-    for (index = 0; index < r1Count; ++index) {
-        dist[index] = DBL_MAX;
-        closest[index] = -1;
-        for (int ndex2 = 0; ndex2 < r2Count; ++ndex2) {
-            if (!pts2[ndex2].approximatelyEqual(pts1[index])) {
-                continue;
-            }
-            double dx = pts2[ndex2].fX - pts1[index].fX;
-            double dy = pts2[ndex2].fY - pts1[index].fY;
-            double distance = dx * dx + dy * dy;
-            if (dist[index] <= distance) {
-                continue;
-            }
-            for (int outer = 0; outer < index; ++outer) {
-                if (closest[outer] != ndex2) {
-                    continue;
-                }
-                if (dist[outer] < distance) {
-                    goto next;
-                }
-                closest[outer] = -1;
-            }
-            dist[index] = distance;
-            closest[index] = ndex2;
-            foundSomething = true;
-        next:
-            ;
-        }
-    }
-    if (r1Count && r2Count && !foundSomething) {
-        if (exactMatch) {
-            SkASSERT(fUsed > 0);
-            return fUsed;
-        }
-        relaxed_is_linear(&q1, 0, 1, &q2, 0, 1, this);
-        if (fUsed) {
-            return fUsed;
-        }
-        // maybe the curves are nearly coincident
-        if (!triedBinary && binary_search(q1, q2, roots1Copy, roots2Copy, pts1)) {
-            insert(roots1Copy[0], roots2Copy[0], pts1[0]);
-        }
-        return fUsed;
-    }
-    int used = 0;
-    do {
-        double lowest = DBL_MAX;
-        int lowestIndex = -1;
-        for (index = 0; index < r1Count; ++index) {
-            if (closest[index] < 0) {
-                continue;
-            }
-            if (roots1Copy[index] < lowest) {
-                lowestIndex = index;
-                lowest = roots1Copy[index];
-            }
-        }
-        if (lowestIndex < 0) {
-            break;
-        }
-        insert(roots1Copy[lowestIndex], roots2Copy[closest[lowestIndex]],
-                pts1[lowestIndex]);
-        closest[lowestIndex] = -1;
-    } while (++used < r1Count);
-    return fUsed;
-}
-
-void SkIntersections::alignQuadPts(const SkPoint q1[3], const SkPoint q2[3]) {
-    for (int index = 0; index < used(); ++index) {
-        const SkPoint result = pt(index).asSkPoint();
-        if (q1[0] == result || q1[2] == result || q2[0] == result || q2[2] == result) {
-            continue;
-        }
-        if (SkDPoint::ApproximatelyEqual(q1[0], result)) {
-            fPt[index].set(q1[0]);
-//            SkASSERT(way_roughly_zero(fT[0][index]));  // this value can be bigger than way rough
-            fT[0][index] = 0;
-        } else if (SkDPoint::ApproximatelyEqual(q1[2], result)) {
-            fPt[index].set(q1[2]);
-//            SkASSERT(way_roughly_equal(fT[0][index], 1));
-            fT[0][index] = 1;
-        }
-        if (SkDPoint::ApproximatelyEqual(q2[0], result)) {
-            fPt[index].set(q2[0]);
-//            SkASSERT(way_roughly_zero(fT[1][index]));
-            fT[1][index] = 0;
-        } else if (SkDPoint::ApproximatelyEqual(q2[2], result)) {
-            fPt[index].set(q2[2]);
-//            SkASSERT(way_roughly_equal(fT[1][index], 1));
-            fT[1][index] = 1;
-        }
-    }
-}
diff --git a/src/pathops/SkDQuadLineIntersection.cpp b/src/pathops/SkDQuadLineIntersection.cpp
index ef8edb0..b8a9a64 100644
--- a/src/pathops/SkDQuadLineIntersection.cpp
+++ b/src/pathops/SkDQuadLineIntersection.cpp
@@ -105,6 +105,29 @@
         fAllowNear = allow;
     }
 
+    void checkCoincident() {
+        int last = fIntersections->used() - 1;
+        for (int index = 0; index < last; ) {
+            double quadMidT = ((*fIntersections)[0][index] + (*fIntersections)[0][index + 1]) / 2;
+            SkDPoint quadMidPt = fQuad.ptAtT(quadMidT);
+            double t = fLine.nearPoint(quadMidPt, NULL);
+            if (t < 0) {
+                ++index;
+                continue;
+            }
+            if (fIntersections->isCoincident(index)) {
+                fIntersections->removeOne(index);
+                --last;
+            } else if (fIntersections->isCoincident(index + 1)) {
+                fIntersections->removeOne(index + 1);
+                --last;
+            } else {
+                fIntersections->setCoincident(index++);
+            }
+            fIntersections->setCoincident(index);
+        }
+    }
+
     int intersectRay(double roots[2]) {
     /*
         solve by rotating line+quad so line is horizontal, then finding the roots
@@ -140,20 +163,17 @@
         if (fAllowNear) {
             addNearEndPoints();
         }
-        if (fIntersections->used() == 2) {
-            // FIXME : need sharable code that turns spans into coincident if middle point is on
-        } else {
-            double rootVals[2];
-            int roots = intersectRay(rootVals);
-            for (int index = 0; index < roots; ++index) {
-                double quadT = rootVals[index];
-                double lineT = findLineT(quadT);
-                SkDPoint pt;
-                if (pinTs(&quadT, &lineT, &pt, kPointUninitialized)) {
-                    fIntersections->insert(quadT, lineT, pt);
-                }
+        double rootVals[2];
+        int roots = intersectRay(rootVals);
+        for (int index = 0; index < roots; ++index) {
+            double quadT = rootVals[index];
+            double lineT = findLineT(quadT);
+            SkDPoint pt;
+            if (pinTs(&quadT, &lineT, &pt, kPointUninitialized) && uniqueAnswer(quadT, pt)) {
+                fIntersections->insert(quadT, lineT, pt);
             }
         }
+        checkCoincident();
         return fIntersections->used();
     }
 
@@ -178,16 +198,41 @@
             double quadT = rootVals[index];
             SkDPoint pt = fQuad.ptAtT(quadT);
             double lineT = (pt.fX - left) / (right - left);
-            if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) {
+            if (pinTs(&quadT, &lineT, &pt, kPointInitialized) && uniqueAnswer(quadT, pt)) {
                 fIntersections->insert(quadT, lineT, pt);
             }
         }
         if (flipped) {
             fIntersections->flip();
         }
+        checkCoincident();
         return fIntersections->used();
     }
 
+    bool uniqueAnswer(double quadT, const SkDPoint& pt) {
+        for (int inner = 0; inner < fIntersections->used(); ++inner) {
+            if (fIntersections->pt(inner) != pt) {
+                continue;
+            }
+            double existingQuadT = (*fIntersections)[0][inner];
+            if (quadT == existingQuadT) {
+                return false;
+            }
+            // check if midway on quad is also same point. If so, discard this
+            double quadMidT = (existingQuadT + quadT) / 2;
+            SkDPoint quadMidPt = fQuad.ptAtT(quadMidT);
+            if (quadMidPt.approximatelyEqual(pt)) {
+                return false;
+            }
+        }
+#if ONE_OFF_DEBUG
+        SkDPoint qPt = fQuad.ptAtT(quadT);
+        SkDebugf("%s pt=(%1.9g,%1.9g) cPt=(%1.9g,%1.9g)\n", __FUNCTION__, pt.fX, pt.fY,
+                qPt.fX, qPt.fY);
+#endif
+        return true;
+    }
+
     int verticalIntersect(double axisIntercept, double roots[2]) {
         double D = fQuad[2].fX;  // f
         double E = fQuad[1].fX;  // e
@@ -209,13 +254,14 @@
             double quadT = rootVals[index];
             SkDPoint pt = fQuad.ptAtT(quadT);
             double lineT = (pt.fY - top) / (bottom - top);
-            if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) {
+            if (pinTs(&quadT, &lineT, &pt, kPointInitialized) && uniqueAnswer(quadT, pt)) {
                 fIntersections->insert(quadT, lineT, pt);
             }
         }
         if (flipped) {
             fIntersections->flip();
         }
+        checkCoincident();
         return fIntersections->used();
     }
 
diff --git a/src/pathops/SkIntersectionHelper.h b/src/pathops/SkIntersectionHelper.h
index 3569c93..c633fd0 100644
--- a/src/pathops/SkIntersectionHelper.h
+++ b/src/pathops/SkIntersectionHelper.h
@@ -5,6 +5,7 @@
  * found in the LICENSE file.
  */
 #include "SkOpContour.h"
+#include "SkOpSegment.h"
 #include "SkPath.h"
 
 #ifdef SK_DEBUG
@@ -21,42 +22,9 @@
         kCubic_Segment = SkPath::kCubic_Verb,
     };
 
-    bool addCoincident(SkIntersectionHelper& other, const SkIntersections& ts, bool swap) {
-        return fContour->addCoincident(fIndex, other.fContour, other.fIndex, ts, swap);
-    }
-
-    // FIXME: does it make sense to write otherIndex now if we're going to
-    // fix it up later?
-    void addOtherT(int index, double otherT, int otherIndex) {
-        fContour->addOtherT(fIndex, index, otherT, otherIndex);
-    }
-
-    bool addPartialCoincident(SkIntersectionHelper& other, const SkIntersections& ts, int index,
-            bool swap) {
-        return fContour->addPartialCoincident(fIndex, other.fContour, other.fIndex, ts, index,
-                swap);
-    }
-
-    // Avoid collapsing t values that are close to the same since
-    // we walk ts to describe consecutive intersections. Since a pair of ts can
-    // be nearly equal, any problems caused by this should be taken care
-    // of later.
-    // On the edge or out of range values are negative; add 2 to get end
-    int addT(const SkIntersectionHelper& other, const SkPoint& pt, double newT) {
-        return fContour->addT(fIndex, other.fContour, other.fIndex, pt, newT);
-    }
-
-    int addSelfT(const SkPoint& pt, double newT) {
-        return fContour->addSelfT(fIndex, pt, newT);
-    }
-
     bool advance() {
-        return ++fIndex < fLast;
-    }
-
-    void alignTPt(SkIntersectionHelper& other, bool swap, int index,
-            SkIntersections* ts, SkPoint* point) {
-        fContour->alignTPt(fIndex, other.fContour, other.fIndex, swap, index, ts, point);
+        fSegment = fSegment->next();
+        return fSegment != NULL;
     }
 
     SkScalar bottom() const {
@@ -64,30 +32,15 @@
     }
 
     const SkPathOpsBounds& bounds() const {
-        return fContour->segments()[fIndex].bounds();
+        return fSegment->bounds();
+    }
+
+    SkOpContour* contour() const {
+        return fSegment->contour();
     }
 
     void init(SkOpContour* contour) {
-        fContour = contour;
-        fIndex = 0;
-        fLast = contour->segments().count();
-    }
-
-    bool isAdjacent(const SkIntersectionHelper& next) {
-        return fContour == next.fContour && fIndex + 1 == next.fIndex;
-    }
-
-    bool isFirstLast(const SkIntersectionHelper& next) {
-        return fContour == next.fContour && fIndex == 0
-                && next.fIndex == fLast - 1;
-    }
-
-    bool isPartial(double t1, double t2, const SkDPoint& pt1, const SkDPoint& pt2) const {
-        const SkOpSegment& segment = fContour->segments()[fIndex];
-        double mid = (t1 + t2) / 2;
-        SkDPoint midPtByT = segment.dPtAtT(mid);
-        SkDPoint midPtByAvg = SkDPoint::Mid(pt1, pt2);
-        return midPtByT.approximatelyPEqual(midPtByAvg);
+        fSegment = contour->first();
     }
 
     SkScalar left() const {
@@ -95,41 +48,40 @@
     }
 
     const SkPoint* pts() const {
-        return fContour->segments()[fIndex].pts();
+        return fSegment->pts();
     }
 
     SkScalar right() const {
         return bounds().fRight;
     }
 
+    SkOpSegment* segment() const {
+        return fSegment;
+    }
+
     SegmentType segmentType() const {
-        const SkOpSegment& segment = fContour->segments()[fIndex];
-        SegmentType type = (SegmentType) segment.verb();
+        SegmentType type = (SegmentType) fSegment->verb();
         if (type != kLine_Segment) {
             return type;
         }
-        if (segment.isHorizontal()) {
+        if (fSegment->isHorizontal()) {
             return kHorizontalLine_Segment;
         }
-        if (segment.isVertical()) {
+        if (fSegment->isVertical()) {
             return kVerticalLine_Segment;
         }
         return kLine_Segment;
     }
 
     bool startAfter(const SkIntersectionHelper& after) {
-        fIndex = after.fIndex;
-        return advance();
+        fSegment = after.fSegment->next();
+        return fSegment != NULL;
     }
 
     SkScalar top() const {
         return bounds().fTop;
     }
 
-    SkPath::Verb verb() const {
-        return fContour->segments()[fIndex].verb();
-    }
-
     SkScalar x() const {
         return bounds().fLeft;
     }
@@ -147,10 +99,5 @@
     }
 
 private:
-    // utility callable by the user from the debugger when the implementation code is linked in
-    void dump() const;
-
-    SkOpContour* fContour;
-    int fIndex;
-    int fLast;
+    SkOpSegment* fSegment;
 };
diff --git a/src/pathops/SkIntersections.cpp b/src/pathops/SkIntersections.cpp
index e9875cf..007efa7 100644
--- a/src/pathops/SkIntersections.cpp
+++ b/src/pathops/SkIntersections.cpp
@@ -7,26 +7,25 @@
 
 #include "SkIntersections.h"
 
-void SkIntersections::append(const SkIntersections& i) {
-    for (int index = 0; index < i.fUsed; ++index) {
-        insert(i[0][index], i[1][index], i.pt(index));
+int SkIntersections::closestTo(double rangeStart, double rangeEnd, const SkDPoint& testPt,
+        double* closestDist) const {
+    int closest = -1;
+    *closestDist = SK_ScalarMax;
+    for (int index = 0; index < fUsed; ++index) {
+        if (!between(rangeStart, fT[0][index], rangeEnd)) {
+            continue;
+        }
+        const SkDPoint& iPt = fPt[index];
+        double dist = testPt.distanceSquared(iPt);
+        if (*closestDist > dist) {
+            *closestDist = dist;
+            closest = index;
+        }
     }
+    return closest;
 }
 
-int (SkIntersections::* const CurveVertical[])(const SkPoint[], SkScalar, SkScalar, SkScalar, bool) = {
-    NULL,
-    &SkIntersections::verticalLine,
-    &SkIntersections::verticalQuad,
-    &SkIntersections::verticalCubic
-};
-
-int ( SkIntersections::* const CurveRay[])(const SkPoint[], const SkDLine&) = {
-    NULL,
-    &SkIntersections::lineRay,
-    &SkIntersections::quadRay,
-    &SkIntersections::cubicRay
-};
-
+// called only by test code
 int SkIntersections::coincidentUsed() const {
     if (!fIsCoincident[0]) {
         SkASSERT(!fIsCoincident[1]);
@@ -48,12 +47,12 @@
     return count;
 }
 
-int SkIntersections::cubicRay(const SkPoint pts[4], const SkDLine& line) {
-    SkDCubic cubic;
-    cubic.set(pts);
-    fMax = 3;
-    return intersectRay(cubic, line);
-}
+int (SkIntersections::* const CurveVertical[])(const SkPoint[], SkScalar, SkScalar, SkScalar, bool) = {
+    NULL,
+    &SkIntersections::verticalLine,
+    &SkIntersections::verticalQuad,
+    &SkIntersections::verticalCubic
+};
 
 void SkIntersections::flip() {
     for (int index = 0; index < fUsed; ++index) {
@@ -105,7 +104,6 @@
     int remaining = fUsed - index;
     if (remaining > 0) {
         memmove(&fPt[index + 1], &fPt[index], sizeof(fPt[0]) * remaining);
-        memmove(&fPt2[index + 1], &fPt2[index], sizeof(fPt2[0]) * remaining);
         memmove(&fT[0][index + 1], &fT[0][index], sizeof(fT[0][0]) * remaining);
         memmove(&fT[1][index + 1], &fT[1][index], sizeof(fT[1][0]) * remaining);
         int clearMask = ~((1 << index) - 1);
@@ -125,39 +123,53 @@
     SkASSERT(one == 0 || one == 1);
     SkASSERT(two == 0 || two == 1);
     SkASSERT(pt1 != pt2);
-    SkASSERT(fNearlySame[(int) one]);
+    fNearlySame[one ? 1 : 0] = true;
     (void) insert(one, two, pt1);
-    fPt2[one ? fUsed - 1 : 0] = pt2;
+    fPt2[one ? 1 : 0] = pt2;
 }
 
-void SkIntersections::insertCoincident(double one, double two, const SkDPoint& pt) {
+int SkIntersections::insertCoincident(double one, double two, const SkDPoint& pt) {
     int index = insertSwap(one, two, pt);
+    if (index >= 0) {
+        setCoincident(index);
+    }
+    return index;
+}
+
+void SkIntersections::setCoincident(int index) {
+    SkASSERT(index >= 0);
     int bit = 1 << index;
     fIsCoincident[0] |= bit;
     fIsCoincident[1] |= bit;
 }
 
-int SkIntersections::lineRay(const SkPoint pts[2], const SkDLine& line) {
-    SkDLine l;
-    l.set(pts);
-    fMax = 2;
-    return intersectRay(l, line);
+void SkIntersections::merge(const SkIntersections& a, int aIndex, const SkIntersections& b,
+        int bIndex) {
+    this->reset();
+    fT[0][0] = a.fT[0][aIndex];
+    fT[1][0] = b.fT[0][bIndex];
+    fPt[0] = a.fPt[aIndex];
+    fPt2[0] = b.fPt[bIndex];
+    fUsed = 1;
 }
 
-void SkIntersections::offset(int base, double start, double end) {
-    for (int index = base; index < fUsed; ++index) {
-        double val = fT[fSwap][index];
-        val *= end - start;
-        val += start;
-        fT[fSwap][index] = val;
+int SkIntersections::mostOutside(double rangeStart, double rangeEnd, const SkDPoint& origin) const {
+    int result = -1;
+    for (int index = 0; index < fUsed; ++index) {
+        if (!between(rangeStart, fT[0][index], rangeEnd)) {
+            continue;
+        }
+        if (result < 0) {
+            result = index;
+            continue;
+        }
+        SkDVector best = fPt[result] - origin;
+        SkDVector test = fPt[index] - origin;
+        if (test.crossCheck(best) < 0) {
+            result = index;
+        }
     }
-}
-
-int SkIntersections::quadRay(const SkPoint pts[3], const SkDLine& line) {
-    SkDQuad quad;
-    quad.set(pts);
-    fMax = 2;
-    return intersectRay(quad, line);
+    return result;
 }
 
 void SkIntersections::quickRemoveOne(int index, int replace) {
@@ -172,7 +184,6 @@
         return;
     }
     memmove(&fPt[index], &fPt[index + 1], sizeof(fPt[0]) * remaining);
-    memmove(&fPt2[index], &fPt2[index + 1], sizeof(fPt2[0]) * remaining);
     memmove(&fT[0][index], &fT[0][index + 1], sizeof(fT[0][0]) * remaining);
     memmove(&fT[1][index], &fT[1][index + 1], sizeof(fT[1][0]) * remaining);
 //    SkASSERT(fIsCoincident[0] == 0);
@@ -182,13 +193,6 @@
     fIsCoincident[1] -= ((fIsCoincident[1] >> 1) & ~((1 << index) - 1)) + coBit;
 }
 
-void SkIntersections::swapPts() {
-    int index;
-    for (index = 0; index < fUsed; ++index) {
-        SkTSwap(fT[0][index], fT[1][index]);
-    }
-}
-
 int SkIntersections::verticalLine(const SkPoint a[2], SkScalar top, SkScalar bottom,
         SkScalar x, bool flipped) {
     SkDLine line;
diff --git a/src/pathops/SkIntersections.h b/src/pathops/SkIntersections.h
index a1bde51..15bac19 100644
--- a/src/pathops/SkIntersections.h
+++ b/src/pathops/SkIntersections.h
@@ -16,7 +16,6 @@
 public:
     SkIntersections()
         : fSwap(0)
-        , fFlatMeasure(false)
 #ifdef SK_DEBUG
         , fDepth(0)
 #endif
@@ -24,7 +23,6 @@
         sk_bzero(fPt, sizeof(fPt));
         sk_bzero(fPt2, sizeof(fPt2));
         sk_bzero(fT, sizeof(fT));
-        sk_bzero(fIsCoincident, sizeof(fIsCoincident));
         sk_bzero(fNearlySame, sizeof(fNearlySame));
         reset();
         fMax = 0;  // require that the caller set the max
@@ -32,7 +30,7 @@
 
     class TArray {
     public:
-        explicit TArray(const double ts[9]) : fTArray(ts) {}
+        explicit TArray(const double ts[10]) : fTArray(ts) {}
         double operator[](int n) const {
             return fTArray[n];
         }
@@ -40,28 +38,15 @@
     };
     TArray operator[](int n) const { return TArray(fT[n]); }
 
-    void allowFlatMeasure(bool flatAllowed) {
-        fFlatMeasure = flatAllowed;
-    }
-
     void allowNear(bool nearAllowed) {
         fAllowNear = nearAllowed;
     }
 
-    int cubic(const SkPoint a[4]) {
-        SkDCubic cubic;
-        cubic.set(a);
-        fMax = 1;  // self intersect
-        return intersect(cubic);
-    }
-
-    int cubicCubic(const SkPoint a[4], const SkPoint b[4]) {
-        SkDCubic aCubic;
-        aCubic.set(a);
-        SkDCubic bCubic;
-        bCubic.set(b);
-        fMax = 9;
-        return intersect(aCubic, bCubic);
+    void clearCoincidence(int index) {
+        SkASSERT(index >= 0);
+        int bit = 1 << index;
+        fIsCoincident[0] &= ~bit;
+        fIsCoincident[1] &= ~bit;
     }
 
     int cubicHorizontal(const SkPoint a[4], SkScalar left, SkScalar right, SkScalar y,
@@ -88,19 +73,6 @@
         return intersect(cubic, line);
     }
 
-    int cubicQuad(const SkPoint a[4], const SkPoint b[3]) {
-        SkDCubic cubic;
-        cubic.set(a);
-        SkDQuad quad;
-        quad.set(b);
-        fMax = 7;
-        return intersect(cubic, quad);
-    }
-
-    bool flatMeasure() const {
-        return fFlatMeasure;
-    }
-
     bool hasT(double t) const {
         SkASSERT(t == 0 || t == 1);
         return fUsed > 0 && (t == 0 ? fT[0][0] == 0 : fT[0][fUsed - 1] == 1);
@@ -178,19 +150,11 @@
         return intersect(quad, line);
     }
 
-    int quadQuad(const SkPoint a[3], const SkPoint b[3]) {
-        SkDQuad aQuad;
-        aQuad.set(a);
-        SkDQuad bQuad;
-        bQuad.set(b);
-        fMax = 4;
-        return intersect(aQuad, bQuad);
-    }
-
     // leaves swap, max alone
     void reset() {
         fAllowNear = true;
         fUsed = 0;
+        sk_bzero(fIsCoincident, sizeof(fIsCoincident));
     }
 
     void set(bool swap, int tIndex, double t) {
@@ -205,8 +169,6 @@
         fSwap ^= true;
     }
 
-    void swapPts();
-
     bool swapped() const {
         return fSwap;
     }
@@ -219,19 +181,27 @@
         SkASSERT(--fDepth >= 0);
     }
 
+    bool unBumpT(int index) {
+        SkASSERT(fUsed == 1);
+        fT[0][index] = fT[0][index] * (1 + BUMP_EPSILON * 2) - BUMP_EPSILON;
+        if (!between(0, fT[0][index], 1)) {
+            fUsed = 0;
+            return false;
+        }
+        return true;
+    }
+
     void upDepth() {
         SkASSERT(++fDepth < 16);
     }
 
     void alignQuadPts(const SkPoint a[3], const SkPoint b[3]);
-    void append(const SkIntersections& );
     int cleanUpCoincidence();
+    int closestTo(double rangeStart, double rangeEnd, const SkDPoint& testPt, double* dist) const;
     int coincidentUsed() const;
     void cubicInsert(double one, double two, const SkDPoint& pt, const SkDCubic& c1,
                      const SkDCubic& c2);
-    int cubicRay(const SkPoint pts[4], const SkDLine& line);
     void flip();
-    int horizontal(const SkDLine&, double y);
     int horizontal(const SkDLine&, double left, double right, double y, bool flipped);
     int horizontal(const SkDQuad&, double left, double right, double y, bool flipped);
     int horizontal(const SkDQuad&, double left, double right, double y, double tRange[2]);
@@ -242,25 +212,20 @@
     int insert(double one, double two, const SkDPoint& pt);
     void insertNear(double one, double two, const SkDPoint& pt1, const SkDPoint& pt2);
     // start if index == 0 : end if index == 1
-    void insertCoincident(double one, double two, const SkDPoint& pt);
+    int insertCoincident(double one, double two, const SkDPoint& pt);
     int intersect(const SkDLine&, const SkDLine&);
     int intersect(const SkDQuad&, const SkDLine&);
     int intersect(const SkDQuad&, const SkDQuad&);
-    int intersect(const SkDCubic&);  // return true if cubic self-intersects
     int intersect(const SkDCubic&, const SkDLine&);
-    int intersect(const SkDCubic&, const SkDQuad&);
     int intersect(const SkDCubic&, const SkDCubic&);
     int intersectRay(const SkDLine&, const SkDLine&);
     int intersectRay(const SkDQuad&, const SkDLine&);
     int intersectRay(const SkDCubic&, const SkDLine&);
-    static SkDPoint Line(const SkDLine&, const SkDLine&);
-    int lineRay(const SkPoint pts[2], const SkDLine& line);
-    void offset(int base, double start, double end);
+    void merge(const SkIntersections& , int , const SkIntersections& , int );
+    int mostOutside(double rangeStart, double rangeEnd, const SkDPoint& origin) const;
     void quickRemoveOne(int index, int replace);
-    int quadRay(const SkPoint pts[3], const SkDLine& line);
     void removeOne(int index);
-    static bool Test(const SkDLine& , const SkDLine&);
-    int vertical(const SkDLine&, double x);
+    void setCoincident(int index);
     int vertical(const SkDLine&, double top, double bottom, double x, bool flipped);
     int vertical(const SkDQuad&, double top, double bottom, double x, bool flipped);
     int vertical(const SkDCubic&, double top, double bottom, double x, bool flipped);
@@ -276,6 +241,8 @@
 #endif
     }
 
+    void dump() const;  // implemented for testing only
+
 private:
     bool cubicCheckCoincidence(const SkDCubic& c1, const SkDCubic& c2);
     bool cubicExactEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2);
@@ -283,22 +250,20 @@
     void cleanUpParallelLines(bool parallel);
     void computePoints(const SkDLine& line, int used);
 
-    SkDPoint fPt[9];  // FIXME: since scans store points as SkPoint, this should also
-    SkDPoint fPt2[9];  // used by nearly same to store alternate intersection point
-    double fT[2][9];
+    SkDPoint fPt[10];  // FIXME: since scans store points as SkPoint, this should also
+    SkDPoint fPt2[2];  // used by nearly same to store alternate intersection point
+    double fT[2][10];
     uint16_t fIsCoincident[2];  // bit set for each curve's coincident T
     bool fNearlySame[2];  // true if end points nearly match
     unsigned char fUsed;
     unsigned char fMax;
     bool fAllowNear;
     bool fSwap;
-    bool fFlatMeasure;  // backwards-compatibility when cubics uses quad intersection
 #ifdef SK_DEBUG
     int fDepth;
 #endif
 };
 
-extern int (SkIntersections::* const CurveRay[])(const SkPoint[], const SkDLine& );
 extern int (SkIntersections::* const CurveVertical[])(const SkPoint[], SkScalar top, SkScalar bottom,
             SkScalar x, bool flipped);
 
diff --git a/src/pathops/SkOpAngle.cpp b/src/pathops/SkOpAngle.cpp
index b3a188c..c13a51a 100644
--- a/src/pathops/SkOpAngle.cpp
+++ b/src/pathops/SkOpAngle.cpp
@@ -4,26 +4,26 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SkIntersections.h"
 #include "SkOpAngle.h"
 #include "SkOpSegment.h"
 #include "SkPathOpsCurve.h"
 #include "SkTSort.h"
 
-#if DEBUG_ANGLE
-#include "SkString.h"
-#endif
-
 /* Angles are sorted counterclockwise. The smallest angle has a positive x and the smallest
    positive y. The largest angle has a positive x and a zero y. */
 
 #if DEBUG_ANGLE
-    static bool CompareResult(SkString* bugOut, int append, bool compare) {
+    static bool CompareResult(const char* func, SkString* bugOut, SkString* bugPart, int append,
+             bool compare) {
         SkDebugf("%s %c %d\n", bugOut->c_str(), compare ? 'T' : 'F', append);
+        SkDebugf("%sPart %s\n", func, bugPart[0].c_str());
+        SkDebugf("%sPart %s\n", func, bugPart[1].c_str());
+        SkDebugf("%sPart %s\n", func, bugPart[2].c_str());
         return compare;
     }
 
-    #define COMPARE_RESULT(append, compare) CompareResult(&bugOut, append, compare)
+    #define COMPARE_RESULT(append, compare) CompareResult(__FUNCTION__, &bugOut, bugPart, append, \
+            compare)
 #else
     #define COMPARE_RESULT(append, compare) compare
 #endif
@@ -58,51 +58,50 @@
 */
 
 // return true if lh < this < rh
-bool SkOpAngle::after(const SkOpAngle* test) const {
-    const SkOpAngle& lh = *test;
-    const SkOpAngle& rh = *lh.fNext;
-    SkASSERT(&lh != &rh);
+bool SkOpAngle::after(SkOpAngle* test) {
+    SkOpAngle* lh = test;
+    SkOpAngle* rh = lh->fNext;
+    SkASSERT(lh != rh);
 #if DEBUG_ANGLE
     SkString bugOut;
     bugOut.printf("%s [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
                   " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
                   " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g ", __FUNCTION__,
-            lh.fSegment->debugID(), lh.debugID(), lh.fSectorStart, lh.fSectorEnd,
-            lh.fSegment->t(lh.fStart), lh.fSegment->t(lh.fEnd),
-            fSegment->debugID(), debugID(), fSectorStart, fSectorEnd, fSegment->t(fStart),
-            fSegment->t(fEnd),
-            rh.fSegment->debugID(), rh.debugID(), rh.fSectorStart, rh.fSectorEnd,
-            rh.fSegment->t(rh.fStart), rh.fSegment->t(rh.fEnd));
+            lh->segment()->debugID(), lh->debugID(), lh->fSectorStart, lh->fSectorEnd,
+            lh->fStart->t(), lh->fEnd->t(),
+            segment()->debugID(), debugID(), fSectorStart, fSectorEnd, fStart->t(), fEnd->t(),
+            rh->segment()->debugID(), rh->debugID(), rh->fSectorStart, rh->fSectorEnd,
+            rh->fStart->t(), rh->fEnd->t());
+    SkString bugPart[3] = { lh->debugPart(), this->debugPart(), rh->debugPart() };
 #endif
-    if (lh.fComputeSector && !const_cast<SkOpAngle&>(lh).computeSector()) {
+    if (lh->fComputeSector && !lh->computeSector()) {
         return COMPARE_RESULT(1, true);
     }
-    if (fComputeSector && !const_cast<SkOpAngle*>(this)->computeSector()) {
+    if (fComputeSector && !this->computeSector()) {
         return COMPARE_RESULT(2, true);
     }
-    if (rh.fComputeSector && !const_cast<SkOpAngle&>(rh).computeSector()) {
+    if (rh->fComputeSector && !rh->computeSector()) {
         return COMPARE_RESULT(3, true);
     }
 #if DEBUG_ANGLE  // reset bugOut with computed sectors
     bugOut.printf("%s [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
                   " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
                   " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g ", __FUNCTION__,
-            lh.fSegment->debugID(), lh.debugID(), lh.fSectorStart, lh.fSectorEnd,
-            lh.fSegment->t(lh.fStart), lh.fSegment->t(lh.fEnd),
-            fSegment->debugID(), debugID(), fSectorStart, fSectorEnd, fSegment->t(fStart),
-            fSegment->t(fEnd),
-            rh.fSegment->debugID(), rh.debugID(), rh.fSectorStart, rh.fSectorEnd,
-            rh.fSegment->t(rh.fStart), rh.fSegment->t(rh.fEnd));
+            lh->segment()->debugID(), lh->debugID(), lh->fSectorStart, lh->fSectorEnd,
+            lh->fStart->t(), lh->fEnd->t(),
+            segment()->debugID(), debugID(), fSectorStart, fSectorEnd, fStart->t(), fEnd->t(),
+            rh->segment()->debugID(), rh->debugID(), rh->fSectorStart, rh->fSectorEnd,
+            rh->fStart->t(), rh->fEnd->t());
 #endif
-    bool ltrOverlap = (lh.fSectorMask | rh.fSectorMask) & fSectorMask;
-    bool lrOverlap = lh.fSectorMask & rh.fSectorMask;
+    bool ltrOverlap = (lh->fSectorMask | rh->fSectorMask) & fSectorMask;
+    bool lrOverlap = lh->fSectorMask & rh->fSectorMask;
     int lrOrder;  // set to -1 if either order works
     if (!lrOverlap) {  // no lh/rh sector overlap
         if (!ltrOverlap) {  // no lh/this/rh sector overlap
-            return COMPARE_RESULT(4,  (lh.fSectorEnd > rh.fSectorStart)
-                    ^ (fSectorStart > lh.fSectorEnd) ^ (fSectorStart > rh.fSectorStart));
+            return COMPARE_RESULT(4,  (lh->fSectorEnd > rh->fSectorStart)
+                    ^ (fSectorStart > lh->fSectorEnd) ^ (fSectorStart > rh->fSectorStart));
         }
-        int lrGap = (rh.fSectorStart - lh.fSectorStart + 32) & 0x1f;
+        int lrGap = (rh->fSectorStart - lh->fSectorStart + 32) & 0x1f;
         /* A tiny change can move the start +/- 4. The order can only be determined if
            lr gap is not 12 to 20 or -12 to -20.
                -31 ..-21      1
@@ -115,24 +114,24 @@
          */
         lrOrder = lrGap > 20 ? 0 : lrGap > 11 ? -1 : 1;
     } else {
-        lrOrder = (int) lh.orderable(rh);
+        lrOrder = (int) lh->orderable(rh);
         if (!ltrOverlap) {
             return COMPARE_RESULT(5, !lrOrder);
         }
     }
     int ltOrder;
-    SkASSERT((lh.fSectorMask & fSectorMask) || (rh.fSectorMask & fSectorMask));
-    if (lh.fSectorMask & fSectorMask) {
-        ltOrder = (int) lh.orderable(*this);
+    SkASSERT((lh->fSectorMask & fSectorMask) || (rh->fSectorMask & fSectorMask));
+    if (lh->fSectorMask & fSectorMask) {
+        ltOrder = (int) lh->orderable(this);
     } else {
-        int ltGap = (fSectorStart - lh.fSectorStart + 32) & 0x1f;
+        int ltGap = (fSectorStart - lh->fSectorStart + 32) & 0x1f;
         ltOrder = ltGap > 20 ? 0 : ltGap > 11 ? -1 : 1;
     }
     int trOrder;
-    if (rh.fSectorMask & fSectorMask) {
+    if (rh->fSectorMask & fSectorMask) {
         trOrder = (int) orderable(rh);
     } else {
-        int trGap = (rh.fSectorStart - fSectorStart + 32) & 0x1f;
+        int trGap = (rh->fSectorStart - fSectorStart + 32) & 0x1f;
         trOrder = trGap > 20 ? 0 : trGap > 11 ? -1 : 1;
     }
     if (lrOrder >= 0 && ltOrder >= 0 && trOrder >= 0) {
@@ -145,20 +144,20 @@
     if (ltOrder == 0 && lrOrder == 0) {
         SkASSERT(trOrder < 0);
         // FIXME : once this is verified to work, remove one opposite angle call
-        SkDEBUGCODE(bool lrOpposite = lh.oppositePlanes(rh));
-        bool ltOpposite = lh.oppositePlanes(*this);
+        SkDEBUGCODE(bool lrOpposite = lh->oppositePlanes(rh));
+        bool ltOpposite = lh->oppositePlanes(this);
         SkASSERT(lrOpposite != ltOpposite);
         return COMPARE_RESULT(8, ltOpposite);
     } else if (ltOrder == 1 && trOrder == 0) {
         SkASSERT(lrOrder < 0);
-        SkDEBUGCODE(bool ltOpposite = lh.oppositePlanes(*this));
+        SkDEBUGCODE(bool ltOpposite = lh->oppositePlanes(this));
         bool trOpposite = oppositePlanes(rh);
         SkASSERT(ltOpposite != trOpposite);
         return COMPARE_RESULT(9, trOpposite);
     } else if (lrOrder == 1 && trOrder == 1) {
         SkASSERT(ltOrder < 0);
         SkDEBUGCODE(bool trOpposite = oppositePlanes(rh));
-        bool lrOpposite = lh.oppositePlanes(rh);
+        bool lrOpposite = lh->oppositePlanes(rh);
         SkASSERT(lrOpposite != trOpposite);
         return COMPARE_RESULT(10, lrOpposite);
     }
@@ -173,77 +172,50 @@
 
 // given a line, see if the opposite curve's convex hull is all on one side
 // returns -1=not on one side    0=this CW of test   1=this CCW of test
-int SkOpAngle::allOnOneSide(const SkOpAngle& test) const {
+int SkOpAngle::allOnOneSide(const SkOpAngle* test) {
     SkASSERT(!fIsCurve);
-    SkASSERT(test.fIsCurve);
-    const SkDPoint& origin = test.fCurvePart[0];
+    SkASSERT(test->fIsCurve);
+    const SkDPoint& origin = test->fCurvePart[0];
     SkVector line;
-    if (fSegment->verb() == SkPath::kLine_Verb) {
-        const SkPoint* linePts = fSegment->pts();
-        int lineStart = fStart < fEnd ? 0 : 1;
+    if (segment()->verb() == SkPath::kLine_Verb) {
+        const SkPoint* linePts = segment()->pts();
+        int lineStart = fStart->t() < fEnd->t() ? 0 : 1;
         line = linePts[lineStart ^ 1] - linePts[lineStart];
     } else {
         SkPoint shortPts[2] = { fCurvePart[0].asSkPoint(), fCurvePart[1].asSkPoint() };
         line = shortPts[1] - shortPts[0];
     }
     float crosses[3];
-    SkPath::Verb testVerb = test.fSegment->verb();
+    SkPath::Verb testVerb = test->segment()->verb();
     int iMax = SkPathOpsVerbToPoints(testVerb);
 //    SkASSERT(origin == test.fCurveHalf[0]);
-    const SkDCubic& testCurve = test.fCurvePart;
-//    do {
-        for (int index = 1; index <= iMax; ++index) {
-            float xy1 = (float) (line.fX * (testCurve[index].fY - origin.fY));
-            float xy2 = (float) (line.fY * (testCurve[index].fX - origin.fX));
-            crosses[index - 1] = AlmostEqualUlps(xy1, xy2) ? 0 : xy1 - xy2;
-        }
-        if (crosses[0] * crosses[1] < 0) {
+    const SkDCubic& testCurve = test->fCurvePart;
+    for (int index = 1; index <= iMax; ++index) {
+        float xy1 = (float) (line.fX * (testCurve[index].fY - origin.fY));
+        float xy2 = (float) (line.fY * (testCurve[index].fX - origin.fX));
+        crosses[index - 1] = AlmostEqualUlps(xy1, xy2) ? 0 : xy1 - xy2;
+    }
+    if (crosses[0] * crosses[1] < 0) {
+        return -1;
+    }
+    if (SkPath::kCubic_Verb == testVerb) {
+        if (crosses[0] * crosses[2] < 0 || crosses[1] * crosses[2] < 0) {
             return -1;
         }
-        if (SkPath::kCubic_Verb == testVerb) {
-            if (crosses[0] * crosses[2] < 0 || crosses[1] * crosses[2] < 0) {
-                return -1;
-            }
-        }
-        if (crosses[0]) {
-            return crosses[0] < 0;
-        }
-        if (crosses[1]) {
-            return crosses[1] < 0;
-        }
-        if (SkPath::kCubic_Verb == testVerb && crosses[2]) {
-            return crosses[2] < 0;
-        }
+    }
+    if (crosses[0]) {
+        return crosses[0] < 0;
+    }
+    if (crosses[1]) {
+        return crosses[1] < 0;
+    }
+    if (SkPath::kCubic_Verb == testVerb && crosses[2]) {
+        return crosses[2] < 0;
+    }
     fUnorderable = true;
     return -1;
 }
 
-bool SkOpAngle::calcSlop(double x, double y, double rx, double ry, bool* result) const {
-    double absX = fabs(x);
-    double absY = fabs(y);
-    double length = absX < absY ? absX / 2 + absY : absX + absY / 2;
-    int exponent;
-    (void) frexp(length, &exponent);
-    double epsilon = ldexp(FLT_EPSILON, exponent);
-    SkPath::Verb verb = fSegment->verb();
-    SkASSERT(verb == SkPath::kQuad_Verb || verb == SkPath::kCubic_Verb);
-    // FIXME: the quad and cubic factors are made up ; determine actual values
-    double slop = verb == SkPath::kQuad_Verb ? 4 * epsilon : 512 * epsilon;
-    double xSlop = slop;
-    double ySlop = x * y < 0 ? -xSlop : xSlop; // OPTIMIZATION: use copysign / _copysign ?
-    double x1 = x - xSlop;
-    double y1 = y + ySlop;
-    double x_ry1 = x1 * ry;
-    double rx_y1 = rx * y1;
-    *result = x_ry1 < rx_y1;
-    double x2 = x + xSlop;
-    double y2 = y - ySlop;
-    double x_ry2 = x2 * ry;
-    double rx_y2 = rx * y2;
-    bool less2 = x_ry2 < rx_y2;
-    return *result == less2;
-}
-
 bool SkOpAngle::checkCrossesZero() const {
     int start = SkTMin(fSectorStart, fSectorEnd);
     int end = SkTMax(fSectorStart, fSectorEnd);
@@ -251,31 +223,94 @@
     return crossesZero;
 }
 
-bool SkOpAngle::checkParallel(const SkOpAngle& rh) const {
+// loop looking for a pair of angle parts that are too close to be sorted
+/* This is called after other more simple intersection and angle sorting tests have been exhausted.
+   This should be rarely called -- the test below is thorough and time consuming.
+   This checks the distance between start points; the distance between 
+*/
+void SkOpAngle::checkNearCoincidence() {
+    SkOpAngle* test = this;
+    do {
+        SkOpSegment* testSegment = test->segment();
+        double testStartT = test->start()->t();
+        SkDPoint testStartPt = testSegment->dPtAtT(testStartT);
+        double testEndT = test->end()->t();
+        SkDPoint testEndPt = testSegment->dPtAtT(testEndT);
+        double testLenSq = testStartPt.distanceSquared(testEndPt);
+        if (0) {
+            SkDebugf("%s testLenSq=%1.9g id=%d\n", __FUNCTION__, testLenSq, testSegment->debugID());
+        }
+        double testMidT = (testStartT + testEndT) / 2;
+        SkOpAngle* next = test;
+        while ((next = next->fNext) != this) {
+            SkOpSegment* nextSegment = next->segment();
+            double testMidDistSq = testSegment->distSq(testMidT, next);
+            double testEndDistSq = testSegment->distSq(testEndT, next);
+            double nextStartT = next->start()->t();
+            SkDPoint nextStartPt = nextSegment->dPtAtT(nextStartT);
+            double distSq = testStartPt.distanceSquared(nextStartPt);
+            double nextEndT = next->end()->t();
+            double nextMidT = (nextStartT + nextEndT) / 2;
+            double nextMidDistSq = nextSegment->distSq(nextMidT, test);
+            double nextEndDistSq = nextSegment->distSq(nextEndT, test);
+            if (0) {
+                SkDebugf("%s distSq=%1.9g testId=%d nextId=%d\n", __FUNCTION__, distSq,
+                        testSegment->debugID(), nextSegment->debugID());
+                SkDebugf("%s testMidDistSq=%1.9g\n", __FUNCTION__, testMidDistSq);
+                SkDebugf("%s testEndDistSq=%1.9g\n", __FUNCTION__, testEndDistSq);
+                SkDebugf("%s nextMidDistSq=%1.9g\n", __FUNCTION__, nextMidDistSq);
+                SkDebugf("%s nextEndDistSq=%1.9g\n", __FUNCTION__, nextEndDistSq);
+                SkDPoint nextEndPt = nextSegment->dPtAtT(nextEndT);
+                double nextLenSq = nextStartPt.distanceSquared(nextEndPt);
+                SkDebugf("%s nextLenSq=%1.9g\n", __FUNCTION__, nextLenSq);
+                SkDebugf("\n");
+            }
+        }
+        test = test->fNext;
+    } while (test->fNext != this); 
+}
+
+bool SkOpAngle::checkParallel(SkOpAngle* rh) {
     SkDVector scratch[2];
     const SkDVector* sweep, * tweep;
-    if (!fUnorderedSweep) {
-        sweep = fSweep;
+    if (!this->fUnorderedSweep) {
+        sweep = this->fSweep;
     } else {
-        scratch[0] = fCurvePart[1] - fCurvePart[0];
+        scratch[0] = this->fCurvePart[1] - this->fCurvePart[0];
         sweep = &scratch[0];
     }
-    if (!rh.fUnorderedSweep) {
-        tweep = rh.fSweep;
+    if (!rh->fUnorderedSweep) {
+        tweep = rh->fSweep;
     } else {
-        scratch[1] = rh.fCurvePart[1] - rh.fCurvePart[0];
+        scratch[1] = rh->fCurvePart[1] - rh->fCurvePart[0];
         tweep = &scratch[1];
     }
     double s0xt0 = sweep->crossCheck(*tweep);
     if (tangentsDiverge(rh, s0xt0)) {
         return s0xt0 < 0;
     }
-    SkDVector m0 = fSegment->dPtAtT(midT()) - fCurvePart[0];
-    SkDVector m1 = rh.fSegment->dPtAtT(rh.midT()) - rh.fCurvePart[0];
+    // compute the perpendicular to the endpoints and see where it intersects the opposite curve
+    // if the intersections within the t range, do a cross check on those
+    bool inside;
+    if (this->endToSide(rh, &inside)) {
+        return inside;
+    }
+    if (rh->endToSide(this, &inside)) {
+        return !inside;
+    }
+    if (this->midToSide(rh, &inside)) {
+        return inside;
+    }
+    if (rh->midToSide(this, &inside)) {
+        return !inside;
+    }
+    // compute the cross check from the mid T values (last resort)
+    SkDVector m0 = segment()->dPtAtT(this->midT()) - this->fCurvePart[0];
+    SkDVector m1 = rh->segment()->dPtAtT(rh->midT()) - rh->fCurvePart[0];
     double m0xm1 = m0.crossCheck(m1);
     if (m0xm1 == 0) {
-        fUnorderable = true;
-        rh.fUnorderable = true;
+        this->fUnorderable = true;
+        rh->fUnorderable = true;
         return true;
     }
     return m0xm1 < 0;
@@ -288,48 +323,51 @@
     if (fComputedSector) {
         return !fUnorderable;
     }
-//    SkASSERT(fSegment->verb() != SkPath::kLine_Verb && small());
     fComputedSector = true;
-    int step = fStart < fEnd ? 1 : -1;
-    int limit = step > 0 ? fSegment->count() : -1;
-    int checkEnd = fEnd;
-    do {
-// advance end
-        const SkOpSpan& span = fSegment->span(checkEnd);
-        const SkOpSegment* other = span.fOther;
-        int oCount = other->count();
-        for (int oIndex = 0; oIndex < oCount; ++oIndex) {
-            const SkOpSpan& oSpan = other->span(oIndex);
-            if (oSpan.fOther != fSegment) {
-                continue;
-            }
-            if (oSpan.fOtherIndex == checkEnd) {
-                continue;
-            }
-            if (!approximately_equal(oSpan.fOtherT, span.fT)) {
-                continue;
-            }
-            goto recomputeSector;
-        }
-        checkEnd += step;
-    } while (checkEnd != limit);
-recomputeSector:
-    if (checkEnd == fEnd || checkEnd - step == fEnd) {
+    bool stepUp = fStart->t() < fEnd->t();
+    const SkOpSpanBase* checkEnd = fEnd;
+    if (checkEnd->final() && stepUp) {
         fUnorderable = true;
         return false;
     }
-    int saveEnd = fEnd;
-    fComputedEnd = fEnd = checkEnd - step;
+    do {
+// advance end
+        const SkOpSegment* other = checkEnd->segment();
+        const SkOpSpanBase* oSpan = other->head();
+        do {
+            if (oSpan->segment() != segment()) {
+                continue;
+            }
+            if (oSpan == checkEnd) {
+                continue;
+            }
+            if (!approximately_equal(oSpan->t(), checkEnd->t())) {
+                continue;
+            }
+            goto recomputeSector;
+        } while (!oSpan->final() && (oSpan = oSpan->upCast()->next()));
+        checkEnd = stepUp ? !checkEnd->final()
+                ? checkEnd->upCast()->next() : NULL
+                : checkEnd->prev();
+    } while (checkEnd);
+recomputeSector:
+    SkOpSpanBase* computedEnd = stepUp ? checkEnd ? checkEnd->prev() : fEnd->segment()->head() 
+            : checkEnd ? checkEnd->upCast()->next() : fEnd->segment()->tail();
+    if (checkEnd == fEnd || computedEnd == fEnd || computedEnd == fStart) {
+        fUnorderable = true;
+        return false;
+    }
+    SkOpSpanBase* saveEnd = fEnd;
+    fComputedEnd = fEnd = computedEnd;
     setSpans();
     setSector();
     fEnd = saveEnd;
     return !fUnorderable;
 }
 
-// returns -1 if overlaps   0 if no overlap cw    1 if no overlap ccw
-int SkOpAngle::convexHullOverlaps(const SkOpAngle& rh) const {
-    const SkDVector* sweep = fSweep;
-    const SkDVector* tweep = rh.fSweep;
+int SkOpAngle::convexHullOverlaps(const SkOpAngle* rh) const {
+    const SkDVector* sweep = this->fSweep;
+    const SkDVector* tweep = rh->fSweep;
     double s0xs1 = sweep[0].crossCheck(sweep[1]);
     double s0xt0 = sweep[0].crossCheck(tweep[0]);
     double s1xt0 = sweep[1].crossCheck(tweep[0]);
@@ -359,8 +397,8 @@
     // if the outside sweeps are greater than 180 degress:
         // first assume the inital tangents are the ordering
         // if the midpoint direction matches the inital order, that is enough
-    SkDVector m0 = fSegment->dPtAtT(midT()) - fCurvePart[0];
-    SkDVector m1 = rh.fSegment->dPtAtT(rh.midT()) - rh.fCurvePart[0];
+    SkDVector m0 = this->segment()->dPtAtT(this->midT()) - this->fCurvePart[0];
+    SkDVector m1 = rh->segment()->dPtAtT(rh->midT()) - rh->fCurvePart[0];
     double m0xm1 = m0.crossCheck(m1);
     if (s0xt0 > 0 && m0xm1 > 0) {
         return 0;
@@ -394,34 +432,30 @@
     return sqrt(longest) / dist;
 }
 
-bool SkOpAngle::endsIntersect(const SkOpAngle& rh) const {
-    SkPath::Verb lVerb = fSegment->verb();
-    SkPath::Verb rVerb = rh.fSegment->verb();
+bool SkOpAngle::endsIntersect(SkOpAngle* rh) {
+    SkPath::Verb lVerb = this->segment()->verb();
+    SkPath::Verb rVerb = rh->segment()->verb();
     int lPts = SkPathOpsVerbToPoints(lVerb);
     int rPts = SkPathOpsVerbToPoints(rVerb);
-    SkDLine rays[] = {{{fCurvePart[0], rh.fCurvePart[rPts]}},
-            {{fCurvePart[0], fCurvePart[lPts]}}};
+    SkDLine rays[] = {{{this->fCurvePart[0], rh->fCurvePart[rPts]}},
+            {{this->fCurvePart[0], this->fCurvePart[lPts]}}};
     if (rays[0][1] == rays[1][1]) {
         return checkParallel(rh);
     }
     double smallTs[2] = {-1, -1};
     bool limited[2] = {false, false};
     for (int index = 0; index < 2; ++index) {
-        const SkOpSegment& segment = index ? *rh.fSegment : *fSegment;
-        SkIntersections i;
         int cPts = index ? rPts : lPts;
-        (*CurveIntersectRay[cPts])(segment.pts(), rays[index], &i);
         // if the curve is a line, then the line and the ray intersect only at their crossing
         if (cPts == 1) { // line
             continue;
         }
-//      SkASSERT(i.used() >= 1);
-//        if (i.used() <= 1) {
-//            continue;
-//        }
-        double tStart = segment.t(index ? rh.fStart : fStart);
-        double tEnd = segment.t(index ? rh.fComputedEnd : fComputedEnd);
-        bool testAscends = index ? rh.fStart < rh.fComputedEnd : fStart < fComputedEnd;
+        const SkOpSegment& segment = index ? *rh->segment() : *this->segment();
+        SkIntersections i;
+        (*CurveIntersectRay[cPts])(segment.pts(), rays[index], &i);
+        double tStart = index ? rh->fStart->t() : this->fStart->t();
+        double tEnd = index ? rh->fComputedEnd->t() : this->fComputedEnd->t();
+        bool testAscends = tStart < (index ? rh->fComputedEnd->t() : this->fComputedEnd->t());
         double t = testAscends ? 0 : 1;
         for (int idx2 = 0; idx2 < i.used(); ++idx2) {
             double testT = i[0][idx2];
@@ -435,29 +469,6 @@
             limited[index] = approximately_equal_orderable(t, tEnd);
         }
     }
-#if 0
-    if (smallTs[0] < 0 && smallTs[1] < 0) {  // if neither ray intersects, do endpoint sort
-        double m0xm1 = 0;
-        if (lVerb == SkPath::kLine_Verb) {
-            SkASSERT(rVerb != SkPath::kLine_Verb);
-            SkDVector m0 = rays[1][1] - fCurvePart[0];
-            SkDPoint endPt;
-            endPt.set(rh.fSegment->pts()[rh.fStart < rh.fEnd ? rPts : 0]);
-            SkDVector m1 = endPt - fCurvePart[0];
-            m0xm1 = m0.crossCheck(m1);
-        }
-        if (rVerb == SkPath::kLine_Verb) {
-            SkDPoint endPt;
-            endPt.set(fSegment->pts()[fStart < fEnd ? lPts : 0]);
-            SkDVector m0 = endPt - fCurvePart[0];
-            SkDVector m1 = rays[0][1] - fCurvePart[0];
-            m0xm1 = m0.crossCheck(m1);
-        }
-        if (m0xm1 != 0) {
-            return m0xm1 < 0;
-        }
-    }
-#endif
     bool sRayLonger = false;
     SkDVector sCept = {0, 0};
     double sCeptT = -1;
@@ -467,7 +478,7 @@
         if (smallTs[index] < 0) {
             continue;
         }
-        const SkOpSegment& segment = index ? *rh.fSegment : *fSegment;
+        const SkOpSegment& segment = index ? *rh->segment() : *this->segment();
         const SkDPoint& dPt = segment.dPtAtT(smallTs[index]);
         SkDVector cept = dPt - rays[index][0];
         // If this point is on the curve, it should have been detected earlier by ordinary
@@ -498,7 +509,7 @@
         double minX, minY, maxX, maxY;
         minX = minY = SK_ScalarInfinity;
         maxX = maxY = -SK_ScalarInfinity;
-        const SkDCubic& curve = index ? rh.fCurvePart : fCurvePart;
+        const SkDCubic& curve = index ? rh->fCurvePart : this->fCurvePart;
         int ptCount = index ? rPts : lPts;
         for (int idx2 = 0; idx2 <= ptCount; ++idx2) {
             minX = SkTMin(minX, curve[idx2].fX);
@@ -508,7 +519,7 @@
         }
         double maxWidth = SkTMax(maxX - minX, maxY - minY);
         delta /= maxWidth;
-        if (delta > 1e-4 && (useIntersect ^= true)) {  // FIXME: move this magic number
+        if (delta > 1e-3 && (useIntersect ^= true)) {  // FIXME: move this magic number
             sRayLonger = rayLonger;
             sCept = cept;
             sCeptT = smallTs[index];
@@ -516,9 +527,9 @@
         }
     }
     if (useIntersect) {
-        const SkDCubic& curve = sIndex ? rh.fCurvePart : fCurvePart;
-        const SkOpSegment& segment = sIndex ? *rh.fSegment : *fSegment;
-        double tStart = segment.t(sIndex ? rh.fStart : fStart);
+        const SkDCubic& curve = sIndex ? rh->fCurvePart : this->fCurvePart;
+        const SkOpSegment& segment = sIndex ? *rh->segment() : *this->segment();
+        double tStart = sIndex ? rh->fStart->t() : fStart->t();
         SkDVector mid = segment.dPtAtT(tStart + (sCeptT - tStart) / 2) - curve[0];
         double septDir = mid.crossCheck(sCept);
         if (!septDir) {
@@ -530,12 +541,65 @@
     }
 }
 
+bool SkOpAngle::endToSide(const SkOpAngle* rh, bool* inside) const {
+    const SkOpSegment* segment = this->segment();
+    SkPath::Verb verb = segment->verb();
+    int pts = SkPathOpsVerbToPoints(verb);
+    SkDLine rayEnd;
+    rayEnd[0].set(this->fEnd->pt());
+    rayEnd[1] = rayEnd[0];
+    SkDVector slopeAtEnd = (*CurveDSlopeAtT[pts])(segment->pts(), this->fEnd->t());
+    rayEnd[1].fX += slopeAtEnd.fY;
+    rayEnd[1].fY -= slopeAtEnd.fX;
+    SkIntersections iEnd;
+    const SkOpSegment* oppSegment = rh->segment();
+    SkPath::Verb oppVerb = oppSegment->verb();
+    int oppPts = SkPathOpsVerbToPoints(oppVerb);
+    (*CurveIntersectRay[oppPts])(oppSegment->pts(), rayEnd, &iEnd);
+    double endDist;
+    int closestEnd = iEnd.closestTo(rh->fStart->t(), rh->fEnd->t(), rayEnd[0], &endDist);
+    if (closestEnd < 0) {
+        return false;
+    }
+    if (!endDist) {
+        return false;
+    }
+    SkDPoint start;
+    start.set(this->fStart->pt());
+    // OPTIMIZATION: multiple times in the code we find the max scalar
+    double minX, minY, maxX, maxY;
+    minX = minY = SK_ScalarInfinity;
+    maxX = maxY = -SK_ScalarInfinity;
+    const SkDCubic& curve = rh->fCurvePart;
+    for (int idx2 = 0; idx2 <= oppPts; ++idx2) {
+        minX = SkTMin(minX, curve[idx2].fX);
+        minY = SkTMin(minY, curve[idx2].fY);
+        maxX = SkTMax(maxX, curve[idx2].fX);
+        maxY = SkTMax(maxY, curve[idx2].fY);
+    }
+    double maxWidth = SkTMax(maxX - minX, maxY - minY);
+    endDist /= maxWidth;
+    if (endDist < 5e-11) {  // empirically found
+        return false;
+    }
+    const SkDPoint* endPt = &rayEnd[0];
+    SkDPoint oppPt = iEnd.pt(closestEnd);
+    SkDVector vLeft = *endPt - start;
+    SkDVector vRight = oppPt - start;
+    double dir = vLeft.crossCheck(vRight);
+    if (!dir) {
+        return false;
+    }
+    *inside = dir < 0;
+    return true;
+}
+
 // Most of the time, the first one can be found trivially by detecting the smallest sector value.
 // If all angles have the same sector value, actual sorting is required.
-const SkOpAngle* SkOpAngle::findFirst() const {
-    const SkOpAngle* best = this;
+SkOpAngle* SkOpAngle::findFirst() {
+    SkOpAngle* best = this;
     int bestStart = SkTMin(fSectorStart, fSectorEnd);
-    const SkOpAngle* angle = this;
+    SkOpAngle* angle = this;
     while ((angle = angle->fNext) != this) {
         int angleEnd = SkTMax(angle->fSectorStart, angle->fSectorEnd);
         if (angleEnd < bestStart) {
@@ -548,7 +612,7 @@
         }
     }
     // back up to the first possible angle
-    const SkOpAngle* firstBest = best;
+    SkOpAngle* firstBest = best;
     angle = best;
     int bestEnd = SkTMax(best->fSectorStart, best->fSectorEnd);
     while ((angle = angle->previous()) != firstBest) {
@@ -572,7 +636,7 @@
         if (angle->fStop) {
             return firstBest;
         }
-        bool orderable = best->orderable(*angle);  // note: may return an unorderable angle
+        bool orderable = best->orderable(angle);  // note: may return an unorderable angle
         if (orderable == 0) {
             return angle;
         }
@@ -639,6 +703,11 @@
     return sector;
 }
 
+SkOpGlobalState* SkOpAngle::globalState() const {
+    return this->segment()->globalState();
+}
+
+
 // OPTIMIZE: if this loops to only one other angle, after first compare fails, insert on other side
 // OPTIMIZE: return where insertion succeeded. Then, start next insertion on opposite side
 void SkOpAngle::insert(SkOpAngle* angle) {
@@ -662,9 +731,6 @@
     }
     SkOpAngle* next = fNext;
     if (next->fNext == this) {
-        if (angle->overlap(*this)) {  // angles are essentially coincident
-            return;
-        }
         if (singleton || angle->after(this)) {
             this->fNext = angle;
             angle->fNext = next;
@@ -678,9 +744,6 @@
     SkOpAngle* last = this;
     do {
         SkASSERT(last->fNext == next);
-        if (angle->overlap(*last) || angle->overlap(*next)) {
-            return;
-        }
         if (angle->after(last)) {
             last->fNext = angle;
             angle->fNext = next;
@@ -689,48 +752,49 @@
         }
         last = next;
         next = next->fNext;
-        if (last == this && next->fUnorderable) {
-            fUnorderable = true;
+        if (last == this) {
+            if (next->fUnorderable) {
+                fUnorderable = true;
+            } else {
+                globalState()->setAngleCoincidence();
+                this->fNext = angle;
+                angle->fNext = next;
+                angle->fCheckCoincidence = true;
+            }
             return;
         }
-        SkASSERT(last != this);
     } while (true);
 }
 
-bool SkOpAngle::isHorizontal() const {
-    return !fIsCurve && fSweep[0].fY == 0;
-}
-
-SkOpSpan* SkOpAngle::lastMarked() const {
+SkOpSpanBase* SkOpAngle::lastMarked() const {
     if (fLastMarked) {
-        if (fLastMarked->fChased) {
+        if (fLastMarked->chased()) {
             return NULL;
         }
-        fLastMarked->fChased = true;
+        fLastMarked->setChased(true);
     }
     return fLastMarked;
 }
 
-bool SkOpAngle::loopContains(const SkOpAngle& test) const {
+bool SkOpAngle::loopContains(const SkOpAngle* angle) const {
     if (!fNext) {
         return false;
     }
     const SkOpAngle* first = this;
     const SkOpAngle* loop = this;
-    const SkOpSegment* tSegment = test.fSegment;
-    double tStart = tSegment->span(test.fStart).fT;
-    double tEnd = tSegment->span(test.fEnd).fT;
+    const SkOpSegment* tSegment = angle->fStart->segment();
+    double tStart = angle->fStart->t();
+    double tEnd = angle->fEnd->t();
     do {
-        const SkOpSegment* lSegment = loop->fSegment;
-        // FIXME : use precisely_equal ? or compare points exactly ?
+        const SkOpSegment* lSegment = loop->fStart->segment();
         if (lSegment != tSegment) {
             continue;
         }
-        double lStart = lSegment->span(loop->fStart).fT;
+        double lStart = loop->fStart->t();
         if (lStart != tEnd) {
             continue;
         }
-        double lEnd = lSegment->span(loop->fEnd).fT;
+        double lEnd = loop->fEnd->t();
         if (lEnd == tStart) {
             return true;
         }
@@ -782,39 +846,65 @@
         working = next;
     } while (working != angle);
     // it's likely that a pair of the angles are unorderable
-#if 0 && DEBUG_ANGLE
-    SkOpAngle* last = angle;
-    working = angle->fNext;
-    do {
-        SkASSERT(last->fNext == working);
-        last->fNext = working->fNext;
-        SkASSERT(working->after(last));
-        last->fNext = working;
-        last = working;
-        working = working->fNext;
-    } while (last != angle);
-#endif
     debugValidateNext();
     return true;
 }
 
 double SkOpAngle::midT() const {
-    return (fSegment->t(fStart) + fSegment->t(fEnd)) / 2;
+    return (fStart->t() + fEnd->t()) / 2;
 }
 
-bool SkOpAngle::oppositePlanes(const SkOpAngle& rh) const {
-    int startSpan = abs(rh.fSectorStart - fSectorStart);
+bool SkOpAngle::midToSide(const SkOpAngle* rh, bool* inside) const {
+    const SkOpSegment* segment = this->segment();
+    SkPath::Verb verb = segment->verb();
+    int pts = SkPathOpsVerbToPoints(verb);
+    const SkPoint& startPt = this->fStart->pt();
+    const SkPoint& endPt = this->fEnd->pt();
+    SkDPoint dStartPt;
+    dStartPt.set(startPt);
+    SkDLine rayMid;
+    rayMid[0].fX = (startPt.fX + endPt.fX) / 2;
+    rayMid[0].fY = (startPt.fY + endPt.fY) / 2;
+    rayMid[1].fX = rayMid[0].fX + (endPt.fY - startPt.fY);
+    rayMid[1].fY = rayMid[0].fY - (endPt.fX - startPt.fX);
+    SkIntersections iMid;
+    (*CurveIntersectRay[pts])(segment->pts(), rayMid, &iMid);
+    int iOutside = iMid.mostOutside(this->fStart->t(), this->fEnd->t(), dStartPt);
+    if (iOutside < 0) {
+        return false;
+    }
+    const SkOpSegment* oppSegment = rh->segment();
+    SkPath::Verb oppVerb = oppSegment->verb();
+    int oppPts = SkPathOpsVerbToPoints(oppVerb);
+    SkIntersections oppMid;
+    (*CurveIntersectRay[oppPts])(oppSegment->pts(), rayMid, &oppMid);
+    int oppOutside = oppMid.mostOutside(rh->fStart->t(), rh->fEnd->t(), dStartPt);
+    if (oppOutside < 0) {
+        return false;
+    }
+    SkDVector iSide = iMid.pt(iOutside) - dStartPt;
+    SkDVector oppSide = oppMid.pt(oppOutside) - dStartPt;
+    double dir = iSide.crossCheck(oppSide);
+    if (!dir) {
+        return false;
+    }
+    *inside = dir < 0;
+    return true;
+}
+
+bool SkOpAngle::oppositePlanes(const SkOpAngle* rh) const {
+    int startSpan = abs(rh->fSectorStart - fSectorStart);
     return startSpan >= 8;
 }
 
-bool SkOpAngle::orderable(const SkOpAngle& rh) const {
+bool SkOpAngle::orderable(SkOpAngle* rh) {
     int result;
     if (!fIsCurve) {
-        if (!rh.fIsCurve) {
+        if (!rh->fIsCurve) {
             double leftX = fTangentHalf.dx();
             double leftY = fTangentHalf.dy();
-            double rightX = rh.fTangentHalf.dx();
-            double rightY = rh.fTangentHalf.dy();
+            double rightX = rh->fTangentHalf.dx();
+            double rightY = rh->fTangentHalf.dy();
             double x_ry = leftX * rightY;
             double rx_y = rightX * leftY;
             if (x_ry == rx_y) {
@@ -829,14 +919,14 @@
         if ((result = allOnOneSide(rh)) >= 0) {
             return result;
         }
-        if (fUnorderable || approximately_zero(rh.fSide)) {
+        if (fUnorderable || approximately_zero(rh->fSide)) {
             goto unorderable;
         }
-    } else if (!rh.fIsCurve) {
-        if ((result = rh.allOnOneSide(*this)) >= 0) {
+    } else if (!rh->fIsCurve) {
+        if ((result = rh->allOnOneSide(this)) >= 0) {
             return !result;
         }
-        if (rh.fUnorderable || approximately_zero(fSide)) {
+        if (rh->fUnorderable || approximately_zero(fSide)) {
             goto unorderable;
         }
     }
@@ -846,27 +936,10 @@
     return endsIntersect(rh);
 unorderable:
     fUnorderable = true;
-    rh.fUnorderable = true;
+    rh->fUnorderable = true;
     return true;
 }
 
-bool SkOpAngle::overlap(const SkOpAngle& other) const {
-    int min = SkTMin(fStart, fEnd);
-    const SkOpSpan& span = fSegment->span(min);
-    const SkOpSegment* oSeg = other.fSegment;
-    int oMin = SkTMin(other.fStart, other.fEnd);
-    const SkOpSpan& oSpan = oSeg->span(oMin);
-    if (!span.fSmall && !oSpan.fSmall) {
-        return false;
-    }
-    if (fSegment->span(fStart).fPt != oSeg->span(other.fStart).fPt) {
-        return false;
-    }
-    // see if small span is contained by opposite span
-    return span.fSmall ? oSeg->containsPt(fSegment->span(fEnd).fPt, other.fEnd, other.fStart)
-            : fSegment->containsPt(oSeg->span(other.fEnd).fPt, fEnd, fStart);
-}
-
 // OPTIMIZE: if this shows up in a profile, add a previous pointer
 // as is, this should be rarely called
 SkOpAngle* SkOpAngle::previous() const {
@@ -880,26 +953,32 @@
     } while (true);
 }
 
-void SkOpAngle::set(const SkOpSegment* segment, int start, int end) {
-    fSegment = segment;
+SkOpSegment* SkOpAngle::segment() const {
+    return fStart->segment();
+}
+
+void SkOpAngle::set(SkOpSpanBase* start, SkOpSpanBase* end) {
     fStart = start;
     fComputedEnd = fEnd = end;
+    SkASSERT(start != end);
     fNext = NULL;
-    fComputeSector = fComputedSector = false;
+    fComputeSector = fComputedSector = fCheckCoincidence = false;
     fStop = false;
     setSpans();
     setSector();
+    PATH_OPS_DEBUG_CODE(fID = start->globalState()->nextAngleID());
 }
 
 void SkOpAngle::setCurveHullSweep() {
     fUnorderedSweep = false;
     fSweep[0] = fCurvePart[1] - fCurvePart[0];
-    if (SkPath::kLine_Verb == fSegment->verb()) {
+    const SkOpSegment* segment = fStart->segment();
+    if (SkPath::kLine_Verb == segment->verb()) {
         fSweep[1] = fSweep[0];
         return;
     }
     fSweep[1] = fCurvePart[2] - fCurvePart[0];
-    if (SkPath::kCubic_Verb != fSegment->verb()) {
+    if (SkPath::kCubic_Verb != segment->verb()) {
         if (!fSweep[0].fX && !fSweep[0].fY) {
             fSweep[0] = fSweep[1];
         }
@@ -933,64 +1012,16 @@
     fSweep[1] = thirdSweep;
 }
 
-void SkOpAngle::setSector() {
-    SkPath::Verb verb = fSegment->verb();
-    if (SkPath::kLine_Verb != verb && small()) {
-        goto deferTilLater;
-    }
-    fSectorStart = findSector(verb, fSweep[0].fX, fSweep[0].fY);
-    if (fSectorStart < 0) {
-        goto deferTilLater;
-    }
-    if (!fIsCurve) {  // if it's a line or line-like, note that both sectors are the same
-        SkASSERT(fSectorStart >= 0);
-        fSectorEnd = fSectorStart;
-        fSectorMask = 1 << fSectorStart;
-        return;
-    }
-    SkASSERT(SkPath::kLine_Verb != verb);
-    fSectorEnd = findSector(verb, fSweep[1].fX, fSweep[1].fY);
-    if (fSectorEnd < 0) {
-deferTilLater:
-        fSectorStart = fSectorEnd = -1;
-        fSectorMask = 0;
-        fComputeSector = true;  // can't determine sector until segment length can be found
-        return;
-    }
-    if (fSectorEnd == fSectorStart) {
-        SkASSERT((fSectorStart & 3) != 3);  // if the sector has no span, it can't be an exact angle
-        fSectorMask = 1 << fSectorStart;
-        return;
-    }
-    bool crossesZero = checkCrossesZero();
-    int start = SkTMin(fSectorStart, fSectorEnd);
-    bool curveBendsCCW = (fSectorStart == start) ^ crossesZero;
-    // bump the start and end of the sector span if they are on exact compass points
-    if ((fSectorStart & 3) == 3) {
-        fSectorStart = (fSectorStart + (curveBendsCCW ? 1 : 31)) & 0x1f;
-    }
-    if ((fSectorEnd & 3) == 3) {
-        fSectorEnd = (fSectorEnd + (curveBendsCCW ? 31 : 1)) & 0x1f;
-    }
-    crossesZero = checkCrossesZero();
-    start = SkTMin(fSectorStart, fSectorEnd);
-    int end = SkTMax(fSectorStart, fSectorEnd);
-    if (!crossesZero) {
-        fSectorMask = (unsigned) -1 >> (31 - end + start) << start;
-    } else {
-        fSectorMask = (unsigned) -1 >> (31 - start) | (-1 << end);
-    }
-}
-
 void SkOpAngle::setSpans() {
-    fUnorderable = fSegment->isTiny(this);
+    fUnorderable = false;
     fLastMarked = NULL;
-    const SkPoint* pts = fSegment->pts();
+    const SkOpSegment* segment = fStart->segment();
+    const SkPoint* pts = segment->pts();
     SkDEBUGCODE(fCurvePart[2].fX = fCurvePart[2].fY = fCurvePart[3].fX = fCurvePart[3].fY
             = SK_ScalarNaN);
-    fSegment->subDivide(fStart, fEnd, &fCurvePart);
+    segment->subDivide(fStart, fEnd, &fCurvePart);
     setCurveHullSweep();
-    const SkPath::Verb verb = fSegment->verb();
+    const SkPath::Verb verb = segment->verb();
     if (verb != SkPath::kLine_Verb
             && !(fIsCurve = fSweep[0].crossCheck(fSweep[1]) != 0)) {
         SkDLine lineHalf;
@@ -1002,9 +1033,9 @@
     switch (verb) {
     case SkPath::kLine_Verb: {
         SkASSERT(fStart != fEnd);
-        const SkPoint& cP1 = pts[fStart < fEnd];
+        const SkPoint& cP1 = pts[fStart->t() < fEnd->t()];
         SkDLine lineHalf;
-        lineHalf[0].set(fSegment->span(fStart).fPt);
+        lineHalf[0].set(fStart->pt());
         lineHalf[1].set(cP1);
         fTangentHalf.lineEndPoints(lineHalf);
         fSide = 0;
@@ -1023,8 +1054,8 @@
         double testTs[4];
         // OPTIMIZATION: keep inflections precomputed with cubic segment?
         int testCount = SkDCubic::FindInflections(pts, testTs);
-        double startT = fSegment->t(fStart);
-        double endT = fSegment->t(fEnd);
+        double startT = fStart->t();
+        double endT = fEnd->t();
         double limitT = endT;
         int index;
         for (index = 0; index < testCount; ++index) {
@@ -1064,19 +1095,63 @@
     }
 }
 
-bool SkOpAngle::small() const {
-    int min = SkMin32(fStart, fEnd);
-    int max = SkMax32(fStart, fEnd);
-    for (int index = min; index < max; ++index) {
-        const SkOpSpan& mSpan = fSegment->span(index);
-        if (!mSpan.fSmall) {
-            return false;
-        }
+void SkOpAngle::setSector() {
+    const SkOpSegment* segment = fStart->segment();
+    SkPath::Verb verb = segment->verb();
+    fSectorStart = this->findSector(verb, fSweep[0].fX, fSweep[0].fY);
+    if (fSectorStart < 0) {
+        goto deferTilLater;
     }
-    return true;
+    if (!fIsCurve) {  // if it's a line or line-like, note that both sectors are the same
+        SkASSERT(fSectorStart >= 0);
+        fSectorEnd = fSectorStart;
+        fSectorMask = 1 << fSectorStart;
+        return;
+    }
+    SkASSERT(SkPath::kLine_Verb != verb);
+    fSectorEnd = this->findSector(verb, fSweep[1].fX, fSweep[1].fY);
+    if (fSectorEnd < 0) {
+deferTilLater:
+        fSectorStart = fSectorEnd = -1;
+        fSectorMask = 0;
+        fComputeSector = true;  // can't determine sector until segment length can be found
+        return;
+    }
+    if (fSectorEnd == fSectorStart
+            && (fSectorStart & 3) != 3) { // if the sector has no span, it can't be an exact angle
+        fSectorMask = 1 << fSectorStart;
+        return;
+    }
+    bool crossesZero = this->checkCrossesZero();
+    int start = SkTMin(fSectorStart, fSectorEnd);
+    bool curveBendsCCW = (fSectorStart == start) ^ crossesZero;
+    // bump the start and end of the sector span if they are on exact compass points
+    if ((fSectorStart & 3) == 3) {
+        fSectorStart = (fSectorStart + (curveBendsCCW ? 1 : 31)) & 0x1f;
+    }
+    if ((fSectorEnd & 3) == 3) {
+        fSectorEnd = (fSectorEnd + (curveBendsCCW ? 31 : 1)) & 0x1f;
+    }
+    crossesZero = this->checkCrossesZero();
+    start = SkTMin(fSectorStart, fSectorEnd);
+    int end = SkTMax(fSectorStart, fSectorEnd);
+    if (!crossesZero) {
+        fSectorMask = (unsigned) -1 >> (31 - end + start) << start;
+    } else {
+        fSectorMask = (unsigned) -1 >> (31 - start) | (-1 << end);
+    }
 }
 
-bool SkOpAngle::tangentsDiverge(const SkOpAngle& rh, double s0xt0) const {
+int SkOpAngle::sign() const {
+    SkASSERT(fStart->t() != fEnd->t());
+    return fStart->t() < fEnd->t() ? -1 : 1;
+}
+
+SkOpSpan* SkOpAngle::starter() {
+    return fStart->starter(fEnd);
+}
+
+bool SkOpAngle::tangentsDiverge(const SkOpAngle* rh, double s0xt0) const {
     if (s0xt0 == 0) {
         return false;
     }
@@ -1090,7 +1165,7 @@
     // m = (v2.y * v1.x - v2.x * v1.y) / (v2.x * v1.x + v2.y * v1.y)
     // m = v1.cross(v2) / v1.dot(v2)
     const SkDVector* sweep = fSweep;
-    const SkDVector* tweep = rh.fSweep;
+    const SkDVector* tweep = rh->fSweep;
     double s0dt0 = sweep[0].dot(tweep[0]);
     if (!s0dt0) {
         return true;
@@ -1100,36 +1175,6 @@
     double sDist = sweep[0].length() * m;
     double tDist = tweep[0].length() * m;
     bool useS = fabs(sDist) < fabs(tDist);
-    double mFactor = fabs(useS ? distEndRatio(sDist) : rh.distEndRatio(tDist));
+    double mFactor = fabs(useS ? this->distEndRatio(sDist) : rh->distEndRatio(tDist));
     return mFactor < 5000;  // empirically found limit
 }
-
-SkOpAngleSet::SkOpAngleSet() 
-    : fAngles(NULL)
-#if DEBUG_ANGLE
-    , fCount(0)
-#endif
-{
-}
-
-SkOpAngleSet::~SkOpAngleSet() {
-    SkDELETE(fAngles);
-}
-
-SkOpAngle& SkOpAngleSet::push_back() {
-    if (!fAngles) {
-        fAngles = SkNEW_ARGS(SkChunkAlloc, (2));
-    }
-    void* ptr = fAngles->allocThrow(sizeof(SkOpAngle));
-    SkOpAngle* angle = (SkOpAngle*) ptr;
-#if DEBUG_ANGLE
-    angle->setID(++fCount);
-#endif
-    return *angle;
-}
-
-void SkOpAngleSet::reset() {
-    if (fAngles) {
-        fAngles->reset();
-    }
-}
diff --git a/src/pathops/SkOpAngle.h b/src/pathops/SkOpAngle.h
index 1dc4250..84b3701 100644
--- a/src/pathops/SkOpAngle.h
+++ b/src/pathops/SkOpAngle.h
@@ -7,17 +7,18 @@
 #ifndef SkOpAngle_DEFINED
 #define SkOpAngle_DEFINED
 
-#include "SkChunkAlloc.h"
 #include "SkLineParameters.h"
+#if DEBUG_ANGLE
+#include "SkString.h"
+#endif
 
+class SkOpContour;
+class SkOpPtT;
 class SkOpSegment;
-struct SkOpSpan;
+class SkOpSpanBase;
+class SkOpSpan;
 
-// sorting angles
-// given angles of {dx dy ddx ddy dddx dddy} sort them
-class SkOpAngle {
-public:
-    enum { kStackBasedCount = 8 }; // FIXME: determine what this should be
+struct SkOpAngle {
     enum IncludeType {
         kUnaryWinding,
         kUnaryXor,
@@ -25,29 +26,66 @@
         kBinaryOpp,
     };
 
+    bool after(SkOpAngle* test);
+    int allOnOneSide(const SkOpAngle* test);
+    bool checkCrossesZero() const;
+    void checkNearCoincidence();
+    bool checkParallel(SkOpAngle* );
+    bool computeSector();
+    int convexHullOverlaps(const SkOpAngle* ) const;
 
-    int end() const {
+    const SkOpAngle* debugAngle(int id) const;
+    SkOpContour* debugContour(int id);
+
+    int debugID() const {
+        return PATH_OPS_DEBUG_RELEASE(fID, -1);
+    }
+
+#if DEBUG_SORT
+    void debugLoop() const;
+#endif
+
+#if DEBUG_ANGLE
+    SkString debugPart() const;
+#endif
+    const SkOpPtT* debugPtT(int id) const;
+    const SkOpSegment* debugSegment(int id) const;
+    const SkOpSpanBase* debugSpan(int id) const;
+    void debugValidate() const; 
+    void debugValidateNext() const;  // in debug builds, verify that angle loop is uncorrupted
+    double distEndRatio(double dist) const;
+    // available to testing only
+    void dump() const;
+    void dumpCurves() const;
+    void dumpLoop() const;
+    void dumpOne(bool functionHeader) const;
+    void dumpTo(const SkOpSegment* fromSeg, const SkOpAngle* ) const;
+    void dumpTest() const;
+
+    SkOpSpanBase* end() const {
         return fEnd;
     }
 
-    const SkOpAngle* findFirst() const;
-
-    bool inLoop() const {
-        return !!fNext;
-    }
-
+    bool endsIntersect(SkOpAngle* );
+    bool endToSide(const SkOpAngle* rh, bool* inside) const;
+    SkOpAngle* findFirst();
+    int findSector(SkPath::Verb verb, double x, double y) const;
+    SkOpGlobalState* globalState() const;
     void insert(SkOpAngle* );
-    bool isHorizontal() const;
-    SkOpSpan* lastMarked() const;
-    bool loopContains(const SkOpAngle& ) const;
+    SkOpSpanBase* lastMarked() const;
+    bool loopContains(const SkOpAngle* ) const;
     int loopCount() const;
     void markStops();
     bool merge(SkOpAngle* );
+    double midT() const;
+    bool midToSide(const SkOpAngle* rh, bool* inside) const;
 
     SkOpAngle* next() const {
         return fNext;
     }
 
+    bool oppositePlanes(const SkOpAngle* rh) const;
+    bool orderable(SkOpAngle* rh);  // false == this < rh ; true == this > rh
     SkOpAngle* previous() const;
 
     int sectorEnd() const {
@@ -58,120 +96,57 @@
         return fSectorStart;
     }
 
-    void set(const SkOpSegment* segment, int start, int end);
+    SkOpSegment* segment() const;
 
-    void setLastMarked(SkOpSpan* marked) {
+    void set(SkOpSpanBase* start, SkOpSpanBase* end);
+    void setCurveHullSweep();
+
+    void setID(int id) {
+        PATH_OPS_DEBUG_CODE(fID = id);
+    }
+
+    void setLastMarked(SkOpSpanBase* marked) {
         fLastMarked = marked;
     }
 
-    SkOpSegment* segment() const {
-        return const_cast<SkOpSegment*>(fSegment);
-    }
+    void setSector();
+    void setSpans();
+    int sign() const;
 
-    int sign() const {
-        return SkSign32(fStart - fEnd);
-    }
-
-    bool small() const;
-
-    int start() const {
+    SkOpSpanBase* start() const {
         return fStart;
     }
 
+    SkOpSpan* starter();
+    bool tangentsDiverge(const SkOpAngle* rh, double s0xt0) const;
+
     bool unorderable() const {
         return fUnorderable;
     }
 
-    // available to testing only
-#if DEBUG_SORT
-    void debugLoop() const;  // called by code during run
-#endif
-#if DEBUG_ANGLE
-    void debugSameAs(const SkOpAngle* compare) const;
-#endif
-    void dump() const;
-    void dumpLoop() const;
-    void dumpTo(const SkOpSegment* fromSeg, const SkOpAngle* ) const;
-
-#if DEBUG_ANGLE
-    int debugID() const { return fID; }
-
-    void setID(int id) {
-        fID = id;
-    }
-#else
-    int debugID() const { return 0; }
-#endif
-
-#if DEBUG_VALIDATE
-    void debugValidateLoop() const;
-#endif
-
-private:
-    bool after(const SkOpAngle* test) const;
-    int allOnOneSide(const SkOpAngle& test) const;
-    bool calcSlop(double x, double y, double rx, double ry, bool* result) const;
-    bool checkCrossesZero() const;
-    bool checkParallel(const SkOpAngle& ) const;
-    bool computeSector();
-    int convexHullOverlaps(const SkOpAngle& ) const;
-    double distEndRatio(double dist) const;
-    int findSector(SkPath::Verb verb, double x, double y) const;
-    bool endsIntersect(const SkOpAngle& ) const;
-    double midT() const;
-    bool oppositePlanes(const SkOpAngle& rh) const;
-    bool orderable(const SkOpAngle& rh) const;  // false == this < rh ; true == this > rh
-    bool overlap(const SkOpAngle& test) const;
-    void setCurveHullSweep();
-    void setSector();
-    void setSpans();
-    bool tangentsDiverge(const SkOpAngle& rh, double s0xt0) const;
-
-    SkDCubic fCurvePart; // the curve from start to end
+    SkDCubic fCurvePart;  // the curve from start to end
     double fSide;
     SkLineParameters fTangentHalf;  // used only to sort a pair of lines or line-like sections
-    const SkOpSegment* fSegment;
     SkOpAngle* fNext;
-    SkOpSpan* fLastMarked;
+    SkOpSpanBase* fLastMarked;
     SkDVector fSweep[2];
-    int fStart;
-    int fEnd;
-    int fComputedEnd;
+    SkOpSpanBase* fStart;
+    SkOpSpanBase* fEnd;
+    SkOpSpanBase* fComputedEnd;
     int fSectorMask;
     int8_t fSectorStart;  // in 32nds of a circle
     int8_t fSectorEnd;
     bool fIsCurve;
-    bool fStop; // set if ordered angle is greater than the previous
-    mutable bool fUnorderable;  // this is editable by orderable()
+    bool fStop;  // set if ordered angle is greater than the previous
+    bool fUnorderable;
     bool fUnorderedSweep;  // set when a cubic's first control point between the sweep vectors
     bool fComputeSector;
     bool fComputedSector;
+    bool fCheckCoincidence;
+    PATH_OPS_DEBUG_CODE(int fID);
 
-#if DEBUG_ANGLE
-    int fID;
-#endif
-#if DEBUG_VALIDATE
-    void debugValidateNext() const;  // in debug builds, verify that angle loop is uncorrupted
-#else
-    void debugValidateNext() const {}
-#endif
-    void dumpOne(bool showFunc) const;  // available to testing only
-    void dumpPartials() const;  // utility to be called by user from debugger
-    friend class PathOpsAngleTester;
 };
 
-class SkOpAngleSet {
-public:
-    SkOpAngleSet();
-    ~SkOpAngleSet();
-    SkOpAngle& push_back();
-    void reset();
-private:
-    void dump() const;  // utility to be called by user from debugger
-    SkChunkAlloc* fAngles;
-#if DEBUG_ANGLE
-    int fCount;
-#endif
-};
+
 
 #endif
diff --git a/src/pathops/SkOpCoincidence.cpp b/src/pathops/SkOpCoincidence.cpp
new file mode 100755
index 0000000..45eee0a
--- /dev/null
+++ b/src/pathops/SkOpCoincidence.cpp
@@ -0,0 +1,388 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkOpCoincidence.h"
+#include "SkOpSegment.h"
+#include "SkPathOpsTSect.h"
+
+void SkOpCoincidence::add(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart,
+        SkOpPtT* oppPtTEnd, SkChunkAlloc* allocator) {
+    SkASSERT(coinPtTStart->fT < coinPtTEnd->fT);
+    bool flipped = oppPtTStart->fT > oppPtTEnd->fT;
+    SkCoincidentSpans* coinRec = SkOpTAllocator<SkCoincidentSpans>::Allocate(allocator);
+    coinRec->fNext = this->fHead;
+    coinRec->fCoinPtTStart = coinPtTStart;
+    coinRec->fCoinPtTEnd = coinPtTEnd;
+    coinRec->fOppPtTStart = oppPtTStart;
+    coinRec->fOppPtTEnd = oppPtTEnd;
+    coinRec->fFlipped = flipped;
+    this->fHead = coinRec;
+}
+
+static void tRange(const SkOpPtT* overS, const SkOpPtT* overE, double tStart, double tEnd,
+        const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, double* coinTs, double* coinTe) {
+    double denom = overE->fT - overS->fT;
+    double start = 0 < denom ? tStart : tEnd;
+    double end = 0 < denom ? tEnd : tStart;
+    double sRatio = (start - overS->fT) / denom;
+    double eRatio = (end - overS->fT) / denom;
+    *coinTs = coinPtTStart->fT + (coinPtTEnd->fT - coinPtTStart->fT) * sRatio;
+    *coinTe = coinPtTStart->fT + (coinPtTEnd->fT - coinPtTStart->fT) * eRatio;
+}
+
+bool SkOpCoincidence::addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e,
+                      const SkOpPtT* over2s, const SkOpPtT* over2e, double tStart, double tEnd,
+        SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
+        SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd, SkChunkAlloc* allocator) {
+    double coinTs, coinTe, oppTs, oppTe;
+    tRange(over1s, over1e, tStart, tEnd, coinPtTStart, coinPtTEnd, &coinTs, &coinTe);
+    tRange(over2s, over2e, tStart, tEnd, oppPtTStart, oppPtTEnd, &oppTs, &oppTe);
+    SkOpSegment* coinSeg = coinPtTStart->segment();
+    SkOpSegment* oppSeg = oppPtTStart->segment();
+    SkASSERT(coinSeg != oppSeg);
+    SkCoincidentSpans* check = this->fHead;
+    do {
+        const SkOpSegment* checkCoinSeg = check->fCoinPtTStart->segment();
+        if (checkCoinSeg != coinSeg && checkCoinSeg != oppSeg) {
+            continue;
+        }
+        const SkOpSegment* checkOppSeg = check->fOppPtTStart->segment();
+        if (checkOppSeg != coinSeg && checkOppSeg != oppSeg) {
+            continue;
+        }
+        int cTs = coinTs;
+        int cTe = coinTe;
+        int oTs = oppTs;
+        int oTe = oppTe;
+        if (checkCoinSeg != coinSeg) {
+            SkASSERT(checkOppSeg != oppSeg);
+            SkTSwap(cTs, oTs);
+            SkTSwap(cTe, oTe);
+        }
+        int tweenCount = (int) between(check->fCoinPtTStart->fT, cTs, check->fCoinPtTEnd->fT)
+                       + (int) between(check->fCoinPtTStart->fT, cTe, check->fCoinPtTEnd->fT)
+                       + (int) between(check->fOppPtTStart->fT, oTs, check->fOppPtTEnd->fT)
+                       + (int) between(check->fOppPtTStart->fT, oTe, check->fOppPtTEnd->fT);
+//        SkASSERT(tweenCount == 0 || tweenCount == 4);
+        if (tweenCount) {
+            return true;
+        }
+    } while ((check = check->fNext));
+    if ((over1s->fT < over1e->fT) != (over2s->fT < over2e->fT)) {
+        SkTSwap(oppTs, oppTe);
+    }
+    if (coinTs > coinTe) {
+        SkTSwap(coinTs, coinTe);
+        SkTSwap(oppTs, oppTe);
+    }
+    SkOpPtT* cs = coinSeg->addMissing(coinTs, oppSeg, allocator);
+    SkOpPtT* ce = coinSeg->addMissing(coinTe, oppSeg, allocator);
+    if (cs == ce) {
+        return false;
+    }
+    SkOpPtT* os = oppSeg->addMissing(oppTs, coinSeg, allocator);
+    SkOpPtT* oe = oppSeg->addMissing(oppTe, coinSeg, allocator);
+    SkASSERT(os != oe);
+    cs->addOpp(os);
+    ce->addOpp(oe);
+    this->add(cs, ce, os, oe, allocator);
+    return true;
+}
+
+bool SkOpCoincidence::addMissing(SkChunkAlloc* allocator) {
+    SkCoincidentSpans* outer = this->fHead;
+    if (!outer) {
+        return true;
+    }
+    do {
+        SkCoincidentSpans* inner = outer;
+        while ((inner = inner->fNext)) {
+            double overS, overE;
+            if (this->overlap(outer->fCoinPtTStart, outer->fCoinPtTEnd,
+                    inner->fCoinPtTStart, inner->fCoinPtTEnd, &overS, &overE)) {
+                if (!addIfMissing(outer->fCoinPtTStart, outer->fCoinPtTEnd,
+                        inner->fCoinPtTStart, inner->fCoinPtTEnd, overS, overE,
+                        outer->fOppPtTStart, outer->fOppPtTEnd,
+                        inner->fOppPtTStart, inner->fOppPtTEnd, allocator)) {
+                    return false;
+                }
+            } else if (this->overlap(outer->fCoinPtTStart, outer->fCoinPtTEnd,
+                    inner->fOppPtTStart, inner->fOppPtTEnd, &overS, &overE)) {
+                if (!addIfMissing(outer->fCoinPtTStart, outer->fCoinPtTEnd,
+                        inner->fOppPtTStart, inner->fOppPtTEnd, overS, overE,
+                        outer->fOppPtTStart, outer->fOppPtTEnd,
+                        inner->fCoinPtTStart, inner->fCoinPtTEnd, allocator)) {
+                    return false;
+                }
+            } else if (this->overlap(outer->fOppPtTStart, outer->fOppPtTEnd,
+                    inner->fCoinPtTStart, inner->fCoinPtTEnd, &overS, &overE)) {
+                if (!addIfMissing(outer->fOppPtTStart, outer->fOppPtTEnd,
+                        inner->fCoinPtTStart, inner->fCoinPtTEnd, overS, overE,
+                        outer->fCoinPtTStart, outer->fCoinPtTEnd,
+                        inner->fOppPtTStart, inner->fOppPtTEnd, allocator)) {
+                    return false;
+                }
+            } else if (this->overlap(outer->fOppPtTStart, outer->fOppPtTEnd,
+                    inner->fOppPtTStart, inner->fOppPtTEnd, &overS, &overE)) {
+                if (!addIfMissing(outer->fOppPtTStart, outer->fOppPtTEnd,
+                        inner->fOppPtTStart, inner->fOppPtTEnd, overS, overE,
+                        outer->fCoinPtTStart, outer->fCoinPtTEnd,
+                        inner->fCoinPtTStart, inner->fCoinPtTEnd, allocator)) {
+                    return false;
+                }
+            }
+        }
+
+    } while ((outer = outer->fNext));
+    return true;
+}
+
+
+bool SkOpCoincidence::contains(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart,
+        SkOpPtT* oppPtTEnd, bool flipped) {
+    SkCoincidentSpans* coin = fHead;
+    if (!coin) {
+        return false;
+    }
+    do {
+        if (coin->fCoinPtTStart == coinPtTStart &&  coin->fCoinPtTEnd == coinPtTEnd
+                && coin->fOppPtTStart == oppPtTStart && coin->fOppPtTEnd == oppPtTEnd
+                && coin->fFlipped == flipped) {
+            return true;
+        }
+    } while ((coin = coin->fNext));
+    return false;
+}
+
+// walk span sets in parallel, moving winding from one to the other
+bool SkOpCoincidence::apply() {
+    SkCoincidentSpans* coin = fHead;
+    if (!coin) {
+        return true;
+    }
+    do {
+        SkOpSpanBase* end = coin->fCoinPtTEnd->span();
+        SkOpSpan* start = coin->fCoinPtTStart->span()->upCast();
+        SkASSERT(start == start->starter(end));
+        bool flipped = coin->fFlipped;
+        SkOpSpanBase* oEnd = (flipped ? coin->fOppPtTStart : coin->fOppPtTEnd)->span();
+        SkOpSpan* oStart = (flipped ? coin->fOppPtTEnd : coin->fOppPtTStart)->span()->upCast();
+        SkASSERT(oStart == oStart->starter(oEnd));
+        SkOpSegment* segment = start->segment();
+        SkOpSegment* oSegment = oStart->segment();
+        bool operandSwap = segment->operand() != oSegment->operand();
+        if (flipped) {
+            do {
+                SkOpSpanBase* oNext = oStart->next();
+                if (oNext == oEnd) {
+                    break;
+                }
+                oStart = oNext->upCast();
+            } while (true);
+        }
+        bool isXor = segment->isXor();
+        bool oppXor = oSegment->isXor();
+        do {
+            int windValue = start->windValue();
+            int oWindValue = oStart->windValue();
+            int oppValue = start->oppValue();
+            int oOppValue = oStart->oppValue();
+            // winding values are added or subtracted depending on direction and wind type
+            // same or opposite values are summed depending on the operand value
+            if (windValue >= oWindValue) {
+                if (operandSwap) {
+                    SkTSwap(oWindValue, oOppValue);
+                }
+                if (flipped) {
+                    windValue -= oWindValue;
+                    oppValue -= oOppValue;
+                } else {
+                    windValue += oWindValue;
+                    oppValue += oOppValue;
+                }
+                if (isXor) {
+                    windValue &= 1;
+                }
+                if (oppXor) {
+                    oppValue &= 1;
+                }
+                oWindValue = oOppValue = 0;
+            } else {
+                if (operandSwap) {
+                    SkTSwap(windValue, oppValue);
+                }
+                if (flipped) {
+                    oWindValue -= windValue;
+                    oOppValue -= oppValue;
+                } else {
+                    oWindValue += windValue;
+                    oOppValue += oppValue;
+                }
+                if (isXor) {
+                    oOppValue &= 1;
+                }
+                if (oppXor) {
+                    oWindValue &= 1;
+                }
+                windValue = oppValue = 0;
+            }
+            start->setWindValue(windValue);
+            start->setOppValue(oppValue);
+            oStart->setWindValue(oWindValue);
+            oStart->setOppValue(oOppValue);
+            if (!windValue && !oppValue) {
+                segment->markDone(start);
+            }
+            if (!oWindValue && !oOppValue) {
+                oSegment->markDone(oStart);
+            }
+            SkOpSpanBase* next = start->next();
+            SkOpSpanBase* oNext = flipped ? oStart->prev() : oStart->next();
+            if (next == end) {
+                break;
+            }
+            start = next->upCast();
+            if (!oNext) {
+                return false;
+            }
+            if (!oNext->upCastable()) {
+                return false;
+            }
+            oStart = oNext->upCast();
+        } while (true);
+    } while ((coin = coin->fNext));
+    return true;
+}
+
+void SkOpCoincidence::detach(SkCoincidentSpans* remove) {
+    SkCoincidentSpans* coin = fHead;
+    SkCoincidentSpans* prev = NULL;
+    SkCoincidentSpans* next;
+    do {
+        next = coin->fNext;
+        if (coin == remove) {
+            if (prev) {
+                prev->fNext = next;
+            } else {
+                fHead = next;
+            }
+            break;
+        }
+        prev = coin;
+    } while ((coin = next));
+    SkASSERT(coin);
+}
+
+void SkOpCoincidence::expand() {
+    SkCoincidentSpans* coin = fHead;
+    if (!coin) {
+        return;
+    }
+    do {
+        SkOpSpan* start = coin->fCoinPtTStart->span()->upCast();
+        SkOpSpanBase* end = coin->fCoinPtTEnd->span();
+        SkOpSegment* segment = coin->fCoinPtTStart->segment();
+        SkOpSegment* oppSegment = coin->fOppPtTStart->segment();
+        SkOpSpan* prev = start->prev();
+        SkOpPtT* oppPtT;
+        if (prev && (oppPtT = prev->contains(oppSegment))) {
+            double midT = (prev->t() + start->t()) / 2;
+            if (segment->isClose(midT, oppSegment)) {
+                coin->fCoinPtTStart = prev->ptT();
+                coin->fOppPtTStart = oppPtT;
+            }
+        }
+        SkOpSpanBase* next = end->final() ? NULL : end->upCast()->next();
+        if (next && (oppPtT = next->contains(oppSegment))) {
+            double midT = (end->t() + next->t()) / 2;
+            if (segment->isClose(midT, oppSegment)) {
+                coin->fCoinPtTEnd = next->ptT();
+                coin->fOppPtTEnd = oppPtT;
+            }
+        }
+    } while ((coin = coin->fNext));
+}
+
+void SkOpCoincidence::fixUp(SkOpPtT* deleted, SkOpPtT* kept) {
+    SkCoincidentSpans* coin = fHead;
+    if (!coin) {
+        return;
+    }
+    do {
+        if (coin->fCoinPtTStart == deleted) {
+            if (coin->fCoinPtTEnd->span() == kept->span()) {
+                return this->detach(coin);
+            }
+            coin->fCoinPtTStart = kept;
+        }
+        if (coin->fCoinPtTEnd == deleted) {
+            if (coin->fCoinPtTStart->span() == kept->span()) {
+                return this->detach(coin);
+            }
+            coin->fCoinPtTEnd = kept;
+        }
+        if (coin->fOppPtTStart == deleted) {
+            if (coin->fOppPtTEnd->span() == kept->span()) {
+                return this->detach(coin);
+            }
+            coin->fOppPtTStart = kept;
+        }
+        if (coin->fOppPtTEnd == deleted) {
+            if (coin->fOppPtTStart->span() == kept->span()) {
+                return this->detach(coin);
+            }
+            coin->fOppPtTEnd = kept;
+        }
+    } while ((coin = coin->fNext));
+}
+
+void SkOpCoincidence::mark() {
+    SkCoincidentSpans* coin = fHead;
+    if (!coin) {
+        return;
+    }
+    do {
+        SkOpSpanBase* end = coin->fCoinPtTEnd->span();
+        SkOpSpanBase* oldEnd = end;
+        SkOpSpan* start = coin->fCoinPtTStart->span()->starter(&end);
+        SkOpSpanBase* oEnd = coin->fOppPtTEnd->span();
+        SkOpSpanBase* oOldEnd = oEnd;
+        SkOpSpanBase* oStart = coin->fOppPtTStart->span()->starter(&oEnd);
+        bool flipped = (end == oldEnd) != (oEnd == oOldEnd);
+        if (flipped) {
+            SkTSwap(oStart, oEnd);
+        }
+        SkOpSpanBase* next = start;
+        SkOpSpanBase* oNext = oStart;
+        // check to see if coincident span could be bigger
+
+        do {
+            next = next->upCast()->next();
+            oNext = flipped ? oNext->prev() : oNext->upCast()->next();
+            if (next == end || oNext == oEnd) {
+                break;
+            }
+            if (!next->containsCoinEnd(oNext)) {
+                next->insertCoinEnd(oNext);
+            }
+            SkOpSpan* nextSpan = next->upCast();
+            SkOpSpan* oNextSpan = oNext->upCast();
+            if (!nextSpan->containsCoincidence(oNextSpan)) {
+                nextSpan->insertCoincidence(oNextSpan);
+            }
+        } while (true);
+    } while ((coin = coin->fNext));
+}
+
+bool SkOpCoincidence::overlap(const SkOpPtT* coin1s, const SkOpPtT* coin1e, 
+        const SkOpPtT* coin2s, const SkOpPtT* coin2e, double* overS, double* overE) const {
+    if (coin1s->segment() != coin2s->segment()) {
+        return false;
+    }
+    *overS = SkTMax(SkTMin(coin1s->fT, coin1e->fT), SkTMin(coin2s->fT, coin2e->fT));
+    *overE = SkTMin(SkTMax(coin1s->fT, coin1e->fT), SkTMax(coin2s->fT, coin2e->fT));
+    return *overS < *overE;
+}
diff --git a/src/pathops/SkOpCoincidence.h b/src/pathops/SkOpCoincidence.h
index 287bfd1..b79b88b 100644
--- a/src/pathops/SkOpCoincidence.h
+++ b/src/pathops/SkOpCoincidence.h
@@ -19,6 +19,8 @@
     SkOpPtT* fOppPtTStart;
     SkOpPtT* fOppPtTEnd;
     bool fFlipped;
+
+    void dump() const;
 };
 
 class SkOpCoincidence {
@@ -28,13 +30,27 @@
     }
 
     void add(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart,
-             SkOpPtT* oppPtTEnd, bool flipped, SkChunkAlloc* allocator);
-    void apply();
+             SkOpPtT* oppPtTEnd, SkChunkAlloc* allocator);
+    bool addMissing(SkChunkAlloc* allocator);
+    bool apply();
     bool contains(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart,
                   SkOpPtT* oppPtTEnd, bool flipped);
+    void detach(SkCoincidentSpans* );
     void dump() const;
+    void expand();
+    void fixUp(SkOpPtT* deleted, SkOpPtT* kept);
     void mark();
 
+private:
+    bool addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e,
+                      const SkOpPtT* over2s, const SkOpPtT* over2e, double tStart, double tEnd,
+                      SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
+                      SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd,
+                      SkChunkAlloc* allocator);
+    bool overlap(const SkOpPtT* coinStart1, const SkOpPtT* coinEnd1,
+                 const SkOpPtT* coinStart2, const SkOpPtT* coinEnd2,
+                 double* overS, double* overE) const;
+
     SkCoincidentSpans* fHead;
 };
 
diff --git a/src/pathops/SkOpContour.cpp b/src/pathops/SkOpContour.cpp
index 28c072a..d17b189 100644
--- a/src/pathops/SkOpContour.cpp
+++ b/src/pathops/SkOpContour.cpp
@@ -4,42 +4,35 @@
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
-#include "SkIntersections.h"
 #include "SkOpContour.h"
+#include "SkOpTAllocator.h"
 #include "SkPathWriter.h"
+#include "SkReduceOrder.h"
 #include "SkTSort.h"
 
-bool SkOpContour::addCoincident(int index, SkOpContour* other, int otherIndex,
-        const SkIntersections& ts, bool swap) {
-    SkPoint pt0 = ts.pt(0).asSkPoint();
-    SkPoint pt1 = ts.pt(1).asSkPoint();
-    if (pt0 == pt1 || ts[0][0] == ts[0][1] || ts[1][0] == ts[1][1]) {
-        // FIXME: one could imagine a case where it would be incorrect to ignore this
-        // suppose two self-intersecting cubics overlap to be coincident --
-        // this needs to check that by some measure the t values are far enough apart
-        // or needs to check to see if the self-intersection bit was set on the cubic segment
-        return false;
+void SkOpContour::addCurve(SkPath::Verb verb, const SkPoint pts[4], SkChunkAlloc* allocator) {
+    switch (verb) {
+        case SkPath::kLine_Verb: {
+            SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 2);
+            memcpy(ptStorage, pts, sizeof(SkPoint) * 2);
+            appendSegment(allocator).addLine(ptStorage, this);
+        } break;
+        case SkPath::kQuad_Verb: {
+            SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3);
+            memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
+            appendSegment(allocator).addQuad(ptStorage, this);
+        } break;
+        case SkPath::kCubic_Verb: {
+            SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 4);
+            memcpy(ptStorage, pts, sizeof(SkPoint) * 4);
+            appendSegment(allocator).addCubic(ptStorage, this);
+        } break;
+        default:
+            SkASSERT(0);
     }
-    SkCoincidence& coincidence = fCoincidences.push_back();
-    coincidence.fOther = other;
-    coincidence.fSegments[0] = index;
-    coincidence.fSegments[1] = otherIndex;
-    coincidence.fTs[swap][0] = ts[0][0];
-    coincidence.fTs[swap][1] = ts[0][1];
-    coincidence.fTs[!swap][0] = ts[1][0];
-    coincidence.fTs[!swap][1] = ts[1][1];
-    coincidence.fPts[swap][0] = pt0;
-    coincidence.fPts[swap][1] = pt1;
-    bool nearStart = ts.nearlySame(0);
-    bool nearEnd = ts.nearlySame(1);
-    coincidence.fPts[!swap][0] = nearStart ? ts.pt2(0).asSkPoint() : pt0;
-    coincidence.fPts[!swap][1] = nearEnd ? ts.pt2(1).asSkPoint() : pt1;
-    coincidence.fNearly[0] = nearStart;
-    coincidence.fNearly[1] = nearEnd;
-    return true;
 }
 
-SkOpSegment* SkOpContour::nonVerticalSegment(int* start, int* end) {
+SkOpSegment* SkOpContour::nonVerticalSegment(SkOpSpanBase** start, SkOpSpanBase** end) {
     int segmentCount = fSortedSegments.count();
     SkASSERT(segmentCount > 0);
     for (int sortedIndex = fFirstSorted; sortedIndex < segmentCount; ++sortedIndex) {
@@ -47,627 +40,27 @@
         if (testSegment->done()) {
             continue;
         }
-        *start = *end = 0;
-        while (testSegment->nextCandidate(start, end)) {
-            if (!testSegment->isVertical(*start, *end)) {
+        SkOpSpanBase* span = testSegment->head();
+        SkOpSpanBase* testS, * testE;
+        while (SkOpSegment::NextCandidate(span, &testS, &testE)) {
+            if (!testSegment->isVertical(testS, testE)) {
+                *start = testS;
+                *end = testE;
                 return testSegment;
             }
+            span = span->upCast()->next();
         }
     }
     return NULL;
 }
 
-// if one is very large the smaller may have collapsed to nothing
-static void bump_out_close_span(double* startTPtr, double* endTPtr) {
-    double startT = *startTPtr;
-    double endT = *endTPtr;
-    if (approximately_negative(endT - startT)) {
-        if (endT <= 1 - FLT_EPSILON) {
-            *endTPtr += FLT_EPSILON;
-            SkASSERT(*endTPtr <= 1);
-        } else {
-            *startTPtr -= FLT_EPSILON;
-            SkASSERT(*startTPtr >= 0);
-        }
-    }
-}
-
-// first pass, add missing T values
-// second pass, determine winding values of overlaps
-void SkOpContour::addCoincidentPoints() {
-    int count = fCoincidences.count();
-    for (int index = 0; index < count; ++index) {
-        SkCoincidence& coincidence = fCoincidences[index];
-        int thisIndex = coincidence.fSegments[0];
-        SkOpSegment& thisOne = fSegments[thisIndex];
-        SkOpContour* otherContour = coincidence.fOther;
-        int otherIndex = coincidence.fSegments[1];
-        SkOpSegment& other = otherContour->fSegments[otherIndex];
-        if ((thisOne.done() || other.done()) && thisOne.complete() && other.complete()) {
-            // OPTIMIZATION: remove from array
-            continue;
-        }
-    #if DEBUG_CONCIDENT
-        thisOne.debugShowTs("-");
-        other.debugShowTs("o");
-    #endif
-        double startT = coincidence.fTs[0][0];
-        double endT = coincidence.fTs[0][1];
-        bool startSwapped, oStartSwapped, cancelers;
-        if ((cancelers = startSwapped = startT > endT)) {
-            SkTSwap(startT, endT);
-        }
-        bump_out_close_span(&startT, &endT);
-        SkASSERT(!approximately_negative(endT - startT));
-        double oStartT = coincidence.fTs[1][0];
-        double oEndT = coincidence.fTs[1][1];
-        if ((oStartSwapped = oStartT > oEndT)) {
-            SkTSwap(oStartT, oEndT);
-            cancelers ^= true;
-        }
-        bump_out_close_span(&oStartT, &oEndT);
-        SkASSERT(!approximately_negative(oEndT - oStartT));
-        const SkPoint& startPt = coincidence.fPts[0][startSwapped];
-        if (cancelers) {
-            // make sure startT and endT have t entries
-            if (startT > 0 || oEndT < 1
-                    || thisOne.isMissing(startT, startPt) || other.isMissing(oEndT, startPt)) {
-                thisOne.addTPair(startT, &other, oEndT, true, startPt,
-                        coincidence.fPts[1][startSwapped]);
-            }
-            const SkPoint& oStartPt = coincidence.fPts[1][oStartSwapped];
-            if (oStartT > 0 || endT < 1
-                    || thisOne.isMissing(endT, oStartPt) || other.isMissing(oStartT, oStartPt)) {
-                other.addTPair(oStartT, &thisOne, endT, true, oStartPt,
-                        coincidence.fPts[0][oStartSwapped]);
-            }
-        } else {
-            if (startT > 0 || oStartT > 0
-                    || thisOne.isMissing(startT, startPt) || other.isMissing(oStartT, startPt)) {
-                thisOne.addTPair(startT, &other, oStartT, true, startPt,
-                        coincidence.fPts[1][startSwapped]);
-            }
-            const SkPoint& oEndPt = coincidence.fPts[1][!oStartSwapped];
-            if (endT < 1 || oEndT < 1
-                    || thisOne.isMissing(endT, oEndPt) || other.isMissing(oEndT, oEndPt)) {
-                other.addTPair(oEndT, &thisOne, endT, true, oEndPt,
-                        coincidence.fPts[0][!oStartSwapped]);
-            }
-        }
-    #if DEBUG_CONCIDENT
-        thisOne.debugShowTs("+");
-        other.debugShowTs("o");
-    #endif
-    }
-    // if there are multiple pairs of coincidence that share an edge, see if the opposite
-    // are also coincident
-    for (int index = 0; index < count - 1; ++index) {
-        const SkCoincidence& coincidence = fCoincidences[index];
-        int thisIndex = coincidence.fSegments[0];
-        SkOpContour* otherContour = coincidence.fOther;
-        int otherIndex = coincidence.fSegments[1];
-        for (int idx2 = 1; idx2 < count; ++idx2) {
-            const SkCoincidence& innerCoin = fCoincidences[idx2];
-            int innerThisIndex = innerCoin.fSegments[0];
-            if (thisIndex == innerThisIndex) {
-                checkCoincidentPair(coincidence, 1, innerCoin, 1, false);
-            }
-            if (this == otherContour && otherIndex == innerThisIndex) {
-                checkCoincidentPair(coincidence, 0, innerCoin, 1, false);
-            }
-            SkOpContour* innerOtherContour = innerCoin.fOther;
-            innerThisIndex = innerCoin.fSegments[1];
-            if (this == innerOtherContour && thisIndex == innerThisIndex) {
-                checkCoincidentPair(coincidence, 1, innerCoin, 0, false);
-            }
-            if (otherContour == innerOtherContour && otherIndex == innerThisIndex) {
-                checkCoincidentPair(coincidence, 0, innerCoin, 0, false);
-            }
-        }
-    }
-}
-
-bool SkOpContour::addPartialCoincident(int index, SkOpContour* other, int otherIndex,
-        const SkIntersections& ts, int ptIndex, bool swap) {
-    SkPoint pt0 = ts.pt(ptIndex).asSkPoint();
-    SkPoint pt1 = ts.pt(ptIndex + 1).asSkPoint();
-    if (SkDPoint::ApproximatelyEqual(pt0, pt1)) {
-        // FIXME: one could imagine a case where it would be incorrect to ignore this
-        // suppose two self-intersecting cubics overlap to form a partial coincidence --
-        // although it isn't clear why the regular coincidence could wouldn't pick this up
-        // this is exceptional enough to ignore for now
-        return false;
-    }
-    SkCoincidence& coincidence = fPartialCoincidences.push_back();
-    coincidence.fOther = other;
-    coincidence.fSegments[0] = index;
-    coincidence.fSegments[1] = otherIndex;
-    coincidence.fTs[swap][0] = ts[0][ptIndex];
-    coincidence.fTs[swap][1] = ts[0][ptIndex + 1];
-    coincidence.fTs[!swap][0] = ts[1][ptIndex];
-    coincidence.fTs[!swap][1] = ts[1][ptIndex + 1];
-    coincidence.fPts[0][0] = coincidence.fPts[1][0] = pt0;
-    coincidence.fPts[0][1] = coincidence.fPts[1][1] = pt1;
-    coincidence.fNearly[0] = 0;
-    coincidence.fNearly[1] = 0;
-    return true;
-}
-
-void SkOpContour::align(const SkOpSegment::AlignedSpan& aligned, bool swap,
-        SkCoincidence* coincidence) {
-    for (int idx2 = 0; idx2 < 2; ++idx2) {
-        if (coincidence->fPts[0][idx2] == aligned.fOldPt
-                && coincidence->fTs[swap][idx2] == aligned.fOldT) {
-            SkASSERT(SkDPoint::RoughlyEqual(coincidence->fPts[0][idx2], aligned.fPt));
-            coincidence->fPts[0][idx2] = aligned.fPt;
-            SkASSERT(way_roughly_equal(coincidence->fTs[swap][idx2], aligned.fT));
-            coincidence->fTs[swap][idx2] = aligned.fT;
-        }
-    }
-}
-
-void SkOpContour::alignCoincidence(const SkOpSegment::AlignedSpan& aligned,
-        SkTArray<SkCoincidence, true>* coincidences) {
-    int count = coincidences->count();
-    for (int index = 0; index < count; ++index) {
-        SkCoincidence& coincidence = (*coincidences)[index];
-        int thisIndex = coincidence.fSegments[0];
-        const SkOpSegment* thisOne = &fSegments[thisIndex];
-        const SkOpContour* otherContour = coincidence.fOther;
-        int otherIndex = coincidence.fSegments[1];
-        const SkOpSegment* other = &otherContour->fSegments[otherIndex];
-        if (thisOne == aligned.fOther1 && other == aligned.fOther2) {
-            align(aligned, false, &coincidence);
-        } else if (thisOne == aligned.fOther2 && other == aligned.fOther1) {
-            align(aligned, true, &coincidence);
-        }
-    }
-}
-
-void SkOpContour::alignTPt(int segmentIndex, const SkOpContour* other, int otherIndex, 
-        bool swap, int tIndex, SkIntersections* ts, SkPoint* point) const {
-    int zeroPt;
-    if ((zeroPt = alignT(swap, tIndex, ts)) >= 0) {
-        alignPt(segmentIndex, point, zeroPt);
-    }
-    if ((zeroPt = other->alignT(!swap, tIndex, ts)) >= 0) {
-        other->alignPt(otherIndex, point, zeroPt);
-    }
-}
-
-void SkOpContour::alignPt(int index, SkPoint* point, int zeroPt) const {
-    const SkOpSegment& segment = fSegments[index];
-    if (0 == zeroPt) {     
-        *point = segment.pts()[0];
-    } else {
-        *point = segment.pts()[SkPathOpsVerbToPoints(segment.verb())];
-    }
-}
-
-int SkOpContour::alignT(bool swap, int tIndex, SkIntersections* ts) const {
-    double tVal = (*ts)[swap][tIndex];
-    if (tVal != 0 && precisely_zero(tVal)) {
-        ts->set(swap, tIndex, 0);
-        return 0;
-    } 
-     if (tVal != 1 && precisely_equal(tVal, 1)) {
-        ts->set(swap, tIndex, 1);
-        return 1;
-    }
-    return -1;
-}
-
-bool SkOpContour::calcAngles() {
-    int segmentCount = fSegments.count();
-    for (int test = 0; test < segmentCount; ++test) {
-        if (!fSegments[test].calcAngles()) {
-            return false;
-        }
-    }
-    return true;
-}
-
-bool SkOpContour::calcCoincidentWinding() {
-    int count = fCoincidences.count();
-#if DEBUG_CONCIDENT
-    if (count > 0) {
-        SkDebugf("%s count=%d\n", __FUNCTION__, count);
-    }
-#endif
-    for (int index = 0; index < count; ++index) {
-        SkCoincidence& coincidence = fCoincidences[index];
-        if (!calcCommonCoincidentWinding(coincidence)) {
-            return false;
-        }
-    }
-    return true;
-}
-
-void SkOpContour::calcPartialCoincidentWinding() {
-    int count = fPartialCoincidences.count();
-#if DEBUG_CONCIDENT
-    if (count > 0) {
-        SkDebugf("%s count=%d\n", __FUNCTION__, count);
-    }
-#endif
-    for (int index = 0; index < count; ++index) {
-        SkCoincidence& coincidence = fPartialCoincidences[index];
-        calcCommonCoincidentWinding(coincidence);
-    }
-    // if there are multiple pairs of partial coincidence that share an edge, see if the opposite
-    // are also coincident
-    for (int index = 0; index < count - 1; ++index) {
-        const SkCoincidence& coincidence = fPartialCoincidences[index];
-        int thisIndex = coincidence.fSegments[0];
-        SkOpContour* otherContour = coincidence.fOther;
-        int otherIndex = coincidence.fSegments[1];
-        for (int idx2 = 1; idx2 < count; ++idx2) {
-            const SkCoincidence& innerCoin = fPartialCoincidences[idx2];
-            int innerThisIndex = innerCoin.fSegments[0];
-            if (thisIndex == innerThisIndex) {
-                checkCoincidentPair(coincidence, 1, innerCoin, 1, true);
-            }
-            if (this == otherContour && otherIndex == innerThisIndex) {
-                checkCoincidentPair(coincidence, 0, innerCoin, 1, true);
-            }
-            SkOpContour* innerOtherContour = innerCoin.fOther;
-            innerThisIndex = innerCoin.fSegments[1];
-            if (this == innerOtherContour && thisIndex == innerThisIndex) {
-                checkCoincidentPair(coincidence, 1, innerCoin, 0, true);
-            }
-            if (otherContour == innerOtherContour && otherIndex == innerThisIndex) {
-                checkCoincidentPair(coincidence, 0, innerCoin, 0, true);
-            }
-        }
-    }
-}
-
-void SkOpContour::checkCoincidentPair(const SkCoincidence& oneCoin, int oneIdx,
-        const SkCoincidence& twoCoin, int twoIdx, bool partial) {
-    SkASSERT((oneIdx ? this : oneCoin.fOther) == (twoIdx ? this : twoCoin.fOther));
-    SkASSERT(oneCoin.fSegments[!oneIdx] == twoCoin.fSegments[!twoIdx]);
-    // look for common overlap
-    double min = SK_ScalarMax;
-    double max = SK_ScalarMin;
-    double min1 = oneCoin.fTs[!oneIdx][0];
-    double max1 = oneCoin.fTs[!oneIdx][1];
-    double min2 = twoCoin.fTs[!twoIdx][0];
-    double max2 = twoCoin.fTs[!twoIdx][1];
-    bool cancelers = (min1 < max1) != (min2 < max2);
-    if (min1 > max1) {
-        SkTSwap(min1, max1);
-    }
-    if (min2 > max2) {
-        SkTSwap(min2, max2);
-    }
-    if (between(min1, min2, max1)) {
-        min = min2;
-    }
-    if (between(min1, max2, max1)) {
-        max = max2;
-    }
-    if (between(min2, min1, max2)) {
-        min = SkTMin(min, min1);
-    }
-    if (between(min2, max1, max2)) {
-        max = SkTMax(max, max1);
-    }
-    if (min >= max) {
-        return;  // no overlap
-    }
-    // look to see if opposite are different segments
-    int seg1Index = oneCoin.fSegments[oneIdx];
-    int seg2Index = twoCoin.fSegments[twoIdx];
-    if (seg1Index == seg2Index) {
-        return;
-    }
-    SkOpContour* contour1 = oneIdx ? oneCoin.fOther : this;
-    SkOpContour* contour2 = twoIdx ? twoCoin.fOther : this;
-    SkOpSegment* segment1 = &contour1->fSegments[seg1Index];
-    SkOpSegment* segment2 = &contour2->fSegments[seg2Index];
-    // find opposite t value ranges corresponding to reference min/max range
-    const SkOpContour* refContour = oneIdx ? this : oneCoin.fOther;
-    const int refSegIndex = oneCoin.fSegments[!oneIdx];
-    const SkOpSegment* refSegment = &refContour->fSegments[refSegIndex];
-    int seg1Start = segment1->findOtherT(min, refSegment);
-    int seg1End = segment1->findOtherT(max, refSegment);
-    int seg2Start = segment2->findOtherT(min, refSegment);
-    int seg2End = segment2->findOtherT(max, refSegment);
-    // if the opposite pairs already contain min/max, we're done
-    if (seg1Start >= 0 && seg1End >= 0 && seg2Start >= 0 && seg2End >= 0) {
-        return;
-    }
-    double loEnd = SkTMin(min1, min2);
-    double hiEnd = SkTMax(max1, max2);
-    // insert the missing coincident point(s)
-    double missingT1 = -1;
-    double otherT1 = -1;
-    if (seg1Start < 0) {
-        if (seg2Start < 0) {
-            return;
-        }
-        missingT1 = segment1->calcMissingTStart(refSegment, loEnd, min, max, hiEnd,
-                segment2, seg1End);
-        if (missingT1 < 0) {
-            return;
-        }
-        const SkOpSpan* missingSpan = &segment2->span(seg2Start);
-        otherT1 = missingSpan->fT;
-    } else if (seg2Start < 0) {
-        SkASSERT(seg1Start >= 0);
-        missingT1 = segment2->calcMissingTStart(refSegment, loEnd, min, max, hiEnd,
-                segment1, seg2End);
-        if (missingT1 < 0) {
-            return;
-        }
-        const SkOpSpan* missingSpan = &segment1->span(seg1Start);
-        otherT1 = missingSpan->fT;
-    }
-    SkPoint missingPt1;
-    SkOpSegment* addTo1 = NULL;
-    SkOpSegment* addOther1 = seg1Start < 0 ? segment2 : segment1;
-    int minTIndex = refSegment->findExactT(min, addOther1);
-    SkASSERT(minTIndex >= 0);
-    if (missingT1 >= 0) {
-        missingPt1 = refSegment->span(minTIndex).fPt;
-        addTo1 = seg1Start < 0 ? segment1 : segment2;
-    }
-    double missingT2 = -1;
-    double otherT2 = -1;
-    if (seg1End < 0) {
-        if (seg2End < 0) {
-            return;
-        }
-        missingT2 = segment1->calcMissingTEnd(refSegment, loEnd, min, max, hiEnd,
-                segment2, seg1Start);
-        if (missingT2 < 0) {
-            return;
-        }
-        const SkOpSpan* missingSpan = &segment2->span(seg2End);
-        otherT2 = missingSpan->fT;
-    } else if (seg2End < 0) {
-        SkASSERT(seg1End >= 0);
-        missingT2 = segment2->calcMissingTEnd(refSegment, loEnd, min, max, hiEnd,
-                segment1, seg2Start);
-        if (missingT2 < 0) {
-            return;
-        }
-        const SkOpSpan* missingSpan = &segment1->span(seg1End);
-        otherT2 = missingSpan->fT;
-    }
-    SkPoint missingPt2;
-    SkOpSegment* addTo2 = NULL;
-    SkOpSegment* addOther2 = seg1End < 0 ? segment2 : segment1;
-    int maxTIndex = refSegment->findExactT(max, addOther2);
-    SkASSERT(maxTIndex >= 0);
-    if (missingT2 >= 0) {
-        missingPt2 = refSegment->span(maxTIndex).fPt;
-        addTo2 = seg1End < 0 ? segment1 : segment2;
-    }
-    if (missingT1 >= 0) {
-        addTo1->pinT(missingPt1, &missingT1);
-        addTo1->addTPair(missingT1, addOther1, otherT1, false, missingPt1);
-    } else {
-        SkASSERT(minTIndex >= 0);
-        missingPt1 = refSegment->span(minTIndex).fPt;
-    }
-    if (missingT2 >= 0) {
-        addTo2->pinT(missingPt2, &missingT2);
-        addTo2->addTPair(missingT2, addOther2, otherT2, false, missingPt2);
-    } else {
-        SkASSERT(minTIndex >= 0);
-        missingPt2 = refSegment->span(maxTIndex).fPt;
-    }
-    if (!partial) {
-        return;
-    }
-    if (cancelers) {
-        if (missingT1 >= 0) {
-            if (addTo1->reversePoints(missingPt1, missingPt2)) {
-                SkTSwap(missingPt1, missingPt2);
-            }
-            addTo1->addTCancel(missingPt1, missingPt2, addOther1);
-        } else {
-            if (addTo2->reversePoints(missingPt1, missingPt2)) {
-                SkTSwap(missingPt1, missingPt2);
-            }
-            addTo2->addTCancel(missingPt1, missingPt2, addOther2);
-        }
-    } else if (missingT1 >= 0) {
-        SkAssertResult(addTo1->addTCoincident(missingPt1, missingPt2,
-                addTo1 == addTo2 ? missingT2 : otherT2, addOther1));
-    } else {
-        SkAssertResult(addTo2->addTCoincident(missingPt2, missingPt1,
-                addTo2 == addTo1 ? missingT1 : otherT1, addOther2));
-    }
-}
-
-void SkOpContour::joinCoincidence(const SkTArray<SkCoincidence, true>& coincidences, bool partial) {
-    int count = coincidences.count();
-#if DEBUG_CONCIDENT
-    if (count > 0) {
-        SkDebugf("%s count=%d\n", __FUNCTION__, count);
-    }
-#endif
-    // look for a lineup where the partial implies another adjoining coincidence
-    for (int index = 0; index < count; ++index) {
-        const SkCoincidence& coincidence = coincidences[index];
-        int thisIndex = coincidence.fSegments[0];
-        SkOpSegment& thisOne = fSegments[thisIndex];
-        if (thisOne.done()) {
-            continue;
-        }
-        SkOpContour* otherContour = coincidence.fOther;
-        int otherIndex = coincidence.fSegments[1];
-        SkOpSegment& other = otherContour->fSegments[otherIndex];
-        if (other.done()) {
-            continue;
-        }
-        double startT = coincidence.fTs[0][0];
-        double endT = coincidence.fTs[0][1];
-        if (startT == endT) {  // this can happen in very large compares
-            continue;
-        }
-        double oStartT = coincidence.fTs[1][0];
-        double oEndT = coincidence.fTs[1][1];
-        if (oStartT == oEndT) {
-            continue;
-        }
-        bool swapStart = startT > endT;
-        bool swapOther = oStartT > oEndT;
-        const SkPoint* startPt = &coincidence.fPts[0][0];
-        const SkPoint* endPt = &coincidence.fPts[0][1];
-        if (swapStart) {
-            SkTSwap(startT, endT);
-            SkTSwap(oStartT, oEndT);
-            SkTSwap(startPt, endPt);
-        }
-        bool cancel = swapOther != swapStart;
-        int step = swapStart ? -1 : 1;
-        int oStep = swapOther ? -1 : 1;
-        double oMatchStart = cancel ? oEndT : oStartT;
-        if (partial ? startT != 0 || oMatchStart != 0 : (startT == 0) != (oMatchStart == 0)) {
-            bool added = false;
-            if (oMatchStart != 0) {
-                const SkPoint& oMatchStartPt = cancel ? *endPt : *startPt;
-                added = thisOne.joinCoincidence(&other, oMatchStart, oMatchStartPt, oStep, cancel);
-            }
-            if (!cancel && startT != 0 && !added) {
-                (void) other.joinCoincidence(&thisOne, startT, *startPt, step, cancel);
-            }
-        }
-        double oMatchEnd = cancel ? oStartT : oEndT;
-        if (partial ? endT != 1 || oMatchEnd != 1 : (endT == 1) != (oMatchEnd == 1)) {
-            bool added = false;
-            if (cancel && endT != 1 && !added) {
-                (void) other.joinCoincidence(&thisOne, endT, *endPt, -step, cancel);
-            }
-        }
-    }
-}
-
-bool SkOpContour::calcCommonCoincidentWinding(const SkCoincidence& coincidence) {
-    if (coincidence.fNearly[0] && coincidence.fNearly[1]) {
-        return true;
-    }
-    int thisIndex = coincidence.fSegments[0];
-    SkOpSegment& thisOne = fSegments[thisIndex];
-    if (thisOne.done()) {
-        return true;
-    }
-    SkOpContour* otherContour = coincidence.fOther;
-    int otherIndex = coincidence.fSegments[1];
-    SkOpSegment& other = otherContour->fSegments[otherIndex];
-    if (other.done()) {
-        return true;
-    }
-    double startT = coincidence.fTs[0][0];
-    double endT = coincidence.fTs[0][1];
-    const SkPoint* startPt = &coincidence.fPts[0][0];
-    const SkPoint* endPt = &coincidence.fPts[0][1];
-    bool cancelers;
-    if ((cancelers = startT > endT)) {
-        SkTSwap<double>(startT, endT);
-        SkTSwap<const SkPoint*>(startPt, endPt);
-    }
-    bump_out_close_span(&startT, &endT);
-    SkASSERT(!approximately_negative(endT - startT));
-    double oStartT = coincidence.fTs[1][0];
-    double oEndT = coincidence.fTs[1][1];
-    if (oStartT > oEndT) {
-        SkTSwap<double>(oStartT, oEndT);
-        cancelers ^= true;
-    }
-    bump_out_close_span(&oStartT, &oEndT);
-    SkASSERT(!approximately_negative(oEndT - oStartT));
-    bool success = true;
-    if (cancelers) {
-        thisOne.addTCancel(*startPt, *endPt, &other);
-    } else {
-        success = thisOne.addTCoincident(*startPt, *endPt, endT, &other);
-    }
-#if DEBUG_CONCIDENT
-    thisOne.debugShowTs("p");
-    other.debugShowTs("o");
-#endif
-    return success;
-}
-
-void SkOpContour::resolveNearCoincidence() {
-    int count = fCoincidences.count();
-    for (int index = 0; index < count; ++index) {
-        SkCoincidence& coincidence = fCoincidences[index];
-        if (!coincidence.fNearly[0] || !coincidence.fNearly[1]) {
-            continue;
-        }
-        int thisIndex = coincidence.fSegments[0];
-        SkOpSegment& thisOne = fSegments[thisIndex];
-        SkOpContour* otherContour = coincidence.fOther;
-        int otherIndex = coincidence.fSegments[1];
-        SkOpSegment& other = otherContour->fSegments[otherIndex];
-        if ((thisOne.done() || other.done()) && thisOne.complete() && other.complete()) {
-            // OPTIMIZATION: remove from coincidence array
-            continue;
-        }
-    #if DEBUG_CONCIDENT
-        thisOne.debugShowTs("-");
-        other.debugShowTs("o");
-    #endif
-        double startT = coincidence.fTs[0][0];
-        double endT = coincidence.fTs[0][1];
-        bool cancelers;
-        if ((cancelers = startT > endT)) {
-            SkTSwap<double>(startT, endT);
-        }
-        if (startT == endT) { // if span is very large, the smaller may have collapsed to nothing
-            if (endT <= 1 - FLT_EPSILON) {
-                endT += FLT_EPSILON;
-                SkASSERT(endT <= 1);
-            } else {
-                startT -= FLT_EPSILON;
-                SkASSERT(startT >= 0);
-            }
-        }
-        SkASSERT(!approximately_negative(endT - startT));
-        double oStartT = coincidence.fTs[1][0];
-        double oEndT = coincidence.fTs[1][1];
-        if (oStartT > oEndT) {
-            SkTSwap<double>(oStartT, oEndT);
-            cancelers ^= true;
-        }
-        SkASSERT(!approximately_negative(oEndT - oStartT));
-        if (cancelers) {
-            thisOne.blindCancel(coincidence, &other);
-        } else {
-            thisOne.blindCoincident(coincidence, &other);
-        }
-    }
-}
-
-void SkOpContour::sortAngles() {
-    int segmentCount = fSegments.count();
-    for (int test = 0; test < segmentCount; ++test) {
-        fSegments[test].sortAngles();
-    }
-}
-
-void SkOpContour::sortSegments() {
-    int segmentCount = fSegments.count();
-    fSortedSegments.push_back_n(segmentCount);
-    for (int test = 0; test < segmentCount; ++test) {
-        fSortedSegments[test] = &fSegments[test];
-    }
-    SkTQSort<SkOpSegment>(fSortedSegments.begin(), fSortedSegments.end() - 1);
-    fFirstSorted = 0;
-}
-
 void SkOpContour::toPath(SkPathWriter* path) const {
-    int segmentCount = fSegments.count();
-    const SkPoint& pt = fSegments.front().pts()[0];
+    const SkPoint& pt = fHead.pts()[0];
     path->deferredMove(pt);
-    for (int test = 0; test < segmentCount; ++test) {
-        fSegments[test].addCurveTo(0, 1, path, true);
-    }
+    const SkOpSegment* segment = &fHead;
+    do {
+        segment->addCurveTo(segment->head(), segment->tail(), path, true);
+    } while ((segment = segment->next()));
     path->close();
 }
 
@@ -706,57 +99,14 @@
     }
 }
 
-SkOpSegment* SkOpContour::undoneSegment(int* start, int* end) {
-    int segmentCount = fSegments.count();
-    for (int test = 0; test < segmentCount; ++test) {
-        SkOpSegment* testSegment = &fSegments[test];
-        if (testSegment->done()) {
+SkOpSegment* SkOpContour::undoneSegment(SkOpSpanBase** startPtr, SkOpSpanBase** endPtr) {
+    SkOpSegment* segment = &fHead;
+    do {
+        if (segment->done()) {
             continue;
         }
-        testSegment->undoneSpan(start, end);
-        return testSegment;
-    }
+        segment->undoneSpan(startPtr, endPtr);
+        return segment;
+    } while ((segment = segment->next()));
     return NULL;
 }
-
-#if DEBUG_SHOW_WINDING
-int SkOpContour::debugShowWindingValues(int totalSegments, int ofInterest) {
-    int count = fSegments.count();
-    int sum = 0;
-    for (int index = 0; index < count; ++index) {
-        sum += fSegments[index].debugShowWindingValues(totalSegments, ofInterest);
-    }
-//      SkDebugf("%s sum=%d\n", __FUNCTION__, sum);
-    return sum;
-}
-
-void SkOpContour::debugShowWindingValues(const SkTArray<SkOpContour*, true>& contourList) {
-//     int ofInterest = 1 << 1 | 1 << 5 | 1 << 9 | 1 << 13;
-//    int ofInterest = 1 << 4 | 1 << 8 | 1 << 12 | 1 << 16;
-    int ofInterest = 1 << 5 | 1 << 8;
-    int total = 0;
-    int index;
-    for (index = 0; index < contourList.count(); ++index) {
-        total += contourList[index]->segments().count();
-    }
-    int sum = 0;
-    for (index = 0; index < contourList.count(); ++index) {
-        sum += contourList[index]->debugShowWindingValues(total, ofInterest);
-    }
-//       SkDebugf("%s total=%d\n", __FUNCTION__, sum);
-}
-#endif
-
-void SkOpContour::setBounds() {
-    int count = fSegments.count();
-    if (count == 0) {
-        SkDebugf("%s empty contour\n", __FUNCTION__);
-        SkASSERT(0);
-        // FIXME: delete empty contour?
-        return;
-    }
-    fBounds = fSegments.front().bounds();
-    for (int index = 1; index < count; ++index) {
-        fBounds.add(fSegments[index].bounds());
-    }
-}
diff --git a/src/pathops/SkOpContour.h b/src/pathops/SkOpContour.h
index 7a1cc09..be1f59f 100644
--- a/src/pathops/SkOpContour.h
+++ b/src/pathops/SkOpContour.h
@@ -8,31 +8,16 @@
 #define SkOpContour_DEFINED
 
 #include "SkOpSegment.h"
-#include "SkTArray.h"
+#include "SkTDArray.h"
+#include "SkTSort.h"
 
-#if defined(SK_DEBUG) || !FORCE_RELEASE
-#include "SkThread.h"
-#endif
-
-class SkIntersections;
-class SkOpContour;
+class SkChunkAlloc;
 class SkPathWriter;
 
-struct SkCoincidence {
-    SkOpContour* fOther;
-    int fSegments[2];
-    double fTs[2][2];
-    SkPoint fPts[2][2];
-    int fNearly[2];
-};
-
 class SkOpContour {
 public:
     SkOpContour() {
         reset();
-#if defined(SK_DEBUG) || !FORCE_RELEASE
-        fID = sk_atomic_inc(&SkPathOpsDebug::gContourID);
-#endif
     }
 
     bool operator<(const SkOpContour& rh) const {
@@ -41,211 +26,255 @@
                 : fBounds.fTop < rh.fBounds.fTop;
     }
 
-    bool addCoincident(int index, SkOpContour* other, int otherIndex,
-                       const SkIntersections& ts, bool swap);
-    void addCoincidentPoints();
+    void addCubic(SkPoint pts[4], SkChunkAlloc* allocator) {
+        appendSegment(allocator).addCubic(pts, this);
+    }
 
-    void addCross(const SkOpContour* crosser) {
-#ifdef DEBUG_CROSS
-        for (int index = 0; index < fCrosses.count(); ++index) {
-            SkASSERT(fCrosses[index] != crosser);
+    void addCurve(SkPath::Verb verb, const SkPoint pts[4], SkChunkAlloc* allocator);
+
+    void addLine(SkPoint pts[2], SkChunkAlloc* allocator) {
+        appendSegment(allocator).addLine(pts, this);
+    }
+
+    void addQuad(SkPoint pts[3], SkChunkAlloc* allocator) {
+        appendSegment(allocator).addQuad(pts, this);
+    }
+
+    void align() {
+        SkASSERT(fCount > 0);
+        SkOpSegment* segment = &fHead;
+        do {
+            segment->align();
+        } while ((segment = segment->next()));
+    }
+
+    SkOpSegment& appendSegment(SkChunkAlloc* allocator) {
+        SkOpSegment* result = fCount++
+                ? SkOpTAllocator<SkOpSegment>::Allocate(allocator) : &fHead;
+        result->setPrev(fTail);
+        if (fTail) {
+            fTail->setNext(result);
         }
-#endif
-        fCrosses.push_back(crosser);
+        fTail = result;
+        return *result;
     }
 
-    void addCubic(const SkPoint pts[4]) {
-        fSegments.push_back().addCubic(pts, fOperand, fXor);
-        fContainsCurves = fContainsCubics = true;
-    }
-
-    int addLine(const SkPoint pts[2]) {
-        fSegments.push_back().addLine(pts, fOperand, fXor);
-        return fSegments.count();
-    }
-
-    void addOtherT(int segIndex, int tIndex, double otherT, int otherIndex) {
-        fSegments[segIndex].addOtherT(tIndex, otherT, otherIndex);
-    }
-
-    bool addPartialCoincident(int index, SkOpContour* other, int otherIndex,
-                       const SkIntersections& ts, int ptIndex, bool swap);
-
-    int addQuad(const SkPoint pts[3]) {
-        fSegments.push_back().addQuad(pts, fOperand, fXor);
-        fContainsCurves = true;
-        return fSegments.count();
-    }
-
-    int addT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint& pt, double newT) {
-        setContainsIntercepts();
-        return fSegments[segIndex].addT(&other->fSegments[otherIndex], pt, newT);
-    }
-
-    int addSelfT(int segIndex, const SkPoint& pt, double newT) {
-        setContainsIntercepts();
-        return fSegments[segIndex].addSelfT(pt, newT);
-    }
-
-    void align(const SkOpSegment::AlignedSpan& aligned, bool swap, SkCoincidence* coincidence);
-    void alignCoincidence(const SkOpSegment::AlignedSpan& aligned,
-            SkTArray<SkCoincidence, true>* coincidences);
-
-    void alignCoincidence(const SkOpSegment::AlignedSpan& aligned) {
-        alignCoincidence(aligned, &fCoincidences);
-        alignCoincidence(aligned, &fPartialCoincidences);
-    }
-
-    void alignMultiples(SkTDArray<SkOpSegment::AlignedSpan>* aligned) {
-        int segmentCount = fSegments.count();
-        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
-            SkOpSegment& segment = fSegments[sIndex];
-            if (segment.hasMultiples()) {
-                segment.alignMultiples(aligned);
-            }
+    SkOpContour* appendContour(SkChunkAlloc* allocator) {
+        SkOpContour* contour = SkOpTAllocator<SkOpContour>::New(allocator);
+        
+        SkOpContour* prev = this;
+        SkOpContour* next;
+        while ((next = prev->next())) {
+            prev = next;
         }
+        prev->setNext(contour);
+        return contour;
     }
-
-    void alignTPt(int segmentIndex, const SkOpContour* other, int otherIndex,
-                  bool swap, int tIndex, SkIntersections* ts, SkPoint* point) const;
-
+    
     const SkPathOpsBounds& bounds() const {
         return fBounds;
     }
 
-    bool calcAngles();
-    bool calcCoincidentWinding();
-    void calcPartialCoincidentWinding();
-
-    void checkDuplicates() {
-        int segmentCount = fSegments.count();
-        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
-            SkOpSegment& segment = fSegments[sIndex];
-            if (segment.count() > 2) {
-                segment.checkDuplicates();
-            }
-        }
-    }
-
-    bool checkEnds() {
-        if (!fContainsCurves) {
-            return true;
-        }
-        int segmentCount = fSegments.count();
-        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
-            SkOpSegment* segment = &fSegments[sIndex];
-            if (segment->verb() == SkPath::kLine_Verb) {
-                continue;
-            }
-            if (segment->done()) {
-                continue;   // likely coincident, nothing to do
-            }
-            if (!segment->checkEnds()) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    void checkMultiples() {
-        int segmentCount = fSegments.count();
-        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
-            SkOpSegment& segment = fSegments[sIndex];
-            if (segment.count() > 2) {
-                segment.checkMultiples();
-                fMultiples |= segment.hasMultiples();
-            }
-        }
-    }
-
-    void checkSmall() {
-        int segmentCount = fSegments.count();
-        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
-            SkOpSegment& segment = fSegments[sIndex];
-            // OPTIMIZATION : skip segments that are done?
-            if (segment.hasSmall()) {
-                segment.checkSmall();
-            }
-        }
-    }
-
-    // if same point has different T values, choose a common T
-    void checkTiny() {
-        int segmentCount = fSegments.count();
-        if (segmentCount <= 2) {
-            return;
-        }
-        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
-            SkOpSegment& segment = fSegments[sIndex];
-            if (segment.hasTiny()) {
-                segment.checkTiny();
-            }
-        }
+    void calcAngles(SkChunkAlloc* allocator) {
+        SkASSERT(fCount > 0);
+        SkOpSegment* segment = &fHead;
+        do {
+            segment->calcAngles(allocator);
+        } while ((segment = segment->next()));
     }
 
     void complete() {
         setBounds();
-        fContainsIntercepts = false;
     }
 
-    bool containsCubics() const {
-        return fContainsCubics;
+    int count() const {
+        return fCount;
     }
 
-    bool crosses(const SkOpContour* crosser) const {
-        for (int index = 0; index < fCrosses.count(); ++index) {
-            if (fCrosses[index] == crosser) {
-                return true;
-            }
-        }
-        return false;
+    int debugID() const {
+        return PATH_OPS_DEBUG_RELEASE(fID, -1);
+    }
+
+    int debugIndent() const {
+        return PATH_OPS_DEBUG_RELEASE(fIndent, 0);
+    }
+
+#if DEBUG_ACTIVE_SPANS
+    void debugShowActiveSpans() {
+        SkOpSegment* segment = &fHead;
+        do {
+            segment->debugShowActiveSpans();
+        } while ((segment = segment->next()));
+    }
+#endif
+
+    const SkOpAngle* debugAngle(int id) const {
+        return PATH_OPS_DEBUG_RELEASE(globalState()->debugAngle(id), NULL);
+    }
+
+    SkOpContour* debugContour(int id) {
+        return PATH_OPS_DEBUG_RELEASE(globalState()->debugContour(id), NULL);
+    }
+
+    const SkOpPtT* debugPtT(int id) const {
+        return PATH_OPS_DEBUG_RELEASE(globalState()->debugPtT(id), NULL);
+    }
+
+    const SkOpSegment* debugSegment(int id) const {
+        return PATH_OPS_DEBUG_RELEASE(globalState()->debugSegment(id), NULL);
+    }
+
+    const SkOpSpanBase* debugSpan(int id) const {
+        return PATH_OPS_DEBUG_RELEASE(globalState()->debugSpan(id), NULL);
+    }
+
+    SkOpGlobalState* globalState() const {
+        return fState; 
+    }
+
+    void debugValidate() const {
+#if DEBUG_VALIDATE
+        const SkOpSegment* segment = &fHead;
+        const SkOpSegment* prior = NULL;
+        do {
+            segment->debugValidate();
+            SkASSERT(segment->prev() == prior);
+            prior = segment;
+        } while ((segment = segment->next()));
+        SkASSERT(prior == fTail);
+#endif
     }
 
     bool done() const {
         return fDone;
     }
 
+    void dump();
+    void dumpAll();
+    void dumpAngles() const;
+    void dumpPt(int ) const;
+    void dumpPts() const;
+    void dumpPtsX() const;
+    void dumpSegment(int ) const;
+    void dumpSegments(SkPathOp op) const;
+    void dumpSpan(int ) const;
+    void dumpSpans() const;
+
     const SkPoint& end() const {
-        const SkOpSegment& segment = fSegments.back();
-        return segment.pts()[SkPathOpsVerbToPoints(segment.verb())];
+        return fTail->pts()[SkPathOpsVerbToPoints(fTail->verb())];
     }
 
-    void fixOtherTIndex() {
-        int segmentCount = fSegments.count();
-        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
-            fSegments[sIndex].fixOtherTIndex();
-        }
+    SkOpSegment* first() {
+        SkASSERT(fCount > 0);
+        return &fHead;
     }
 
-    bool hasMultiples() const {
-        return fMultiples;
+    const SkOpSegment* first() const {
+        SkASSERT(fCount > 0);
+        return &fHead;
     }
 
-    void joinCoincidence() {
-        joinCoincidence(fCoincidences, false);
-        joinCoincidence(fPartialCoincidences, true);
+    void indentDump() {
+        PATH_OPS_DEBUG_CODE(fIndent += 2);
     }
 
-    SkOpSegment* nonVerticalSegment(int* start, int* end);
+    void init(SkOpGlobalState* globalState, bool operand, bool isXor) {
+        fState = globalState;
+        fOperand = operand;
+        fXor = isXor;
+    }
+
+    bool isXor() const {
+        return fXor;
+    }
+
+    void missingCoincidence(SkOpCoincidence* coincidences, SkChunkAlloc* allocator) {
+        SkASSERT(fCount > 0);
+        SkOpSegment* segment = &fHead;
+        do {
+            if (fState->angleCoincidence()) {
+                segment->checkAngleCoin(coincidences, allocator);
+            } else {
+                segment->missingCoincidence(coincidences, allocator);
+            }
+        } while ((segment = segment->next()));
+    }
+
+    bool moveNearby() {
+        SkASSERT(fCount > 0);
+        SkOpSegment* segment = &fHead;
+        do {
+            if (!segment->moveNearby()) {
+                return false;
+            }
+        } while ((segment = segment->next()));
+        return true;
+    }
+
+    SkOpContour* next() {
+        return fNext;
+    }
+
+    const SkOpContour* next() const {
+        return fNext;
+    }
+
+    SkOpSegment* nonVerticalSegment(SkOpSpanBase** start, SkOpSpanBase** end);
 
     bool operand() const {
         return fOperand;
     }
 
+    bool oppXor() const {
+        return fOppXor;
+    }
+
+    void outdentDump() {
+        PATH_OPS_DEBUG_CODE(fIndent -= 2);
+    }
+
+    void remove(SkOpContour* contour) {
+        if (contour == this) {
+            SkASSERT(fCount == 0);
+            return;
+        }
+        SkASSERT(contour->fNext == NULL);
+        SkOpContour* prev = this;
+        SkOpContour* next;
+        while ((next = prev->next()) != contour) {
+            SkASSERT(next);
+            prev = next;
+        }
+        SkASSERT(prev);
+        prev->setNext(NULL);
+    }
+
     void reset() {
-        fSegments.reset();
-        fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, SK_ScalarMax);
-        fContainsCurves = fContainsCubics = fContainsIntercepts = fDone = fMultiples = false;
+        fTail = NULL;
+        fNext = NULL;
+        fCount = 0;
+        fDone = false;
+        SkDEBUGCODE(fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMin, SK_ScalarMin));
+        SkDEBUGCODE(fFirstSorted = -1);
+        PATH_OPS_DEBUG_CODE(fIndent = 0);
     }
 
-    void resolveNearCoincidence();
-
-    SkTArray<SkOpSegment>& segments() {
-        return fSegments;
+    void setBounds() {
+        SkASSERT(fCount > 0);
+        const SkOpSegment* segment = &fHead;
+        fBounds = segment->bounds();
+        while ((segment = segment->next())) {
+            fBounds.add(segment->bounds());
+        }
     }
 
-    void setContainsIntercepts() {
-        fContainsIntercepts = true;
+    void setGlobalState(SkOpGlobalState* state) {
+        fState = state;
+    }
+
+    void setNext(SkOpContour* contour) {
+        SkASSERT(!fNext == !!contour);
+        fNext = contour;
     }
 
     void setOperand(bool isOp) {
@@ -254,107 +283,68 @@
 
     void setOppXor(bool isOppXor) {
         fOppXor = isOppXor;
-        int segmentCount = fSegments.count();
-        for (int test = 0; test < segmentCount; ++test) {
-            fSegments[test].setOppXor(isOppXor);
-        }
     }
 
     void setXor(bool isXor) {
         fXor = isXor;
     }
 
-    void sortAngles();
-    void sortSegments();
+    SkPath::Verb simplifyCubic(SkPoint pts[4]);
 
-    const SkPoint& start() const {
-        return fSegments.front().pts()[0];
+    void sortAngles() {
+        SkASSERT(fCount > 0);
+        SkOpSegment* segment = &fHead;
+        do {
+            segment->sortAngles();
+        } while ((segment = segment->next()));
     }
 
-    void toPath(SkPathWriter* path) const;
+    void sortSegments() {
+        SkOpSegment* segment = &fHead;
+        do {
+            *fSortedSegments.append() = segment;
+        } while ((segment = segment->next()));
+        SkTQSort<SkOpSegment>(fSortedSegments.begin(), fSortedSegments.end() - 1);
+        fFirstSorted = 0;
+    }
+
+    const SkPoint& start() const {
+        return fHead.pts()[0];
+    }
 
     void toPartialBackward(SkPathWriter* path) const {
-        int segmentCount = fSegments.count();
-        for (int test = segmentCount - 1; test >= 0; --test) {
-            fSegments[test].addCurveTo(1, 0, path, true);
-        }
+        const SkOpSegment* segment = fTail;
+        do {
+            segment->addCurveTo(segment->tail(), segment->head(), path, true);
+        } while ((segment = segment->prev()));
     }
 
     void toPartialForward(SkPathWriter* path) const {
-        int segmentCount = fSegments.count();
-        for (int test = 0; test < segmentCount; ++test) {
-            fSegments[test].addCurveTo(0, 1, path, true);
-        }
+        const SkOpSegment* segment = &fHead;
+        do {
+            segment->addCurveTo(segment->head(), segment->tail(), path, true);
+        } while ((segment = segment->next()));
     }
 
+    void toPath(SkPathWriter* path) const;
     void topSortableSegment(const SkPoint& topLeft, SkPoint* bestXY, SkOpSegment** topStart);
-    SkOpSegment* undoneSegment(int* start, int* end);
-
-    int updateSegment(int index, const SkPoint* pts) {
-        SkOpSegment& segment = fSegments[index];
-        segment.updatePts(pts);
-        return SkPathOpsVerbToPoints(segment.verb()) + 1;
-    }
-
-#if DEBUG_TEST
-    SkTArray<SkOpSegment>& debugSegments() {
-        return fSegments;
-    }
-#endif
-
-#if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
-    void debugShowActiveSpans() {
-        for (int index = 0; index < fSegments.count(); ++index) {
-            fSegments[index].debugShowActiveSpans();
-        }
-    }
-#endif
-
-#if DEBUG_SHOW_WINDING
-    int debugShowWindingValues(int totalSegments, int ofInterest);
-    static void debugShowWindingValues(const SkTArray<SkOpContour*, true>& contourList);
-#endif
-
-    // available to test routines only
-    void dump() const;
-    void dumpAngles() const;
-    void dumpCoincidence(const SkCoincidence& ) const;
-    void dumpCoincidences() const;
-    void dumpPt(int ) const;
-    void dumpPts() const;
-    void dumpSpan(int ) const;
-    void dumpSpans() const;
+    SkOpSegment* undoneSegment(SkOpSpanBase** startPtr, SkOpSpanBase** endPtr);
 
 private:
-    void alignPt(int index, SkPoint* point, int zeroPt) const;
-    int alignT(bool swap, int tIndex, SkIntersections* ts) const;
-    bool calcCommonCoincidentWinding(const SkCoincidence& );
-    void checkCoincidentPair(const SkCoincidence& oneCoin, int oneIdx,
-                             const SkCoincidence& twoCoin, int twoIdx, bool partial);
-    void joinCoincidence(const SkTArray<SkCoincidence, true>& , bool partial);
-    void setBounds();
-
-    SkTArray<SkOpSegment> fSegments;
-    SkTArray<SkOpSegment*, true> fSortedSegments;
-    int fFirstSorted;
-    SkTArray<SkCoincidence, true> fCoincidences;
-    SkTArray<SkCoincidence, true> fPartialCoincidences;
-    SkTArray<const SkOpContour*, true> fCrosses;
+    SkOpGlobalState* fState;
+    SkOpSegment fHead;
+    SkOpSegment* fTail;
+    SkOpContour* fNext;
+    SkTDArray<SkOpSegment*> fSortedSegments;  // set by find top segment
     SkPathOpsBounds fBounds;
-    bool fContainsIntercepts;  // FIXME: is this used by anybody?
-    bool fContainsCubics;
-    bool fContainsCurves;
-    bool fDone;
-    bool fMultiples;  // set if some segment has multiple identical intersections with other curves
+    int fCount;
+    int fFirstSorted;
+    bool fDone;  // set by find top segment
     bool fOperand;  // true for the second argument to a binary operator
-    bool fXor;
-    bool fOppXor;
-#if defined(SK_DEBUG) || !FORCE_RELEASE
-    int debugID() const { return fID; }
-    int fID;
-#else
-    int debugID() const { return -1; }
-#endif
+    bool fXor;  // set if original path had even-odd fill
+    bool fOppXor;  // set if opposite path had even-odd fill
+    PATH_OPS_DEBUG_CODE(int fID);
+    PATH_OPS_DEBUG_CODE(int fIndent);
 };
 
 #endif
diff --git a/src/pathops/SkOpEdgeBuilder.cpp b/src/pathops/SkOpEdgeBuilder.cpp
index 803a5f4..bd21d72 100644
--- a/src/pathops/SkOpEdgeBuilder.cpp
+++ b/src/pathops/SkOpEdgeBuilder.cpp
@@ -9,7 +9,7 @@
 #include "SkReduceOrder.h"
 
 void SkOpEdgeBuilder::init() {
-    fCurrentContour = NULL;
+    fCurrentContour = fContoursHead;
     fOperand = false;
     fXorMask[0] = fXorMask[1] = (fPath->getFillType() & 1) ? kEvenOdd_PathOpsMask
             : kWinding_PathOpsMask;
@@ -19,32 +19,43 @@
 
 void SkOpEdgeBuilder::addOperand(const SkPath& path) {
     SkASSERT(fPathVerbs.count() > 0 && fPathVerbs.end()[-1] == SkPath::kDone_Verb);
-    fPathVerbs.pop_back();
+    fPathVerbs.pop();
     fPath = &path;
     fXorMask[1] = (fPath->getFillType() & 1) ? kEvenOdd_PathOpsMask
             : kWinding_PathOpsMask;
     preFetch();
 }
 
-bool SkOpEdgeBuilder::finish() {
-    if (fUnparseable || !walk()) {
+int SkOpEdgeBuilder::count() const {
+    SkOpContour* contour = fContoursHead;
+    int count = 0;
+    while (contour) {
+        count += contour->count() > 0;
+        contour = contour->next();
+    }
+    return count;
+}
+
+bool SkOpEdgeBuilder::finish(SkChunkAlloc* allocator) {
+    fOperand = false;
+    if (fUnparseable || !walk(allocator)) {
         return false;
     }
     complete();
-    if (fCurrentContour && !fCurrentContour->segments().count()) {
-        fContours.pop_back();
+    if (fCurrentContour && !fCurrentContour->count()) {
+        fContoursHead->remove(fCurrentContour);
     }
     return true;
 }
 
 void SkOpEdgeBuilder::closeContour(const SkPoint& curveEnd, const SkPoint& curveStart) {
     if (!SkDPoint::ApproximatelyEqual(curveEnd, curveStart)) {
-        fPathVerbs.push_back(SkPath::kLine_Verb);
-        fPathPts.push_back_n(1, &curveStart);
+        *fPathVerbs.append() = SkPath::kLine_Verb;
+        *fPathPts.append() = curveStart;
     } else {
         fPathPts[fPathPts.count() - 1] = curveStart;
     }
-    fPathVerbs.push_back(SkPath::kClose_Verb);
+    *fPathVerbs.append() = SkPath::kClose_Verb;
 }
 
 // very tiny points cause numerical instability : don't allow them
@@ -57,7 +68,6 @@
     }
 }
 
-
 int SkOpEdgeBuilder::preFetch() {
     if (!fPath->isFinite()) {
         fUnparseable = true;
@@ -78,18 +88,18 @@
                 if (!fAllowOpenContours && lastCurve) {
                     closeContour(curve[0], curveStart);
                 }
-                fPathVerbs.push_back(verb);
+                *fPathVerbs.append() = verb;
                 force_small_to_zero(&pts[0]);
-                fPathPts.push_back(pts[0]);
+                *fPathPts.append() = pts[0];
                 curveStart = curve[0] = pts[0];
                 lastCurve = false;
                 continue;
             case SkPath::kLine_Verb:
                 force_small_to_zero(&pts[1]);
                 if (SkDPoint::ApproximatelyEqual(curve[0], pts[1])) {
-                    uint8_t lastVerb = fPathVerbs.back();
+                    uint8_t lastVerb = fPathVerbs.top();
                     if (lastVerb != SkPath::kLine_Verb && lastVerb != SkPath::kMove_Verb) {
-                        fPathPts.back() = pts[1];
+                        fPathPts.top() = pts[1];
                     }
                     continue;  // skip degenerate points
                 }
@@ -109,9 +119,9 @@
                             quadderTol);
                     const int nQuads = quadder.countQuads();
                     for (int i = 0; i < nQuads; ++i) {
-                       fPathVerbs.push_back(SkPath::kQuad_Verb);
+                       *fPathVerbs.append() = SkPath::kQuad_Verb;
                     }
-                    fPathPts.push_back_n(nQuads * 2, &quadPts[1]);
+                    fPathPts.append(nQuads * 2, &quadPts[1]);
                     curve[0] = pts[2];
                     lastCurve = true;
                 }
@@ -135,16 +145,16 @@
             case SkPath::kDone_Verb:
                 continue;
         }
-        fPathVerbs.push_back(verb);
+        *fPathVerbs.append() = verb;
         int ptCount = SkPathOpsVerbToPoints(verb);
-        fPathPts.push_back_n(ptCount, &pts[1]);
+        fPathPts.append(ptCount, &pts[1]);
         curve[0] = pts[ptCount];
         lastCurve = true;
     } while (verb != SkPath::kDone_Verb);
     if (!fAllowOpenContours && lastCurve) {
         closeContour(curve[0], curveStart);
     }
-    fPathVerbs.push_back(SkPath::kDone_Verb);
+    *fPathVerbs.append() = SkPath::kDone_Verb;
     return fPathVerbs.count() - 1;
 }
 
@@ -153,10 +163,10 @@
     return true;
 }
 
-bool SkOpEdgeBuilder::walk() {
+bool SkOpEdgeBuilder::walk(SkChunkAlloc* allocator) {
     uint8_t* verbPtr = fPathVerbs.begin();
     uint8_t* endOfFirstHalf = &verbPtr[fSecondHalf];
-    const SkPoint* pointsPtr = fPathPts.begin() - 1;
+    SkPoint* pointsPtr = fPathPts.begin() - 1;
     SkPath::Verb verb;
     while ((verb = (SkPath::Verb) *verbPtr) != SkPath::kDone_Verb) {
         if (verbPtr == endOfFirstHalf) {
@@ -165,7 +175,7 @@
         verbPtr++;
         switch (verb) {
             case SkPath::kMove_Verb:
-                if (fCurrentContour) {
+                if (fCurrentContour && fCurrentContour->count()) {
                     if (fAllowOpenContours) {
                         complete();
                     } else if (!close()) {
@@ -173,21 +183,44 @@
                     }
                 }
                 if (!fCurrentContour) {
-                    fCurrentContour = fContours.push_back_n(1);
-                    fCurrentContour->setOperand(fOperand);
-                    fCurrentContour->setXor(fXorMask[fOperand] == kEvenOdd_PathOpsMask);
+                    fCurrentContour = fContoursHead->appendContour(allocator);
                 }
+                fCurrentContour->init(fGlobalState, fOperand,
+                    fXorMask[fOperand] == kEvenOdd_PathOpsMask);
                 pointsPtr += 1;
                 continue;
             case SkPath::kLine_Verb:
-                fCurrentContour->addLine(pointsPtr);
+                fCurrentContour->addLine(pointsPtr, fAllocator);
                 break;
             case SkPath::kQuad_Verb:
-                fCurrentContour->addQuad(pointsPtr);
+                fCurrentContour->addQuad(pointsPtr, fAllocator);
                 break;
-            case SkPath::kCubic_Verb:
-                fCurrentContour->addCubic(pointsPtr);
-                break;
+            case SkPath::kCubic_Verb: {
+                // split self-intersecting cubics in two before proceeding
+                // if the cubic is convex, it doesn't self intersect.
+                SkScalar loopT;
+                if (SkDCubic::ComplexBreak(pointsPtr, &loopT)) {
+                    SkPoint cubicPair[7]; 
+                    SkChopCubicAt(pointsPtr, cubicPair, loopT);
+                    SkPoint cStorage[2][4];
+                    SkPath::Verb v1 = SkReduceOrder::Cubic(&cubicPair[0], cStorage[0]);
+                    SkPath::Verb v2 = SkReduceOrder::Cubic(&cubicPair[3], cStorage[1]);
+                    if (v1 != SkPath::kMove_Verb && v2 != SkPath::kMove_Verb) {
+                        SkPoint* curve1 = v1 == SkPath::kCubic_Verb ? &cubicPair[0] : cStorage[0];
+                        SkPoint* curve2 = v2 == SkPath::kCubic_Verb ? &cubicPair[3] : cStorage[1];
+                        for (size_t index = 0; index < SK_ARRAY_COUNT(curve1); ++index) {
+                            force_small_to_zero(&curve1[index]);
+                            force_small_to_zero(&curve2[index]);
+                        }
+                        fCurrentContour->addCurve(v1, curve1, fAllocator);
+                        fCurrentContour->addCurve(v2, curve2, fAllocator);
+                    } else {
+                        fCurrentContour->addCubic(pointsPtr, fAllocator);
+                    }
+                } else {
+                    fCurrentContour->addCubic(pointsPtr, fAllocator);
+                }
+                } break;
             case SkPath::kClose_Verb:
                 SkASSERT(fCurrentContour);
                 if (!close()) {
@@ -198,10 +231,11 @@
                 SkDEBUGFAIL("bad verb");
                 return false;
         }
-        pointsPtr += SkPathOpsVerbToPoints(verb);
         SkASSERT(fCurrentContour);
+        fCurrentContour->debugValidate();
+        pointsPtr += SkPathOpsVerbToPoints(verb);
     }
-   if (fCurrentContour && !fAllowOpenContours && !close()) {
+   if (fCurrentContour && fCurrentContour->count() &&!fAllowOpenContours && !close()) {
        return false;
    }
    return true;
diff --git a/src/pathops/SkOpEdgeBuilder.h b/src/pathops/SkOpEdgeBuilder.h
index fd07445..3ecc915 100644
--- a/src/pathops/SkOpEdgeBuilder.h
+++ b/src/pathops/SkOpEdgeBuilder.h
@@ -9,20 +9,25 @@
 
 #include "SkOpContour.h"
 #include "SkPathWriter.h"
-#include "SkTArray.h"
 
 class SkOpEdgeBuilder {
 public:
-    SkOpEdgeBuilder(const SkPathWriter& path, SkTArray<SkOpContour>& contours)
-        : fPath(path.nativePath())
-        , fContours(contours)
+    SkOpEdgeBuilder(const SkPathWriter& path, SkOpContour* contours2, SkChunkAlloc* allocator,
+            SkOpGlobalState* globalState)
+        : fAllocator(allocator)  // FIXME: replace with const, tune this
+        , fGlobalState(globalState)
+        , fPath(path.nativePath())
+        , fContoursHead(contours2)
         , fAllowOpenContours(true) {
         init();
     }
 
-    SkOpEdgeBuilder(const SkPath& path, SkTArray<SkOpContour>& contours)
-        : fPath(&path)
-        , fContours(contours)
+    SkOpEdgeBuilder(const SkPath& path, SkOpContour* contours2, SkChunkAlloc* allocator,
+            SkOpGlobalState* globalState)
+        : fAllocator(allocator)
+        , fGlobalState(globalState)
+        , fPath(&path)
+        , fContoursHead(contours2)
         , fAllowOpenContours(false) {
         init();
     }
@@ -30,13 +35,19 @@
     void addOperand(const SkPath& path);
 
     void complete() {
-        if (fCurrentContour && fCurrentContour->segments().count()) {
+        if (fCurrentContour && fCurrentContour->count()) {
             fCurrentContour->complete();
             fCurrentContour = NULL;
         }
     }
 
-    bool finish();
+    int count() const;
+    bool finish(SkChunkAlloc* );
+
+    const SkOpContour* head() const {
+        return fContoursHead;
+    }
+
     void init();
     bool unparseable() const { return fUnparseable; }
     SkPathOpsMask xorMask() const { return fXorMask[fOperand]; }
@@ -45,13 +56,15 @@
     void closeContour(const SkPoint& curveEnd, const SkPoint& curveStart);
     bool close();
     int preFetch();
-    bool walk();
+    bool walk(SkChunkAlloc* );
 
+    SkChunkAlloc* fAllocator;
+    SkOpGlobalState* fGlobalState;
     const SkPath* fPath;
-    SkTArray<SkPoint, true> fPathPts;
-    SkTArray<uint8_t, true> fPathVerbs;
+    SkTDArray<SkPoint> fPathPts;
+    SkTDArray<uint8_t> fPathVerbs;
     SkOpContour* fCurrentContour;
-    SkTArray<SkOpContour>& fContours;
+    SkOpContour* fContoursHead;
     SkPathOpsMask fXorMask[2];
     int fSecondHalf;
     bool fOperand;
diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp
index 1fb5afa..902f273 100644
--- a/src/pathops/SkOpSegment.cpp
+++ b/src/pathops/SkOpSegment.cpp
@@ -4,11 +4,20 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SkIntersections.h"
+#include "SkOpCoincidence.h"
 #include "SkOpContour.h"
 #include "SkOpSegment.h"
 #include "SkPathWriter.h"
-#include "SkTSort.h"
+
+/*
+After computing raw intersections, post process all segments to:
+- find small collections of points that can be collapsed to a single point
+- find missing intersections to resolve differences caused by different algorithms
+
+Consider segments containing tiny or small intervals. Consider coincident segments
+because coincidence finds intersections through distance measurement that non-coincident
+intersection tests cannot.
+ */
 
 #define F (false)      // discard the edge
 #define T (true)       // keep the edge
@@ -33,147 +42,125 @@
 #undef F
 #undef T
 
-enum {
-    kOutsideTrackedTCount = 16,  // FIXME: determine what this should be
-    kMissingSpanCount = 4,  // FIXME: determine what this should be
-};
-
-const SkOpAngle* SkOpSegment::activeAngle(int index, int* start, int* end, bool* done,
-        bool* sortable) const {
-    if (const SkOpAngle* result = activeAngleInner(index, start, end, done, sortable)) {
+SkOpAngle* SkOpSegment::activeAngle(SkOpSpanBase* start, SkOpSpanBase** startPtr,
+        SkOpSpanBase** endPtr, bool* done, bool* sortable) {
+    if (SkOpAngle* result = activeAngleInner(start, startPtr, endPtr, done, sortable)) {
         return result;
     }
-    double referenceT = fTs[index].fT;
-    int lesser = index;
-    while (--lesser >= 0
-            && (precisely_negative(referenceT - fTs[lesser].fT) || fTs[lesser].fTiny)) {
-        if (const SkOpAngle* result = activeAngleOther(lesser, start, end, done, sortable)) {
-            return result;
-        }
+    if (SkOpAngle* result = activeAngleOther(start, startPtr, endPtr, done, sortable)) {
+        return result;
     }
-    do {
-        if (const SkOpAngle* result = activeAngleOther(index, start, end, done, sortable)) {
-            return result;
-        }
-        if (++index == fTs.count()) {
-            break;
-        }
-        if (fTs[index - 1].fTiny) {
-            referenceT = fTs[index].fT;
-            continue;
-        }
-    } while (precisely_negative(fTs[index].fT - referenceT));
     return NULL;
 }
 
-const SkOpAngle* SkOpSegment::activeAngleInner(int index, int* start, int* end, bool* done,
-        bool* sortable) const {
-    int next = nextExactSpan(index, 1);
-    if (next > 0) {
-        const SkOpSpan& upSpan = fTs[index];
-        if (upSpan.fWindValue || upSpan.fOppValue) {
-            if (*end < 0) {
-                *start = index;
-                *end = next;
+SkOpAngle* SkOpSegment::activeAngleInner(SkOpSpanBase* start, SkOpSpanBase** startPtr,
+        SkOpSpanBase** endPtr, bool* done, bool* sortable) {
+    SkOpSpan* upSpan = start->upCastable();
+    if (upSpan) {
+        if (upSpan->windValue() || upSpan->oppValue()) {
+            SkOpSpanBase* next = upSpan->next();
+            if (!*endPtr) {
+                *startPtr = start;
+                *endPtr = next;
             }
-            if (!upSpan.fDone) {
-                if (upSpan.fWindSum != SK_MinS32) {
-                    return spanToAngle(index, next);
+            if (!upSpan->done()) {
+                if (upSpan->windSum() != SK_MinS32) {
+                    return spanToAngle(start, next);
                 }
                 *done = false;
             }
         } else {
-            SkASSERT(upSpan.fDone);
+            SkASSERT(upSpan->done());
         }
     }
-    int prev = nextExactSpan(index, -1);
+    SkOpSpan* downSpan = start->prev();
     // edge leading into junction
-    if (prev >= 0) {
-        const SkOpSpan& downSpan = fTs[prev];
-        if (downSpan.fWindValue || downSpan.fOppValue) {
-            if (*end < 0) {
-                *start = index;
-                *end = prev;
+    if (downSpan) {
+        if (downSpan->windValue() || downSpan->oppValue()) {
+            if (!*endPtr) {
+                *startPtr = start;
+                *endPtr = downSpan;
             }
-            if (!downSpan.fDone) {
-                if (downSpan.fWindSum != SK_MinS32) {
-                    return spanToAngle(index, prev);
+            if (!downSpan->done()) {
+                if (downSpan->windSum() != SK_MinS32) {
+                    return spanToAngle(start, downSpan);
                 }
                 *done = false;
             }
         } else {
-            SkASSERT(downSpan.fDone);
+            SkASSERT(downSpan->done());
         }
     }
     return NULL;
 }
 
-const SkOpAngle* SkOpSegment::activeAngleOther(int index, int* start, int* end, bool* done,
-        bool* sortable) const {
-    const SkOpSpan* span = &fTs[index];
-    SkOpSegment* other = span->fOther;
-    int oIndex = span->fOtherIndex;
-    return other->activeAngleInner(oIndex, start, end, done, sortable);
+SkOpAngle* SkOpSegment::activeAngleOther(SkOpSpanBase* start, SkOpSpanBase** startPtr,
+        SkOpSpanBase** endPtr, bool* done, bool* sortable) {
+    SkOpPtT* oPtT = start->ptT()->next();
+    SkOpSegment* other = oPtT->segment();
+    SkOpSpanBase* oSpan = oPtT->span();
+    return other->activeAngleInner(oSpan, startPtr, endPtr, done, sortable);
 }
 
-SkPoint SkOpSegment::activeLeftTop(int* firstT) const {
+SkPoint SkOpSegment::activeLeftTop(SkOpSpanBase** firstSpan) {
     SkASSERT(!done());
     SkPoint topPt = {SK_ScalarMax, SK_ScalarMax};
-    int count = fTs.count();
     // see if either end is not done since we want smaller Y of the pair
     bool lastDone = true;
     double lastT = -1;
-    for (int index = 0; index < count; ++index) {
-        const SkOpSpan& span = fTs[index];
-        if (span.fDone && lastDone) {
-            goto next;
-        }
-        if (approximately_negative(span.fT - lastT)) {
+    SkOpSpanBase* span = &fHead;
+    do {
+        if (lastDone && (span->final() || span->upCast()->done())) {
             goto next;
         }
         {
-            const SkPoint& xy = xyAtT(&span);
+            const SkPoint& xy = span->pt();
             if (topPt.fY > xy.fY || (topPt.fY == xy.fY && topPt.fX > xy.fX)) {
                 topPt = xy;
-                if (firstT) {
-                    *firstT = index;
+                if (firstSpan) {
+                    *firstSpan = span;
                 }
             }
             if (fVerb != SkPath::kLine_Verb && !lastDone) {
-                SkPoint curveTop = (*CurveTop[SkPathOpsVerbToPoints(fVerb)])(fPts, lastT, span.fT);
+                SkPoint curveTop = (*CurveTop[SkPathOpsVerbToPoints(fVerb)])(fPts, lastT,
+                        span->t());
                 if (topPt.fY > curveTop.fY || (topPt.fY == curveTop.fY
                         && topPt.fX > curveTop.fX)) {
                     topPt = curveTop;
-                    if (firstT) {
-                        *firstT = index;
+                    if (firstSpan) {
+                        *firstSpan = span;
                     }
                 }
             }
-            lastT = span.fT;
+            lastT = span->t();
         }
 next:
-        lastDone = span.fDone;
-    }
+        if (span->final()) {
+            break;
+        }
+        lastDone = span->upCast()->done();
+    } while ((span = span->upCast()->next()));
     return topPt;
 }
 
-bool SkOpSegment::activeOp(int index, int endIndex, int xorMiMask, int xorSuMask, SkPathOp op) {
-    int sumMiWinding = updateWinding(endIndex, index);
-    int sumSuWinding = updateOppWinding(endIndex, index);
+bool SkOpSegment::activeOp(SkOpSpanBase* start, SkOpSpanBase* end, int xorMiMask, int xorSuMask,
+        SkPathOp op) {
+    int sumMiWinding = this->updateWinding(end, start);
+    int sumSuWinding = this->updateOppWinding(end, start);
 #if DEBUG_LIMIT_WIND_SUM
     SkASSERT(abs(sumMiWinding) <= DEBUG_LIMIT_WIND_SUM);
     SkASSERT(abs(sumSuWinding) <= DEBUG_LIMIT_WIND_SUM);
 #endif
-    if (fOperand) {
+    if (this->operand()) {
         SkTSwap<int>(sumMiWinding, sumSuWinding);
     }
-    return activeOp(xorMiMask, xorSuMask, index, endIndex, op, &sumMiWinding, &sumSuWinding);
+    return this->activeOp(xorMiMask, xorSuMask, start, end, op, &sumMiWinding, &sumSuWinding);
 }
 
-bool SkOpSegment::activeOp(int xorMiMask, int xorSuMask, int index, int endIndex, SkPathOp op,
-        int* sumMiWinding, int* sumSuWinding) {
+bool SkOpSegment::activeOp(int xorMiMask, int xorSuMask, SkOpSpanBase* start, SkOpSpanBase* end,
+        SkPathOp op, int* sumMiWinding, int* sumSuWinding) {
     int maxWinding, sumWinding, oppMaxWinding, oppSumWinding;
-    setUpWindings(index, endIndex, sumMiWinding, sumSuWinding,
+    this->setUpWindings(start, end, sumMiWinding, sumSuWinding,
             &maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding);
     bool miFrom;
     bool miTo;
@@ -193,178 +180,31 @@
     bool result = gActiveEdge[op][miFrom][miTo][suFrom][suTo];
 #if DEBUG_ACTIVE_OP
     SkDebugf("%s id=%d t=%1.9g tEnd=%1.9g op=%s miFrom=%d miTo=%d suFrom=%d suTo=%d result=%d\n",
-            __FUNCTION__, debugID(), span(index).fT, span(endIndex).fT,
+            __FUNCTION__, debugID(), start->t(), end->t(),
             SkPathOpsDebug::kPathOpStr[op], miFrom, miTo, suFrom, suTo, result);
 #endif
     return result;
 }
 
-bool SkOpSegment::activeWinding(int index, int endIndex) {
-    int sumWinding = updateWinding(endIndex, index);
-    return activeWinding(index, endIndex, &sumWinding);
+bool SkOpSegment::activeWinding(SkOpSpanBase* start, SkOpSpanBase* end) {
+    int sumWinding = updateWinding(end, start);
+    return activeWinding(start, end, &sumWinding);
 }
 
-bool SkOpSegment::activeWinding(int index, int endIndex, int* sumWinding) {
+bool SkOpSegment::activeWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* sumWinding) {
     int maxWinding;
-    setUpWinding(index, endIndex, &maxWinding, sumWinding);
+    setUpWinding(start, end, &maxWinding, sumWinding);
     bool from = maxWinding != 0;
     bool to = *sumWinding  != 0;
     bool result = gUnaryActiveEdge[from][to];
     return result;
 }
 
-void SkOpSegment::addCancelOutsides(const SkPoint& startPt, const SkPoint& endPt,
-        SkOpSegment* other) {
-    int tIndex = -1;
-    int tCount = fTs.count();
-    int oIndex = -1;
-    int oCount = other->fTs.count();
-    do {
-        ++tIndex;
-    } while (startPt != fTs[tIndex].fPt && tIndex < tCount);
-    int tIndexStart = tIndex;
-    do {
-        ++oIndex;
-    } while (endPt != other->fTs[oIndex].fPt && oIndex < oCount);
-    int oIndexStart = oIndex;
-    const SkPoint* nextPt;
-    do {
-        nextPt = &fTs[++tIndex].fPt;
-        SkASSERT(fTs[tIndex].fT < 1 || startPt != *nextPt);
-    } while (startPt == *nextPt);
-    double nextT = fTs[tIndex].fT;
-    const SkPoint* oNextPt;
-    do {
-        oNextPt = &other->fTs[++oIndex].fPt;
-        SkASSERT(other->fTs[oIndex].fT < 1 || endPt != *oNextPt);
-    } while (endPt == *oNextPt);
-    double oNextT = other->fTs[oIndex].fT;
-    // at this point, spans before and after are at:
-    //  fTs[tIndexStart - 1], fTs[tIndexStart], fTs[tIndex]
-    // if tIndexStart == 0, no prior span
-    // if nextT == 1, no following span
-
-    // advance the span with zero winding
-    // if the following span exists (not past the end, non-zero winding)
-    // connect the two edges
-    if (!fTs[tIndexStart].fWindValue) {
-        if (tIndexStart > 0 && fTs[tIndexStart - 1].fWindValue) {
-#if DEBUG_CONCIDENT
-            SkDebugf("%s 1 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n",
-                    __FUNCTION__, fID, other->fID, tIndexStart - 1,
-                    fTs[tIndexStart].fT, xyAtT(tIndexStart).fX,
-                    xyAtT(tIndexStart).fY);
-#endif
-            SkPoint copy = fTs[tIndexStart].fPt;  // add t pair may move the point array
-            addTPair(fTs[tIndexStart].fT, other, other->fTs[oIndex].fT, false, copy);
-        }
-        if (nextT < 1 && fTs[tIndex].fWindValue) {
-#if DEBUG_CONCIDENT
-            SkDebugf("%s 2 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n",
-                    __FUNCTION__, fID, other->fID, tIndex,
-                    fTs[tIndex].fT, xyAtT(tIndex).fX,
-                    xyAtT(tIndex).fY);
-#endif
-            SkPoint copy = fTs[tIndex].fPt;  // add t pair may move the point array
-            addTPair(fTs[tIndex].fT, other, other->fTs[oIndexStart].fT, false, copy);
-        }
-    } else {
-        SkASSERT(!other->fTs[oIndexStart].fWindValue);
-        if (oIndexStart > 0 && other->fTs[oIndexStart - 1].fWindValue) {
-#if DEBUG_CONCIDENT
-            SkDebugf("%s 3 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n",
-                    __FUNCTION__, fID, other->fID, oIndexStart - 1,
-                    other->fTs[oIndexStart].fT, other->xyAtT(oIndexStart).fX,
-                    other->xyAtT(oIndexStart).fY);
-            other->debugAddTPair(other->fTs[oIndexStart].fT, *this, fTs[tIndex].fT);
-#endif
-        }
-        if (oNextT < 1 && other->fTs[oIndex].fWindValue) {
-#if DEBUG_CONCIDENT
-            SkDebugf("%s 4 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n",
-                    __FUNCTION__, fID, other->fID, oIndex,
-                    other->fTs[oIndex].fT, other->xyAtT(oIndex).fX,
-                    other->xyAtT(oIndex).fY);
-            other->debugAddTPair(other->fTs[oIndex].fT, *this, fTs[tIndexStart].fT);
-#endif
-        }
-    }
-}
-
-void SkOpSegment::addCoinOutsides(const SkPoint& startPt, const SkPoint& endPt,
-        SkOpSegment* other) {
-    // walk this to startPt
-    // walk other to startPt
-    // if either is > 0, add a pointer to the other, copying adjacent winding
-    int tIndex = -1;
-    int oIndex = -1;
-    do {
-        ++tIndex;
-    } while (startPt != fTs[tIndex].fPt);
-    int ttIndex = tIndex;
-    bool checkOtherTMatch = false;
-    do {
-        const SkOpSpan& span = fTs[ttIndex];
-        if (startPt != span.fPt) {
-            break;
-        }
-        if (span.fOther == other && span.fPt == startPt) {
-            checkOtherTMatch = true;
-            break;
-        }
-    } while (++ttIndex < count());
-    do {
-        ++oIndex;
-    } while (startPt != other->fTs[oIndex].fPt);
-    bool skipAdd = false;
-    if (checkOtherTMatch) {
-        int ooIndex = oIndex;
-        do {
-            const SkOpSpan& oSpan = other->fTs[ooIndex];
-            if (startPt != oSpan.fPt) {
-                break;
-            }
-            if (oSpan.fT == fTs[ttIndex].fOtherT) {
-                skipAdd = true;
-                break;
-            }
-        } while (++ooIndex < other->count());
-    }
-    if ((tIndex > 0 || oIndex > 0 || fOperand != other->fOperand) && !skipAdd) {
-        addTPair(fTs[tIndex].fT, other, other->fTs[oIndex].fT, false, startPt);
-    }
-    SkPoint nextPt = startPt;
-    do {
-        const SkPoint* workPt;
-        do {
-            workPt = &fTs[++tIndex].fPt;
-        } while (nextPt == *workPt);
-        const SkPoint* oWorkPt;
-        do {
-            oWorkPt = &other->fTs[++oIndex].fPt;
-        } while (nextPt == *oWorkPt);
-        nextPt = *workPt;
-        double tStart = fTs[tIndex].fT;
-        double oStart = other->fTs[oIndex].fT;
-        if (tStart == 1 && oStart == 1 && fOperand == other->fOperand) {
-            break;
-        }
-        if (*workPt == *oWorkPt) {
-            addTPair(tStart, other, oStart, false, nextPt);
-        }
-    } while (endPt != nextPt);
-}
-
-void SkOpSegment::addCubic(const SkPoint pts[4], bool operand, bool evenOdd) {
-    init(pts, SkPath::kCubic_Verb, operand, evenOdd);
-    fBounds.setCubicBounds(pts);
-}
-
-void SkOpSegment::addCurveTo(int start, int end, SkPathWriter* path, bool active) const {
+void SkOpSegment::addCurveTo(const SkOpSpanBase* start, const SkOpSpanBase* end,
+        SkPathWriter* path, bool active) const {
     SkPoint edge[4];
     const SkPoint* ePtr;
-    int lastT = fTs.count() - 1;
-    if (lastT < 0 || (start == 0 && end == lastT) || (start == lastT && end == 0)) {
+    if ((start == &fHead && end == &fTail) || (start == &fTail && end == &fHead)) {
         ePtr = fPts;
     } else {
     // OPTIMIZE? if not active, skip remainder and return xyAtT(end)
@@ -372,7 +212,7 @@
         ePtr = edge;
     }
     if (active) {
-        bool reverse = ePtr == fPts && start != 0;
+        bool reverse = ePtr == fPts && start != &fHead;
         if (reverse) {
             path->deferredMoveLine(ePtr[SkPathOpsVerbToPoints(fVerb)]);
             switch (fVerb) {
@@ -388,7 +228,6 @@
                 default:
                     SkASSERT(0);
             }
-   //         return ePtr[0];
        } else {
             path->deferredMoveLine(ePtr[0]);
             switch (fVerb) {
@@ -406,1538 +245,285 @@
             }
         }
     }
-  //  return ePtr[SkPathOpsVerbToPoints(fVerb)];
 }
 
-void SkOpSegment::addEndSpan(int endIndex) {
-    SkASSERT(span(endIndex).fT == 1 || (span(endIndex).fTiny
-//            && approximately_greater_than_one(span(endIndex).fT)
-    ));
-    int spanCount = fTs.count();
-    int startIndex = endIndex - 1;
-    while (fTs[startIndex].fT == 1 || fTs[startIndex].fTiny) {
-        --startIndex;
-        SkASSERT(startIndex > 0);
-        --endIndex;
-    }
-    SkOpAngle& angle = fAngles.push_back();
-    angle.set(this, spanCount - 1, startIndex);
-#if DEBUG_ANGLE
-    debugCheckPointsEqualish(endIndex, spanCount);
-#endif
-    setFromAngle(endIndex, &angle);
-}
-
-void SkOpSegment::setFromAngle(int endIndex, SkOpAngle* angle) {
-    int spanCount = fTs.count();
+SkOpPtT* SkOpSegment::addMissing(double t, SkOpSegment* opp, SkChunkAlloc* allocator) {
+    SkOpSpanBase* existing = NULL;
+    SkOpSpanBase* test = &fHead;
+    double testT;
     do {
-        fTs[endIndex].fFromAngle = angle;
-    } while (++endIndex < spanCount);
-}
-
-void SkOpSegment::addLine(const SkPoint pts[2], bool operand, bool evenOdd) {
-    init(pts, SkPath::kLine_Verb, operand, evenOdd);
-    fBounds.set(pts, 2);
-}
-
-// add 2 to edge or out of range values to get T extremes
-void SkOpSegment::addOtherT(int index, double otherT, int otherIndex) {
-    SkOpSpan& span = fTs[index];
-    if (precisely_zero(otherT)) {
-        otherT = 0;
-    } else if (precisely_equal(otherT, 1)) {
-        otherT = 1;
-    }
-    span.fOtherT = otherT;
-    span.fOtherIndex = otherIndex;
-}
-
-void SkOpSegment::addQuad(const SkPoint pts[3], bool operand, bool evenOdd) {
-    init(pts, SkPath::kQuad_Verb, operand, evenOdd);
-    fBounds.setQuadBounds(pts);
-}
-
-SkOpAngle* SkOpSegment::addSingletonAngleDown(SkOpSegment** otherPtr, SkOpAngle** anglePtr) {
-    int spanIndex = count() - 1;
-    int startIndex = nextExactSpan(spanIndex, -1);
-    SkASSERT(startIndex >= 0);
-    SkOpAngle& angle = fAngles.push_back();
-    *anglePtr = &angle;
-    angle.set(this, spanIndex, startIndex);
-    setFromAngle(spanIndex, &angle);
-    SkOpSegment* other;
-    int oStartIndex, oEndIndex;
-    do {
-        const SkOpSpan& span = fTs[spanIndex];
-        SkASSERT(span.fT > 0);
-        other = span.fOther;
-        oStartIndex = span.fOtherIndex;
-        oEndIndex = other->nextExactSpan(oStartIndex, 1);
-        if (oEndIndex > 0 && other->span(oStartIndex).fWindValue) {
+        if ((testT = test->ptT()->fT) >= t) {
+            if (testT == t) {
+                existing = test;
+            }
             break;
         }
-        oEndIndex = oStartIndex;
-        oStartIndex = other->nextExactSpan(oEndIndex, -1);
-        --spanIndex;
-    } while (oStartIndex < 0 || !other->span(oStartIndex).fWindSum);
-    SkOpAngle& oAngle = other->fAngles.push_back();
-    oAngle.set(other, oStartIndex, oEndIndex);
-    other->setToAngle(oEndIndex, &oAngle);
-    *otherPtr = other;
-    return &oAngle;
+    } while ((test = test->upCast()->next()));
+    SkOpPtT* result;
+    if (existing && existing->contains(opp)) {
+        result = existing->ptT();
+    } else {
+        result = this->addT(t, SkOpSegment::kNoAlias, allocator);
+    }
+    SkASSERT(result);
+    return result;
 }
 
-SkOpAngle* SkOpSegment::addSingletonAngleUp(SkOpSegment** otherPtr, SkOpAngle** anglePtr) {
-    int endIndex = nextExactSpan(0, 1);
-    SkASSERT(endIndex > 0);
-    SkOpAngle& angle = fAngles.push_back();
-    *anglePtr = &angle;
-    angle.set(this, 0, endIndex);
-    setToAngle(endIndex, &angle);
-    int spanIndex = 0;
-    SkOpSegment* other;
-    int oStartIndex, oEndIndex;
-    do {
-        const SkOpSpan& span = fTs[spanIndex];
-        SkASSERT(span.fT < 1);
-        other = span.fOther;
-        oEndIndex = span.fOtherIndex;
-        oStartIndex = other->nextExactSpan(oEndIndex, -1);
-        if (oStartIndex >= 0 && other->span(oStartIndex).fWindValue) {
+SkOpAngle* SkOpSegment::addSingletonAngleDown(SkOpSegment** otherPtr, SkOpAngle** anglePtr,
+        SkChunkAlloc* allocator) {
+    SkOpSpan* startSpan = fTail.prev();
+    SkASSERT(startSpan);
+    SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(allocator);
+    *anglePtr = angle;
+    angle->set(&fTail, startSpan);
+    fTail.setFromAngle(angle);
+    SkOpSegment* other = NULL;  // these initializations silence a release build warning
+    SkOpSpan* oStartSpan = NULL;
+    SkOpSpanBase* oEndSpan = NULL;
+    SkOpPtT* ptT = fTail.ptT(), * startPtT = ptT;
+    while ((ptT = ptT->next()) != startPtT) {
+        other = ptT->segment();
+        oStartSpan = ptT->span()->upCastable();
+        if (oStartSpan && oStartSpan->windValue()) {
+            oEndSpan = oStartSpan->next();
             break;
         }
-        oStartIndex = oEndIndex;
-        oEndIndex = other->nextExactSpan(oStartIndex, 1);
-        ++spanIndex;
-    } while (oEndIndex < 0 || !other->span(oStartIndex).fWindValue);
-    SkOpAngle& oAngle = other->fAngles.push_back();
-    oAngle.set(other, oEndIndex, oStartIndex);
-    other->setFromAngle(oEndIndex, &oAngle);
+        oEndSpan = ptT->span();
+        oStartSpan = oEndSpan->prev();
+        if (oStartSpan && oStartSpan->windValue()) {
+            break;
+        }
+    }
+    SkOpAngle* oAngle = SkOpTAllocator<SkOpAngle>::Allocate(allocator);
+    oAngle->set(oStartSpan, oEndSpan);
+    oStartSpan->setToAngle(oAngle);
     *otherPtr = other;
-    return &oAngle;
+    return oAngle;
 }
 
-SkOpAngle* SkOpSegment::addSingletonAngles(int step) {
+SkOpAngle* SkOpSegment::addSingletonAngles(int step, SkChunkAlloc* allocator) {
     SkOpSegment* other;
     SkOpAngle* angle, * otherAngle;
     if (step > 0) {
-        otherAngle = addSingletonAngleUp(&other, &angle);
+        otherAngle = addSingletonAngleUp(&other, &angle, allocator);
     } else {
-        otherAngle = addSingletonAngleDown(&other, &angle);
+        otherAngle = addSingletonAngleDown(&other, &angle, allocator);
     }
     angle->insert(otherAngle);
     return angle;
 }
 
-void SkOpSegment::addStartSpan(int endIndex) {
-    int index = 0;
-    SkOpAngle& angle = fAngles.push_back();
-    angle.set(this, index, endIndex);
-#if DEBUG_ANGLE
-    debugCheckPointsEqualish(index, endIndex);
-#endif
-    setToAngle(endIndex, &angle);
-}
-
-void SkOpSegment::setToAngle(int endIndex, SkOpAngle* angle) {
-    int index = 0;
-    do {
-        fTs[index].fToAngle = angle;
-    } while (++index < endIndex);
-}
-
-    // Defer all coincident edge processing until
-    // after normal intersections have been computed
-
-// no need to be tricky; insert in normal T order
-// resolve overlapping ts when considering coincidence later
-
-    // add non-coincident intersection. Resulting edges are sorted in T.
-int SkOpSegment::addT(SkOpSegment* other, const SkPoint& pt, double newT) {
-    SkASSERT(this != other || fVerb == SkPath::kCubic_Verb);
- #if 0  // this needs an even rougher association to be useful
-    SkASSERT(SkDPoint::RoughlyEqual(ptAtT(newT), pt));
- #endif
-    const SkPoint& firstPt = fPts[0];
-    const SkPoint& lastPt = fPts[SkPathOpsVerbToPoints(fVerb)];
-    SkASSERT(newT == 0 || !precisely_zero(newT));
-    SkASSERT(newT == 1 || !precisely_equal(newT, 1));
-    // FIXME: in the pathological case where there is a ton of intercepts,
-    //  binary search?
-    int insertedAt = -1;
-    int tCount = fTs.count();
-    for (int index = 0; index < tCount; ++index) {
-        // OPTIMIZATION: if there are three or more identical Ts, then
-        // the fourth and following could be further insertion-sorted so
-        // that all the edges are clockwise or counterclockwise.
-        // This could later limit segment tests to the two adjacent
-        // neighbors, although it doesn't help with determining which
-        // circular direction to go in.
-        const SkOpSpan& span = fTs[index];
-        if (newT < span.fT) {
-            insertedAt = index;
+SkOpAngle* SkOpSegment::addSingletonAngleUp(SkOpSegment** otherPtr, SkOpAngle** anglePtr,
+        SkChunkAlloc* allocator) {
+    SkOpSpanBase* endSpan = fHead.next();
+    SkASSERT(endSpan);
+    SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(allocator);
+    *anglePtr = angle;
+    angle->set(&fHead, endSpan);
+    fHead.setToAngle(angle);
+    SkOpSegment* other = NULL;  // these initializations silence a release build warning
+    SkOpSpan* oStartSpan = NULL;
+    SkOpSpanBase* oEndSpan = NULL;
+    SkOpPtT* ptT = fHead.ptT(), * startPtT = ptT;
+    while ((ptT = ptT->next()) != startPtT) {
+        other = ptT->segment();
+        oEndSpan = ptT->span();
+        oStartSpan = oEndSpan->prev();
+        if (oStartSpan && oStartSpan->windValue()) {
             break;
         }
-        if (newT == span.fT) {
-            if (pt == span.fPt) {
-                insertedAt = index;
-                break;
-            }
-            if ((pt == firstPt && newT == 0) || (span.fPt == lastPt && newT == 1)) {
-                insertedAt = index;
-                break;
-            }
-        }
-    }
-    SkOpSpan* span;
-    if (insertedAt >= 0) {
-        span = fTs.insert(insertedAt);
-    } else {
-        insertedAt = tCount;
-        span = fTs.append();
-    }
-    span->fT = newT;
-    span->fOtherT = -1;
-    span->fOther = other;
-    span->fPt = pt;
-#if 0
-    // cubics, for instance, may not be exact enough to satisfy this check (e.g., cubicOp69d)
-    SkASSERT(approximately_equal(xyAtT(newT).fX, pt.fX)
-            && approximately_equal(xyAtT(newT).fY, pt.fY));
-#endif
-    span->fFromAngle = NULL;
-    span->fToAngle = NULL;
-    span->fWindSum = SK_MinS32;
-    span->fOppSum = SK_MinS32;
-    span->fWindValue = 1;
-    span->fOppValue = 0;
-    span->fChased = false;
-    span->fCoincident = false;
-    span->fLoop = false;
-    span->fNear = false;
-    span->fMultiple = false;
-    span->fSmall = false;
-    span->fTiny = false;
-    if ((span->fDone = newT == 1)) {
-        ++fDoneSpans;
-    }
-    setSpanFlags(pt, newT, span);
-    return insertedAt;
-}
-
-void SkOpSegment::setSpanFlags(const SkPoint& pt, double newT, SkOpSpan* span) {
-    int less = -1;
-// FIXME: note that this relies on spans being a continguous array
-// find range of spans with nearly the same point as this one
-    // FIXME: SkDPoint::ApproximatelyEqual is better but breaks tests at the moment
-    while (&span[less + 1] - fTs.begin() > 0 && AlmostEqualUlps(span[less].fPt, pt)) {
-        if (fVerb == SkPath::kCubic_Verb) {
-            double tInterval = newT - span[less].fT;
-            double tMid = newT - tInterval / 2;
-            SkDPoint midPt = dcubic_xy_at_t(fPts, tMid);
-            if (!midPt.approximatelyEqual(xyAtT(span))) {
-                break;
-            }
-        }
-        --less;
-    }
-    int more = 1;
-    // FIXME: SkDPoint::ApproximatelyEqual is better but breaks tests at the moment
-    while (fTs.end() - &span[more - 1] > 1 && AlmostEqualUlps(span[more].fPt, pt)) {
-        if (fVerb == SkPath::kCubic_Verb) {
-            double tEndInterval = span[more].fT - newT;
-            double tMid = newT - tEndInterval / 2;
-            SkDPoint midEndPt = dcubic_xy_at_t(fPts, tMid);
-            if (!midEndPt.approximatelyEqual(xyAtT(span))) {
-                break;
-            }
-        }
-        ++more;
-    }
-    ++less;
-    --more;
-    while (more - 1 > less && span[more].fPt == span[more - 1].fPt
-            && span[more].fT == span[more - 1].fT) {
-        --more;
-    }
-    if (less == more) {
-        return;
-    }
-    if (precisely_negative(span[more].fT - span[less].fT)) {
-        return;
-    }
-// if the total range of t values is big enough, mark all tiny
-    bool tiny = span[less].fPt == span[more].fPt;
-    int index = less;
-    do {
-        fSmall = span[index].fSmall = true;
-        fTiny |= span[index].fTiny = tiny;
-        if (!span[index].fDone) {
-            span[index].fDone = true;
-            ++fDoneSpans;
-        }
-    } while (++index < more);
-    return;
-}
-
-void SkOpSegment::resetSpanFlags() {
-    fSmall = fTiny = false;
-    fDoneSpans = 0;
-    int start = 0;
-    int last = this->count() - 1;
-    do {
-        SkOpSpan* startSpan = &this->fTs[start];
-        double startT = startSpan->fT;
-        startSpan->fSmall = startSpan->fTiny = false;  // sets range initial
-        bool terminus = startT == 1;
-        if ((startSpan->fDone = !startSpan->fWindValue | terminus)) {
-            ++fDoneSpans;
-        }
-        ++start;  // range initial + 1
-        if (terminus) {
-            continue;
-        }
-        const SkPoint& pt = startSpan->fPt;
-        int end = start;  // range initial + 1
-        while (end <= last) {
-            const SkOpSpan& endSpan = this->span(end);
-            if (!AlmostEqualUlps(endSpan.fPt, pt)) {
-                break;
-            }
-            if (fVerb == SkPath::kCubic_Verb) {
-                double tMid = (startSpan->fT + endSpan.fT) / 2;
-                SkDPoint midEndPt = dcubic_xy_at_t(fPts, tMid);
-                if (!midEndPt.approximatelyEqual(xyAtT(startSpan))) {
-                    break;
-                }
-            }
-            ++end;
-        }
-        if (start == end) {  // end == range final + 1
-            continue;
-        }
-        while (--end >= start) {  // end == range final
-            const SkOpSpan& endSpan = this->span(end);
-            const SkOpSpan& priorSpan = this->span(end - 1);
-            if (endSpan.fPt != priorSpan.fPt || endSpan.fT != priorSpan.fT) {
-                break;  // end == range final + 1
-            }
-        }
-        if (end < start) {  // end == range final + 1
-            continue;
-        }
-        int index = start - 1;  // index == range initial
-        start = end;  // start = range final + 1
-        const SkOpSpan& nextSpan = this->span(end);
-        if (precisely_negative(nextSpan.fT - startSpan->fT)) {
-            while (++index < end) {
-                startSpan = &this->fTs[index];
-                startSpan->fSmall = startSpan->fTiny = false;  // sets range initial + 1
-                if ((startSpan->fDone = !startSpan->fWindValue)) {
-                    ++fDoneSpans;
-                }
-            }
-            continue;
-        }
-        if (!startSpan->fWindValue) {
-            --fDoneSpans;  // added back below
-        }
-        bool tiny = nextSpan.fPt == startSpan->fPt;
-        do {
-            fSmall = startSpan->fSmall = true;  // sets range initial
-            fTiny |= startSpan->fTiny = tiny;
-            startSpan->fDone = true;
-            ++fDoneSpans;
-            startSpan = &this->fTs[++index];
-        } while (index < end);  // loop through tiny small range end (last)
-    } while (start <= last);
-}
-
-// set spans from start to end to decrement by one
-// note this walks other backwards
-// FIXME: there's probably an edge case that can be constructed where
-// two span in one segment are separated by float epsilon on one span but
-// not the other, if one segment is very small. For this
-// case the counts asserted below may or may not be enough to separate the
-// spans. Even if the counts work out, what if the spans aren't correctly
-// sorted? It feels better in such a case to match the span's other span
-// pointer since both coincident segments must contain the same spans.
-// FIXME? It seems that decrementing by one will fail for complex paths that
-// have three or more coincident edges. Shouldn't this subtract the difference
-// between the winding values?
-/*                                      |-->                           |-->
-this     0>>>>1>>>>2>>>>3>>>4      0>>>>1>>>>2>>>>3>>>4      0>>>>1>>>>2>>>>3>>>4
-other         2<<<<1<<<<0               2<<<<1<<<<0               2<<<<1<<<<0
-              ^         ^                 <--|                           <--|
-           startPt    endPt        test/oTest first pos      test/oTest final pos
-*/
-void SkOpSegment::addTCancel(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other) {
-    bool binary = fOperand != other->fOperand;
-    int index = 0;
-    while (startPt != fTs[index].fPt) {
-        SkASSERT(index < fTs.count());
-        ++index;
-    }
-    while (index > 0 && precisely_equal(fTs[index].fT, fTs[index - 1].fT)) {
-        --index;
-    }
-    bool oFoundEnd = false;
-    int oIndex = other->fTs.count();
-    while (startPt != other->fTs[--oIndex].fPt) {  // look for startPt match
-        SkASSERT(oIndex > 0);
-    }
-    double oStartT = other->fTs[oIndex].fT;
-    // look for first point beyond match
-    while (startPt == other->fTs[--oIndex].fPt || precisely_equal(oStartT, other->fTs[oIndex].fT)) {
-        if (!oIndex) {
-            return;  // tiny spans may move in the wrong direction
-        }
-    }
-    SkOpSpan* test = &fTs[index];
-    SkOpSpan* oTest = &other->fTs[oIndex];
-    SkSTArray<kOutsideTrackedTCount, SkPoint, true> outsidePts;
-    SkSTArray<kOutsideTrackedTCount, SkPoint, true> oOutsidePts;
-    bool decrement, track, bigger;
-    int originalWindValue;
-    const SkPoint* testPt;
-    const SkPoint* oTestPt;
-    do {
-        SkASSERT(test->fT < 1);
-        SkASSERT(oTest->fT < 1);
-        decrement = test->fWindValue && oTest->fWindValue;
-        track = test->fWindValue || oTest->fWindValue;
-        bigger = test->fWindValue >= oTest->fWindValue;
-        testPt = &test->fPt;
-        double testT = test->fT;
-        oTestPt = &oTest->fPt;
-        double oTestT = oTest->fT;
-        do {
-            if (decrement) {
-                if (binary && bigger) {
-                    test->fOppValue--;
-                } else {
-                    decrementSpan(test);
-                }
-            } else if (track) {
-                TrackOutsidePair(&outsidePts, *testPt, *oTestPt);
-            }
-            SkASSERT(index < fTs.count() - 1);
-            test = &fTs[++index];
-        } while (*testPt == test->fPt || precisely_equal(testT, test->fT));
-        originalWindValue = oTest->fWindValue;
-        do {
-            SkASSERT(oTest->fT < 1);
-            SkASSERT(originalWindValue == oTest->fWindValue);
-            if (decrement) {
-                if (binary && !bigger) {
-                    oTest->fOppValue--;
-                } else {
-                    other->decrementSpan(oTest);
-                }
-            } else if (track) {
-                TrackOutsidePair(&oOutsidePts, *oTestPt, *testPt);
-            }
-            if (!oIndex) {
-                break;
-            }
-            oFoundEnd |= endPt == oTest->fPt;
-            oTest = &other->fTs[--oIndex];
-        } while (*oTestPt == oTest->fPt || precisely_equal(oTestT, oTest->fT));
-    } while (endPt != test->fPt && test->fT < 1);
-    // FIXME: determine if canceled edges need outside ts added
-    if (!oFoundEnd) {
-        for (int oIdx2 = oIndex; oIdx2 >= 0; --oIdx2) {
-            SkOpSpan* oTst2 = &other->fTs[oIdx2];            
-            if (originalWindValue != oTst2->fWindValue) {
-                goto skipAdvanceOtherCancel;
-            }
-            if (!oTst2->fWindValue) {
-                goto skipAdvanceOtherCancel;
-            }
-            if (endPt == other->fTs[oIdx2].fPt) {
-                break;
-            }
-        }
-        oFoundEnd = endPt == oTest->fPt;
-        do {
-            SkASSERT(originalWindValue == oTest->fWindValue);
-            if (decrement) {
-                if (binary && !bigger) {
-                    oTest->fOppValue--;
-                } else {
-                    other->decrementSpan(oTest);
-                }
-            } else if (track) {
-                TrackOutsidePair(&oOutsidePts, *oTestPt, *testPt);
-            }
-            if (!oIndex) {
-                break;
-            }
-            oTest = &other->fTs[--oIndex];
-            oFoundEnd |= endPt == oTest->fPt;
-        } while (!oFoundEnd || endPt == oTest->fPt);
-    }
-skipAdvanceOtherCancel:
-    int outCount = outsidePts.count();
-    if (!done() && outCount) {
-        addCancelOutsides(outsidePts[0], outsidePts[1], other);
-        if (outCount > 2) {
-            addCancelOutsides(outsidePts[outCount - 2], outsidePts[outCount - 1], other);
-        }
-    }
-    if (!other->done() && oOutsidePts.count()) {
-        other->addCancelOutsides(oOutsidePts[0], oOutsidePts[1], this);
-    }
-    setCoincidentRange(startPt, endPt, other);
-    other->setCoincidentRange(startPt, endPt, this);
-}
-
-int SkOpSegment::addSelfT(const SkPoint& pt, double newT) {
-    // if the tail nearly intersects itself but not quite, the caller records this separately
-    int result = addT(this, pt, newT);
-    SkOpSpan* span = &fTs[result];
-    fLoop = span->fLoop = true;
-    return result;
-}
-
-// find the starting or ending span with an existing loop of angles
-// FIXME? replicate for all identical starting/ending spans?
-// OPTIMIZE? remove the spans pointing to windValue==0 here or earlier?
-// FIXME? assert that only one other span has a valid windValue or oppValue
-void SkOpSegment::addSimpleAngle(int index) {
-    SkOpSpan* span = &fTs[index];
-    int idx;
-    int start, end;
-    if (span->fT == 0) {
-        idx = 0;
-        span = &fTs[0];
-        do {
-            if (span->fToAngle) {
-                SkASSERT(span->fToAngle->loopCount() == 2);
-                SkASSERT(!span->fFromAngle);
-                span->fFromAngle = span->fToAngle->next();
-                return;
-            }
-            span = &fTs[++idx];
-        } while (span->fT == 0);
-        SkASSERT(!fTs[0].fTiny && fTs[idx].fT > 0);
-        addStartSpan(idx);
-        start = 0;
-        end = idx;
-    } else {
-        idx = count() - 1;
-        span = &fTs[idx];
-        do {
-            if (span->fFromAngle) {
-                SkASSERT(span->fFromAngle->loopCount() == 2);
-                SkASSERT(!span->fToAngle);
-                span->fToAngle = span->fFromAngle->next();
-                return;
-            }
-            span = &fTs[--idx];
-        } while (span->fT == 1);
-        SkASSERT(!fTs[idx].fTiny && fTs[idx].fT < 1);
-        addEndSpan(++idx);
-        start = idx;
-        end = count();
-    }
-    SkOpSegment* other;
-    SkOpSpan* oSpan;
-    index = start;
-    do {
-        span = &fTs[index];
-        other = span->fOther;
-        int oFrom = span->fOtherIndex;
-        oSpan = &other->fTs[oFrom];
-        if (oSpan->fT < 1 && oSpan->fWindValue) {
+        oStartSpan = oEndSpan->upCastable();
+        if (oStartSpan && oStartSpan->windValue()) {
+            oEndSpan = oStartSpan->next();
             break;
         }
-        if (oSpan->fT == 0) {
-            continue;
-        }
-        oFrom = other->nextExactSpan(oFrom, -1);
-        SkOpSpan* oFromSpan = &other->fTs[oFrom];
-        SkASSERT(oFromSpan->fT < 1);
-        if (oFromSpan->fWindValue) {
-            break;
-        }
-    } while (++index < end);
-    SkOpAngle* angle, * oAngle;
-    if (span->fT == 0) {
-        SkASSERT(span->fOtherIndex - 1 >= 0);
-        SkASSERT(span->fOtherT == 1);
-        SkDEBUGCODE(int oPriorIndex = other->nextExactSpan(span->fOtherIndex, -1));
-        SkDEBUGCODE(const SkOpSpan& oPrior = other->span(oPriorIndex));
-        SkASSERT(!oPrior.fTiny && oPrior.fT < 1);
-        other->addEndSpan(span->fOtherIndex);
-        angle = span->fToAngle;
-        oAngle = oSpan->fFromAngle;
-    } else {
-        SkASSERT(span->fOtherIndex + 1 < other->count());
-        SkASSERT(span->fOtherT == 0);
-        SkASSERT(!oSpan->fTiny && (other->fTs[span->fOtherIndex + 1].fT > 0
-                || (other->fTs[span->fOtherIndex + 1].fFromAngle == NULL
-                && other->fTs[span->fOtherIndex + 1].fToAngle == NULL)));
-        int oIndex = 1;
-        do {
-            const SkOpSpan& osSpan = other->span(oIndex);
-            if (osSpan.fFromAngle || osSpan.fT > 0) {
-                break;
-            }
-            ++oIndex;
-            SkASSERT(oIndex < other->count());
-        } while (true);
-        other->addStartSpan(oIndex);
-        angle = span->fFromAngle;
-        oAngle = oSpan->fToAngle;
     }
-    angle->insert(oAngle);
+    SkOpAngle* oAngle = SkOpTAllocator<SkOpAngle>::Allocate(allocator);
+    oAngle->set(oEndSpan, oStartSpan);
+    oEndSpan->setFromAngle(oAngle);
+    *otherPtr = other;
+    return oAngle;
 }
 
-void SkOpSegment::alignMultiples(SkTDArray<AlignedSpan>* alignedArray) {
+SkOpPtT* SkOpSegment::addT(double t, AllowAlias allowAlias, SkChunkAlloc* allocator) {
     debugValidate();
-    int count = this->count();
-    for (int index = 0; index < count; ++index) {
-        SkOpSpan& span = fTs[index];
-        if (!span.fMultiple) {
-            continue;
+    SkPoint pt = this->ptAtT(t);
+    SkOpSpanBase* span = &fHead;
+    do {
+        SkOpPtT* result = span->ptT();
+        if (t == result->fT) {
+            return result;
         }
-        int end = nextExactSpan(index, 1);
-        SkASSERT(end > index + 1);
-        const SkPoint& thisPt = span.fPt;
-        while (index < end - 1) {
-            SkOpSegment* other1 = span.fOther;
-            int oCnt = other1->count();
-            for (int idx2 = index + 1; idx2 < end; ++idx2) {
-                SkOpSpan& span2 = fTs[idx2];
-                SkOpSegment* other2 = span2.fOther;
-                for (int oIdx = 0; oIdx < oCnt; ++oIdx) {
-                    SkOpSpan& oSpan = other1->fTs[oIdx];
-                    if (oSpan.fOther != other2) {
-                        continue;
-                    }
-                    if (oSpan.fPt == thisPt) {
-                        goto skipExactMatches;
-                    }
+        if (this->match(result, this, t, pt)) {
+            // see if any existing alias matches segment, pt, and t
+            SkOpPtT* loop = result->next();
+            bool duplicatePt = false;
+            while (loop != result) {
+                bool ptMatch = loop->fPt == pt;
+                if (loop->segment() == this && loop->fT == t && ptMatch) {
+                    return result;
                 }
-                for (int oIdx = 0; oIdx < oCnt; ++oIdx) {
-                    SkOpSpan& oSpan = other1->fTs[oIdx];
-                    if (oSpan.fOther != other2) {
-                        continue;
-                    }
-                    if (SkDPoint::RoughlyEqual(oSpan.fPt, thisPt)) {
-                        SkOpSpan& oSpan2 = other2->fTs[oSpan.fOtherIndex];
-                        if (zero_or_one(span.fOtherT) || zero_or_one(oSpan.fT)
-                                || zero_or_one(span2.fOtherT) || zero_or_one(oSpan2.fT)) {
-                            return;
-                        }
-                        if (!way_roughly_equal(span.fOtherT, oSpan.fT)
-                                || !way_roughly_equal(span2.fOtherT, oSpan2.fT)
-                                || !way_roughly_equal(span2.fOtherT, oSpan.fOtherT)
-                                || !way_roughly_equal(span.fOtherT, oSpan2.fOtherT)) {
-                            return;
-                        }
-                        alignSpan(thisPt, span.fOtherT, other1, span2.fOtherT,
-                                other2, &oSpan, alignedArray);
-                        alignSpan(thisPt, span2.fOtherT, other2, span.fOtherT, 
-                                other1, &oSpan2, alignedArray);
-                        break;
-                    }
-                }
-        skipExactMatches:
-                ;
+                duplicatePt |= ptMatch;
+                loop = loop->next();
             }
-            ++index;
+            if (kNoAlias == allowAlias) {
+                return result;
+            }
+            SkOpPtT* alias = SkOpTAllocator<SkOpPtT>::Allocate(allocator);
+            alias->init(result->span(), t, pt, duplicatePt);
+            result->insert(alias);
+            result->span()->unaligned();
+            this->debugValidate();
+#if DEBUG_ADD_T
+            SkDebugf("%s alias t=%1.9g segID=%d spanID=%d\n",  __FUNCTION__, t,
+                    alias->segment()->debugID(), alias->span()->debugID());
+#endif
+            return alias;
         }
+        if (t < result->fT) {
+            SkOpSpan* prev = result->span()->prev();
+            SkOpSpan* span = insert(prev, allocator);
+            span->init(this, prev, t, pt);
+            this->debugValidate();
+#if DEBUG_ADD_T
+            SkDebugf("%s insert t=%1.9g segID=%d spanID=%d\n", __FUNCTION__, t,
+                    span->segment()->debugID(), span->debugID());
+#endif
+            return span->ptT();
+        }
+        SkASSERT(span != &fTail);
+    } while ((span = span->upCast()->next()));
+    SkASSERT(0);
+    return NULL;
+}
+
+// choose a solitary t and pt value; remove aliases; align the opposite ends
+void SkOpSegment::align() {
+    debugValidate();
+    SkOpSpanBase* span = &fHead;
+    if (!span->aligned()) {
+        span->alignEnd(0, fPts[0]);
+    }
+    while ((span = span->upCast()->next())) {
+        if (span == &fTail) {
+            break;
+        }
+        span->align();
+    }
+    if (!span->aligned()) {
+        span->alignEnd(1, fPts[SkPathOpsVerbToPoints(fVerb)]);
     }
     debugValidate();
 }
 
-void SkOpSegment::alignRange(int lower, int upper,
-        const SkOpSegment* other, int oLower, int oUpper) {
-    for (int oIndex = oLower; oIndex <= oUpper; ++oIndex) {
-        const SkOpSpan& oSpan = other->span(oIndex);
-        const SkOpSegment* oOther = oSpan.fOther;
-        if (oOther == this) {
-            continue;
-        }
-        SkOpSpan* matchSpan;
-        int matchIndex;
-        const SkOpSpan* refSpan;
-        for (int iIndex = lower; iIndex <= upper; ++iIndex) {
-            const SkOpSpan& iSpan = this->span(iIndex);
-            const SkOpSegment* iOther = iSpan.fOther;
-            if (iOther == other) {
-                continue;
-            }
-            if (iOther == oOther) {
-                goto nextI;
-            }
-        }
-        {
-            // oSpan does not have a match in this
-            int iCount = this->count();
-            const SkOpSpan* iMatch = NULL;
-            double iMatchTDiff;
-            matchIndex = -1;
-            for (int iIndex = 0; iIndex < iCount; ++iIndex) {
-                const SkOpSpan& iSpan = this->span(iIndex);
-                const SkOpSegment* iOther = iSpan.fOther;
-                if (iOther != oOther) {
-                    continue;
-                }
-                double testTDiff = fabs(iSpan.fOtherT - oSpan.fOtherT);
-                if (!iMatch || testTDiff < iMatchTDiff) {
-                    matchIndex = iIndex;
-                    iMatch = &iSpan;
-                    iMatchTDiff = testTDiff;
-                }
-            }
-            if (matchIndex < 0) {
-                continue;  // the entry is missing, & will be picked up later (FIXME: fix it here?)
-            }
-            matchSpan = &this->fTs[matchIndex];
-            refSpan = &this->span(lower);
-            if (!SkDPoint::ApproximatelyEqual(matchSpan->fPt, refSpan->fPt)) {
-                goto nextI;
-            }
-            if (matchIndex != lower - 1 && matchIndex != upper + 1) {
-                // the consecutive spans need to be rearranged to get the missing one close 
-                continue;  // FIXME: more work to do
-            }
-        }
-        {
-            this->fixOtherTIndex();
-            SkScalar newT;
-            if (matchSpan->fT != 0 && matchSpan->fT != 1) {
-                newT = matchSpan->fT = refSpan->fT;
-                matchSpan->fOther->fTs[matchSpan->fOtherIndex].fOtherT = refSpan->fT;
-            } else {  // leave span at the start or end there and adjust the neighbors
-                newT = matchSpan->fT;
-                for (int iIndex = lower; iIndex <= upper; ++iIndex) {
-                    matchSpan = &this->fTs[iIndex];
-                    matchSpan->fT = newT;
-                    matchSpan->fOther->fTs[matchSpan->fOtherIndex].fOtherT = newT;
-                }
-            }
-            this->resetSpanFlags();  // fix up small / tiny / done
-            // align ts of other ranges with adjacent spans that match the aligned points
-            lower = SkTMin(lower, matchIndex);
-            while (lower > 0) {
-                const SkOpSpan& span = this->span(lower - 1);
-                if (span.fT != newT) {
-                    break;
-                }
-                --lower;
-            }
-            upper = SkTMax(upper, matchIndex);
-            int last = this->count() - 1;
-            while (upper < last) {
-                const SkOpSpan& span = this->span(upper + 1);
-                if (span.fT != newT) {
-                    break;
-                }
-                ++upper;
-            }
-            for (int iIndex = lower; iIndex <= upper; ++iIndex) {
-                const SkOpSpan& span = this->span(iIndex);
-                SkOpSegment* aOther = span.fOther;
-                int aLower = span.fOtherIndex;
-                SkScalar aT = span.fOtherT;
-                bool aResetFlags = false;
-                while (aLower > 0) {
-                    SkOpSpan* aSpan = &aOther->fTs[aLower - 1];
-                    for (int iIndex = lower; iIndex <= upper; ++iIndex) {
-                        if (aSpan->fPt == this->fTs[iIndex].fPt) {
-                            goto matchFound;
-                        }
-                    }
-                    break;
-            matchFound:
-                    --aLower;
-                }
-                int aUpper = span.fOtherIndex;
-                int aLast = aOther->count() - 1;
-                while (aUpper < aLast) {
-                    SkOpSpan* aSpan = &aOther->fTs[aUpper + 1];
-                    for (int iIndex = lower; iIndex <= upper; ++iIndex) {
-                        if (aSpan->fPt == this->fTs[iIndex].fPt) {
-                            goto matchFound2;
-                        }
-                    }
-                    break;
-            matchFound2:
-                    ++aUpper;
-                }
-                if (aOther->fTs[aLower].fT == 0) {
-                    aT = 0;
-                } else if (aOther->fTs[aUpper].fT == 1) {
-                    aT = 1;
-                }
-                bool aFixed = false;
-                for (int aIndex = aLower; aIndex <= aUpper; ++aIndex) {
-                    SkOpSpan* aSpan = &aOther->fTs[aIndex];
-                    if (aSpan->fT == aT) {
-                        continue;
-                    }
-                    SkASSERT(way_roughly_equal(aSpan->fT, aT));
-                    if (!aFixed) {
-                        aOther->fixOtherTIndex();
-                        aFixed = true;
-                    }
-                    aSpan->fT = aT;
-                    aSpan->fOther->fTs[aSpan->fOtherIndex].fOtherT = aT;
-                    aResetFlags = true;
-                }
-                if (aResetFlags) {
-                    aOther->resetSpanFlags();
-                }
-            }
-        }
-nextI: ;
+bool SkOpSegment::BetweenTs(const SkOpSpanBase* lesser, double testT,
+        const SkOpSpanBase* greater) {
+    if (lesser->t() > greater->t()) {
+        SkTSwap<const SkOpSpanBase*>(lesser, greater);
     }
+    return approximately_between(lesser->t(), testT, greater->t());
 }
 
-void SkOpSegment::alignSpan(const SkPoint& newPt, double newT, const SkOpSegment* other,
-        double otherT, const SkOpSegment* other2, SkOpSpan* oSpan,
-        SkTDArray<AlignedSpan>* alignedArray) {
-    AlignedSpan* aligned = alignedArray->append();
-    aligned->fOldPt = oSpan->fPt;
-    aligned->fPt = newPt;
-    aligned->fOldT = oSpan->fT;
-    aligned->fT = newT;
-    aligned->fSegment = this;  // OPTIMIZE: may be unused, can remove
-    aligned->fOther1 = other;
-    aligned->fOther2 = other2;
-    SkASSERT(SkDPoint::RoughlyEqual(oSpan->fPt, newPt));
-    oSpan->fPt = newPt;
-//    SkASSERT(way_roughly_equal(oSpan->fT, newT));
-    oSpan->fT = newT;
-//    SkASSERT(way_roughly_equal(oSpan->fOtherT, otherT));
-    oSpan->fOtherT = otherT;
-}
-
-bool SkOpSegment::alignSpan(int index, double thisT, const SkPoint& thisPt) {
-    bool aligned = false;
-    SkOpSpan* span = &fTs[index];
-    SkOpSegment* other = span->fOther;
-    int oIndex = span->fOtherIndex;
-    SkOpSpan* oSpan = &other->fTs[oIndex];
-    if (span->fT != thisT) {
-        span->fT = thisT;
-        oSpan->fOtherT = thisT;
-        aligned = true;
+void SkOpSegment::calcAngles(SkChunkAlloc* allocator) {
+    bool activePrior = !fHead.isCanceled();
+    if (activePrior && !fHead.simple()) {
+        addStartSpan(allocator);
     }
-    if (span->fPt != thisPt) {
-        span->fPt = thisPt;
-        oSpan->fPt = thisPt;
-        aligned = true;
-    }
-    double oT = oSpan->fT;
-    if (oT == 0) {
-        return aligned;
-    }
-    int oStart = other->nextSpan(oIndex, -1) + 1;
-    oSpan = &other->fTs[oStart];
-    int otherIndex = oStart;
-    if (oT == 1) {
-        if (aligned) {
-            while (oSpan->fPt == thisPt && oSpan->fT != 1) {
-                oSpan->fTiny = true;
-                ++oSpan;
-            }
+    SkOpSpan* prior = &fHead;
+    SkOpSpanBase* spanBase = fHead.next();
+    while (spanBase != &fTail) {
+        if (activePrior) {
+            SkOpAngle* priorAngle = SkOpTAllocator<SkOpAngle>::Allocate(allocator);
+            priorAngle->set(spanBase, prior);
+            spanBase->setFromAngle(priorAngle);
         }
-        return aligned;
-    }
-    oT = oSpan->fT;
-    int oEnd = other->nextSpan(oIndex, 1);
-    bool oAligned = false;
-    if (oSpan->fPt != thisPt) {
-        oAligned |= other->alignSpan(oStart, oT, thisPt);
-    }
-    while (++otherIndex < oEnd) {
-        SkOpSpan* oNextSpan = &other->fTs[otherIndex];
-        if (oNextSpan->fT != oT || oNextSpan->fPt != thisPt) {
-            oAligned |= other->alignSpan(otherIndex, oT, thisPt);
+        SkOpSpan* span = spanBase->upCast();
+        bool active = !span->isCanceled();
+        SkOpSpanBase* next = span->next();
+        if (active) {
+            SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(allocator);
+            angle->set(span, next);
+            span->setToAngle(angle);
         }
-    }
-    if (oAligned) {
-        other->alignSpanState(oStart, oEnd);
-    }
-    return aligned;
-}
-
-void SkOpSegment::alignSpanState(int start, int end) {
-    SkOpSpan* lastSpan = &fTs[--end];
-    bool allSmall = lastSpan->fSmall;
-    bool allTiny = lastSpan->fTiny;
-    bool allDone = lastSpan->fDone;
-    SkDEBUGCODE(int winding = lastSpan->fWindValue);
-    SkDEBUGCODE(int oppWinding = lastSpan->fOppValue);
-    int index = start;
-    while (index < end) {
-        SkOpSpan* span = &fTs[index];
-        span->fSmall = allSmall;
-        span->fTiny = allTiny;
-        if (span->fDone != allDone) {
-            span->fDone = allDone;
-            fDoneSpans += allDone ? 1 : -1;
-        }
-        SkASSERT(span->fWindValue == winding);
-        SkASSERT(span->fOppValue == oppWinding);
-        ++index;
-    }
-}
-
-void SkOpSegment::blindCancel(const SkCoincidence& coincidence, SkOpSegment* other) {
-    bool binary = fOperand != other->fOperand;
-    int index = 0;
-    int last = this->count();
-    do {
-        SkOpSpan& span = this->fTs[--last];
-        if (span.fT != 1 && !span.fSmall) {
-            break;
-        }
-        span.fCoincident = true;
-    } while (true);
-    int oIndex = other->count();
-    do {
-        SkOpSpan& oSpan = other->fTs[--oIndex];
-        if (oSpan.fT != 1 && !oSpan.fSmall) {
-            break;
-        }
-        oSpan.fCoincident = true;
-    } while (true);
-    do {
-        SkOpSpan* test = &this->fTs[index];
-        int baseWind = test->fWindValue;
-        int baseOpp = test->fOppValue;
-        int endIndex = index;
-        while (++endIndex <= last) {
-            SkOpSpan* endSpan = &this->fTs[endIndex];
-            SkASSERT(endSpan->fT < 1);
-            if (endSpan->fWindValue != baseWind || endSpan->fOppValue != baseOpp) {
-                break;
-            }
-            endSpan->fCoincident = true;
-        }
-        SkOpSpan* oTest = &other->fTs[oIndex];
-        int oBaseWind = oTest->fWindValue;
-        int oBaseOpp = oTest->fOppValue;
-        int oStartIndex = oIndex;
-        while (--oStartIndex >= 0) {
-            SkOpSpan* oStartSpan = &other->fTs[oStartIndex];
-            if (oStartSpan->fWindValue != oBaseWind || oStartSpan->fOppValue != oBaseOpp) {
-                break;
-            }
-            oStartSpan->fCoincident = true;
-        }
-        bool decrement = baseWind && oBaseWind;
-        bool bigger = baseWind >= oBaseWind;
-        do {
-            SkASSERT(test->fT < 1);
-            if (decrement) {
-                if (binary && bigger) {
-                    test->fOppValue--;
-                } else {
-                    decrementSpan(test);
-                }
-            }
-            test->fCoincident = true;
-            test = &fTs[++index];
-        } while (index < endIndex);
-        do {
-            SkASSERT(oTest->fT < 1);
-            if (decrement) {
-                if (binary && !bigger) {
-                    oTest->fOppValue--;
-                } else {
-                    other->decrementSpan(oTest);
-                }
-            }
-            oTest->fCoincident = true;
-            oTest = &other->fTs[--oIndex];
-        } while (oIndex > oStartIndex);
-    } while (index <= last && oIndex >= 0);
-    SkASSERT(index > last);
-    SkASSERT(oIndex < 0);
-}
-
-void SkOpSegment::blindCoincident(const SkCoincidence& coincidence, SkOpSegment* other) {
-    bool binary = fOperand != other->fOperand;
-    int index = 0;
-    int last = this->count();
-    do {
-        SkOpSpan& span = this->fTs[--last];
-        if (span.fT != 1 && !span.fSmall) {
-            break;
-        }
-        span.fCoincident = true;
-    } while (true);
-    int oIndex = 0;
-    int oLast = other->count();
-    do {
-        SkOpSpan& oSpan = other->fTs[--oLast];
-        if (oSpan.fT != 1 && !oSpan.fSmall) {
-            break;
-        }
-        oSpan.fCoincident = true;
-    } while (true);
-    do {
-        SkOpSpan* test = &this->fTs[index];
-        int baseWind = test->fWindValue;
-        int baseOpp = test->fOppValue;
-        int endIndex = index;
-        SkOpSpan* endSpan;
-        while (++endIndex <= last) {
-            endSpan = &this->fTs[endIndex];
-            SkASSERT(endSpan->fT < 1);
-            if (endSpan->fWindValue != baseWind || endSpan->fOppValue != baseOpp) {
-                break;
-            }
-            endSpan->fCoincident = true;
-        }
-        SkOpSpan* oTest = &other->fTs[oIndex];
-        int oBaseWind = oTest->fWindValue;
-        int oBaseOpp = oTest->fOppValue;
-        int oEndIndex = oIndex;
-        SkOpSpan* oEndSpan;
-        while (++oEndIndex <= oLast) {
-            oEndSpan = &this->fTs[oEndIndex];
-            SkASSERT(oEndSpan->fT < 1);
-            if (oEndSpan->fWindValue != oBaseWind || oEndSpan->fOppValue != oBaseOpp) {
-                break;
-            }
-            oEndSpan->fCoincident = true;
-        }
-        // consolidate the winding count even if done
-        if ((test->fWindValue || test->fOppValue) && (oTest->fWindValue || oTest->fOppValue)) {
-            if (!binary || test->fWindValue + oTest->fOppValue >= 0) {
-                bumpCoincidentBlind(binary, index, endIndex);
-                other->bumpCoincidentOBlind(oIndex, oEndIndex);
-            } else {
-                other->bumpCoincidentBlind(binary, oIndex, oEndIndex);
-                bumpCoincidentOBlind(index, endIndex);
-            }
-        }
-        index = endIndex;
-        oIndex = oEndIndex;
-    } while (index <= last && oIndex <= oLast);
-    SkASSERT(index > last);
-    SkASSERT(oIndex > oLast);
-}
-
-void SkOpSegment::bumpCoincidentBlind(bool binary, int index, int endIndex) {
-    const SkOpSpan& oTest = fTs[index];
-    int oWindValue = oTest.fWindValue;
-    int oOppValue = oTest.fOppValue;
-    if (binary) {
-        SkTSwap<int>(oWindValue, oOppValue);
-    }
-    do {
-        (void) bumpSpan(&fTs[index], oWindValue, oOppValue);
-    } while (++index < endIndex);
-}
-
-bool SkOpSegment::bumpCoincidentThis(const SkOpSpan& oTest, bool binary, int* indexPtr,
-        SkTArray<SkPoint, true>* outsideTs) {
-    int index = *indexPtr;
-    int oWindValue = oTest.fWindValue;
-    int oOppValue = oTest.fOppValue;
-    if (binary) {
-        SkTSwap<int>(oWindValue, oOppValue);
-    }
-    SkOpSpan* const test = &fTs[index];
-    SkOpSpan* end = test;
-    const SkPoint& oStartPt = oTest.fPt;
-    do {
-        if (end->fDone && !end->fTiny && !end->fSmall) {  // extremely large paths trigger this
-            return false;
-        }
-        if (bumpSpan(end, oWindValue, oOppValue)) {
-            TrackOutside(outsideTs, oStartPt);
-        }
-        end = &fTs[++index];
-    } while ((end->fPt == test->fPt || precisely_equal(end->fT, test->fT)) && end->fT < 1);
-    *indexPtr = index;
-    return true;
-}
-
-void SkOpSegment::bumpCoincidentOBlind(int index, int endIndex) {
-    do {
-        zeroSpan(&fTs[index]);
-    } while (++index < endIndex);
-}
-
-// because of the order in which coincidences are resolved, this and other
-// may not have the same intermediate points. Compute the corresponding
-// intermediate T values (using this as the master, other as the follower)
-// and walk other conditionally -- hoping that it catches up in the end
-bool SkOpSegment::bumpCoincidentOther(const SkOpSpan& test, int* oIndexPtr,
-        SkTArray<SkPoint, true>* oOutsidePts, const SkPoint& oEndPt) {
-    int oIndex = *oIndexPtr;
-    SkOpSpan* const oTest = &fTs[oIndex];
-    SkOpSpan* oEnd = oTest;
-    const SkPoint& oStartPt = oTest->fPt;
-    double oStartT = oTest->fT;
-#if 0  // FIXME : figure out what disabling this breaks
-    const SkPoint& startPt = test.fPt;
-    // this is always true since oEnd == oTest && oStartPt == oTest->fPt -- find proper condition
-    if (oStartPt == oEnd->fPt || precisely_equal(oStartT, oEnd->fT)) {
-        TrackOutside(oOutsidePts, startPt);
-    }
-#endif
-    bool foundEnd = false;
-    while (oStartPt == oEnd->fPt || precisely_equal(oStartT, oEnd->fT)) {
-        foundEnd |= oEndPt == oEnd->fPt;
-        zeroSpan(oEnd);
-        oEnd = &fTs[++oIndex];
-    }
-    *oIndexPtr = oIndex;
-    return foundEnd;
-}
-
-// FIXME: need to test this case:
-// contourA has two segments that are coincident
-// contourB has two segments that are coincident in the same place
-// each ends up with +2/0 pairs for winding count
-// since logic below doesn't transfer count (only increments/decrements) can this be
-// resolved to +4/0 ?
-
-// set spans from start to end to increment the greater by one and decrement
-// the lesser
-bool SkOpSegment::addTCoincident(const SkPoint& startPt, const SkPoint& endPt, double endT,
-        SkOpSegment* other) {
-    bool binary = fOperand != other->fOperand;
-    int index = 0;
-    while (startPt != fTs[index].fPt) {
-        SkASSERT(index < fTs.count());
-        ++index;
-    }
-    double startT = fTs[index].fT;
-    while (index > 0 && precisely_equal(fTs[index - 1].fT, startT)) {
-        --index;
-    }
-    int oIndex = 0;
-    while (startPt != other->fTs[oIndex].fPt) {
-        SkASSERT(oIndex < other->fTs.count());
-        ++oIndex;
-    }
-    double oStartT = other->fTs[oIndex].fT;
-    while (oIndex > 0 && precisely_equal(other->fTs[oIndex - 1].fT, oStartT)) {
-        --oIndex;
-    }
-    SkSTArray<kOutsideTrackedTCount, SkPoint, true> outsidePts;
-    SkSTArray<kOutsideTrackedTCount, SkPoint, true> oOutsidePts;
-    SkOpSpan* test = &fTs[index];
-    const SkPoint* testPt = &test->fPt;
-    double testT = test->fT;
-    SkOpSpan* oTest = &other->fTs[oIndex];
-    const SkPoint* oTestPt = &oTest->fPt;
-    // paths with extreme data will fail this test and eject out of pathops altogether later on
-    // SkASSERT(AlmostEqualUlps(*testPt, *oTestPt));
-    do {
-        SkASSERT(test->fT < 1);
-        if (oTest->fT == 1) {
-            // paths with extreme data may be so mismatched that we fail here
-            return false;
-        }
-
-        // consolidate the winding count even if done
-        bool foundEnd = false;
-        if ((test->fWindValue == 0 && test->fOppValue == 0)
-                || (oTest->fWindValue == 0 && oTest->fOppValue == 0)) {
-            SkDEBUGCODE(int firstWind = test->fWindValue);
-            SkDEBUGCODE(int firstOpp = test->fOppValue);
-            do {
-                SkASSERT(firstWind == fTs[index].fWindValue);
-                SkASSERT(firstOpp == fTs[index].fOppValue);
-                ++index;
-                SkASSERT(index < fTs.count());
-            } while (*testPt == fTs[index].fPt);
-            SkDEBUGCODE(firstWind = oTest->fWindValue);
-            SkDEBUGCODE(firstOpp = oTest->fOppValue);
-            do {
-                SkASSERT(firstWind == other->fTs[oIndex].fWindValue);
-                SkASSERT(firstOpp == other->fTs[oIndex].fOppValue);
-                ++oIndex;
-                SkASSERT(oIndex < other->fTs.count());
-            } while (*oTestPt == other->fTs[oIndex].fPt);
-        } else {
-            if (!binary || test->fWindValue + oTest->fOppValue >= 0) {
-                if (!bumpCoincidentThis(*oTest, binary, &index, &outsidePts)) {
-                    return false;
-                }
-                foundEnd = other->bumpCoincidentOther(*test, &oIndex, &oOutsidePts, endPt);
-            } else {
-                if (!other->bumpCoincidentThis(*test, binary, &oIndex, &oOutsidePts)) {
-                    return false;
-                }
-                foundEnd = bumpCoincidentOther(*oTest, &index, &outsidePts, endPt);
-            }
-        }
-        test = &fTs[index];
-        testPt = &test->fPt;
-        testT = test->fT;
-        oTest = &other->fTs[oIndex];
-        oTestPt = &oTest->fPt;
-        if (endPt == *testPt || precisely_equal(endT, testT)) {
-            break;
-        }
-        if (0 && foundEnd) {  // FIXME: this is likely needed but wait until a test case triggers it
-            break;
-        }
-//        SkASSERT(AlmostEqualUlps(*testPt, *oTestPt));
-    } while (endPt != *oTestPt);
-    // in rare cases, one may have ended before the other
-    if (endPt != *testPt && !precisely_equal(endT, testT)) {
-        int lastWind = test[-1].fWindValue;
-        int lastOpp = test[-1].fOppValue;
-        bool zero = lastWind == 0 && lastOpp == 0;
-        do {
-            if (test->fWindValue || test->fOppValue) {
-                test->fWindValue = lastWind;
-                test->fOppValue = lastOpp;
-                if (zero) {
-                    SkASSERT(!test->fDone);
-                    test->fDone = true;
-                    ++fDoneSpans;
-                }
-            }
-            test = &fTs[++index];
-            testPt = &test->fPt;
-        } while (endPt != *testPt);
-    }
-    if (endPt != *oTestPt) {
-        // look ahead to see if zeroing more spans will allows us to catch up
-        int oPeekIndex = oIndex;
-        bool success = true;
-        SkOpSpan* oPeek;
-        int oCount = other->count();
-        do {
-            oPeek = &other->fTs[oPeekIndex];
-            if (++oPeekIndex == oCount) {
-                success = false;
-                break;
-            }
-        } while (endPt != oPeek->fPt);
-        if (success) {
-            // make sure the matching point completes the coincidence span
-            success = false;
-            do {
-                if (oPeek->fOther == this) {
-                    success = true;
-                    break;
-                }
-                if (++oPeekIndex == oCount) {
-                    break;
-                }
-                oPeek = &other->fTs[oPeekIndex];
-            } while (endPt == oPeek->fPt);
-        }
-        if (success) {
-            do {
-                if (!binary || test->fWindValue + oTest->fOppValue >= 0) {
-                    if (other->bumpCoincidentOther(*test, &oIndex, &oOutsidePts, endPt)) {
-                        break;
-                    }
-                } else {
-                    if (!other->bumpCoincidentThis(*test, binary, &oIndex, &oOutsidePts)) {
-                        return false;
-                    }
-                }
-                oTest = &other->fTs[oIndex];
-                oTestPt = &oTest->fPt;
-            } while (endPt != *oTestPt);
-        }
-    }
-    int outCount = outsidePts.count();
-    if (!done() && outCount) {
-        addCoinOutsides(outsidePts[0], endPt, other);
-    }
-    if (!other->done() && oOutsidePts.count()) {
-        other->addCoinOutsides(oOutsidePts[0], endPt, this);
-    }
-    setCoincidentRange(startPt, endPt, other);
-    other->setCoincidentRange(startPt, endPt, this);
-    return true;
-}
-
-// FIXME: this doesn't prevent the same span from being added twice
-// fix in caller, SkASSERT here?
-// FIXME: this may erroneously reject adds for cubic loops
-const SkOpSpan* SkOpSegment::addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind,
-        const SkPoint& pt, const SkPoint& pt2) {
-    int tCount = fTs.count();
-    for (int tIndex = 0; tIndex < tCount; ++tIndex) {
-        const SkOpSpan& span = fTs[tIndex];
-        if (!approximately_negative(span.fT - t)) {
-            break;
-        }
-        if (span.fOther == other) {
-            bool tsMatch = approximately_equal(span.fT, t);
-            bool otherTsMatch = approximately_equal(span.fOtherT, otherT);
-            // FIXME: add cubic loop detecting logic here
-            // if fLoop bit is set on span, that could be enough if addOtherT copies the bit
-            // or if a new bit is added ala fOtherLoop
-            if (tsMatch || otherTsMatch) {
-#if DEBUG_ADD_T_PAIR
-                SkDebugf("%s addTPair duplicate this=%d %1.9g other=%d %1.9g\n",
-                        __FUNCTION__, fID, t, other->fID, otherT);
-#endif
-                return NULL;
-            }
-        }
-    }
-    int oCount = other->count();
-    for (int oIndex = 0; oIndex < oCount; ++oIndex) {
-        const SkOpSpan& oSpan = other->span(oIndex);
-        if (!approximately_negative(oSpan.fT - otherT)) {
-            break;
-        }
-        if (oSpan.fOther == this) {
-            bool otherTsMatch = approximately_equal(oSpan.fT, otherT);
-            bool tsMatch = approximately_equal(oSpan.fOtherT, t);
-            if (otherTsMatch || tsMatch) {
-#if DEBUG_ADD_T_PAIR
-                SkDebugf("%s addTPair other duplicate this=%d %1.9g other=%d %1.9g\n",
-                        __FUNCTION__, fID, t, other->fID, otherT);
-#endif
-                return NULL;
-            }
-        }
-    }
-#if DEBUG_ADD_T_PAIR
-    SkDebugf("%s addTPair this=%d %1.9g other=%d %1.9g\n",
-            __FUNCTION__, fID, t, other->fID, otherT);
-#endif
-    SkASSERT(other != this);
-    int insertedAt = addT(other, pt, t);
-    int otherInsertedAt = other->addT(this, pt2, otherT);
-    this->addOtherT(insertedAt, otherT, otherInsertedAt);
-    other->addOtherT(otherInsertedAt, t, insertedAt);
-    this->matchWindingValue(insertedAt, t, borrowWind);
-    other->matchWindingValue(otherInsertedAt, otherT, borrowWind);
-    SkOpSpan& span = this->fTs[insertedAt];
-    if (pt != pt2) {
-        span.fNear = true;
-        SkOpSpan& oSpan = other->fTs[otherInsertedAt];
-        oSpan.fNear = true;
-    }
-    // if the newly inserted spans match a neighbor on one but not the other, make them agree
-    int lower = this->nextExactSpan(insertedAt, -1) + 1;
-    int upper = this->nextExactSpan(insertedAt, 1) - 1;
-    if (upper < 0) {
-        upper = this->count() - 1;
-    }
-    int oLower = other->nextExactSpan(otherInsertedAt, -1) + 1;
-    int oUpper = other->nextExactSpan(otherInsertedAt, 1) - 1;
-    if (oUpper < 0) {
-        oUpper = other->count() - 1;
-    }
-    if (lower == upper && oLower == oUpper) {
-        return &span;
-    }
-#if DEBUG_CONCIDENT
-    SkDebugf("%s id=%d lower=%d upper=%d other=%d oLower=%d oUpper=%d\n", __FUNCTION__,
-            debugID(), lower, upper, other->debugID(), oLower, oUpper);
-#endif
-    // find the nearby spans in one range missing in the other
-    this->alignRange(lower, upper, other, oLower, oUpper);
-    other->alignRange(oLower, oUpper, this, lower, upper);
-    return &span;
-}
-
-const SkOpSpan* SkOpSegment::addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind,
-                           const SkPoint& pt) {
-    return addTPair(t, other, otherT, borrowWind, pt, pt);
-}
-
-bool SkOpSegment::betweenPoints(double midT, const SkPoint& pt1, const SkPoint& pt2) const {
-    const SkPoint midPt = ptAtT(midT);
-    SkPathOpsBounds bounds;
-    bounds.set(pt1.fX, pt1.fY, pt2.fX, pt2.fY);
-    bounds.sort();
-    return bounds.almostContains(midPt);
-}
-
-bool SkOpSegment::betweenTs(int lesser, double testT, int greater) const {
-    if (lesser > greater) {
-        SkTSwap<int>(lesser, greater);
-    }
-    return approximately_between(fTs[lesser].fT, testT, fTs[greater].fT);
-}
-
-// in extreme cases (like the buffer overflow test) return false to abort
-// for now, if one t value represents two different points, then the values are too extreme
-// to generate meaningful results
-bool SkOpSegment::calcAngles() {
-    int spanCount = fTs.count();
-    if (spanCount <= 2) {
-        return spanCount == 2;
-    }
-    int index = 1;
-    const SkOpSpan* firstSpan = &fTs[index];
-    int activePrior = checkSetAngle(0);
-    const SkOpSpan* span = &fTs[0];
-    if (firstSpan->fT == 0 || span->fTiny || span->fOtherT != 1 || span->fOther->multipleEnds()) {
-        index = findStartSpan(0);  // curve start intersects
-        if (fTs[index].fT == 0) {
-            return false;
-        }
-        SkASSERT(index > 0);
-        if (activePrior >= 0) {
-            addStartSpan(index);
-        }
-    }
-    bool addEnd;
-    int endIndex = spanCount - 1;
-    span = &fTs[endIndex - 1];
-    if ((addEnd = span->fT == 1 || span->fTiny)) {  // if curve end intersects
-        endIndex = findEndSpan(endIndex);
-        SkASSERT(endIndex > 0);
-    } else {
-        addEnd = fTs[endIndex].fOtherT != 0 || fTs[endIndex].fOther->multipleStarts();
-    }
-    SkASSERT(endIndex >= index);
-    int prior = 0;
-    while (index < endIndex) {
-        const SkOpSpan& fromSpan = fTs[index];  // for each intermediate intersection
-        const SkOpSpan* lastSpan;
-        span = &fromSpan;
-        int start = index;
-        do {
-            lastSpan = span;
-            span = &fTs[++index];
-            SkASSERT(index < spanCount);
-            if (!precisely_negative(span->fT - lastSpan->fT) && !lastSpan->fTiny) {
-                break;
-            }
-            if (!SkDPoint::ApproximatelyEqual(lastSpan->fPt, span->fPt)) {
-                return false;
-            }
-        } while (true);
-        SkOpAngle* angle = NULL;
-        SkOpAngle* priorAngle;
-        if (activePrior >= 0) {
-            int pActive = firstActive(prior);
-            SkASSERT(pActive < start);
-            priorAngle = &fAngles.push_back();
-            priorAngle->set(this, start, pActive);
-        }
-        int active = checkSetAngle(start);
-        if (active >= 0) {
-            SkASSERT(active < index);
-            angle = &fAngles.push_back();
-            angle->set(this, active, index);
-        }
-    #if DEBUG_ANGLE
-        debugCheckPointsEqualish(start, index);
-    #endif
-        prior = start;
-        do {
-            const SkOpSpan* startSpan = &fTs[start - 1];
-            if (!startSpan->fSmall || isCanceled(start - 1) || startSpan->fFromAngle
-                    || startSpan->fToAngle) {
-                break;
-            }
-            --start;
-        } while (start > 0);
-        do {
-            if (activePrior >= 0) {
-                SkASSERT(fTs[start].fFromAngle == NULL);
-                fTs[start].fFromAngle = priorAngle;
-            }
-            if (active >= 0) {
-                SkASSERT(fTs[start].fToAngle == NULL);
-                fTs[start].fToAngle = angle;
-            }
-        } while (++start < index);
         activePrior = active;
+        prior = span;
+        spanBase = next;
     }
-    if (addEnd && activePrior >= 0) {
-        addEndSpan(endIndex);
+    if (activePrior && !fTail.simple()) {
+        addEndSpan(allocator);
     }
-    return true;
 }
 
-int SkOpSegment::checkSetAngle(int tIndex) const {
-    const SkOpSpan* span = &fTs[tIndex];
-    while (span->fTiny /* || span->fSmall */) {
-        span = &fTs[++tIndex];
-    }
-    return isCanceled(tIndex) ? -1 : tIndex;
-}
-
-// at this point, the span is already ordered, or unorderable
-int SkOpSegment::computeSum(int startIndex, int endIndex, SkOpAngle::IncludeType includeType) {
-    SkASSERT(includeType != SkOpAngle::kUnaryXor);
-    SkOpAngle* firstAngle = spanToAngle(endIndex, startIndex);
-    if (NULL == firstAngle || NULL == firstAngle->next()) {
-        return SK_NaN32;
-    }
-    // if all angles have a computed winding,
-    //  or if no adjacent angles are orderable,
-    //  or if adjacent orderable angles have no computed winding,
-    //  there's nothing to do
-    // if two orderable angles are adjacent, and both are next to orderable angles,
-    //  and one has winding computed, transfer to the other
-    SkOpAngle* baseAngle = NULL;
-    bool tryReverse = false;
-    // look for counterclockwise transfers
-    SkOpAngle* angle = firstAngle->previous();
-    SkOpAngle* next = angle->next();
-    firstAngle = next;
+void SkOpSegment::checkAngleCoin(SkOpCoincidence* coincidences, SkChunkAlloc* allocator) {
+    SkOpSpanBase* base = &fHead;
+    SkOpSpan* span;
     do {
-        SkOpAngle* prior = angle;
-        angle = next;
-        next = angle->next();
-        SkASSERT(prior->next() == angle);
-        SkASSERT(angle->next() == next);
-        if (prior->unorderable() || angle->unorderable() || next->unorderable()) {
-            baseAngle = NULL;
-            continue;
+        SkOpAngle* angle = base->fromAngle();
+        if (angle && angle->fCheckCoincidence) {
+            angle->checkNearCoincidence();
         }
-        int testWinding = angle->segment()->windSum(angle);
-        if (SK_MinS32 != testWinding) {
-            baseAngle = angle;
-            tryReverse = true;
-            continue;
+        if (base->final()) {
+             break;
         }
-        if (baseAngle) {
-            ComputeOneSum(baseAngle, angle, includeType);
-            baseAngle = SK_MinS32 != angle->segment()->windSum(angle) ? angle : NULL;
+        span = base->upCast();
+        angle = span->toAngle();
+        if (angle && angle->fCheckCoincidence) {
+            angle->checkNearCoincidence();
         }
-    } while (next != firstAngle);
-    if (baseAngle && SK_MinS32 == firstAngle->segment()->windSum(firstAngle)) {
-        firstAngle = baseAngle;
-        tryReverse = true;
+    } while ((base = span->next()));
+}
+
+// from http://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order
+bool SkOpSegment::clockwise(const SkOpSpanBase* start, const SkOpSpanBase* end, bool* swap) const {
+    SkASSERT(fVerb != SkPath::kLine_Verb);
+    SkPoint edge[4];
+    if (fVerb == SkPath::kCubic_Verb) {
+        double startT = start->t();
+        double endT = end->t();
+        bool flip = startT > endT;
+        SkDCubic cubic;
+        cubic.set(fPts);
+        double inflectionTs[2];
+        int inflections = cubic.findInflections(inflectionTs);
+        for (int index = 0; index < inflections; ++index) {
+            double inflectionT = inflectionTs[index];
+            if (between(startT, inflectionT, endT)) {
+                if (flip) {
+                    if (inflectionT != endT) {
+                        startT = inflectionT;
+                    }
+                } else {
+                    if (inflectionT != startT) {
+                        endT = inflectionT;
+                    }
+                }
+            }
+        }
+        SkDCubic part = cubic.subDivide(startT, endT);
+        for (int index = 0; index < 4; ++index) {
+            edge[index] = part[index].asSkPoint();
+        }
+    } else {
+    subDivide(start, end, edge);
     }
-    if (tryReverse) {
-        baseAngle = NULL;
-        SkOpAngle* prior = firstAngle;
-        do {
-            angle = prior;
-            prior = angle->previous();
-            SkASSERT(prior->next() == angle);
-            next = angle->next();
-            if (prior->unorderable() || angle->unorderable() || next->unorderable()) {
-                baseAngle = NULL;
-                continue;
-            }
-            int testWinding = angle->segment()->windSum(angle);
-            if (SK_MinS32 != testWinding) {
-                baseAngle = angle;
-                continue;
-            }
-            if (baseAngle) {
-                ComputeOneSumReverse(baseAngle, angle, includeType);
-                baseAngle = SK_MinS32 != angle->segment()->windSum(angle) ? angle : NULL;
-            }
-        } while (prior != firstAngle);
+    bool sumSet = false;
+    int points = SkPathOpsVerbToPoints(fVerb);
+    double sum = (edge[0].fX - edge[points].fX) * (edge[0].fY + edge[points].fY);
+    if (!sumSet) {
+        for (int idx = 0; idx < points; ++idx){
+            sum += (edge[idx + 1].fX - edge[idx].fX) * (edge[idx + 1].fY + edge[idx].fY);
+        }
     }
-    int minIndex = SkMin32(startIndex, endIndex);
-    return windSum(minIndex);
+    if (fVerb == SkPath::kCubic_Verb) {
+        SkDCubic cubic;
+        cubic.set(edge);
+        *swap = sum > 0 && !cubic.monotonicInY();
+    } else {
+        SkDQuad quad;
+        quad.set(edge);
+        *swap = sum > 0 && !quad.monotonicInY();
+    }
+    return sum <= 0;
 }
 
 void SkOpSegment::ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
@@ -1954,7 +540,7 @@
     }
     SkOpSegment* nextSegment = nextAngle->segment();
     int maxWinding, sumWinding;
-    SkOpSpan* last;
+    SkOpSpanBase* last;
     if (binary) {
         int oppMaxWinding, oppSumWinding;
         nextSegment->setUpWindings(nextAngle->start(), nextAngle->end(), &sumMiWinding,
@@ -1983,7 +569,7 @@
     }
     SkOpSegment* nextSegment = nextAngle->segment();
     int maxWinding, sumWinding;
-    SkOpSpan* last;
+    SkOpSpanBase* last;
     if (binary) {
         int oppMaxWinding, oppSumWinding;
         nextSegment->setUpWindings(nextAngle->end(), nextAngle->start(), &sumMiWinding,
@@ -1998,64 +584,98 @@
     nextAngle->setLastMarked(last);
 }
 
-bool SkOpSegment::containsPt(const SkPoint& pt, int index, int endIndex) const {
-    int step = index < endIndex ? 1 : -1;
+// at this point, the span is already ordered, or unorderable
+int SkOpSegment::computeSum(SkOpSpanBase* start, SkOpSpanBase* end,
+        SkOpAngle::IncludeType includeType) {
+    SkASSERT(includeType != SkOpAngle::kUnaryXor);
+    SkOpAngle* firstAngle = this->spanToAngle(end, start);
+    if (NULL == firstAngle || NULL == firstAngle->next()) {
+        return SK_NaN32;
+    }
+    // if all angles have a computed winding,
+    //  or if no adjacent angles are orderable,
+    //  or if adjacent orderable angles have no computed winding,
+    //  there's nothing to do
+    // if two orderable angles are adjacent, and both are next to orderable angles,
+    //  and one has winding computed, transfer to the other
+    SkOpAngle* baseAngle = NULL;
+    bool tryReverse = false;
+    // look for counterclockwise transfers
+    SkOpAngle* angle = firstAngle->previous();
+    SkOpAngle* next = angle->next();
+    firstAngle = next;
     do {
-        const SkOpSpan& span = this->span(index);
-        if (span.fPt == pt) {
-            const SkOpSpan& endSpan = this->span(endIndex);
-            return span.fT == endSpan.fT && pt != endSpan.fPt;
+        SkOpAngle* prior = angle;
+        angle = next;
+        next = angle->next();
+        SkASSERT(prior->next() == angle);
+        SkASSERT(angle->next() == next);
+        if (prior->unorderable() || angle->unorderable() || next->unorderable()) {
+            baseAngle = NULL;
+            continue;
         }
-        index += step;
-    } while (index != endIndex);
-    return false;
-}
-
-bool SkOpSegment::containsT(double t, const SkOpSegment* other, double otherT) const {
-    int count = this->count();
-    for (int index = 0; index < count; ++index) {
-        const SkOpSpan& span = fTs[index];
-        if (t < span.fT) {
-            return false;
+        int testWinding = angle->starter()->windSum();
+        if (SK_MinS32 != testWinding) {
+            baseAngle = angle;
+            tryReverse = true;
+            continue;
         }
-        if (t == span.fT) {
-            if (other != span.fOther) {
+        if (baseAngle) {
+            ComputeOneSum(baseAngle, angle, includeType);
+            baseAngle = SK_MinS32 != angle->starter()->windSum() ? angle : NULL;
+        }
+    } while (next != firstAngle);
+    if (baseAngle && SK_MinS32 == firstAngle->starter()->windSum()) {
+        firstAngle = baseAngle;
+        tryReverse = true;
+    }
+    if (tryReverse) {
+        baseAngle = NULL;
+        SkOpAngle* prior = firstAngle;
+        do {
+            angle = prior;
+            prior = angle->previous();
+            SkASSERT(prior->next() == angle);
+            next = angle->next();
+            if (prior->unorderable() || angle->unorderable() || next->unorderable()) {
+                baseAngle = NULL;
                 continue;
             }
-            if (other->fVerb != SkPath::kCubic_Verb) {
-                return true;
+            int testWinding = angle->starter()->windSum();
+            if (SK_MinS32 != testWinding) {
+                baseAngle = angle;
+                continue;
             }
-            if (!other->fLoop) {
-                return true;
+            if (baseAngle) {
+                ComputeOneSumReverse(baseAngle, angle, includeType);
+                baseAngle = SK_MinS32 != angle->starter()->windSum() ? angle : NULL;
             }
-            double otherMidT = (otherT + span.fOtherT) / 2;
-            SkPoint otherPt = other->ptAtT(otherMidT);
-            return SkDPoint::ApproximatelyEqual(span.fPt, otherPt);
-        }
+        } while (prior != firstAngle);
     }
-    return false;
+    return start->starter(end)->windSum();
 }
 
-int SkOpSegment::crossedSpanY(const SkPoint& basePt, SkScalar* bestY, double* hitT,
-                              bool* hitSomething, double mid, bool opp, bool current) const {
+SkOpSpan* SkOpSegment::crossedSpanY(const SkPoint& basePt, double mid, bool opp, bool current,
+        SkScalar* bestY, double* hitT, bool* hitSomething, bool* vertical) {
     SkScalar bottom = fBounds.fBottom;
-    int bestTIndex = -1;
+    *vertical = false;
     if (bottom <= *bestY) {
-        return bestTIndex;
+        return NULL;
     }
     SkScalar top = fBounds.fTop;
     if (top >= basePt.fY) {
-        return bestTIndex;
+        return NULL;
     }
     if (fBounds.fLeft > basePt.fX) {
-        return bestTIndex;
+        return NULL;
     }
     if (fBounds.fRight < basePt.fX) {
-        return bestTIndex;
+        return NULL;
     }
     if (fBounds.fLeft == fBounds.fRight) {
         // if vertical, and directly above test point, wait for another one
-        return AlmostEqualUlps(basePt.fX, fBounds.fLeft) ? SK_MinS32 : bestTIndex;
+        *vertical = AlmostEqualUlps(basePt.fX, fBounds.fLeft);
+        return NULL;
     }
     // intersect ray starting at basePt with edge
     SkIntersections intersections;
@@ -2065,7 +685,7 @@
     int pts = (intersections.*CurveVertical[SkPathOpsVerbToPoints(fVerb)])
             (fPts, top, bottom, basePt.fX, false);
     if (pts == 0 || (current && pts == 1)) {
-        return bestTIndex;
+        return NULL;
     }
     if (current) {
         SkASSERT(pts > 1);
@@ -2093,933 +713,73 @@
             continue;
         }
         if (pts > 1 && fVerb == SkPath::kLine_Verb) {
-            return SK_MinS32;  // if the intersection is edge on, wait for another one
+            *vertical = true;
+            return NULL;  // if the intersection is edge on, wait for another one
         }
         if (fVerb > SkPath::kLine_Verb) {
             SkScalar dx = (*CurveSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, foundT).fX;
             if (approximately_zero(dx)) {
-                return SK_MinS32;  // hit vertical, wait for another one
+                *vertical = true;
+                return NULL;  // hit vertical, wait for another one
             }
         }
         *bestY = testY;
         bestT = foundT;
     }
     if (bestT < 0) {
-        return bestTIndex;
+        return NULL;
     }
     SkASSERT(bestT >= 0);
-    SkASSERT(bestT <= 1);
-    int start;
-    int end = 0;
+    SkASSERT(bestT < 1);
+    SkOpSpanBase* testTSpanBase = &this->fHead;
+    SkOpSpanBase* nextTSpan;
+    double endT = 0;
     do {
-        start = end;
-        end = nextSpan(start, 1);
-    } while (fTs[end].fT < bestT);
-    // FIXME: see next candidate for a better pattern to find the next start/end pair
-    while (start + 1 < end && fTs[start].fDone) {
-        ++start;
-    }
-    if (!isCanceled(start)) {
+        nextTSpan = testTSpanBase->upCast()->next();
+        endT = nextTSpan->t();
+        if (endT >= bestT) {
+            break;
+        }
+        testTSpanBase = nextTSpan;
+    } while (testTSpanBase);
+    SkOpSpan* bestTSpan = NULL;
+    SkOpSpan* testTSpan = testTSpanBase->upCast();
+    if (!testTSpan->isCanceled()) {
         *hitT = bestT;
-        bestTIndex = start;
+        bestTSpan = testTSpan;
         *hitSomething = true;
     }
-    return bestTIndex;
+    return bestTSpan;
 }
 
-bool SkOpSegment::decrementSpan(SkOpSpan* span) {
-    SkASSERT(span->fWindValue > 0);
-    if (--(span->fWindValue) == 0) {
-        if (!span->fOppValue && !span->fDone) {
-            span->fDone = true;
-            ++fDoneSpans;
-            return true;
-        }
+void SkOpSegment::detach(const SkOpSpan* span) {
+    if (span->done()) {
+        --this->fDoneCount;
     }
-    return false;
+    --this->fCount;
 }
 
-bool SkOpSegment::bumpSpan(SkOpSpan* span, int windDelta, int oppDelta) {
-    SkASSERT(!span->fDone || span->fTiny || span->fSmall);
-    span->fWindValue += windDelta;
-    SkASSERT(span->fWindValue >= 0);
-    span->fOppValue += oppDelta;
-    SkASSERT(span->fOppValue >= 0);
-    if (fXor) {
-        span->fWindValue &= 1;
-    }
-    if (fOppXor) {
-        span->fOppValue &= 1;
-    }
-    if (!span->fWindValue && !span->fOppValue) {
-        if (!span->fDone) {
-            span->fDone = true;
-            ++fDoneSpans;
-        }
-        return true;
-    }
-    return false;
-}
-
-const SkOpSpan& SkOpSegment::firstSpan(const SkOpSpan& thisSpan) const {
-    const SkOpSpan* firstSpan = &thisSpan; // rewind to the start
-    const SkOpSpan* beginSpan = fTs.begin();
-    const SkPoint& testPt = thisSpan.fPt;
-    while (firstSpan > beginSpan && firstSpan[-1].fPt == testPt) {
-        --firstSpan;
-    }
-    return *firstSpan;
-}
-
-const SkOpSpan& SkOpSegment::lastSpan(const SkOpSpan& thisSpan) const {
-    const SkOpSpan* endSpan = fTs.end() - 1;  // last can't be small
-    const SkOpSpan* lastSpan = &thisSpan;  // find the end
-    const SkPoint& testPt = thisSpan.fPt;
-    while (lastSpan < endSpan && lastSpan[1].fPt == testPt) {
-        ++lastSpan;
-    }
-    return *lastSpan;
-}
-
-// with a loop, the comparison is move involved
-// scan backwards and forwards to count all matching points
-// (verify that there are twp scans marked as loops)
-// compare that against 2 matching scans for loop plus other results
-bool SkOpSegment::calcLoopSpanCount(const SkOpSpan& thisSpan, int* smallCounts) {
-    const SkOpSpan& firstSpan = this->firstSpan(thisSpan); // rewind to the start
-    const SkOpSpan& lastSpan = this->lastSpan(thisSpan);  // find the end
-    double firstLoopT = -1, lastLoopT = -1;
-    const SkOpSpan* testSpan = &firstSpan - 1;
-    while (++testSpan <= &lastSpan) {
-        if (testSpan->fLoop) {
-            firstLoopT = testSpan->fT;
-            break;
-        }
-    }
-    testSpan = &lastSpan + 1;
-    while (--testSpan >= &firstSpan) {
-        if (testSpan->fLoop) {
-            lastLoopT = testSpan->fT;
-            break;
-        }
-    }
-    SkASSERT((firstLoopT == -1) == (lastLoopT == -1));
-    if (firstLoopT == -1) {
-        return false;
-    }
-    SkASSERT(firstLoopT < lastLoopT);
-    testSpan = &firstSpan - 1;
-    smallCounts[0] = smallCounts[1] = 0;
-    while (++testSpan <= &lastSpan) {
-        SkASSERT(approximately_equal(testSpan->fT, firstLoopT) +
-                approximately_equal(testSpan->fT, lastLoopT) == 1);
-        smallCounts[approximately_equal(testSpan->fT, lastLoopT)]++;
-    }
-    return true;
-}
-
-double SkOpSegment::calcMissingTEnd(const SkOpSegment* ref, double loEnd, double min, double max,
-        double hiEnd, const SkOpSegment* other, int thisStart) {
-    if (max >= hiEnd) {
-        return -1;
-    }
-    int end = findOtherT(hiEnd, ref);
-    if (end < 0) {
-        return -1;
-    }
-    double tHi = span(end).fT;
-    double tLo, refLo;
-    if (thisStart >= 0) {
-        tLo = span(thisStart).fT;
-        refLo = min;
-    } else {
-        int start1 = findOtherT(loEnd, ref);
-        SkASSERT(start1 >= 0);
-        tLo = span(start1).fT;
-        refLo = loEnd;
-    }
-    double missingT = (max - refLo) / (hiEnd - refLo);
-    missingT = tLo + missingT * (tHi - tLo);
-    return missingT;
-}
-
-double SkOpSegment::calcMissingTStart(const SkOpSegment* ref, double loEnd, double min, double max,
-        double hiEnd, const SkOpSegment* other, int thisEnd) {
-    if (min <= loEnd) {
-        return -1;
-    }
-    int start = findOtherT(loEnd, ref);
-    if (start < 0) {
-        return -1;
-    }
-    double tLo = span(start).fT;
-    double tHi, refHi;
-    if (thisEnd >= 0) {
-        tHi = span(thisEnd).fT;
-        refHi = max;
-    } else {
-        int end1 = findOtherT(hiEnd, ref);
-        if (end1 < 0) {
-            return -1;
-        }
-        tHi = span(end1).fT;
-        refHi = hiEnd;
-    }
-    double missingT = (min - loEnd) / (refHi - loEnd);
-    missingT = tLo + missingT * (tHi - tLo);
-    return missingT;
-}
-
-// see if spans with two or more intersections have the same number on the other end
-void SkOpSegment::checkDuplicates() {
-    debugValidate();
-    SkSTArray<kMissingSpanCount, MissingSpan, true> missingSpans;
-    int index;
-    int endIndex = 0;
-    bool endFound;
-    do {
-        index = endIndex;
-        endIndex = nextExactSpan(index, 1);
-        if ((endFound = endIndex < 0)) {
-            endIndex = count();
-        }
-        int dupCount = endIndex - index;
-        if (dupCount < 2) {
+double SkOpSegment::distSq(double t, SkOpAngle* oppAngle) {
+    SkDPoint testPt = this->dPtAtT(t);
+    SkDLine testPerp = {{ testPt, testPt }};
+    SkDVector slope = this->dSlopeAtT(t);
+    testPerp[1].fX += slope.fY;
+    testPerp[1].fY -= slope.fX;
+    SkIntersections i;
+    SkOpSegment* oppSegment = oppAngle->segment();
+    int oppPtCount = SkPathOpsVerbToPoints(oppSegment->verb());
+    (*CurveIntersectRay[oppPtCount])(oppSegment->pts(), testPerp, &i);
+    double closestDistSq = SK_ScalarInfinity;
+    for (int index = 0; index < i.used(); ++index) {
+        if (!between(oppAngle->start()->t(), i[0][index], oppAngle->end()->t())) {
             continue;
         }
-        do {
-            const SkOpSpan* thisSpan = &fTs[index];
-            if (thisSpan->fNear) {
-                continue;
-            }
-            SkOpSegment* other = thisSpan->fOther;
-            int oIndex = thisSpan->fOtherIndex;
-            int oStart = other->nextExactSpan(oIndex, -1) + 1;
-            int oEnd = other->nextExactSpan(oIndex, 1);
-            if (oEnd < 0) {
-                oEnd = other->count();
-            }
-            int oCount = oEnd - oStart;
-            // force the other to match its t and this pt if not on an end point
-            if (oCount != dupCount) {
-                MissingSpan& missing = missingSpans.push_back();
-                missing.fOther = NULL;
-                SkDEBUGCODE(sk_bzero(&missing, sizeof(missing)));
-                missing.fPt = thisSpan->fPt;
-                const SkOpSpan& oSpan = other->span(oIndex);
-                if (oCount > dupCount) {
-                    missing.fSegment = this;
-                    missing.fT = thisSpan->fT;
-                    other->checkLinks(&oSpan, &missingSpans);
-                } else {
-                    missing.fSegment = other;
-                    missing.fT = oSpan.fT;
-                    checkLinks(thisSpan, &missingSpans);
-                }
-                if (!missingSpans.back().fOther) {
-                    missingSpans.pop_back();
-                }
-            }
-        } while (++index < endIndex);
-    } while (!endFound);
-    int missingCount = missingSpans.count();
-    if (missingCount == 0) {
-        return;
-    }
-    SkSTArray<kMissingSpanCount, MissingSpan, true> missingCoincidence;
-    for (index = 0; index < missingCount; ++index)  {
-        MissingSpan& missing = missingSpans[index];
-        SkOpSegment* missingOther = missing.fOther;
-        if (missing.fSegment == missing.fOther) {
-            continue;
-        }
-#if 0  // FIXME: this eliminates spurious data from skpwww_argus_presse_fr_41 but breaks
-       // skpwww_fashionscandal_com_94 -- calcAngles complains, but I don't understand why
-        if (missing.fSegment->containsT(missing.fT, missing.fOther, missing.fOtherT)) {
-#if DEBUG_DUPLICATES
-            SkDebugf("skip 1 id=%d t=%1.9g other=%d otherT=%1.9g\n", missing.fSegment->fID,
-                    missing.fT, missing.fOther->fID, missing.fOtherT);
-#endif
-            continue;
-        }
-        if (missing.fOther->containsT(missing.fOtherT, missing.fSegment, missing.fT)) {
-#if DEBUG_DUPLICATES
-            SkDebugf("skip 2 id=%d t=%1.9g other=%d otherT=%1.9g\n", missing.fOther->fID,
-                    missing.fOtherT, missing.fSegment->fID, missing.fT);
-#endif
-            continue;
-        }
-#endif
-        // skip if adding would insert point into an existing coincindent span
-        if (missing.fSegment->inCoincidentSpan(missing.fT, missingOther)
-                && missingOther->inCoincidentSpan(missing.fOtherT, this)) {
-            continue;
-        }
-        // skip if the created coincident spans are small
-        if (missing.fSegment->coincidentSmall(missing.fPt, missing.fT, missingOther)
-                && missingOther->coincidentSmall(missing.fPt, missing.fOtherT, missing.fSegment)) {
-            continue;
-        }
-        const SkOpSpan* added = missing.fSegment->addTPair(missing.fT, missingOther,
-                missing.fOtherT, false, missing.fPt);
-        if (added && added->fSmall) {
-            missing.fSegment->checkSmallCoincidence(*added, &missingCoincidence);
+        double testDistSq = testPt.distanceSquared(i.pt(index));
+        if (closestDistSq > testDistSq) {
+            closestDistSq = testDistSq;
         }
     }
-    for (index = 0; index < missingCount; ++index)  {
-        MissingSpan& missing = missingSpans[index];
-        missing.fSegment->fixOtherTIndex();
-        missing.fOther->fixOtherTIndex();
-    }
-    for (index = 0; index < missingCoincidence.count(); ++index) {
-        MissingSpan& missing = missingCoincidence[index];
-        missing.fSegment->fixOtherTIndex();
-    }
-    debugValidate();
-}
-
-// look to see if the curve end intersects an intermediary that intersects the other
-bool SkOpSegment::checkEnds() {
-    debugValidate();
-    SkSTArray<kMissingSpanCount, MissingSpan, true> missingSpans;
-    int count = fTs.count();
-    for (int index = 0; index < count; ++index) {
-        const SkOpSpan& span = fTs[index];
-        double otherT = span.fOtherT;
-        if (otherT != 0 && otherT != 1) { // only check ends
-            continue;
-        }
-        const SkOpSegment* other = span.fOther;
-        // peek start/last describe the range of spans that match the other t of this span
-        int peekStart = span.fOtherIndex;
-        while (--peekStart >= 0 && other->fTs[peekStart].fT == otherT)
-            ;
-        int otherCount = other->fTs.count();
-        int peekLast = span.fOtherIndex;
-        while (++peekLast < otherCount && other->fTs[peekLast].fT == otherT)
-            ;
-        if (++peekStart == --peekLast) { // if there isn't a range, there's nothing to do
-            continue;
-        }
-        // t start/last describe the range of spans that match the t of this span
-        double t = span.fT;
-        double tBottom = -1;
-        int tStart = -1;
-        int tLast = count;
-        bool lastSmall = false;
-        double afterT = t;
-        for (int inner = 0; inner < count; ++inner) {
-            double innerT = fTs[inner].fT;
-            if (innerT <= t && innerT > tBottom) {
-                if (innerT < t || !lastSmall) {
-                    tStart = inner - 1;
-                }
-                tBottom = innerT;
-            }
-            if (innerT > afterT) {
-                if (t == afterT && lastSmall) {
-                    afterT = innerT;
-                } else {
-                    tLast = inner;
-                    break;
-                }
-            }
-            lastSmall = innerT <= t ? fTs[inner].fSmall : false;
-        }
-        for (int peekIndex = peekStart; peekIndex <= peekLast; ++peekIndex) {
-            if (peekIndex == span.fOtherIndex) {  // skip the other span pointed to by this span
-                continue;
-            }
-            const SkOpSpan& peekSpan = other->fTs[peekIndex];
-            SkOpSegment* match = peekSpan.fOther;
-            if (match->done()) {
-                continue;  // if the edge has already been eaten (likely coincidence), ignore it
-            }
-            const double matchT = peekSpan.fOtherT;
-            // see if any of the spans match the other spans
-            for (int tIndex = tStart + 1; tIndex < tLast; ++tIndex) {
-                const SkOpSpan& tSpan = fTs[tIndex];
-                if (tSpan.fOther == match) {
-                    if (tSpan.fOtherT == matchT) {
-                        goto nextPeekIndex;
-                    }
-                    double midT = (tSpan.fOtherT + matchT) / 2;
-                    if (match->betweenPoints(midT, tSpan.fPt, peekSpan.fPt)) {
-                        goto nextPeekIndex;
-                    }
-                }
-            }
-            if (missingSpans.count() > 0) {
-                const MissingSpan& lastMissing = missingSpans.back();
-                if (lastMissing.fT == t
-                        && lastMissing.fOther == match
-                        && lastMissing.fOtherT == matchT) {
-                    SkASSERT(SkDPoint::ApproximatelyEqual(lastMissing.fPt, peekSpan.fPt));
-                    continue;
-                }
-            }
-            if (this == match) {
-                return false; // extremely large paths can trigger this
-            }
-#if DEBUG_CHECK_ALIGN
-            SkDebugf("%s id=%d missing t=%1.9g other=%d otherT=%1.9g pt=(%1.9g,%1.9g)\n",
-                    __FUNCTION__, fID, t, match->fID, matchT, peekSpan.fPt.fX, peekSpan.fPt.fY);
-#endif
-            // this segment is missing a entry that the other contains
-            // remember so we can add the missing one and recompute the indices
-            {
-                MissingSpan& missing = missingSpans.push_back();
-                SkDEBUGCODE(sk_bzero(&missing, sizeof(missing)));
-                missing.fT = t;
-                SkASSERT(this != match);
-                missing.fOther = match;
-                missing.fOtherT = matchT;
-                missing.fPt = peekSpan.fPt;
-            }
-            break;
-nextPeekIndex:
-            ;
-        }
-    }
-    if (missingSpans.count() == 0) {
-        debugValidate();
-        return true;
-    }
-    debugValidate();
-    int missingCount = missingSpans.count();
-    for (int index = 0; index < missingCount; ++index)  {
-        MissingSpan& missing = missingSpans[index];
-        if (this != missing.fOther) {
-            addTPair(missing.fT, missing.fOther, missing.fOtherT, false, missing.fPt);
-        }
-    }
-    fixOtherTIndex();
-    // OPTIMIZATION: this may fix indices more than once. Build an array of unique segments to
-    // avoid this
-    for (int index = 0; index < missingCount; ++index)  {
-        missingSpans[index].fOther->fixOtherTIndex();
-    }
-    debugValidate();
-    return true;
-}
-
-void SkOpSegment::checkLinks(const SkOpSpan* base,
-        SkTArray<MissingSpan, true>* missingSpans) const {
-    const SkOpSpan* first = fTs.begin();
-    const SkOpSpan* last = fTs.end() - 1;
-    SkASSERT(base >= first && last >= base);
-    const SkOpSegment* other = base->fOther;
-    const SkOpSpan* oFirst = other->fTs.begin();
-    const SkOpSpan* oLast = other->fTs.end() - 1;
-    const SkOpSpan* oSpan = &other->fTs[base->fOtherIndex];
-    const SkOpSpan* test = base;
-    const SkOpSpan* missing = NULL;
-    while (test > first && (--test)->fPt == base->fPt) {
-        if (this == test->fOther) {
-            continue;
-        }
-        CheckOneLink(test, oSpan, oFirst, oLast, &missing, missingSpans);
-    }
-    test = base;
-    while (test < last && (++test)->fPt == base->fPt) {
-        SkASSERT(this != test->fOther || test->fLoop);
-        CheckOneLink(test, oSpan, oFirst, oLast, &missing, missingSpans);
-    }
-}
-
-// see if spans with two or more intersections all agree on common t and point values
-void SkOpSegment::checkMultiples() {
-    debugValidate();
-    int index;
-    int end = 0;
-    while (fTs[++end].fT == 0)
-        ;
-    while (fTs[end].fT < 1) {
-        int start = index = end;
-        end = nextExactSpan(index, 1);
-        if (end <= index) {
-            return;  // buffer overflow example triggers this
-        }
-        if (index + 1 == end) {
-            continue;
-        }
-        // force the duplicates to agree on t and pt if not on the end
-        SkOpSpan& span = fTs[index];
-        double thisT = span.fT;
-        const SkPoint& thisPt = span.fPt;
-        span.fMultiple = true;
-        bool aligned = false;
-        while (++index < end) {
-            aligned |= alignSpan(index, thisT, thisPt);
-        }
-        if (aligned) {
-            alignSpanState(start, end);
-        }
-        fMultiples = true;
-    }
-    debugValidate();
-}
-
-void SkOpSegment::CheckOneLink(const SkOpSpan* test, const SkOpSpan* oSpan,
-        const SkOpSpan* oFirst, const SkOpSpan* oLast, const SkOpSpan** missingPtr,
-        SkTArray<MissingSpan, true>* missingSpans) {
-    SkASSERT(oSpan->fPt == test->fPt);
-    const SkOpSpan* oTest = oSpan;
-    while (oTest > oFirst && (--oTest)->fPt == test->fPt) {
-        if (oTest->fOther == test->fOther && oTest->fOtherT == test->fOtherT) {
-            return;
-        }
-    }
-    oTest = oSpan;
-    while (oTest < oLast && (++oTest)->fPt == test->fPt) {
-        if (oTest->fOther == test->fOther && oTest->fOtherT == test->fOtherT) {
-            return;
-        }
-    }
-    if (*missingPtr) {
-        missingSpans->push_back();
-    }
-    MissingSpan& lastMissing = missingSpans->back();
-    if (*missingPtr) {
-        lastMissing = missingSpans->end()[-2];
-    }
-    *missingPtr = test;
-    lastMissing.fOther = test->fOther;
-    lastMissing.fOtherT = test->fOtherT;
-}
-
-bool SkOpSegment::checkSmall(int index) const {
-    if (fTs[index].fSmall) {
-        return true;
-    }
-    double tBase = fTs[index].fT;
-    while (index > 0 && precisely_negative(tBase - fTs[--index].fT))
-        ;
-    return fTs[index].fSmall;
-}
-
-// a pair of curves may turn into coincident lines -- small may be a hint that that happened
-// if a cubic contains a loop, the counts must be adjusted
-void SkOpSegment::checkSmall() {
-    SkSTArray<kMissingSpanCount, MissingSpan, true> missingSpans;
-    const SkOpSpan* beginSpan = fTs.begin();
-    const SkOpSpan* thisSpan = beginSpan - 1;
-    const SkOpSpan* endSpan = fTs.end() - 1;  // last can't be small
-    while (++thisSpan < endSpan) {
-        if (!thisSpan->fSmall) {
-            continue;
-        }
-        if (!thisSpan->fWindValue) {
-            continue;
-        }
-        const SkOpSpan& firstSpan = this->firstSpan(*thisSpan);
-        const SkOpSpan& lastSpan = this->lastSpan(*thisSpan);
-        const SkOpSpan* nextSpan = &firstSpan + 1;
-        ptrdiff_t smallCount = &lastSpan - &firstSpan + 1;
-        SkASSERT(1 <= smallCount && smallCount < count());
-        if (smallCount <= 1 && !nextSpan->fSmall) {
-            SkASSERT(1 == smallCount);
-            checkSmallCoincidence(firstSpan, NULL);
-            continue;
-        }
-        // at this point, check for missing computed intersections
-        const SkPoint& testPt = firstSpan.fPt;
-        thisSpan = &firstSpan - 1;
-        SkOpSegment* other = NULL;
-        while (++thisSpan <= &lastSpan) {
-            other = thisSpan->fOther;
-            if (other != this) {
-                break;
-            }
-        }
-        SkASSERT(other != this);
-        int oIndex = thisSpan->fOtherIndex;
-        const SkOpSpan& oSpan = other->span(oIndex);
-        const SkOpSpan& oFirstSpan = other->firstSpan(oSpan);
-        const SkOpSpan& oLastSpan = other->lastSpan(oSpan);
-        ptrdiff_t oCount = &oLastSpan - &oFirstSpan + 1;
-        if (fLoop) {
-            int smallCounts[2];
-            SkASSERT(!other->fLoop);  // FIXME: we need more complicated logic for pair of loops
-            if (calcLoopSpanCount(*thisSpan, smallCounts)) {
-                if (smallCounts[0] && oCount != smallCounts[0]) {
-                    SkASSERT(0);  // FIXME: need a working test case to properly code & debug
-                }
-                if (smallCounts[1] && oCount != smallCounts[1]) {
-                    SkASSERT(0);  // FIXME: need a working test case to properly code & debug
-                }
-                goto nextSmallCheck;
-            }
-        }
-        if (other->fLoop) {
-            int otherCounts[2];
-            if (other->calcLoopSpanCount(other->span(oIndex), otherCounts)) {
-                if (otherCounts[0] && otherCounts[0] != smallCount) {
-                    SkASSERT(0);  // FIXME: need a working test case to properly code & debug
-                }
-                if (otherCounts[1] && otherCounts[1] != smallCount) {
-                    SkASSERT(0);  // FIXME: need a working test case to properly code & debug
-                }
-                goto nextSmallCheck;
-            }
-        }
-        if (oCount != smallCount) {  // check if number of pts in this match other
-            MissingSpan& missing = missingSpans.push_back();
-            missing.fOther = NULL;
-            SkDEBUGCODE(sk_bzero(&missing, sizeof(missing)));
-            missing.fPt = testPt;
-            const SkOpSpan& oSpan = other->span(oIndex);
-            if (oCount > smallCount) {
-                missing.fSegment = this;
-                missing.fT = thisSpan->fT;
-                other->checkLinks(&oSpan, &missingSpans);
-            } else {
-                missing.fSegment = other;
-                missing.fT = oSpan.fT;
-                checkLinks(thisSpan, &missingSpans);
-            }
-            if (!missingSpans.back().fOther || missing.fSegment->done()) {
-                missingSpans.pop_back();
-            }
-        }
-nextSmallCheck:
-        thisSpan = &lastSpan;
-    }
-    int missingCount = missingSpans.count();
-    for (int index = 0; index < missingCount; ++index)  {
-        MissingSpan& missing = missingSpans[index];
-        SkOpSegment* missingOther = missing.fOther;
-        // note that add t pair may edit span arrays, so prior pointers to spans are no longer valid
-        if (!missing.fSegment->addTPair(missing.fT, missingOther, missing.fOtherT, false,
-                missing.fPt)) {
-            continue;
-        }
-        int otherTIndex = missingOther->findT(missing.fOtherT, missing.fPt, missing.fSegment);
-        const SkOpSpan& otherSpan = missingOther->span(otherTIndex);
-        if (otherSpan.fSmall) {
-            const SkOpSpan* nextSpan = &otherSpan;
-            if (nextSpan->fPt == missing.fPt) {
-                continue;
-            }
-            do {
-                ++nextSpan;
-            } while (nextSpan->fSmall);
-            if (nextSpan->fT == 1) {
-                continue;
-            }
-            SkAssertResult(missing.fSegment->addTCoincident(missing.fPt, nextSpan->fPt,
-                    nextSpan->fT, missingOther));
-        } else if (otherSpan.fT > 0) {
-            const SkOpSpan* priorSpan = &otherSpan;
-            do {
-                --priorSpan;
-            } while (priorSpan->fT == otherSpan.fT);
-            if (priorSpan->fSmall) {
-                missing.fSegment->addTCancel(missing.fPt, priorSpan->fPt, missingOther);
-            }
-        }
-    }
-    // OPTIMIZATION: this may fix indices more than once. Build an array of unique segments to
-    // avoid this
-    for (int index = 0; index < missingCount; ++index)  {
-        MissingSpan& missing = missingSpans[index];
-        missing.fSegment->fixOtherTIndex();
-        missing.fOther->fixOtherTIndex();
-    }
-    debugValidate();
-}
-
-void SkOpSegment::checkSmallCoincidence(const SkOpSpan& span,
-        SkTArray<MissingSpan, true>* checkMultiple) {
-    SkASSERT(span.fSmall);
-    if (0 && !span.fWindValue) {
-        return;
-    }
-    SkASSERT(&span < fTs.end() - 1);
-    const SkOpSpan* next = &span + 1;
-    SkASSERT(!next->fSmall || checkMultiple);
-    if (checkMultiple) {
-        while (next->fSmall) {
-            ++next;
-            SkASSERT(next < fTs.end());
-        }
-    }
-    SkOpSegment* other = span.fOther;
-    while (other != next->fOther) {
-        if (!checkMultiple) {
-            return;
-        }
-        const SkOpSpan* test = next + 1;
-        if (test == fTs.end()) {
-            return;
-        }
-        if (test->fPt != next->fPt || !precisely_equal(test->fT, next->fT)) {
-            return;
-        }
-        next = test;
-    }
-    SkASSERT(span.fT < next->fT);
-    int oStartIndex = other->findExactT(span.fOtherT, this);
-    int oEndIndex = other->findExactT(next->fOtherT, this);
-    // FIXME: be overly conservative by limiting this to the caller that allows multiple smalls
-    if (!checkMultiple || fVerb != SkPath::kLine_Verb || other->fVerb != SkPath::kLine_Verb) {
-        SkPoint mid = ptAtT((span.fT + next->fT) / 2);
-        const SkOpSpan& oSpanStart = other->fTs[oStartIndex];
-        const SkOpSpan& oSpanEnd = other->fTs[oEndIndex];
-        SkPoint oMid = other->ptAtT((oSpanStart.fT + oSpanEnd.fT) / 2);
-        if (!SkDPoint::ApproximatelyEqual(mid, oMid)) {
-            return;
-        }
-    }
-    // FIXME: again, be overly conservative to avoid breaking existing tests
-    const SkOpSpan& oSpan = oStartIndex < oEndIndex ? other->fTs[oStartIndex]
-            : other->fTs[oEndIndex];
-    if (checkMultiple && !oSpan.fSmall) {
-        return;
-    }
-//    SkASSERT(oSpan.fSmall);
-    if (oStartIndex < oEndIndex) {
-        SkAssertResult(addTCoincident(span.fPt, next->fPt, next->fT, other));
-    } else {
-        addTCancel(span.fPt, next->fPt, other);
-    }
-    if (!checkMultiple) {
-        return;
-    }
-    // check to see if either segment is coincident with a third segment -- if it is, and if
-    // the opposite segment is not already coincident with the third, make it so
-    // OPTIMIZE: to make this check easier, add coincident and cancel could set a coincident bit
-    if (span.fWindValue != 1 || span.fOppValue != 0) {
-//        start here;
-        // iterate through the spans, looking for the third coincident case
-        // if we find one, we need to return state to the caller so that the indices can be fixed
-        // this also suggests that all of this function is fragile since it relies on a valid index
-    }
-    // probably should make this a common function rather than copy/paste code
-    if (oSpan.fWindValue != 1 || oSpan.fOppValue != 0) {
-        const SkOpSpan* oTest = &oSpan;
-        while (--oTest >= other->fTs.begin()) {
-            if (oTest->fPt != oSpan.fPt || !precisely_equal(oTest->fT, oSpan.fT)) {
-                break;
-            }
-            SkOpSegment* testOther = oTest->fOther;
-            SkASSERT(testOther != this);
-            // look in both directions to see if there is a coincident span
-            const SkOpSpan* tTest = testOther->fTs.begin();
-            for (int testIndex = 0; testIndex < testOther->count(); ++testIndex) {
-                if (tTest->fPt != span.fPt) {
-                    ++tTest;
-                    continue;
-                }
-                if (testOther->verb() != SkPath::kLine_Verb
-                        || other->verb() != SkPath::kLine_Verb) {
-                    SkPoint mid = ptAtT((span.fT + next->fT) / 2);
-                    SkPoint oMid = other->ptAtT((oTest->fOtherT + tTest->fT) / 2);
-                    if (!SkDPoint::ApproximatelyEqual(mid, oMid)) {
-                        continue;
-                    }
-                }
-#if DEBUG_CONCIDENT
-                SkDebugf("%s coincident found=%d %1.9g %1.9g\n", __FUNCTION__, testOther->fID,
-                        oTest->fOtherT, tTest->fT);
-#endif
-                if (tTest->fT < oTest->fOtherT) {
-                    SkAssertResult(addTCoincident(span.fPt, next->fPt, next->fT, testOther));
-                } else {
-                    addTCancel(span.fPt, next->fPt, testOther);
-                }
-                MissingSpan missing;
-                missing.fSegment = testOther;
-                checkMultiple->push_back(missing);
-                break;
-            }
-        }
-        oTest = &oSpan;
-        while (++oTest < other->fTs.end()) {
-            if (oTest->fPt != oSpan.fPt || !precisely_equal(oTest->fT, oSpan.fT)) {
-                break;
-            }
-
-        }
-    }
-}
-
-// if pair of spans on either side of tiny have the same end point and mid point, mark
-// them as parallel
-void SkOpSegment::checkTiny() {
-    SkSTArray<kMissingSpanCount, MissingSpan, true> missingSpans;
-    SkOpSpan* thisSpan = fTs.begin() - 1;
-    const SkOpSpan* endSpan = fTs.end() - 1;  // last can't be tiny
-    while (++thisSpan < endSpan) {
-        if (!thisSpan->fTiny) {
-            continue;
-        }
-        SkOpSpan* nextSpan = thisSpan + 1;
-        double thisT = thisSpan->fT;
-        double nextT = nextSpan->fT;
-        if (thisT == nextT) {
-            continue;
-        }
-        SkASSERT(thisT < nextT);
-        SkASSERT(thisSpan->fPt == nextSpan->fPt);
-        SkOpSegment* thisOther = thisSpan->fOther;
-        SkOpSegment* nextOther = nextSpan->fOther;
-        int oIndex = thisSpan->fOtherIndex;
-        for (int oStep = -1; oStep <= 1; oStep += 2) {
-            int oEnd = thisOther->nextExactSpan(oIndex, oStep);
-            if (oEnd < 0) {
-                continue;
-            }
-            const SkOpSpan& oSpan = thisOther->span(oEnd);
-            int nIndex = nextSpan->fOtherIndex;
-            for (int nStep = -1; nStep <= 1; nStep += 2) {
-                int nEnd = nextOther->nextExactSpan(nIndex, nStep);
-                if (nEnd < 0) {
-                    continue;
-                }
-                const SkOpSpan& nSpan = nextOther->span(nEnd);
-                if (oSpan.fPt != nSpan.fPt) {
-                    continue;
-                }
-                double oMidT = (thisSpan->fOtherT + oSpan.fT) / 2;
-                const SkPoint& oPt = thisOther->ptAtT(oMidT);
-                double nMidT = (nextSpan->fOtherT + nSpan.fT) / 2;
-                const SkPoint& nPt = nextOther->ptAtT(nMidT);
-                if (!AlmostEqualUlps(oPt, nPt)) {
-                    continue;
-                }
-#if DEBUG_CHECK_TINY
-                SkDebugf("%s [%d] add coincidence [%d] [%d]\n", __FUNCTION__, fID,
-                    thisOther->fID, nextOther->fID);
-#endif
-                // this segment is missing a entry that the other contains
-                // remember so we can add the missing one and recompute the indices
-                MissingSpan& missing = missingSpans.push_back();
-                SkDEBUGCODE(sk_bzero(&missing, sizeof(missing)));
-                missing.fSegment = thisOther;
-                missing.fT = thisSpan->fOtherT;
-                SkASSERT(this != nextOther);
-                missing.fOther = nextOther;
-                missing.fOtherT = nextSpan->fOtherT;
-                missing.fPt = thisSpan->fPt;
-            }
-        }
-    }
-    int missingCount = missingSpans.count();
-    if (!missingCount) {
-        return;
-    }
-    for (int index = 0; index < missingCount; ++index)  {
-        MissingSpan& missing = missingSpans[index];
-        if (missing.fSegment != missing.fOther) {
-            missing.fSegment->addTPair(missing.fT, missing.fOther, missing.fOtherT, false,
-                    missing.fPt);
-        }
-    }
-    // OPTIMIZE: consolidate to avoid multiple calls to fix index
-    for (int index = 0; index < missingCount; ++index)  {
-        MissingSpan& missing = missingSpans[index];
-        missing.fSegment->fixOtherTIndex();
-        missing.fOther->fixOtherTIndex();
-    }
-}
-
-bool SkOpSegment::coincidentSmall(const SkPoint& pt, double t, const SkOpSegment* other) const {
-    int count = this->count();
-    for (int index = 0; index < count; ++index) {
-        const SkOpSpan& span = this->span(index);
-        if (span.fOther != other) {
-            continue;
-        }
-        if (span.fPt == pt) {
-            continue;
-        }
-        if (!AlmostEqualUlps(span.fPt, pt)) {
-            continue;
-        }
-        if (fVerb != SkPath::kCubic_Verb) {
-            return true;
-        }
-        double tInterval = t - span.fT;
-        double tMid = t - tInterval / 2;
-        SkDPoint midPt = dcubic_xy_at_t(fPts, tMid);
-        return midPt.approximatelyEqual(xyAtT(t));
-    }
-    return false;
-}
-
-bool SkOpSegment::findCoincidentMatch(const SkOpSpan* span, const SkOpSegment* other, int oStart,
-        int oEnd, int step, SkPoint* startPt, SkPoint* endPt, double* endT) const {
-    SkASSERT(span->fT == 0 || span->fT == 1);
-    SkASSERT(span->fOtherT == 0 || span->fOtherT == 1);
-    const SkOpSpan* otherSpan = &other->span(oEnd);
-    double refT = otherSpan->fT;
-    const SkPoint& refPt = otherSpan->fPt;
-    const SkOpSpan* lastSpan = &other->span(step > 0 ? other->count() - 1 : 0);
-    do {
-        const SkOpSegment* match = span->fOther;
-        if (match == otherSpan->fOther) {
-            // find start of respective spans and see if both have winding
-            int startIndex, endIndex;
-            if (span->fOtherT == 1) {
-                endIndex = span->fOtherIndex;
-                startIndex = match->nextExactSpan(endIndex, -1);
-            } else {
-                startIndex = span->fOtherIndex;
-                endIndex = match->nextExactSpan(startIndex, 1);
-            }
-            const SkOpSpan& startSpan = match->span(startIndex);
-            if (startSpan.fWindValue != 0) {
-                // draw ray from endSpan.fPt perpendicular to end tangent and measure distance
-                // to other segment.
-                const SkOpSpan& endSpan = match->span(endIndex);
-                SkDLine ray;
-                SkVector dxdy;
-                if (span->fOtherT == 1) {
-                    ray.fPts[0].set(startSpan.fPt);
-                    dxdy = match->dxdy(startIndex);
-                } else {
-                    ray.fPts[0].set(endSpan.fPt);
-                    dxdy = match->dxdy(endIndex);
-                }
-                ray.fPts[1].fX = ray.fPts[0].fX + dxdy.fY;
-                ray.fPts[1].fY = ray.fPts[0].fY - dxdy.fX;
-                SkIntersections i;
-                int roots = (i.*CurveRay[SkPathOpsVerbToPoints(other->verb())])(other->pts(), ray);
-                for (int index = 0; index < roots; ++index) {
-                    if (ray.fPts[0].approximatelyEqual(i.pt(index))) {
-                        double matchMidT = (match->span(startIndex).fT
-                                + match->span(endIndex).fT) / 2;
-                        SkPoint matchMidPt = match->ptAtT(matchMidT);
-                        double otherMidT = (i[0][index] + other->span(oStart).fT) / 2;
-                        SkPoint otherMidPt = other->ptAtT(otherMidT);
-                        if (SkDPoint::ApproximatelyEqual(matchMidPt, otherMidPt)) {
-                            *startPt = startSpan.fPt;
-                            *endPt = endSpan.fPt;
-                            *endT = endSpan.fT;
-                            return true;
-                        }
-                    }
-                }
-            }
-            return false;
-        }
-        if (otherSpan == lastSpan) {
-            break;
-        }
-        otherSpan += step;
-    } while (otherSpan->fT == refT || otherSpan->fPt == refPt);
-    return false;
-}
-
-int SkOpSegment::findEndSpan(int endIndex) const {
-    const SkOpSpan* span = &fTs[--endIndex];
-    const SkPoint& lastPt = span->fPt;
-    double endT = span->fT;
-    do {
-        span = &fTs[--endIndex];
-    } while (SkDPoint::ApproximatelyEqual(span->fPt, lastPt) && (span->fT == endT || span->fTiny));
-    return endIndex + 1;
+    return closestDistSq;
 }
 
 /*
@@ -3029,71 +789,57 @@
  The Opp variable name part designates that the value is for the Opposite operator.
  Opposite values result from combining coincident spans.
  */
-SkOpSegment* SkOpSegment::findNextOp(SkTDArray<SkOpSpan*>* chase, int* nextStart, int* nextEnd,
-                                     bool* unsortable, SkPathOp op, const int xorMiMask,
-                                     const int xorSuMask) {
-    const int startIndex = *nextStart;
-    const int endIndex = *nextEnd;
-    SkASSERT(startIndex != endIndex);
-    SkDEBUGCODE(const int count = fTs.count());
-    SkASSERT(startIndex < endIndex ? startIndex < count - 1 : startIndex > 0);
-    int step = SkSign32(endIndex - startIndex);
-    *nextStart = startIndex;
-    SkOpSegment* other = isSimple(nextStart, &step);
-    if (other) 
-    {
+SkOpSegment* SkOpSegment::findNextOp(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** nextStart,
+        SkOpSpanBase** nextEnd, bool* unsortable, SkPathOp op, int xorMiMask, int xorSuMask) {
+    SkOpSpanBase* start = *nextStart;
+    SkOpSpanBase* end = *nextEnd;
+    SkASSERT(start != end);
+    int step = start->step(end);
+    SkOpSegment* other = this->isSimple(nextStart, &step);  // advances nextStart
+    if (other) {
     // mark the smaller of startIndex, endIndex done, and all adjacent
     // spans with the same T value (but not 'other' spans)
 #if DEBUG_WINDING
         SkDebugf("%s simple\n", __FUNCTION__);
 #endif
-        int min = SkMin32(startIndex, endIndex);
-        if (fTs[min].fDone) {
+        SkOpSpan* startSpan = start->starter(end);
+        if (startSpan->done()) {
             return NULL;
         }
-        markDoneBinary(min);
-        double startT = other->fTs[*nextStart].fT;
-        *nextEnd = *nextStart;
-        do {
-            *nextEnd += step;
-        } while (precisely_zero(startT - other->fTs[*nextEnd].fT));
-        SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count());
-        if (other->isTiny(SkMin32(*nextStart, *nextEnd))) {
-            *unsortable = true;
-            return NULL;
-        }
+        markDone(startSpan);
+        *nextEnd = step > 0 ? (*nextStart)->upCast()->next() : (*nextStart)->prev();
         return other;
     }
-    const int end = nextExactSpan(startIndex, step);
-    SkASSERT(end >= 0);
-    SkASSERT(startIndex - endIndex != 0);
-    SkASSERT((startIndex - endIndex < 0) ^ (step < 0));
+    SkOpSpanBase* endNear = step > 0 ? (*nextStart)->upCast()->next() : (*nextStart)->prev();
+    SkASSERT(endNear == end);  // is this ever not end?
+    SkASSERT(endNear);
+    SkASSERT(start != endNear);
+    SkASSERT((start->t() < endNear->t()) ^ (step < 0));
     // more than one viable candidate -- measure angles to find best
-
-    int calcWinding = computeSum(startIndex, end, SkOpAngle::kBinaryOpp);
+    int calcWinding = computeSum(start, endNear, SkOpAngle::kBinaryOpp);
     bool sortable = calcWinding != SK_NaN32;
     if (!sortable) {
         *unsortable = true;
-        markDoneBinary(SkMin32(startIndex, endIndex));
+        markDone(start->starter(end));
         return NULL;
     }
-    SkOpAngle* angle = spanToAngle(end, startIndex);
+    SkOpAngle* angle = this->spanToAngle(end, start);
     if (angle->unorderable()) {
         *unsortable = true;
-        markDoneBinary(SkMin32(startIndex, endIndex));
+        markDone(start->starter(end));
         return NULL;
     }
 #if DEBUG_SORT
     SkDebugf("%s\n", __FUNCTION__);
     angle->debugLoop();
 #endif
-    int sumMiWinding = updateWinding(endIndex, startIndex);
+    int sumMiWinding = updateWinding(end, start);
     if (sumMiWinding == SK_MinS32) {
         *unsortable = true;
-        markDoneBinary(SkMin32(startIndex, endIndex));
+        markDone(start->starter(end));
         return NULL;
     }
-    int sumSuWinding = updateOppWinding(endIndex, startIndex);
+    int sumSuWinding = updateOppWinding(end, start);
     if (operand()) {
         SkTSwap<int>(sumMiWinding, sumSuWinding);
     }
@@ -3110,11 +856,6 @@
         if (activeAngle) {
             ++activeCount;
             if (!foundAngle || (foundDone && activeCount & 1)) {
-                if (nextSegment->isTiny(nextAngle)) {
-                    *unsortable = true;
-                    markDoneBinary(SkMin32(startIndex, endIndex));
-                    return NULL;
-                }
                 foundAngle = nextAngle;
                 foundDone = nextSegment->done(nextAngle);
             }
@@ -3122,30 +863,24 @@
         if (nextSegment->done()) {
             continue;
         }
-        if (nextSegment->isTiny(nextAngle)) {
-            continue;
-        }
         if (!activeAngle) {
-            (void) nextSegment->markAndChaseDoneBinary(nextAngle->start(), nextAngle->end());
+            (void) nextSegment->markAndChaseDone(nextAngle->start(), nextAngle->end());
         }
-        SkOpSpan* last = nextAngle->lastMarked();
+        SkOpSpanBase* last = nextAngle->lastMarked();
         if (last) {
             SkASSERT(!SkPathOpsDebug::ChaseContains(*chase, last));
             *chase->append() = last;
 #if DEBUG_WINDING
-            SkDebugf("%s chase.append id=%d windSum=%d small=%d\n", __FUNCTION__,
-                    last->fOther->fTs[last->fOtherIndex].fOther->debugID(), last->fWindSum,
-                    last->fSmall);
+            SkDebugf("%s chase.append segment=%d span=%d", __FUNCTION__,
+                    last->segment()->debugID(), last->debugID());
+            if (!last->final()) {
+                SkDebugf(" windSum=%d", last->upCast()->windSum());
+            }
+            SkDebugf("\n");
 #endif
         }
     } while ((nextAngle = nextAngle->next()) != angle);
-#if DEBUG_ANGLE
-    if (foundAngle) {
-        foundAngle->debugSameAs(foundAngle);
-    }
-#endif
-
-    markDoneBinary(SkMin32(startIndex, endIndex));
+    start->segment()->markDone(start->starter(end));
     if (!foundAngle) {
         return NULL;
     }
@@ -3159,62 +894,55 @@
     return nextSegment;
 }
 
-SkOpSegment* SkOpSegment::findNextWinding(SkTDArray<SkOpSpan*>* chase, int* nextStart,
-                                          int* nextEnd, bool* unsortable) {
-    const int startIndex = *nextStart;
-    const int endIndex = *nextEnd;
-    SkASSERT(startIndex != endIndex);
-    SkDEBUGCODE(const int count = fTs.count());
-    SkASSERT(startIndex < endIndex ? startIndex < count - 1 : startIndex > 0);
-    int step = SkSign32(endIndex - startIndex);
-    *nextStart = startIndex;
-    SkOpSegment* other = isSimple(nextStart, &step);
-    if (other) 
-    {
+SkOpSegment* SkOpSegment::findNextWinding(SkTDArray<SkOpSpanBase*>* chase,
+        SkOpSpanBase** nextStart, SkOpSpanBase** nextEnd, bool* unsortable) {
+    SkOpSpanBase* start = *nextStart;
+    SkOpSpanBase* end = *nextEnd;
+    SkASSERT(start != end);
+    int step = start->step(end);
+    SkOpSegment* other = this->isSimple(nextStart, &step);  // advances nextStart
+    if (other) {
     // mark the smaller of startIndex, endIndex done, and all adjacent
     // spans with the same T value (but not 'other' spans)
 #if DEBUG_WINDING
         SkDebugf("%s simple\n", __FUNCTION__);
 #endif
-        int min = SkMin32(startIndex, endIndex);
-        if (fTs[min].fDone) {
+        SkOpSpan* startSpan = start->starter(end);
+        if (startSpan->done()) {
             return NULL;
         }
-        markDoneUnary(min);
-        double startT = other->fTs[*nextStart].fT;
-        *nextEnd = *nextStart;
-        do {
-            *nextEnd += step;
-        } while (precisely_zero(startT - other->fTs[*nextEnd].fT));
-        SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count());
-        if (other->isTiny(SkMin32(*nextStart, *nextEnd))) {
-            *unsortable = true;
-            return NULL;
-        }
+        markDone(startSpan);
+        *nextEnd = step > 0 ? (*nextStart)->upCast()->next() : (*nextStart)->prev();
         return other;
     }
-    const int end = nextExactSpan(startIndex, step);
-    SkASSERT(end >= 0);
-    SkASSERT(startIndex - endIndex != 0);
-    SkASSERT((startIndex - endIndex < 0) ^ (step < 0));
+    SkOpSpanBase* endNear = step > 0 ? (*nextStart)->upCast()->next() : (*nextStart)->prev();
+    SkASSERT(endNear == end);  // is this ever not end?
+    SkASSERT(endNear);
+    SkASSERT(start != endNear);
+    SkASSERT((start->t() < endNear->t()) ^ (step < 0));
     // more than one viable candidate -- measure angles to find best
-
-    int calcWinding = computeSum(startIndex, end, SkOpAngle::kUnaryWinding);
+    int calcWinding = computeSum(start, endNear, SkOpAngle::kUnaryWinding);
     bool sortable = calcWinding != SK_NaN32;
     if (!sortable) {
         *unsortable = true;
-        markDoneUnary(SkMin32(startIndex, endIndex));
+        markDone(start->starter(end));
         return NULL;
     }
-    SkOpAngle* angle = spanToAngle(end, startIndex);
+    SkOpAngle* angle = this->spanToAngle(end, start);
+    if (angle->unorderable()) {
+        *unsortable = true;
+        markDone(start->starter(end));
+        return NULL;
+    }
 #if DEBUG_SORT
     SkDebugf("%s\n", __FUNCTION__);
     angle->debugLoop();
 #endif
-    int sumWinding = updateWinding(endIndex, startIndex);
+    int sumWinding = updateWinding(end, start);
     SkOpAngle* nextAngle = angle->next();
     const SkOpAngle* foundAngle = NULL;
     bool foundDone = false;
+    // iterate through the angle, and compute everyone's winding
     SkOpSegment* nextSegment;
     int activeCount = 0;
     do {
@@ -3224,11 +952,6 @@
         if (activeAngle) {
             ++activeCount;
             if (!foundAngle || (foundDone && activeCount & 1)) {
-                if (nextSegment->isTiny(nextAngle)) {
-                    *unsortable = true;
-                    markDoneUnary(SkMin32(startIndex, endIndex));
-                    return NULL;
-                }
                 foundAngle = nextAngle;
                 foundDone = nextSegment->done(nextAngle);
             }
@@ -3236,24 +959,24 @@
         if (nextSegment->done()) {
             continue;
         }
-        if (nextSegment->isTiny(nextAngle)) {
-            continue;
-        }
         if (!activeAngle) {
-            nextSegment->markAndChaseDoneUnary(nextAngle->start(), nextAngle->end());
+            (void) nextSegment->markAndChaseDone(nextAngle->start(), nextAngle->end());
         }
-        SkOpSpan* last = nextAngle->lastMarked();
+        SkOpSpanBase* last = nextAngle->lastMarked();
         if (last) {
             SkASSERT(!SkPathOpsDebug::ChaseContains(*chase, last));
             *chase->append() = last;
 #if DEBUG_WINDING
-            SkDebugf("%s chase.append id=%d windSum=%d small=%d\n", __FUNCTION__,
-                    last->fOther->fTs[last->fOtherIndex].fOther->debugID(), last->fWindSum,
-                    last->fSmall);
+            SkDebugf("%s chase.append segment=%d span=%d", __FUNCTION__,
+                    last->segment()->debugID(), last->debugID());
+            if (!last->final()) {
+                SkDebugf(" windSum=%d", last->upCast()->windSum());
+            }
+            SkDebugf("\n");
 #endif
         }
     } while ((nextAngle = nextAngle->next()) != angle);
-    markDoneUnary(SkMin32(startIndex, endIndex));
+    start->segment()->markDone(start->starter(end));
     if (!foundAngle) {
         return NULL;
     }
@@ -3267,57 +990,39 @@
     return nextSegment;
 }
 
-SkOpSegment* SkOpSegment::findNextXor(int* nextStart, int* nextEnd, bool* unsortable) {
-    const int startIndex = *nextStart;
-    const int endIndex = *nextEnd;
-    SkASSERT(startIndex != endIndex);
-    SkDEBUGCODE(int count = fTs.count());
-    SkASSERT(startIndex < endIndex ? startIndex < count - 1 : startIndex > 0);
-    int step = SkSign32(endIndex - startIndex);
-// Detect cases where all the ends canceled out (e.g.,
-// there is no angle) and therefore there's only one valid connection 
-    *nextStart = startIndex;
-    SkOpSegment* other = isSimple(nextStart, &step);
-    if (other)
-    {
+SkOpSegment* SkOpSegment::findNextXor(SkOpSpanBase** nextStart, SkOpSpanBase** nextEnd,
+        bool* unsortable) {
+    SkOpSpanBase* start = *nextStart;
+    SkOpSpanBase* end = *nextEnd;
+    SkASSERT(start != end);
+    int step = start->step(end);
+    SkOpSegment* other = this->isSimple(nextStart, &step);  // advances nextStart
+    if (other) {
+    // mark the smaller of startIndex, endIndex done, and all adjacent
+    // spans with the same T value (but not 'other' spans)
 #if DEBUG_WINDING
         SkDebugf("%s simple\n", __FUNCTION__);
 #endif
-        int min = SkMin32(startIndex, endIndex);
-        if (fTs[min].fDone) {
+        SkOpSpan* startSpan = start->starter(end);
+        if (startSpan->done()) {
             return NULL;
         }
-        markDone(min, 1);
-        double startT = other->fTs[*nextStart].fT;
-        // FIXME: I don't know why the logic here is difference from the winding case
-        SkDEBUGCODE(bool firstLoop = true;)
-        if ((approximately_less_than_zero(startT) && step < 0)
-                || (approximately_greater_than_one(startT) && step > 0)) {
-            step = -step;
-            SkDEBUGCODE(firstLoop = false;)
-        }
-        do {
-            *nextEnd = *nextStart;
-            do {
-                *nextEnd += step;
-            } while (precisely_zero(startT - other->fTs[*nextEnd].fT));
-            if (other->fTs[SkMin32(*nextStart, *nextEnd)].fWindValue) {
-                break;
-            }
-            SkASSERT(firstLoop);
-            SkDEBUGCODE(firstLoop = false;)
-            step = -step;
-        } while (true);
-        SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count());
+        markDone(startSpan);
+        *nextEnd = step > 0 ? (*nextStart)->upCast()->next() : (*nextStart)->prev();
         return other;
     }
-    SkASSERT(startIndex - endIndex != 0);
-    SkASSERT((startIndex - endIndex < 0) ^ (step < 0));
-    // parallel block above with presorted version
-    int end = nextExactSpan(startIndex, step);
-    SkASSERT(end >= 0);
-    SkOpAngle* angle = spanToAngle(end, startIndex);
-    SkASSERT(angle);
+    SkDEBUGCODE(SkOpSpanBase* endNear = step > 0 ? (*nextStart)->upCast()->next() \
+            : (*nextStart)->prev());
+    SkASSERT(endNear == end);  // is this ever not end?
+    SkASSERT(endNear);
+    SkASSERT(start != endNear);
+    SkASSERT((start->t() < endNear->t()) ^ (step < 0));
+    SkOpAngle* angle = this->spanToAngle(end, start);
+    if (angle->unorderable()) {
+        *unsortable = true;
+        markDone(start->starter(end));
+        return NULL;
+    }
 #if DEBUG_SORT
     SkDebugf("%s\n", __FUNCTION__);
     angle->debugLoop();
@@ -3325,16 +1030,13 @@
     SkOpAngle* nextAngle = angle->next();
     const SkOpAngle* foundAngle = NULL;
     bool foundDone = false;
+    // iterate through the angle, and compute everyone's winding
     SkOpSegment* nextSegment;
     int activeCount = 0;
     do {
         nextSegment = nextAngle->segment();
         ++activeCount;
         if (!foundAngle || (foundDone && activeCount & 1)) {
-            if (nextSegment->isTiny(nextAngle)) {
-                *unsortable = true;
-                return NULL;
-            }
             foundAngle = nextAngle;
             if (!(foundDone = nextSegment->done(nextAngle))) {
                 break;
@@ -3342,7 +1044,7 @@
         }
         nextAngle = nextAngle->next();
     } while (nextAngle != angle);
-    markDone(SkMin32(startIndex, endIndex), 1);
+    start->segment()->markDone(start->starter(end));
     if (!foundAngle) {
         return NULL;
     }
@@ -3356,105 +1058,39 @@
     return nextSegment;
 }
 
-int SkOpSegment::findStartSpan(int startIndex) const {
-    int index = startIndex;
-    const SkOpSpan* span = &fTs[index];
-    const SkPoint& firstPt = span->fPt;
-    double firstT = span->fT;
-    const SkOpSpan* prior;
-    do {
-        prior = span;
-        span = &fTs[++index];
-    } while (SkDPoint::ApproximatelyEqual(span->fPt, firstPt)
-            && (span->fT == firstT || prior->fTiny));
-    return index;
-}
-
-int SkOpSegment::findExactT(double t, const SkOpSegment* match) const {
-    int count = this->count();
-    for (int index = 0; index < count; ++index) {
-        const SkOpSpan& span = fTs[index];
-        if (span.fT == t && span.fOther == match) {
-            return index;
-        }
-    }
-    SkASSERT(0);
-    return -1;
-}
-
-
-
-int SkOpSegment::findOtherT(double t, const SkOpSegment* match) const {
-    int count = this->count();
-    for (int index = 0; index < count; ++index) {
-        const SkOpSpan& span = fTs[index];
-        if (span.fOtherT == t && span.fOther == match) {
-            return index;
-        }
-    }
-    return -1;
-}
-
-int SkOpSegment::findT(double t, const SkPoint& pt, const SkOpSegment* match) const {
-    int count = this->count();
-    // prefer exact matches over approximate matches
-    for (int index = 0; index < count; ++index) {
-        const SkOpSpan& span = fTs[index];
-        if (span.fT == t && span.fOther == match) {
-            return index;
-        }
-    }
-    for (int index = 0; index < count; ++index) {
-        const SkOpSpan& span = fTs[index];
-        if (approximately_equal_orderable(span.fT, t) && span.fOther == match) {
-            return index;
-        }
-    }
-    // Usually, the pair of ts are an exact match. It's possible that the t values have
-    // been adjusted to make multiple intersections align. In this rare case, look for a
-    // matching point / match pair instead.
-    for (int index = 0; index < count; ++index) {
-        const SkOpSpan& span = fTs[index];
-        if (span.fPt == pt && span.fOther == match) {
-            return index;
-        }
-    }
-    SkASSERT(0);
-    return -1;
-}
-
-SkOpSegment* SkOpSegment::findTop(int* tIndexPtr, int* endIndexPtr, bool* unsortable,
-        bool firstPass) {
+SkOpSegment* SkOpSegment::findTop(bool firstPass, SkOpSpanBase** startPtr, SkOpSpanBase** endPtr,
+        bool* unsortable, SkChunkAlloc* allocator) {
     // iterate through T intersections and return topmost
     // topmost tangent from y-min to first pt is closer to horizontal
     SkASSERT(!done());
-    int firstT = -1;
-    /* SkPoint topPt = */ activeLeftTop(&firstT);
-    if (firstT < 0) {
+    SkOpSpanBase* firstT = NULL;
+    (void) this->activeLeftTop(&firstT);
+    if (!firstT) {
         *unsortable = !firstPass;
-        firstT = 0;
-        while (fTs[firstT].fDone) {
-            SkASSERT(firstT < fTs.count());
-            ++firstT;
+        firstT = &fHead;
+        while (firstT->upCast()->done()) {
+            firstT = firstT->upCast()->next();
         }
-        *tIndexPtr = firstT;
-        *endIndexPtr = nextExactSpan(firstT, 1);
+        *startPtr = firstT;
+        *endPtr = firstT->upCast()->next();
         return this;
     }
     // sort the edges to find the leftmost
     int step = 1;
-    int end;
-    if (span(firstT).fDone || (end = nextSpan(firstT, step)) == -1) {
+    SkOpSpanBase* end;
+    if (firstT->final() || firstT->upCast()->done()) {
         step = -1;
-        end = nextSpan(firstT, step);
-        SkASSERT(end != -1);
+        end = firstT->prev();
+        SkASSERT(end);
+    } else {
+        end = firstT->upCast()->next();
     }
     // if the topmost T is not on end, or is three-way or more, find left
     // look for left-ness from tLeft to firstT (matching y of other)
-    SkASSERT(firstT - end != 0);
+    SkASSERT(firstT != end);
     SkOpAngle* markAngle = spanToAngle(firstT, end);
     if (!markAngle) {
-        markAngle = addSingletonAngles(step);
+        markAngle = addSingletonAngles(step, allocator);
     }
     markAngle->markStops();
     const SkOpAngle* baseAngle = markAngle->next() == markAngle && !isVertical() ? markAngle
@@ -3467,7 +1103,7 @@
     const SkOpAngle* angle = baseAngle;
     do {
         if (!angle->unorderable()) {
-            SkOpSegment* next = angle->segment();
+            const SkOpSegment* next = angle->segment();
             SkPathOpsBounds bounds;
             next->subDivideBounds(angle->end(), angle->start(), &bounds);
             bool nearSame = AlmostEqualUlps(top, bounds.top());
@@ -3495,9 +1131,10 @@
         *unsortable = angle->unorderable();
         if (firstPass || !*unsortable) {
             leftSegment = angle->segment();
-            *tIndexPtr = angle->end();
-            *endIndexPtr = angle->start();
-            if (!leftSegment->fTs[SkMin32(*tIndexPtr, *endIndexPtr)].fDone) {
+            *startPtr = angle->end();
+            *endPtr = angle->start();
+            const SkOpSpan* firstSpan = (*startPtr)->starter(*endPtr);
+            if (!firstSpan->done()) {
                 break;
             }
         }
@@ -3508,157 +1145,52 @@
         return NULL;
     }
     if (leftSegment->verb() >= SkPath::kQuad_Verb) {
-        const int tIndex = *tIndexPtr;
-        const int endIndex = *endIndexPtr;
+        SkOpSpanBase* start = *startPtr;
+        SkOpSpanBase* end = *endPtr;
         bool swap;
-        if (!leftSegment->clockwise(tIndex, endIndex, &swap)) {
+        if (!leftSegment->clockwise(start, end, &swap)) {
     #if DEBUG_SWAP_TOP
-            SkDebugf("%s swap=%d inflections=%d serpentine=%d controlledbyends=%d monotonic=%d\n",
+            SkDebugf("%s swap=%d inflections=%d monotonic=%d\n",
                     __FUNCTION__,
-                    swap, leftSegment->debugInflections(tIndex, endIndex),
-                    leftSegment->serpentine(tIndex, endIndex),
-                    leftSegment->controlsContainedByEnds(tIndex, endIndex),
-                    leftSegment->monotonicInY(tIndex, endIndex));
+                    swap, leftSegment->debugInflections(start, end),
+                    leftSegment->monotonicInY(start, end));
     #endif
             if (swap) {
     // FIXME: I doubt it makes sense to (necessarily) swap if the edge was not the first
     // sorted but merely the first not already processed (i.e., not done)
-                SkTSwap(*tIndexPtr, *endIndexPtr);
+                SkTSwap(*startPtr, *endPtr);
             }
         }
     }
-    SkASSERT(!leftSegment->fTs[SkMin32(*tIndexPtr, *endIndexPtr)].fTiny);
     return leftSegment;
 }
 
-int SkOpSegment::firstActive(int tIndex) const {
-    while (fTs[tIndex].fTiny) {
-        SkASSERT(!isCanceled(tIndex));
-        ++tIndex;
-    }
-    return tIndex;
+SkOpGlobalState* SkOpSegment::globalState() const {
+    return contour()->globalState(); 
 }
 
-// FIXME: not crazy about this
-// when the intersections are performed, the other index is into an
-// incomplete array. As the array grows, the indices become incorrect
-// while the following fixes the indices up again, it isn't smart about
-// skipping segments whose indices are already correct
-// assuming we leave the code that wrote the index in the first place
-// FIXME: if called after remove, this needs to correct tiny
-void SkOpSegment::fixOtherTIndex() {
-    int iCount = fTs.count();
-    for (int i = 0; i < iCount; ++i) {
-        SkOpSpan& iSpan = fTs[i];
-        double oT = iSpan.fOtherT;
-        SkOpSegment* other = iSpan.fOther;
-        int oCount = other->fTs.count();
-        SkDEBUGCODE(iSpan.fOtherIndex = -1);
-        for (int o = 0; o < oCount; ++o) {
-            SkOpSpan& oSpan = other->fTs[o];
-            if (oT == oSpan.fT && this == oSpan.fOther && oSpan.fOtherT == iSpan.fT) {
-                iSpan.fOtherIndex = o;
-                oSpan.fOtherIndex = i;
-                break;
-            }
-        }
-        SkASSERT(iSpan.fOtherIndex >= 0);
-    }
-}
-
-bool SkOpSegment::inCoincidentSpan(double t, const SkOpSegment* other) const {
-    int foundEnds = 0;
-    int count = this->count();
-    for (int index = 0; index < count; ++index) {
-        const SkOpSpan& span = this->span(index);
-        if (span.fCoincident) {
-            foundEnds |= (span.fOther == other) << ((t > span.fT) + (t >= span.fT));
-        }
-    }
-    SkASSERT(foundEnds != 7);
-    return foundEnds == 0x3 || foundEnds == 0x5 || foundEnds == 0x6;  // two bits set
-}
-
-bool SkOpSegment::inconsistentAngle(int maxWinding, int sumWinding, int oppMaxWinding,
-        int oppSumWinding, const SkOpAngle* angle) const {
-    SkASSERT(angle->segment() == this);
-    if (UseInnerWinding(maxWinding, sumWinding)) {
-        maxWinding = sumWinding;
-    }
-    if (oppMaxWinding != oppSumWinding && UseInnerWinding(oppMaxWinding, oppSumWinding)) {
-        oppMaxWinding = oppSumWinding;
-    }
-    return inconsistentWinding(angle, maxWinding, oppMaxWinding);
-}
-
-bool SkOpSegment::inconsistentWinding(const SkOpAngle* angle, int winding,
-        int oppWinding) const {
-    int index = angle->start();
-    int endIndex = angle->end();
-    int min = SkMin32(index, endIndex);
-    int step = SkSign32(endIndex - index);
-    if (inconsistentWinding(min, winding, oppWinding)) {
-        return true;
-    }
-    const SkOpSegment* other = this;
-    while ((other = other->nextChase(&index, &step, &min, NULL))) {
-        if (other->fTs[min].fWindSum != SK_MinS32) {
-            break;
-        }
-        if (fOperand == other->fOperand) {
-            if (other->inconsistentWinding(min, winding, oppWinding)) {
-                return true;
-            }
-        } else {
-            if (other->inconsistentWinding(min, oppWinding, winding)) {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-bool SkOpSegment::inconsistentWinding(int index, int winding, int oppWinding) const {
-    SkASSERT(winding || oppWinding);
-    double referenceT = this->span(index).fT;
-    int lesser = index;
-    while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
-        if (inconsistentWinding(__FUNCTION__, lesser, winding, oppWinding)) {
-            return true;
-        }
-    }
-    do {
-        if (inconsistentWinding(__FUNCTION__, index, winding, oppWinding)) {
-            return true;
-        }
-   } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
-    return false;
-}
-
-bool SkOpSegment::inconsistentWinding(const char* funName, int tIndex, int winding,
-        int oppWinding) const {
-    const SkOpSpan& span = this->span(tIndex);
-    if (span.fDone && !span.fSmall) {
-        return false;
-    }
-    return (span.fWindSum != SK_MinS32 && span.fWindSum != winding)
-            || (span.fOppSum != SK_MinS32 && span.fOppSum != oppWinding);
-}
-
-void SkOpSegment::init(const SkPoint pts[], SkPath::Verb verb, bool operand, bool evenOdd) {
-    fDoneSpans = 0;
-    fOperand = operand;
-    fXor = evenOdd;
+void SkOpSegment::init(SkPoint pts[], SkOpContour* contour, SkPath::Verb verb) {
+    fContour = contour;
+    fNext = NULL;
     fPts = pts;
     fVerb = verb;
-    fLoop = fMultiples = fSmall = fTiny = false;
+    fCount = 0;
+    fDoneCount = 0;
+    fVisited = false;
+    SkOpSpan* zeroSpan = &fHead;
+    zeroSpan->init(this, NULL, 0, fPts[0]);
+    SkOpSpanBase* oneSpan = &fTail;
+    zeroSpan->setNext(oneSpan);
+    oneSpan->initBase(this, zeroSpan, 1, fPts[SkPathOpsVerbToPoints(fVerb)]);
+    PATH_OPS_DEBUG_CODE(fID = globalState()->nextSegmentID());
 }
 
-void SkOpSegment::initWinding(int start, int end, SkOpAngle::IncludeType angleIncludeType) {
-    int local = spanSign(start, end);
+void SkOpSegment::initWinding(SkOpSpanBase* start, SkOpSpanBase* end,
+        SkOpAngle::IncludeType angleIncludeType) {
+    int local = SkOpSegment::SpanSign(start, end);
     SkDEBUGCODE(bool success);
     if (angleIncludeType == SkOpAngle::kBinarySingle) {
-        int oppLocal = oppSign(start, end);
+        int oppLocal = SkOpSegment::OppSign(start, end);
         SkDEBUGCODE(success =) markAndChaseWinding(start, end, local, oppLocal, NULL);
     // OPTIMIZATION: the reverse mark and chase could skip the first marking
         SkDEBUGCODE(success |=) markAndChaseWinding(end, start, local, oppLocal, NULL);
@@ -3679,12 +1211,13 @@
 from has the same x direction as this span, the winding should change. If the dx is opposite, then
 the same winding is shared by both.
 */
-bool SkOpSegment::initWinding(int start, int end, double tHit, int winding, SkScalar hitDx,
-                              int oppWind, SkScalar hitOppDx) {
+bool SkOpSegment::initWinding(SkOpSpanBase* start, SkOpSpanBase* end, double tHit,
+        int winding, SkScalar hitDx, int oppWind, SkScalar hitOppDx) {
+    SkASSERT(this == start->segment());
     SkASSERT(hitDx || !winding);
     SkScalar dx = (*CurveSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, tHit).fX;
-    SkASSERT(dx);
-    int windVal = windValue(SkMin32(start, end));
+//    SkASSERT(dx);
+    int windVal = start->starter(end)->windValue();
 #if DEBUG_WINDING_AT_T
     SkDebugf("%s id=%d oldWinding=%d hitDx=%c dx=%c windVal=%d", __FUNCTION__, debugID(), winding,
             hitDx ? hitDx > 0 ? '+' : '-' : '0', dx > 0 ? '+' : '-', windVal);
@@ -3693,9 +1226,9 @@
     if (abs(winding) < abs(sideWind)) {
         winding = sideWind;
     }
-    SkDEBUGCODE(int oppLocal = oppSign(start, end));
+    SkDEBUGCODE(int oppLocal = SkOpSegment::OppSign(start, end));
     SkASSERT(hitOppDx || !oppWind || !oppLocal);
-    int oppWindVal = oppValue(SkMin32(start, end));
+    int oppWindVal = start->starter(end)->oppValue();
     if (!oppWind) {
         oppWind = dx < 0 ? oppWindVal : -oppWindVal;
     } else if (hitOppDx * dx >= 0) {
@@ -3714,149 +1247,57 @@
     return success;
 }
 
-bool SkOpSegment::inLoop(const SkOpAngle* baseAngle, int spanCount, int* indexPtr) const {
-    if (!baseAngle->inLoop()) {
-        return false;
-    }
-    int index = *indexPtr;
-    SkOpAngle* from = fTs[index].fFromAngle;
-    SkOpAngle* to = fTs[index].fToAngle;
-    while (++index < spanCount) {
-        SkOpAngle* nextFrom = fTs[index].fFromAngle;
-        SkOpAngle* nextTo = fTs[index].fToAngle;
-        if (from != nextFrom || to != nextTo) {
-            break;
-        }
-    }
-    *indexPtr = index;
-    return true;
-}
-
-// OPTIMIZE: successive calls could start were the last leaves off
-// or calls could specialize to walk forwards or backwards
-bool SkOpSegment::isMissing(double startT, const SkPoint& pt) const {
-    int tCount = fTs.count();
-    for (int index = 0; index < tCount; ++index) {
-        const SkOpSpan& span = fTs[index];
-        if (approximately_zero(startT - span.fT) && pt == span.fPt) {
-            return false;
-        }
-    }
-    return true;
-}
-
-
-SkOpSegment* SkOpSegment::isSimple(int* end, int* step) {
-    return nextChase(end, step, NULL, NULL);
-}
-
-bool SkOpSegment::isTiny(const SkOpAngle* angle) const {
-    int start = angle->start();
-    int end = angle->end();
-    const SkOpSpan& mSpan = fTs[SkMin32(start, end)];
-    return mSpan.fTiny;
-}
-
-bool SkOpSegment::isTiny(int index) const {
-    return fTs[index].fTiny;
-}
-
-// look pair of active edges going away from coincident edge
-// one of them should be the continuation of other
-// if both are active, look to see if they both the connect to another coincident pair
-// if at least one is a line, then make the pair coincident
-// if neither is a line, test for coincidence
-bool SkOpSegment::joinCoincidence(SkOpSegment* other, double otherT, const SkPoint& otherPt,
-        int step, bool cancel) {
-    int otherTIndex = other->findT(otherT, otherPt, this);
-    int next = other->nextExactSpan(otherTIndex, step);
-    int otherMin = SkMin32(otherTIndex, next);
-    int otherWind = other->span(otherMin).fWindValue;
-    if (otherWind == 0) {
-        return false;
-    }
-    if (next < 0) {
-        return false;  // can happen if t values were adjusted but coincident ts were not
-    }
-    int tIndex = 0;
-    do {
-        SkOpSpan* test = &fTs[tIndex];
-        SkASSERT(test->fT == 0);
-        if (test->fOther == other || test->fOtherT != 1) {
-            continue;
-        }
-        SkPoint startPt, endPt;
-        double endT;
-        if (findCoincidentMatch(test, other, otherTIndex, next, step, &startPt, &endPt, &endT)) {
-            SkOpSegment* match = test->fOther;
-            if (cancel) {
-                match->addTCancel(startPt, endPt, other);
-            } else {
-                if (!match->addTCoincident(startPt, endPt, endT, other)) {
-                    return false;
-                }
-            }
+bool SkOpSegment::isClose(double t, const SkOpSegment* opp) const {
+    SkDPoint cPt = this->dPtAtT(t);
+    int pts = SkPathOpsVerbToPoints(this->verb());
+    SkDVector dxdy = (*CurveDSlopeAtT[pts])(this->pts(), t);
+    SkDLine perp = {{ cPt, {cPt.fX + dxdy.fY, cPt.fY - dxdy.fX} }};
+    SkIntersections i;
+    int oppPts = SkPathOpsVerbToPoints(opp->verb());
+    (*CurveIntersectRay[oppPts])(opp->pts(), perp, &i);
+    int used = i.used();
+    for (int index = 0; index < used; ++index) {
+        if (cPt.roughlyEqual(i.pt(index))) {
             return true;
         }
-    } while (fTs[++tIndex].fT == 0);
+    }
     return false;
 }
 
-// this span is excluded by the winding rule -- chase the ends
-// as long as they are unambiguous to mark connections as done
-// and give them the same winding value
+bool SkOpSegment::isXor() const {
+    return fContour->isXor();
+}
 
-SkOpSpan* SkOpSegment::markAndChaseDoneBinary(int index, int endIndex) {
-    int step = SkSign32(endIndex - index);
-    int min = SkMin32(index, endIndex);
-    markDoneBinary(min);
-    SkOpSpan* last = NULL;
+SkOpSpanBase* SkOpSegment::markAndChaseDone(SkOpSpanBase* start, SkOpSpanBase* end) {
+    int step = start->step(end);
+    SkOpSpan* minSpan = start->starter(end);
+    markDone(minSpan);
+    SkOpSpanBase* last = NULL;
     SkOpSegment* other = this;
-    while ((other = other->nextChase(&index, &step, &min, &last))) {
+    while ((other = other->nextChase(&start, &step, &minSpan, &last))) {
         if (other->done()) {
             SkASSERT(!last);
             break;
         }
-        other->markDoneBinary(min);
+        other->markDone(minSpan);
     }
     return last;
 }
 
-SkOpSpan* SkOpSegment::markAndChaseDoneUnary(int index, int endIndex) {
-    int step = SkSign32(endIndex - index);
-    int min = SkMin32(index, endIndex);
-    markDoneUnary(min);
-    SkOpSpan* last = NULL;
+bool SkOpSegment::markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding,
+        SkOpSpanBase** lastPtr) {
+    SkOpSpan* spanStart = start->starter(end);
+    int step = start->step(end);
+    bool success = markWinding(spanStart, winding);
+    SkOpSpanBase* last = NULL;
     SkOpSegment* other = this;
-    while ((other = other->nextChase(&index, &step, &min, &last))) {
-        if (other->done()) {
+    while ((other = other->nextChase(&start, &step, &spanStart, &last))) {
+        if (spanStart->windSum() != SK_MinS32) {
+            SkASSERT(spanStart->windSum() == winding);
             SkASSERT(!last);
             break;
         }
-        other->markDoneUnary(min);
-    }
-    return last;
-}
-
-bool SkOpSegment::markAndChaseWinding(const SkOpAngle* angle, int winding, SkOpSpan** lastPtr) {
-    int index = angle->start();
-    int endIndex = angle->end();
-    return markAndChaseWinding(index, endIndex, winding, lastPtr);
-}
-
-bool SkOpSegment::markAndChaseWinding(int index, int endIndex, int winding, SkOpSpan** lastPtr) {
-    int min = SkMin32(index, endIndex);
-    int step = SkSign32(endIndex - index);
-    bool success = markWinding(min, winding);
-    SkOpSpan* last = NULL;
-    SkOpSegment* other = this;
-    while ((other = other->nextChase(&index, &step, &min, &last))) {
-        if (other->fTs[min].fWindSum != SK_MinS32) {
-            SkASSERT(other->fTs[min].fWindSum == winding || other->fTs[min].fLoop);
-            SkASSERT(!last);
-            break;
-        }
-        (void) other->markWinding(min, winding);
+        (void) other->markWinding(spanStart, winding);
     }
     if (lastPtr) {
         *lastPtr = last;
@@ -3864,37 +1305,32 @@
     return success;
 }
 
-bool SkOpSegment::markAndChaseWinding(int index, int endIndex, int winding, int oppWinding,
-        SkOpSpan** lastPtr) {
-    int min = SkMin32(index, endIndex);
-    int step = SkSign32(endIndex - index);
-    bool success = markWinding(min, winding, oppWinding);
-    SkOpSpan* last = NULL;
+bool SkOpSegment::markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end,
+        int winding, int oppWinding, SkOpSpanBase** lastPtr) {
+    SkOpSpan* spanStart = start->starter(end);
+    int step = start->step(end);
+    bool success = markWinding(spanStart, winding, oppWinding);
+    SkOpSpanBase* last = NULL;
     SkOpSegment* other = this;
-    while ((other = other->nextChase(&index, &step, &min, &last))) {
-        if (other->fTs[min].fWindSum != SK_MinS32) {
-#ifdef SK_DEBUG
-            if (!other->fTs[min].fLoop) {
-                if (fOperand == other->fOperand) {
-// FIXME: this is probably a bug -- rects4 asserts here
-//                    SkASSERT(other->fTs[min].fWindSum == winding);
-// FIXME: this is probably a bug -- rects3 asserts here
-//                    SkASSERT(other->fTs[min].fOppSum == oppWinding);
-                } else {
-// FIXME: this is probably a bug -- issue414409b asserts here
-//                    SkASSERT(other->fTs[min].fWindSum == oppWinding);
-// FIXME: this is probably a bug -- skpwww_joomla_org_23 asserts here
-//                    SkASSERT(other->fTs[min].fOppSum == winding);
+    while ((other = other->nextChase(&start, &step, &spanStart, &last))) {
+        if (spanStart->windSum() != SK_MinS32) {
+            if (this->operand() == other->operand()) {
+                SkASSERT(spanStart->windSum() == winding);
+                if (spanStart->oppSum() != oppWinding) {
+                    this->globalState()->setWindingFailed();
+                    return false;
                 }
+            } else {
+                SkASSERT(spanStart->windSum() == oppWinding);
+                SkASSERT(spanStart->oppSum() == winding);
             }
             SkASSERT(!last);
-#endif
             break;
         }
-        if (fOperand == other->fOperand) {
-            (void) other->markWinding(min, winding, oppWinding);
+        if (this->operand() == other->operand()) {
+            (void) other->markWinding(spanStart, winding, oppWinding);
         } else {
-            (void) other->markWinding(min, oppWinding, winding);
+            (void) other->markWinding(spanStart, oppWinding, winding);
         }
     }
     if (lastPtr) {
@@ -3903,33 +1339,29 @@
     return success;
 }
 
-bool SkOpSegment::markAndChaseWinding(const SkOpAngle* angle, int winding, int oppWinding,
-        SkOpSpan** lastPtr) {
-    int start = angle->start();
-    int end = angle->end();
-    return markAndChaseWinding(start, end, winding, oppWinding, lastPtr);
-}
-
-SkOpSpan* SkOpSegment::markAngle(int maxWinding, int sumWinding, const SkOpAngle* angle) {
+SkOpSpanBase* SkOpSegment::markAngle(int maxWinding, int sumWinding, const SkOpAngle* angle) {
     SkASSERT(angle->segment() == this);
     if (UseInnerWinding(maxWinding, sumWinding)) {
         maxWinding = sumWinding;
     }
-    SkOpSpan* last;
-    SkAssertResult(markAndChaseWinding(angle, maxWinding, &last));
+    SkOpSpanBase* last;
+    (void) markAndChaseWinding(angle->start(), angle->end(), maxWinding, &last);
 #if DEBUG_WINDING
     if (last) {
-        SkDebugf("%s last id=%d windSum=", __FUNCTION__,
-                last->fOther->fTs[last->fOtherIndex].fOther->debugID());
-        SkPathOpsDebug::WindingPrintf(last->fWindSum);
-        SkDebugf(" small=%d\n", last->fSmall);
+        SkDebugf("%s last seg=%d span=%d", __FUNCTION__,
+                last->segment()->debugID(), last->debugID());
+        if (!last->final()) {
+            SkDebugf(" windSum=");
+            SkPathOpsDebug::WindingPrintf(last->upCast()->windSum());
+        }
+        SkDebugf("\n");
     }
 #endif
     return last;
 }
 
-SkOpSpan* SkOpSegment::markAngle(int maxWinding, int sumWinding, int oppMaxWinding,
-                                 int oppSumWinding, const SkOpAngle* angle) {
+SkOpSpanBase* SkOpSegment::markAngle(int maxWinding, int sumWinding, int oppMaxWinding,
+                                   int oppSumWinding, const SkOpAngle* angle) {
     SkASSERT(angle->segment() == this);
     if (UseInnerWinding(maxWinding, sumWinding)) {
         maxWinding = sumWinding;
@@ -3937,440 +1369,161 @@
     if (oppMaxWinding != oppSumWinding && UseInnerWinding(oppMaxWinding, oppSumWinding)) {
         oppMaxWinding = oppSumWinding;
     }
-    SkOpSpan* last;
+    SkOpSpanBase* last = NULL;
     // caller doesn't require that this marks anything
-    (void) markAndChaseWinding(angle, maxWinding, oppMaxWinding, &last);
+    (void) markAndChaseWinding(angle->start(), angle->end(), maxWinding, oppMaxWinding, &last);
 #if DEBUG_WINDING
     if (last) {
-        SkDebugf("%s last id=%d windSum=", __FUNCTION__,
-                last->fOther->fTs[last->fOtherIndex].fOther->debugID());
-        SkPathOpsDebug::WindingPrintf(last->fWindSum);
-        SkDebugf(" small=%d\n", last->fSmall);
+        SkDebugf("%s last segment=%d span=%d", __FUNCTION__,
+                last->segment()->debugID(), last->debugID());
+        if (!last->final()) {
+            SkDebugf(" windSum=");
+            SkPathOpsDebug::WindingPrintf(last->upCast()->windSum());
+        }
+        SkDebugf(" \n");
     }
 #endif
     return last;
 }
 
-// FIXME: this should also mark spans with equal (x,y)
-// This may be called when the segment is already marked done. While this
-// wastes time, it shouldn't do any more than spin through the T spans.
-// OPTIMIZATION: abort on first done found (assuming that this code is
-// always called to mark segments done).
-void SkOpSegment::markDone(int index, int winding) {
-  //  SkASSERT(!done());
+void SkOpSegment::markDone(SkOpSpan* span) {
+    SkASSERT(this == span->segment());
+    if (span->done()) {
+        return;
+    }
+#if DEBUG_MARK_DONE
+    debugShowNewWinding(__FUNCTION__, span, span->windSum(), span->oppSum());
+#endif
+    span->setDone(true);
+    ++fDoneCount;
+    debugValidate();
+}
+
+bool SkOpSegment::markWinding(SkOpSpan* span, int winding) {
+    SkASSERT(this == span->segment());
     SkASSERT(winding);
-    double referenceT = fTs[index].fT;
-    int lesser = index;
-    while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
-        markOneDone(__FUNCTION__, lesser, winding);
-    }
-    do {
-        markOneDone(__FUNCTION__, index, winding);
-    } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
-    debugValidate();
-}
-
-void SkOpSegment::markDoneBinary(int index) {
-    double referenceT = fTs[index].fT;
-    int lesser = index;
-    while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
-        markOneDoneBinary(__FUNCTION__, lesser);
-    }
-    do {
-        markOneDoneBinary(__FUNCTION__, index);
-    } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
-    debugValidate();
-}
-
-void SkOpSegment::markDoneFinal(int index) {
-    double referenceT = fTs[index].fT;
-    int lesser = index;
-    while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
-        markOneDoneFinal(__FUNCTION__, lesser);
-    }
-    do {
-        markOneDoneFinal(__FUNCTION__, index);
-    } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
-    debugValidate();
-}
-
-void SkOpSegment::markDoneUnary(int index) {
-    double referenceT = fTs[index].fT;
-    int lesser = index;
-    while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
-        markOneDoneUnary(__FUNCTION__, lesser);
-    }
-    do {
-        markOneDoneUnary(__FUNCTION__, index);
-    } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
-    debugValidate();
-}
-
-void SkOpSegment::markOneDone(const char* funName, int tIndex, int winding) {
-    SkOpSpan* span;
-    (void) markOneWinding(funName, tIndex, winding, &span);  // allowed to do nothing
-    if (span->fDone) {
-        return;
-    }
-    span->fDone = true;
-    ++fDoneSpans;
-}
-
-void SkOpSegment::markOneDoneFinal(const char* funName, int tIndex) {
-    SkOpSpan* span = &fTs[tIndex];
-    if (span->fDone) {
-        return;
-    }
-    span->fDone = true;
-    ++fDoneSpans;
-}
-
-void SkOpSegment::markOneDoneBinary(const char* funName, int tIndex) {
-    SkOpSpan* span = verifyOneWinding(funName, tIndex);
-    if (!span) {
-        return;
-    }
-    SkASSERT(!span->fDone);
-    span->fDone = true;
-    ++fDoneSpans;
-}
-
-void SkOpSegment::markOneDoneUnary(const char* funName, int tIndex) {
-    SkOpSpan* span = verifyOneWindingU(funName, tIndex);
-    if (!span) {
-        return;
-    }
-    if (span->fWindSum == SK_MinS32) {
-        SkDebugf("%s uncomputed\n", __FUNCTION__);
-    }
-    SkASSERT(!span->fDone);
-    span->fDone = true;
-    ++fDoneSpans;
-}
-
-bool SkOpSegment::markOneWinding(const char* funName, int tIndex, int winding, SkOpSpan** lastPtr) {
-    SkOpSpan* span = &fTs[tIndex];
-    if (lastPtr) {
-        *lastPtr = span;
-    }
-    if (span->fDone && !span->fSmall) {
+    if (span->done()) {
         return false;
     }
 #if DEBUG_MARK_DONE
-    debugShowNewWinding(funName, *span, winding);
+    debugShowNewWinding(__FUNCTION__, span, winding);
 #endif
-    SkASSERT(span->fWindSum == SK_MinS32 || span->fWindSum == winding);
-#if DEBUG_LIMIT_WIND_SUM
-    SkASSERT(abs(winding) <= DEBUG_LIMIT_WIND_SUM);
-#endif
-    span->fWindSum = winding;
+    span->setWindSum(winding);
+    debugValidate();
     return true;
 }
 
-bool SkOpSegment::markOneWinding(const char* funName, int tIndex, int winding,
-        int oppWinding, SkOpSpan** lastPtr) {
-    SkOpSpan* span = &fTs[tIndex];
-    if (span->fDone && !span->fSmall) {
-        return false;
-    }
-#if DEBUG_MARK_DONE
-    debugShowNewWinding(funName, *span, winding, oppWinding);
-#endif
-    SkASSERT(span->fWindSum == SK_MinS32 || span->fWindSum == winding);
-#if DEBUG_LIMIT_WIND_SUM
-    SkASSERT(abs(winding) <= DEBUG_LIMIT_WIND_SUM);
-#endif
-    span->fWindSum = winding;
-    SkASSERT(span->fOppSum == SK_MinS32 || span->fOppSum == oppWinding);
-#if DEBUG_LIMIT_WIND_SUM
-    SkASSERT(abs(oppWinding) <= DEBUG_LIMIT_WIND_SUM);
-#endif
-    span->fOppSum = oppWinding;
-    debugValidate();
-    if (lastPtr) {
-        *lastPtr = span;
-    }
-    return true;
-}
-
-// from http://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order
-bool SkOpSegment::clockwise(int tStart, int tEnd, bool* swap) const {
-    SkASSERT(fVerb != SkPath::kLine_Verb);
-    SkPoint edge[4];
-    subDivide(tStart, tEnd, edge);
-    int points = SkPathOpsVerbToPoints(fVerb);
-    double sum = (edge[0].fX - edge[points].fX) * (edge[0].fY + edge[points].fY);
-    bool sumSet = false;
-    if (fVerb == SkPath::kCubic_Verb) {
-        SkDCubic cubic;
-        cubic.set(edge);
-        double inflectionTs[2];
-        int inflections = cubic.findInflections(inflectionTs);
-        // FIXME: this fixes cubicOp114 and breaks cubicOp58d
-        // the trouble is that cubics with inflections confuse whether the curve breaks towards
-        // or away, which in turn is used to determine if it is on the far right or left.
-        // Probably a totally different approach is in order. At one time I tried to project a
-        // horizontal ray to determine winding, but was confused by how to map the vertically
-        // oriented winding computation over. 
-        if (0 && inflections) {
-            double tLo = this->span(tStart).fT;
-            double tHi = this->span(tEnd).fT;
-            double tLoStart = tLo;
-            for (int index = 0; index < inflections; ++index) {
-                if (between(tLo, inflectionTs[index], tHi)) {
-                    tLo = inflectionTs[index];
-                }
-            }
-            if (tLo != tLoStart && tLo != tHi) {
-                SkDPoint sub[2];
-                sub[0] = cubic.ptAtT(tLo);
-                sub[1].set(edge[3]);
-                SkDPoint ctrl[2];
-                SkDCubic::SubDivide(fPts, sub[0], sub[1], tLo, tHi, ctrl);
-                edge[0] = sub[0].asSkPoint();
-                edge[1] = ctrl[0].asSkPoint();
-                edge[2] = ctrl[1].asSkPoint();
-                sum = (edge[0].fX - edge[3].fX) * (edge[0].fY + edge[3].fY);
-            }
-        }
-        SkScalar lesser = SkTMin<SkScalar>(edge[0].fY, edge[3].fY);
-        if (edge[1].fY < lesser && edge[2].fY < lesser) {
-            SkDLine tangent1 = {{ {edge[0].fX, edge[0].fY}, {edge[1].fX, edge[1].fY} }};
-            SkDLine tangent2 = {{ {edge[2].fX, edge[2].fY}, {edge[3].fX, edge[3].fY} }};
-            if (SkIntersections::Test(tangent1, tangent2)) {
-                SkPoint topPt = cubic_top(fPts, fTs[tStart].fT, fTs[tEnd].fT);
-                sum += (topPt.fX - edge[0].fX) * (topPt.fY + edge[0].fY);
-                sum += (edge[3].fX - topPt.fX) * (edge[3].fY + topPt.fY);
-                sumSet = true;
-            }
-        }
-    }
-    if (!sumSet) {
-        for (int idx = 0; idx < points; ++idx){
-            sum += (edge[idx + 1].fX - edge[idx].fX) * (edge[idx + 1].fY + edge[idx].fY);
-        }
-    }
-    if (fVerb == SkPath::kCubic_Verb) {
-        SkDCubic cubic;
-        cubic.set(edge);
-         *swap = sum > 0 && !cubic.monotonicInY() && !cubic.serpentine();
-    } else {
-        SkDQuad quad;
-        quad.set(edge);
-        *swap = sum > 0 && !quad.monotonicInY();
-    }
-    return sum <= 0;
-}
-
-bool SkOpSegment::monotonicInY(int tStart, int tEnd) const {
-    SkASSERT(fVerb != SkPath::kLine_Verb);
-    if (fVerb == SkPath::kQuad_Verb) {
-        SkDQuad dst = SkDQuad::SubDivide(fPts, fTs[tStart].fT, fTs[tEnd].fT);
-        return dst.monotonicInY();
-    }
-    SkASSERT(fVerb == SkPath::kCubic_Verb);
-    SkDCubic dst = SkDCubic::SubDivide(fPts, fTs[tStart].fT, fTs[tEnd].fT);
-    return dst.monotonicInY();
-}
-
-bool SkOpSegment::serpentine(int tStart, int tEnd) const {
-    if (fVerb != SkPath::kCubic_Verb) {
-        return false;
-    }
-    SkDCubic dst = SkDCubic::SubDivide(fPts, fTs[tStart].fT, fTs[tEnd].fT);
-    return dst.serpentine();
-}
-
-SkOpSpan* SkOpSegment::verifyOneWinding(const char* funName, int tIndex) {
-    SkOpSpan& span = fTs[tIndex];
-    if (span.fDone) {
-        return NULL;
-    }
-#if DEBUG_MARK_DONE
-    debugShowNewWinding(funName, span, span.fWindSum, span.fOppSum);
-#endif
-// If the prior angle in the sort is unorderable, the winding sum may not be computable.
-// To enable the assert, the 'prior is unorderable' state could be
-// piped down to this test, but not sure it's worth it.
-// (Once the sort order is stored in the span, this test may be feasible.)
-//    SkASSERT(span.fWindSum != SK_MinS32);
-//    SkASSERT(span.fOppSum != SK_MinS32);
-    return &span;
-}
-
-SkOpSpan* SkOpSegment::verifyOneWindingU(const char* funName, int tIndex) {
-    SkOpSpan& span = fTs[tIndex];
-    if (span.fDone) {
-        return NULL;
-    }
-#if DEBUG_MARK_DONE
-    debugShowNewWinding(funName, span, span.fWindSum);
-#endif
-// If the prior angle in the sort is unorderable, the winding sum may not be computable.
-// To enable the assert, the 'prior is unorderable' state could be
-// piped down to this test, but not sure it's worth it.
-// (Once the sort order is stored in the span, this test may be feasible.)
-//    SkASSERT(span.fWindSum != SK_MinS32);
-    return &span;
-}
-
-bool SkOpSegment::markWinding(int index, int winding) {
-//    SkASSERT(!done());
-    SkASSERT(winding);
-    double referenceT = fTs[index].fT;
-    int lesser = index;
-    bool success = false;
-    while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
-        success |= markOneWinding(__FUNCTION__, lesser, winding, NULL);
-    }
-    do {
-        success |= markOneWinding(__FUNCTION__, index, winding, NULL);
-   } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
-    debugValidate();
-    return success;
-}
-
-bool SkOpSegment::markWinding(int index, int winding, int oppWinding) {
-//    SkASSERT(!done());
+bool SkOpSegment::markWinding(SkOpSpan* span, int winding, int oppWinding) {
+    SkASSERT(this == span->segment());
     SkASSERT(winding || oppWinding);
-    double referenceT = fTs[index].fT;
-    int lesser = index;
-    bool success = false;
-    while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
-        success |= markOneWinding(__FUNCTION__, lesser, winding, oppWinding, NULL);
+    if (span->done()) {
+        return false;
     }
-    do {
-        success |= markOneWinding(__FUNCTION__, index, winding, oppWinding, NULL);
-   } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
+#if DEBUG_MARK_DONE
+    debugShowNewWinding(__FUNCTION__, span, winding, oppWinding);
+#endif
+    span->setWindSum(winding);
+    span->setOppSum(oppWinding);
     debugValidate();
-    return success;
-}
-
-void SkOpSegment::matchWindingValue(int tIndex, double t, bool borrowWind) {
-    int nextDoorWind = SK_MaxS32;
-    int nextOppWind = SK_MaxS32;
-    // prefer exact matches
-    if (tIndex > 0) {
-        const SkOpSpan& below = fTs[tIndex - 1];
-        if (below.fT == t) {
-            nextDoorWind = below.fWindValue;
-            nextOppWind = below.fOppValue;
-        }
-    }
-    if (nextDoorWind == SK_MaxS32 && tIndex + 1 < fTs.count()) {
-        const SkOpSpan& above = fTs[tIndex + 1];
-        if (above.fT == t) {
-            nextDoorWind = above.fWindValue;
-            nextOppWind = above.fOppValue;
-        }
-    }
-    if (nextDoorWind == SK_MaxS32 && tIndex > 0) {
-        const SkOpSpan& below = fTs[tIndex - 1];
-        if (approximately_negative(t - below.fT)) {
-            nextDoorWind = below.fWindValue;
-            nextOppWind = below.fOppValue;
-        }
-    }
-    if (nextDoorWind == SK_MaxS32 && tIndex + 1 < fTs.count()) {
-        const SkOpSpan& above = fTs[tIndex + 1];
-        if (approximately_negative(above.fT - t)) {
-            nextDoorWind = above.fWindValue;
-            nextOppWind = above.fOppValue;
-        }
-    }
-    if (nextDoorWind == SK_MaxS32 && borrowWind && tIndex > 0 && t < 1) {
-        const SkOpSpan& below = fTs[tIndex - 1];
-        nextDoorWind = below.fWindValue;
-        nextOppWind = below.fOppValue;
-    }
-    if (nextDoorWind != SK_MaxS32) {
-        SkOpSpan& newSpan = fTs[tIndex];
-        newSpan.fWindValue = nextDoorWind;
-        newSpan.fOppValue = nextOppWind;
-        if (!nextDoorWind && !nextOppWind && !newSpan.fDone) {
-            newSpan.fDone = true;
-            ++fDoneSpans;
-        }
-    }
-}
-
-bool SkOpSegment::nextCandidate(int* start, int* end) const {
-    while (fTs[*end].fDone) {
-        if (fTs[*end].fT == 1) {
-            return false;
-        }
-        ++(*end);
-    }
-    *start = *end;
-    *end = nextExactSpan(*start, 1);
     return true;
 }
 
-static SkOpSegment* set_last(SkOpSpan** last, const SkOpSpan* endSpan) {
-    if (last && !endSpan->fSmall) {
-        *last = const_cast<SkOpSpan*>(endSpan);  // FIXME: get rid of cast
+bool SkOpSegment::match(const SkOpPtT* base, const SkOpSegment* testParent, double testT,
+        const SkPoint& testPt) const {
+    const SkOpSegment* baseParent = base->segment();
+    if (this == baseParent && this == testParent && precisely_equal(base->fT, testT)) {
+        return true;
+    }
+    if (!SkDPoint::ApproximatelyEqual(testPt, base->fPt)) {
+        return false;
+    }
+    return !ptsDisjoint(base->fT, base->fPt, testT, testPt);
+}
+
+static SkOpSegment* set_last(SkOpSpanBase** last, SkOpSpanBase* endSpan) {
+    if (last) {
+        *last = endSpan;
     }
     return NULL;
 }
 
-SkOpSegment* SkOpSegment::nextChase(int* indexPtr, int* stepPtr, int* minPtr,
-        SkOpSpan** last) const {
-    int origIndex = *indexPtr;
+bool SkOpSegment::monotonicInY(const SkOpSpanBase* start, const SkOpSpanBase* end) const {
+    SkASSERT(fVerb != SkPath::kLine_Verb);
+    if (fVerb == SkPath::kQuad_Verb) {
+        SkDQuad dst = SkDQuad::SubDivide(fPts, start->t(), end->t());
+        return dst.monotonicInY();
+    }
+    SkASSERT(fVerb == SkPath::kCubic_Verb);
+    SkDCubic dst = SkDCubic::SubDivide(fPts, start->t(), end->t());
+    return dst.monotonicInY();
+}
+
+bool SkOpSegment::NextCandidate(SkOpSpanBase* span, SkOpSpanBase** start,
+        SkOpSpanBase** end) {
+    while (span->final() || span->upCast()->done()) {
+        if (span->final()) {
+            return false;
+        }
+        span = span->upCast()->next();
+    }
+    *start = span;
+    *end = span->upCast()->next();
+    return true;
+}
+
+SkOpSegment* SkOpSegment::nextChase(SkOpSpanBase** startPtr, int* stepPtr, SkOpSpan** minPtr,
+        SkOpSpanBase** last) const {
+    SkOpSpanBase* origStart = *startPtr;
     int step = *stepPtr;
-    int end = nextExactSpan(origIndex, step);
-    SkASSERT(end >= 0);
-    const SkOpSpan& endSpan = this->span(end);
-    SkOpAngle* angle = step > 0 ? endSpan.fFromAngle : endSpan.fToAngle;
-    int foundIndex;
-    int otherEnd;
+    SkOpSpanBase* endSpan = step > 0 ? origStart->upCast()->next() : origStart->prev();
+    SkASSERT(endSpan);
+    SkOpAngle* angle = step > 0 ? endSpan->fromAngle() : endSpan->upCast()->toAngle();
+    SkOpSpanBase* foundSpan;
+    SkOpSpanBase* otherEnd;
     SkOpSegment* other;
     if (angle == NULL) {
-        if (endSpan.fT != 0 && endSpan.fT != 1) {
+        if (endSpan->t() != 0 && endSpan->t() != 1) {
             return NULL;
         }
-        other = endSpan.fOther;
-        foundIndex = endSpan.fOtherIndex;
-        otherEnd = other->nextExactSpan(foundIndex, step);
+        SkOpPtT* otherPtT = endSpan->ptT()->next();
+        other = otherPtT->segment();
+        foundSpan = otherPtT->span();
+        otherEnd = step > 0 ? foundSpan->upCast()->next() : foundSpan->prev();
     } else {
         int loopCount = angle->loopCount();
         if (loopCount > 2) {
-            return set_last(last, &endSpan);
+            return set_last(last, endSpan);
         }
         const SkOpAngle* next = angle->next();
         if (NULL == next) {
             return NULL;
         }
-        if (angle->sign() != next->sign()) {
 #if DEBUG_WINDING
+        if (angle->sign() != next->sign() && !angle->segment()->contour()->isXor()
+                && !next->segment()->contour()->isXor()) {
             SkDebugf("%s mismatched signs\n", __FUNCTION__);
-#endif
-        //    return set_last(last, &endSpan);
         }
+#endif
         other = next->segment();
-        foundIndex = end = next->start();
+        foundSpan = endSpan = next->start();
         otherEnd = next->end();
     }
-    int foundStep = foundIndex < otherEnd ? 1 : -1;
+    int foundStep = foundSpan->step(otherEnd);
     if (*stepPtr != foundStep) {
-        return set_last(last, &endSpan);
+        return set_last(last, endSpan);
     }
-    SkASSERT(*indexPtr >= 0);
-    if (otherEnd < 0) {
+    SkASSERT(*startPtr);
+    if (!otherEnd) {
         return NULL;
     }
 //    SkASSERT(otherEnd >= 0);
-#if 1
-    int origMin = origIndex + (step < 0 ? step : 0);
-    const SkOpSpan& orig = this->span(origMin);
-#endif
-    int foundMin = SkMin32(foundIndex, otherEnd);
-#if 1
-    const SkOpSpan& found = other->span(foundMin);
-    if (found.fWindValue != orig.fWindValue || found.fOppValue != orig.fOppValue) {
-          return set_last(last, &endSpan);
+    SkOpSpan* origMin = step < 0 ? origStart->prev() : origStart->upCast();
+    SkOpSpan* foundMin = foundSpan->starter(otherEnd);
+    if (foundMin->windValue() != origMin->windValue()
+            || foundMin->oppValue() != origMin->oppValue()) {
+          return set_last(last, endSpan);
     }
-#endif
-    *indexPtr = foundIndex;
+    *startPtr = foundSpan;
     *stepPtr = foundStep;
     if (minPtr) {
         *minPtr = foundMin;
@@ -4378,101 +1531,217 @@
     return other;
 }
 
-// This has callers for two different situations: one establishes the end
-// of the current span, and one establishes the beginning of the next span
-// (thus the name). When this is looking for the end of the current span,
-// coincidence is found when the beginning Ts contain -step and the end
-// contains step. When it is looking for the beginning of the next, the
-// first Ts found can be ignored and the last Ts should contain -step.
-// OPTIMIZATION: probably should split into two functions
-int SkOpSegment::nextSpan(int from, int step) const {
-    const SkOpSpan& fromSpan = fTs[from];
-    int count = fTs.count();
-    int to = from;
-    while (step > 0 ? ++to < count : --to >= 0) {
-        const SkOpSpan& span = fTs[to];
-        if (approximately_zero(span.fT - fromSpan.fT)) {
-            continue;
+static void clear_visited(SkOpSpan* span) {
+    // reset visited flag back to false
+    do {
+        SkOpPtT* ptT = span->ptT(), * stopPtT = ptT;
+        while ((ptT = ptT->next()) != stopPtT) {
+            SkOpSegment* opp = ptT->segment();
+            opp->resetVisited();
         }
-        return to;
-    }
-    return -1;
+    } while ((span = span->next()->upCastable()));
 }
 
-// FIXME
-// this returns at any difference in T, vs. a preset minimum. It may be
-// that all callers to nextSpan should use this instead.
-int SkOpSegment::nextExactSpan(int from, int step) const {
-    int to = from;
-    if (step < 0) {
-        const SkOpSpan& fromSpan = fTs[from];
-        while (--to >= 0) {
-            const SkOpSpan& span = fTs[to];
-            if (precisely_negative(fromSpan.fT - span.fT) || span.fTiny) {
+// look for pairs of undetected coincident curves
+// assumes that segments going in have visited flag clear
+// curve/curve intersection should now do a pretty good job of finding coincident runs so 
+// this may be only be necessary for line/curve pairs -- so skip unless this is a line and the
+// the opp is not a line
+void SkOpSegment::missingCoincidence(SkOpCoincidence* coincidences, SkChunkAlloc* allocator) {
+    if (this->verb() != SkPath::kLine_Verb) {
+        return;
+    }
+    SkOpSpan* prior = NULL;
+    SkOpSpan* span = &fHead;
+    do {
+        SkOpPtT* ptT = span->ptT(), * spanStopPtT = ptT;
+        SkASSERT(ptT->span() == span);
+        while ((ptT = ptT->next()) != spanStopPtT) {
+            SkOpSegment* opp = ptT->span()->segment();
+            if (opp->setVisited()) {
                 continue;
             }
-            return to;
-        }
-    } else {
-        while (fTs[from].fTiny) {
-            from++;
-        }
-        const SkOpSpan& fromSpan = fTs[from];
-        int count = fTs.count();
-        while (++to < count) {
-            const SkOpSpan& span = fTs[to];
-            if (precisely_negative(span.fT - fromSpan.fT)) {
+            if (opp->verb() == SkPath::kLine_Verb) {
                 continue;
             }
-            return to;
-        }
-    }
-    return -1;
-}
-
-void SkOpSegment::pinT(const SkPoint& pt, double* t) {
-    if (pt == fPts[0]) {
-        *t = 0;
-    }
-    int count = SkPathOpsVerbToPoints(fVerb);
-    if (pt == fPts[count]) {
-        *t = 1;
-    }
-}
-
-bool SkOpSegment::reversePoints(const SkPoint& p1, const SkPoint& p2) const {
-    SkASSERT(p1 != p2);
-    int spanCount = count();
-    int p1IndexMin = -1;
-    int p2IndexMax = spanCount;
-    for (int index = 0; index < spanCount; ++index) {
-        const SkOpSpan& span = fTs[index];
-        if (span.fPt == p1) {
-            if (p1IndexMin < 0) {
-                p1IndexMin = index;
+            if (span->containsCoincidence(opp)) { // FIXME: this assumes that if the opposite
+                                                  // segment is coincident then no more coincidence
+                                                  // needs to be detected. This may not be true. 
+                continue;
             }
-        } else if (span.fPt == p2) {
-            p2IndexMax = index;
+            if (span->containsCoinEnd(opp)) {
+                continue;
+            } 
+            // if already visited and visited again, check for coin
+            if (span == &fHead) {
+                continue;
+            }
+            SkOpPtT* priorPtT = NULL, * priorStopPtT;
+            // find prior span containing opp segment
+            SkOpSegment* priorOpp = NULL;
+            prior = span;
+            while (!priorOpp && (prior = prior->prev())) {
+                priorStopPtT = priorPtT = prior->ptT();
+                while ((priorPtT = priorPtT->next()) != priorStopPtT) {
+                    SkOpSegment* segment = priorPtT->span()->segment();
+                    if (segment == opp) {
+                        priorOpp = opp;
+                        break;
+                    }
+                }
+            }
+            if (!priorOpp) {
+                continue;
+            }
+            SkOpPtT* oppStart = prior->ptT();
+            SkOpPtT* oppEnd = span->ptT();
+            bool swapped = priorPtT->fT > ptT->fT;
+            if (swapped) {
+                SkTSwap(priorPtT, ptT);
+                SkTSwap(oppStart, oppEnd);
+            }
+            bool flipped = oppStart->fT > oppEnd->fT;
+            bool coincident;
+            if (coincidences->contains(priorPtT, ptT, oppStart, oppEnd, flipped)) {
+                goto swapBack;
+            }
+            {
+                // average t, find mid pt
+                double midT = (prior->t() + span->t()) / 2;
+                SkPoint midPt = this->ptAtT(midT);
+                coincident = true;
+                // if the mid pt is not near either end pt, project perpendicular through opp seg
+                if (!SkDPoint::ApproximatelyEqual(priorPtT->fPt, midPt)
+                        && !SkDPoint::ApproximatelyEqual(ptT->fPt, midPt)) {
+                    coincident = false;
+                    SkIntersections i;
+                    int ptCount = SkPathOpsVerbToPoints(this->verb());
+                    SkVector dxdy = (*CurveSlopeAtT[ptCount])(pts(), midT);
+                    SkDLine ray = {{{midPt.fX, midPt.fY},
+                            {midPt.fX + dxdy.fY, midPt.fY - dxdy.fX}}};
+                    int oppPtCount = SkPathOpsVerbToPoints(opp->verb());
+                    (*CurveIntersectRay[oppPtCount])(opp->pts(), ray, &i);
+                    // measure distance and see if it's small enough to denote coincidence
+                    for (int index = 0; index < i.used(); ++index) {
+                        SkDPoint oppPt = i.pt(index);
+                        if (oppPt.approximatelyEqual(midPt)) {
+                            SkVector oppDxdy = (*CurveSlopeAtT[oppPtCount])(opp->pts(),
+                                    i[index][0]);
+                            oppDxdy.normalize();
+                            dxdy.normalize();
+                            SkScalar flatness = SkScalarAbs(dxdy.cross(oppDxdy) / FLT_EPSILON);
+                            coincident |= flatness < 5000;  // FIXME: replace with tuned value
+                        }
+                    }
+                }
+            }
+            if (coincident) {
+            // mark coincidence
+                coincidences->add(priorPtT, ptT, oppStart, oppEnd, allocator);
+                clear_visited(&fHead);
+                missingCoincidence(coincidences, allocator);
+                return;
+            }
+    swapBack:
+            if (swapped) {
+                SkTSwap(priorPtT, ptT);
+            }
         }
-    }
-    return p1IndexMin > p2IndexMax;
+    } while ((span = span->next()->upCastable()));
+    clear_visited(&fHead);
 }
 
-void SkOpSegment::setCoincidentRange(const SkPoint& startPt, const SkPoint& endPt, 
-        SkOpSegment* other) {
-    int count = this->count();
-    for (int index = 0; index < count; ++index) {
-        SkOpSpan &span = fTs[index];
-        if ((startPt == span.fPt || endPt == span.fPt) && other == span.fOther) {
-            span.fCoincident = true;
+// Move nearby t values and pts so they all hang off the same span. Alignment happens later.
+bool SkOpSegment::moveNearby() {
+    debugValidate();
+    SkOpSpanBase* spanS = &fHead;
+    do {
+        SkOpSpanBase* test = spanS->upCast()->next();
+        SkOpSpanBase* next;
+        if (spanS->contains(test)) {
+            if (!test->final()) {
+                test->upCast()->detach(spanS->ptT());
+                continue;
+            } else if (spanS != &fHead) {
+                spanS->upCast()->detach(test->ptT());
+                spanS = test;
+                continue;
+            }
         }
-    }
+        do {  // iterate through all spans associated with start
+            SkOpPtT* startBase = spanS->ptT();
+            next = test->final() ? NULL : test->upCast()->next();
+            do {
+                SkOpPtT* testBase = test->ptT();
+                do {
+                    if (startBase == testBase) {
+                        goto checkNextSpan;
+                    }
+                    if (testBase->duplicate()) {
+                        continue;
+                    }
+                    if (this->match(startBase, testBase->segment(), testBase->fT, testBase->fPt)) {
+                        if (test == &this->fTail) {
+                            if (spanS == &fHead) {
+                                debugValidate();
+                                return true;  // if this span has collapsed, remove it from parent
+                            }
+                            this->fTail.merge(spanS->upCast());
+                            debugValidate();
+                            return true;
+                        }
+                        spanS->merge(test->upCast());
+                        spanS->upCast()->setNext(next);
+                        goto checkNextSpan;
+                    }
+                } while ((testBase = testBase->next()) != test->ptT());
+            } while ((startBase = startBase->next()) != spanS->ptT());
+    checkNextSpan:
+            ;
+        } while ((test = next));
+        spanS = spanS->upCast()->next();
+    } while (!spanS->final());
+    debugValidate();
+    return true;
 }
 
-void SkOpSegment::setUpWindings(int index, int endIndex, int* sumMiWinding, int* sumSuWinding,
-        int* maxWinding, int* sumWinding, int* oppMaxWinding, int* oppSumWinding) {
-    int deltaSum = spanSign(index, endIndex);
-    int oppDeltaSum = oppSign(index, endIndex);
+bool SkOpSegment::operand() const {
+    return fContour->operand();
+}
+
+bool SkOpSegment::oppXor() const {
+    return fContour->oppXor();
+}
+
+bool SkOpSegment::ptsDisjoint(double t1, const SkPoint& pt1, double t2, const SkPoint& pt2) const {
+    if (fVerb == SkPath::kLine_Verb) {
+        return false;
+    }
+    // quads (and cubics) can loop back to nearly a line so that an opposite curve
+    // hits in two places with very different t values.
+    // OPTIMIZATION: curves could be preflighted so that, for example, something like
+    // 'controls contained by ends' could avoid this check for common curves
+    // 'ends are extremes in x or y' is cheaper to compute and real-world common
+    // on the other hand, the below check is relatively inexpensive
+    double midT = (t1 + t2) / 2;
+    SkPoint midPt = this->ptAtT(midT);
+    double seDistSq = SkTMax(pt1.distanceToSqd(pt2) * 2, FLT_EPSILON * 2);
+    return midPt.distanceToSqd(pt1) > seDistSq || midPt.distanceToSqd(pt2) > seDistSq;
+}
+
+void SkOpSegment::setUpWindings(SkOpSpanBase* start, SkOpSpanBase* end, int* sumMiWinding,
+        int* maxWinding, int* sumWinding) {
+    int deltaSum = SpanSign(start, end);
+    *maxWinding = *sumMiWinding;
+    *sumWinding = *sumMiWinding -= deltaSum;
+    SkASSERT(!DEBUG_LIMIT_WIND_SUM || abs(*sumWinding) <= DEBUG_LIMIT_WIND_SUM);
+}
+
+void SkOpSegment::setUpWindings(SkOpSpanBase* start, SkOpSpanBase* end, int* sumMiWinding,
+        int* sumSuWinding, int* maxWinding, int* sumWinding, int* oppMaxWinding,
+        int* oppSumWinding) {
+    int deltaSum = SpanSign(start, end);
+    int oppDeltaSum = OppSign(start, end);
     if (operand()) {
         *maxWinding = *sumSuWinding;
         *sumWinding = *sumSuWinding -= deltaSum;
@@ -4484,130 +1753,94 @@
         *oppMaxWinding = *sumSuWinding;
         *oppSumWinding = *sumSuWinding -= oppDeltaSum;
     }
-#if DEBUG_LIMIT_WIND_SUM
-    SkASSERT(abs(*sumWinding) <= DEBUG_LIMIT_WIND_SUM);
-    SkASSERT(abs(*oppSumWinding) <= DEBUG_LIMIT_WIND_SUM);
-#endif
-}
-
-void SkOpSegment::setUpWindings(int index, int endIndex, int* sumMiWinding,
-        int* maxWinding, int* sumWinding) {
-    int deltaSum = spanSign(index, endIndex);
-    *maxWinding = *sumMiWinding;
-    *sumWinding = *sumMiWinding -= deltaSum;
-#if DEBUG_LIMIT_WIND_SUM
-    SkASSERT(abs(*sumWinding) <= DEBUG_LIMIT_WIND_SUM);
-#endif
+    SkASSERT(!DEBUG_LIMIT_WIND_SUM || abs(*sumWinding) <= DEBUG_LIMIT_WIND_SUM);
+    SkASSERT(!DEBUG_LIMIT_WIND_SUM || abs(*oppSumWinding) <= DEBUG_LIMIT_WIND_SUM);
 }
 
 void SkOpSegment::sortAngles() {
-    int spanCount = fTs.count();
-    if (spanCount <= 2) {
-        return;
-    }
-    int index = 0;
+    SkOpSpanBase* span = &this->fHead;
     do {
-        SkOpAngle* fromAngle = fTs[index].fFromAngle;
-        SkOpAngle* toAngle = fTs[index].fToAngle;
+        SkOpAngle* fromAngle = span->fromAngle();
+        SkOpAngle* toAngle = span->final() ? NULL : span->upCast()->toAngle();
         if (!fromAngle && !toAngle) {
-            index += 1;
             continue;
         }
-        SkOpAngle* baseAngle = NULL;
-        if (fromAngle) {
-            baseAngle = fromAngle;
-            if (inLoop(baseAngle, spanCount, &index)) {
-                continue;
-            }
-        }
 #if DEBUG_ANGLE
         bool wroteAfterHeader = false;
 #endif
-        if (toAngle) {
-            if (!baseAngle) {
-                baseAngle = toAngle;
-                if (inLoop(baseAngle, spanCount, &index)) {
-                    continue;
-                }
-            } else {
-                SkDEBUGCODE(int newIndex = index);
-                SkASSERT(!inLoop(baseAngle, spanCount, &newIndex) && newIndex == index);
+        SkOpAngle* baseAngle = fromAngle;
+        if (fromAngle && toAngle) {
 #if DEBUG_ANGLE
-                SkDebugf("%s [%d] tStart=%1.9g [%d]\n", __FUNCTION__, debugID(), fTs[index].fT,
-                        index);
-                wroteAfterHeader = true;
+            SkDebugf("%s [%d] tStart=%1.9g [%d]\n", __FUNCTION__, debugID(), span->t(),
+                    span->debugID());
+            wroteAfterHeader = true;
 #endif
-                baseAngle->insert(toAngle);
-            }
+            fromAngle->insert(toAngle);
+        } else if (!fromAngle) {
+            baseAngle = toAngle;
         }
-        SkOpAngle* nextFrom, * nextTo;
-        int firstIndex = index;
+        SkOpPtT* ptT = span->ptT(), * stopPtT = ptT;
         do {
-            SkOpSpan& span = fTs[index];
-            SkOpSegment* other = span.fOther;
-            SkOpSpan& oSpan = other->fTs[span.fOtherIndex];
-            SkOpAngle* oAngle = oSpan.fFromAngle;
+            SkOpSpanBase* oSpan = ptT->span();
+            if (oSpan == span) {
+                continue;
+            }
+            SkOpAngle* oAngle = oSpan->fromAngle();
             if (oAngle) {
 #if DEBUG_ANGLE
                 if (!wroteAfterHeader) {
-                    SkDebugf("%s [%d] tStart=%1.9g [%d]\n", __FUNCTION__, debugID(), fTs[index].fT,
-                            index);
+                    SkDebugf("%s [%d] tStart=%1.9g [%d]\n", __FUNCTION__, debugID(),
+                            span->t(), span->debugID());
                     wroteAfterHeader = true;
                 }
 #endif
-                if (!oAngle->loopContains(*baseAngle)) {
+                if (!oAngle->loopContains(baseAngle)) {
                     baseAngle->insert(oAngle);
                 }
             }
-            oAngle = oSpan.fToAngle;
-            if (oAngle) {
+            if (!oSpan->final()) {
+                oAngle = oSpan->upCast()->toAngle();
+                if (oAngle) {
 #if DEBUG_ANGLE
-                if (!wroteAfterHeader) {
-                    SkDebugf("%s [%d] tStart=%1.9g [%d]\n", __FUNCTION__, debugID(), fTs[index].fT,
-                            index);
-                    wroteAfterHeader = true;
-                }
+                    if (!wroteAfterHeader) {
+                        SkDebugf("%s [%d] tStart=%1.9g [%d]\n", __FUNCTION__, debugID(),
+                                span->t(), span->debugID());
+                        wroteAfterHeader = true;
+                    }
 #endif
-                if (!oAngle->loopContains(*baseAngle)) {
-                    baseAngle->insert(oAngle);
+                    if (!oAngle->loopContains(baseAngle)) {
+                        baseAngle->insert(oAngle);
+                    }
                 }
             }
-            if (++index == spanCount) {
-                break;
+        } while ((ptT = ptT->next()) != stopPtT);
+        if (baseAngle->loopCount() == 1) {
+            span->setFromAngle(NULL);
+            if (toAngle) {
+                span->upCast()->setToAngle(NULL);
             }
-            nextFrom = fTs[index].fFromAngle;
-            nextTo = fTs[index].fToAngle;
-        } while (fromAngle == nextFrom && toAngle == nextTo);
-        if (baseAngle && baseAngle->loopCount() == 1) {
-            index = firstIndex;
-            do {
-                SkOpSpan& span = fTs[index];
-                span.fFromAngle = span.fToAngle = NULL;
-                if (++index == spanCount) {
-                    break;
-                }
-                nextFrom = fTs[index].fFromAngle;
-                nextTo = fTs[index].fToAngle;
-            } while (fromAngle == nextFrom && toAngle == nextTo);
             baseAngle = NULL;
         }
 #if DEBUG_SORT
         SkASSERT(!baseAngle || baseAngle->loopCount() > 1);
 #endif
-    } while (index < spanCount);
+    } while (!span->final() && (span = span->upCast()->next()));
 }
 
 // return true if midpoints were computed
-bool SkOpSegment::subDivide(int start, int end, SkPoint edge[4]) const {
+bool SkOpSegment::subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end,
+        SkPoint edge[4]) const {
     SkASSERT(start != end);
-    edge[0] = fTs[start].fPt;
+    const SkOpPtT& startPtT = *start->ptT();
+    const SkOpPtT& endPtT = *end->ptT();
+    edge[0] = startPtT.fPt;
     int points = SkPathOpsVerbToPoints(fVerb);
-    edge[points] = fTs[end].fPt;
+    edge[points] = endPtT.fPt;
     if (fVerb == SkPath::kLine_Verb) {
         return false;
     }
-    double startT = fTs[start].fT;
-    double endT = fTs[end].fT;
+    double startT = startPtT.fT;
+    double endT = endPtT.fT;
     if ((startT == 0 || endT == 0) && (startT == 1 || endT == 1)) {
         // don't compute midpoints if we already have them
         if (fVerb == SkPath::kQuad_Verb) {
@@ -4637,17 +1870,19 @@
     return true;
 }
 
-// return true if midpoints were computed
-bool SkOpSegment::subDivide(int start, int end, SkDCubic* result) const {
+bool SkOpSegment::subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end,
+        SkDCubic* result) const {
     SkASSERT(start != end);
-    (*result)[0].set(fTs[start].fPt);
+    const SkOpPtT& startPtT = *start->ptT();
+    const SkOpPtT& endPtT = *end->ptT();
+    (*result)[0].set(startPtT.fPt);
     int points = SkPathOpsVerbToPoints(fVerb);
-    (*result)[points].set(fTs[end].fPt);
+    (*result)[points].set(endPtT.fPt);
     if (fVerb == SkPath::kLine_Verb) {
         return false;
     }
-    double startT = fTs[start].fT;
-    double endT = fTs[end].fT;
+    double startT = startPtT.fT;
+    double endT = endPtT.fT;
     if ((startT == 0 || endT == 0) && (startT == 1 || endT == 1)) {
         // don't compute midpoints if we already have them
         if (fVerb == SkPath::kQuad_Verb) {
@@ -4655,7 +1890,7 @@
             return false;
         }
         SkASSERT(fVerb == SkPath::kCubic_Verb);
-        if (start < end) {
+        if (startT == 0) {
             (*result)[1].set(fPts[1]);
             (*result)[2].set(fPts[2]);
             return false;
@@ -4673,49 +1908,29 @@
     return true;
 }
 
-void SkOpSegment::subDivideBounds(int start, int end, SkPathOpsBounds* bounds) const {
+void SkOpSegment::subDivideBounds(const SkOpSpanBase* start, const SkOpSpanBase* end,
+        SkPathOpsBounds* bounds) const {
     SkPoint edge[4];
     subDivide(start, end, edge);
     (bounds->*SetCurveBounds[SkPathOpsVerbToPoints(fVerb)])(edge);
 }
 
-void SkOpSegment::TrackOutsidePair(SkTArray<SkPoint, true>* outsidePts, const SkPoint& endPt,
-        const SkPoint& startPt) {
-    int outCount = outsidePts->count();
-    if (outCount == 0 || endPt != (*outsidePts)[outCount - 2]) {
-        outsidePts->push_back(endPt);
-        outsidePts->push_back(startPt);
-    }
-}
-
-void SkOpSegment::TrackOutside(SkTArray<SkPoint, true>* outsidePts, const SkPoint& startPt) {
-    int outCount = outsidePts->count();
-    if (outCount == 0 || startPt != (*outsidePts)[outCount - 1]) {
-        outsidePts->push_back(startPt);
-    }
-}
-
-void SkOpSegment::undoneSpan(int* start, int* end) {
-    int tCount = fTs.count();
-    int index;
-    for (index = 0; index < tCount; ++index) {
-        if (!fTs[index].fDone) {
+void SkOpSegment::undoneSpan(SkOpSpanBase** start, SkOpSpanBase** end) {
+    SkOpSpan* span = this->head();
+    do {
+        if (!span->done()) {
             break;
         }
-    }
-    SkASSERT(index < tCount - 1);
-    *start = index;
-    double startT = fTs[index].fT;
-    while (approximately_negative(fTs[++index].fT - startT))
-        SkASSERT(index < tCount);
-    SkASSERT(index < tCount);
-    *end = index;
+    } while ((span = span->next()->upCastable()));
+    SkASSERT(span);
+    *start = span;
+    *end = span->next();
 }
 
-int SkOpSegment::updateOppWinding(int index, int endIndex) const {
-    int lesser = SkMin32(index, endIndex);
-    int oppWinding = oppSum(lesser);
-    int oppSpanWinding = oppSign(index, endIndex);
+int SkOpSegment::updateOppWinding(const SkOpSpanBase* start, const SkOpSpanBase* end) const {
+    const SkOpSpan* lesser = start->starter(end);
+    int oppWinding = lesser->oppSum();
+    int oppSpanWinding = SkOpSegment::OppSign(start, end);
     if (oppSpanWinding && UseInnerWinding(oppWinding - oppSpanWinding, oppWinding)
             && oppWinding != SK_MaxS32) {
         oppWinding -= oppSpanWinding;
@@ -4724,24 +1939,24 @@
 }
 
 int SkOpSegment::updateOppWinding(const SkOpAngle* angle) const {
-    int startIndex = angle->start();
-    int endIndex = angle->end();
-    return updateOppWinding(endIndex, startIndex);
+    const SkOpSpanBase* startSpan = angle->start();
+    const SkOpSpanBase* endSpan = angle->end();
+    return updateOppWinding(endSpan, startSpan);
 }
 
 int SkOpSegment::updateOppWindingReverse(const SkOpAngle* angle) const {
-    int startIndex = angle->start();
-    int endIndex = angle->end();
-    return updateOppWinding(startIndex, endIndex);
+    const SkOpSpanBase* startSpan = angle->start();
+    const SkOpSpanBase* endSpan = angle->end();
+    return updateOppWinding(startSpan, endSpan);
 }
 
-int SkOpSegment::updateWinding(int index, int endIndex) const {
-    int lesser = SkMin32(index, endIndex);
-    int winding = windSum(lesser);
+int SkOpSegment::updateWinding(const SkOpSpanBase* start, const SkOpSpanBase* end) const {
+    const SkOpSpan* lesser = start->starter(end);
+    int winding = lesser->windSum();
     if (winding == SK_MinS32) {
         return winding;
     }
-    int spanWinding = spanSign(index, endIndex);
+    int spanWinding = SkOpSegment::SpanSign(start, end);
     if (winding && UseInnerWinding(winding - spanWinding, winding)
             && winding != SK_MaxS32) {
         winding -= spanWinding;
@@ -4750,26 +1965,15 @@
 }
 
 int SkOpSegment::updateWinding(const SkOpAngle* angle) const {
-    int startIndex = angle->start();
-    int endIndex = angle->end();
-    return updateWinding(endIndex, startIndex);
-}
-
-int SkOpSegment::updateWindingReverse(int index, int endIndex) const {
-    int lesser = SkMin32(index, endIndex);
-    int winding = windSum(lesser);
-    int spanWinding = spanSign(endIndex, index);
-    if (winding && UseInnerWindingReverse(winding - spanWinding, winding)
-            && winding != SK_MaxS32) {
-        winding -= spanWinding;
-    }
-    return winding;
+    const SkOpSpanBase* startSpan = angle->start();
+    const SkOpSpanBase* endSpan = angle->end();
+    return updateWinding(endSpan, startSpan);
 }
 
 int SkOpSegment::updateWindingReverse(const SkOpAngle* angle) const {
-    int startIndex = angle->start();
-    int endIndex = angle->end();
-    return updateWindingReverse(endIndex, startIndex);
+    const SkOpSpanBase* startSpan = angle->start();
+    const SkOpSpanBase* endSpan = angle->end();
+    return updateWinding(startSpan, endSpan);
 }
 
 // OPTIMIZATION: does the following also work, and is it any faster?
@@ -4784,25 +1988,17 @@
     return result;
 }
 
-bool SkOpSegment::UseInnerWindingReverse(int outerWinding, int innerWinding) {
-    SkASSERT(outerWinding != SK_MaxS32);
-    SkASSERT(innerWinding != SK_MaxS32);
-    int absOut = abs(outerWinding);
-    int absIn = abs(innerWinding);
-    bool result = absOut == absIn ? true : absOut < absIn;
-    return result;
-}
-
-int SkOpSegment::windingAtT(double tHit, int tIndex, bool crossOpp, SkScalar* dx) const {
-    if (approximately_zero(tHit - t(tIndex))) {  // if we hit the end of a span, disregard
+int SkOpSegment::windingAtT(double tHit, const SkOpSpan* span, bool crossOpp,
+        SkScalar* dx) const {
+    if (approximately_zero(tHit - span->t())) {  // if we hit the end of a span, disregard
         return SK_MinS32;
     }
-    int winding = crossOpp ? oppSum(tIndex) : windSum(tIndex);
+    int winding = crossOpp ? span->oppSum() : span->windSum();
     SkASSERT(winding != SK_MinS32);
-    int windVal = crossOpp ? oppValue(tIndex) : windValue(tIndex);
+    int windVal = crossOpp ? span->oppValue() : span->windValue();
 #if DEBUG_WINDING_AT_T
     SkDebugf("%s id=%d opp=%d tHit=%1.9g t=%1.9g oldWinding=%d windValue=%d", __FUNCTION__,
-            debugID(), crossOpp, tHit, t(tIndex), winding, windVal);
+            debugID(), crossOpp, tHit, span->t(), winding, windVal);
 #endif
     // see if a + change in T results in a +/- change in X (compute x'(T))
     *dx = (*CurveSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, tHit).fX;
@@ -4828,20 +2024,6 @@
 }
 
 int SkOpSegment::windSum(const SkOpAngle* angle) const {
-    int start = angle->start();
-    int end = angle->end();
-    int index = SkMin32(start, end);
-    return windSum(index);
-}
-
-void SkOpSegment::zeroSpan(SkOpSpan* span) {
-    SkASSERT(span->fWindValue > 0 || span->fOppValue != 0);
-    span->fWindValue = 0;
-    span->fOppValue = 0;
-    if (span->fTiny || span->fSmall) {
-        return;
-    }
-    SkASSERT(!span->fDone);
-    span->fDone = true;
-    ++fDoneSpans;
+    const SkOpSpan* minSpan = angle->start()->starter(angle->end());
+    return minSpan->windSum();
 }
diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h
index b4da929..c1c6e69 100644
--- a/src/pathops/SkOpSegment.h
+++ b/src/pathops/SkOpSegment.h
@@ -9,160 +9,262 @@
 
 #include "SkOpAngle.h"
 #include "SkOpSpan.h"
+#include "SkOpTAllocator.h"
 #include "SkPathOpsBounds.h"
 #include "SkPathOpsCurve.h"
-#include "SkTArray.h"
-#include "SkTDArray.h"
 
-#if defined(SK_DEBUG) || !FORCE_RELEASE
-#include "SkThread.h"
-#endif
-
-struct SkCoincidence;
+class SkOpCoincidence;
+class SkOpContour;
 class SkPathWriter;
 
 class SkOpSegment {
 public:
-    SkOpSegment() {
-#if defined(SK_DEBUG) || !FORCE_RELEASE
-        fID = sk_atomic_inc(&SkPathOpsDebug::gSegmentID);
-#endif
-    }
+    enum AllowAlias {
+        kAllowAlias,
+        kNoAlias
+    };
 
     bool operator<(const SkOpSegment& rh) const {
         return fBounds.fTop < rh.fBounds.fTop;
     }
 
-    struct AlignedSpan  {
-        double fOldT;
-        double fT;
-        SkPoint fOldPt;
-        SkPoint fPt;
-        const SkOpSegment* fSegment;
-        const SkOpSegment* fOther1;
-        const SkOpSegment* fOther2;
-    };
+    SkOpAngle* activeAngle(SkOpSpanBase* start, SkOpSpanBase** startPtr, SkOpSpanBase** endPtr,
+                            bool* done, bool* sortable);
+    SkOpAngle* activeAngleInner(SkOpSpanBase* start, SkOpSpanBase** startPtr,
+                                       SkOpSpanBase** endPtr, bool* done, bool* sortable);
+    SkOpAngle* activeAngleOther(SkOpSpanBase* start, SkOpSpanBase** startPtr,
+                                       SkOpSpanBase** endPtr, bool* done, bool* sortable);
+    bool activeOp(SkOpSpanBase* start, SkOpSpanBase* end, int xorMiMask, int xorSuMask,
+                  SkPathOp op);
+    bool activeOp(int xorMiMask, int xorSuMask, SkOpSpanBase* start, SkOpSpanBase* end, SkPathOp op,
+                  int* sumMiWinding, int* sumSuWinding);
+
+    SkPoint activeLeftTop(SkOpSpanBase** firstT);
+
+    bool activeWinding(SkOpSpanBase* start, SkOpSpanBase* end);
+    bool activeWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* sumWinding);
+
+    void addCubic(SkPoint pts[4], SkOpContour* parent) {
+        init(pts, parent, SkPath::kCubic_Verb);
+        fBounds.setCubicBounds(pts);
+    }
+
+    void addCurveTo(const SkOpSpanBase* start, const SkOpSpanBase* end, SkPathWriter* path,
+                    bool active) const;
+
+    SkOpAngle* addEndSpan(SkChunkAlloc* allocator) {
+        SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(allocator);
+        angle->set(&fTail, fTail.prev());
+        fTail.setFromAngle(angle);
+        return angle;
+    }
+
+    void addLine(SkPoint pts[2], SkOpContour* parent) {
+        init(pts, parent, SkPath::kLine_Verb);
+        fBounds.set(pts, 2);
+    }
+
+    SkOpPtT* addMissing(double t, SkOpSegment* opp, SkChunkAlloc* );
+    SkOpAngle* addSingletonAngleDown(SkOpSegment** otherPtr, SkOpAngle** , SkChunkAlloc* );
+    SkOpAngle* addSingletonAngles(int step, SkChunkAlloc* );
+    SkOpAngle* addSingletonAngleUp(SkOpSegment** otherPtr, SkOpAngle** , SkChunkAlloc* );
+
+    SkOpAngle* addStartSpan(SkChunkAlloc* allocator) {
+        SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(allocator);
+        angle->set(&fHead, fHead.next());
+        fHead.setToAngle(angle);
+        return angle;
+    }
+
+    void addQuad(SkPoint pts[3], SkOpContour* parent) {
+        init(pts, parent, SkPath::kQuad_Verb);
+        fBounds.setQuadBounds(pts);
+    }
+
+    SkOpPtT* addT(double t, AllowAlias , SkChunkAlloc* );
+
+    void align();
+    static bool BetweenTs(const SkOpSpanBase* lesser, double testT, const SkOpSpanBase* greater);
 
     const SkPathOpsBounds& bounds() const {
         return fBounds;
     }
 
-    // OPTIMIZE
-    // when the edges are initially walked, they don't automatically get the prior and next
-    // edges assigned to positions t=0 and t=1. Doing that would remove the need for this check,
-    // and would additionally remove the need for similar checks in condition edges. It would
-    // also allow intersection code to assume end of segment intersections (maybe?)
-    bool complete() const {
-        int count = fTs.count();
-        return count > 1 && fTs[0].fT == 0 && fTs[--count].fT == 1;
+    void bumpCount() {
+        ++fCount;
+    }
+
+    void calcAngles(SkChunkAlloc*);
+    void checkAngleCoin(SkOpCoincidence* coincidences, SkChunkAlloc* allocator);
+    void checkNearCoincidence(SkOpAngle* );
+    bool clockwise(const SkOpSpanBase* start, const SkOpSpanBase* end, bool* swap) const;
+    static void ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
+                              SkOpAngle::IncludeType );
+    static void ComputeOneSumReverse(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
+                                     SkOpAngle::IncludeType );
+    int computeSum(SkOpSpanBase* start, SkOpSpanBase* end, SkOpAngle::IncludeType includeType);
+
+    SkOpContour* contour() const {
+        return fContour;
     }
 
     int count() const {
-        return fTs.count();
+        return fCount;
     }
 
+    SkOpSpan* crossedSpanY(const SkPoint& basePt, double mid, bool opp, bool current,
+                            SkScalar* bestY, double* hitT, bool* hitSomething, bool* vertical);
+
+    void debugAddAngle(double startT, double endT, SkChunkAlloc*);
+    const SkOpAngle* debugAngle(int id) const;
+    SkOpContour* debugContour(int id);
+
+    int debugID() const {
+        return PATH_OPS_DEBUG_RELEASE(fID, -1);
+    }
+
+#if DEBUG_SWAP_TOP
+    int debugInflections(const SkOpSpanBase* start, const SkOpSpanBase* end) const;
+#endif
+
+    SkOpAngle* debugLastAngle();
+    const SkOpPtT* debugPtT(int id) const;
+    void debugReset();
+    const SkOpSegment* debugSegment(int id) const;
+
+#if DEBUG_ACTIVE_SPANS
+    void debugShowActiveSpans() const;
+#endif
+#if DEBUG_MARK_DONE
+    void debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding);
+    void debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding, int oppWinding);
+#endif
+
+    const SkOpSpanBase* debugSpan(int id) const;
+    void debugValidate() const;
+    void detach(const SkOpSpan* );
+    double distSq(double t, SkOpAngle* opp);
+
     bool done() const {
-        SkASSERT(fDoneSpans <= fTs.count());
-        return fDoneSpans == fTs.count();
-    }
-
-    bool done(int min) const {
-        return fTs[min].fDone;
+        SkASSERT(fDoneCount <= fCount);
+        return fDoneCount == fCount;
     }
 
     bool done(const SkOpAngle* angle) const {
-        return done(SkMin32(angle->start(), angle->end()));
+        return angle->start()->starter(angle->end())->done();
     }
 
     SkDPoint dPtAtT(double mid) const {
         return (*CurveDPointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, mid);
     }
 
-    SkVector dxdy(int index) const {
-        return (*CurveSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, fTs[index].fT);
+    SkDVector dSlopeAtT(double mid) const {
+        return (*CurveDSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, mid);
     }
 
-    SkScalar dy(int index) const {
-        return dxdy(index).fY;
+    void dump() const;
+    void dumpAll() const;
+    void dumpAngles() const;
+    void dumpCoin() const;
+    void dumpPts() const;
+
+    SkOpSegment* findNextOp(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** nextStart,
+                             SkOpSpanBase** nextEnd, bool* unsortable, SkPathOp op,
+                             int xorMiMask, int xorSuMask);
+    SkOpSegment* findNextWinding(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** nextStart,
+                                  SkOpSpanBase** nextEnd, bool* unsortable);
+    SkOpSegment* findNextXor(SkOpSpanBase** nextStart, SkOpSpanBase** nextEnd, bool* unsortable);
+    SkOpSegment* findTop(bool firstPass, SkOpSpanBase** startPtr, SkOpSpanBase** endPtr,
+                          bool* unsortable, SkChunkAlloc* );
+    SkOpGlobalState* globalState() const;
+
+    const SkOpSpan* head() const {
+        return &fHead;
     }
 
-    bool hasMultiples() const {
-        return fMultiples;
+    SkOpSpan* head() {
+        return &fHead;
     }
 
-    bool hasSmall() const {
-        return fSmall;
+    void init(SkPoint pts[], SkOpContour* parent, SkPath::Verb verb);
+    void initWinding(SkOpSpanBase* start, SkOpSpanBase* end,
+                     SkOpAngle::IncludeType angleIncludeType);
+    bool initWinding(SkOpSpanBase* start, SkOpSpanBase* end, double tHit, int winding,
+            SkScalar hitDx, int oppWind, SkScalar hitOppDx);
+
+    SkOpSpan* insert(SkOpSpan* prev, SkChunkAlloc* allocator) {
+        SkOpSpan* result = SkOpTAllocator<SkOpSpan>::Allocate(allocator);
+        SkOpSpanBase* next = prev->next();
+        result->setPrev(prev);
+        prev->setNext(result);
+        SkDEBUGCODE(result->ptT()->fT = 0);
+        result->setNext(next);
+        if (next) {
+            next->setPrev(result);
+        }
+        return result;
     }
 
-    bool hasTiny() const {
-        return fTiny;
-    }
-
-    bool intersected() const {
-        return fTs.count() > 0;
-    }
-
-    bool isCanceled(int tIndex) const {
-        return fTs[tIndex].fWindValue == 0 && fTs[tIndex].fOppValue == 0;
-    }
-
-    bool isConnected(int startIndex, int endIndex) const {
-        return fTs[startIndex].fWindSum != SK_MinS32 || fTs[endIndex].fWindSum != SK_MinS32;
-    }
+    bool isClose(double t, const SkOpSegment* opp) const;
 
     bool isHorizontal() const {
         return fBounds.fTop == fBounds.fBottom;
     }
 
+    SkOpSegment* isSimple(SkOpSpanBase** end, int* step) {
+        return nextChase(end, step, NULL, NULL);
+    }
+
     bool isVertical() const {
         return fBounds.fLeft == fBounds.fRight;
     }
 
-    bool isVertical(int start, int end) const {
-        return (*CurveIsVertical[SkPathOpsVerbToPoints(fVerb)])(fPts, start, end);
+    bool isVertical(SkOpSpanBase* start, SkOpSpanBase* end) const {
+        return (*CurveIsVertical[SkPathOpsVerbToPoints(fVerb)])(fPts, start->t(), end->t());
     }
 
-    bool operand() const {
-        return fOperand;
+    bool isXor() const;
+
+    const SkPoint& lastPt() const {
+        return fPts[SkPathOpsVerbToPoints(fVerb)];
     }
 
-    int oppSign(const SkOpAngle* angle) const {
-        SkASSERT(angle->segment() == this);
-        return oppSign(angle->start(), angle->end());
+    SkOpSpanBase* markAndChaseDone(SkOpSpanBase* start, SkOpSpanBase* end);
+    bool markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding,
+            SkOpSpanBase** lastPtr);
+    bool markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding,
+            int oppWinding, SkOpSpanBase** lastPtr);
+    SkOpSpanBase* markAngle(int maxWinding, int sumWinding, const SkOpAngle* angle);
+    SkOpSpanBase* markAngle(int maxWinding, int sumWinding, int oppMaxWinding, int oppSumWinding,
+                         const SkOpAngle* angle);
+    void markDone(SkOpSpan* );
+    bool markWinding(SkOpSpan* , int winding);
+    bool markWinding(SkOpSpan* , int winding, int oppWinding);
+    bool match(const SkOpPtT* span, const SkOpSegment* parent, double t, const SkPoint& pt) const;
+    void missingCoincidence(SkOpCoincidence* coincidences, SkChunkAlloc* allocator);
+    bool monotonicInY(const SkOpSpanBase* start, const SkOpSpanBase* end) const;
+    bool moveNearby();
+
+    SkOpSegment* next() const {
+        return fNext;
     }
 
-    int oppSign(int startIndex, int endIndex) const {
-        int result = startIndex < endIndex ? -fTs[startIndex].fOppValue : fTs[endIndex].fOppValue;
-#if DEBUG_WIND_BUMP
-        SkDebugf("%s oppSign=%d\n", __FUNCTION__, result);
-#endif
+    static bool NextCandidate(SkOpSpanBase* span, SkOpSpanBase** start, SkOpSpanBase** end);
+    SkOpSegment* nextChase(SkOpSpanBase** , int* step, SkOpSpan** , SkOpSpanBase** last) const;
+    bool operand() const;
+
+    static int OppSign(const SkOpSpanBase* start, const SkOpSpanBase* end) {
+        int result = start->t() < end->t() ? -start->upCast()->oppValue()
+                : end->upCast()->oppValue();
         return result;
     }
 
-    int oppSum(int tIndex) const {
-        return fTs[tIndex].fOppSum;
-    }
+    bool oppXor() const;
 
-    int oppSum(const SkOpAngle* angle) const {
-        int lesser = SkMin32(angle->start(), angle->end());
-        return fTs[lesser].fOppSum;
+    const SkOpSegment* prev() const {
+        return fPrev;
     }
 
-    int oppValue(int tIndex) const {
-        return fTs[tIndex].fOppValue;
-    }
-
-    int oppValue(const SkOpAngle* angle) const {
-        int lesser = SkMin32(angle->start(), angle->end());
-        return fTs[lesser].fOppValue;
-    }
-
-#if DEBUG_VALIDATE
-    bool oppXor() const {
-        return fOppXor;
-    }
-#endif
-
     SkPoint ptAtT(double mid) const {
         return (*CurvePointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, mid);
     }
@@ -171,399 +273,113 @@
         return fPts;
     }
 
-    void reset() {
-        init(NULL, (SkPath::Verb) -1, false, false);
-        fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, SK_ScalarMax);
-        fTs.reset();
+    bool ptsDisjoint(const SkOpPtT& span, const SkOpPtT& test) const {
+        return ptsDisjoint(span.fT, span.fPt, test.fT, test.fPt);
     }
 
-    bool reversePoints(const SkPoint& p1, const SkPoint& p2) const;
-
-    void setOppXor(bool isOppXor) {
-        fOppXor = isOppXor;
+    bool ptsDisjoint(const SkOpPtT& span, double t, const SkPoint& pt) const {
+        return ptsDisjoint(span.fT, span.fPt, t, pt);
     }
 
-    void setUpWinding(int index, int endIndex, int* maxWinding, int* sumWinding) {
-        int deltaSum = spanSign(index, endIndex);
+    bool ptsDisjoint(double t1, const SkPoint& pt1, double t2, const SkPoint& pt2) const;
+
+    void resetVisited() {
+        fVisited = false;
+    }
+
+    void setContour(SkOpContour* contour) {
+        fContour = contour;
+    }
+
+    void setNext(SkOpSegment* next) {
+        fNext = next;
+    }
+
+    void setPrev(SkOpSegment* prev) {
+        fPrev = prev;
+    }
+
+    bool setVisited() {
+        if (fVisited) {
+            return false;
+        }
+        return (fVisited = true);
+    }
+
+    void setUpWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* maxWinding, int* sumWinding) {
+        int deltaSum = SpanSign(start, end);
         *maxWinding = *sumWinding;
         *sumWinding -= deltaSum;
     }
 
-    const SkOpSpan& span(int tIndex) const {
-        return fTs[tIndex];
-    }
+    void setUpWindings(SkOpSpanBase* start, SkOpSpanBase* end, int* sumMiWinding,
+                       int* maxWinding, int* sumWinding);
+    void setUpWindings(SkOpSpanBase* start, SkOpSpanBase* end, int* sumMiWinding, int* sumSuWinding,
+                       int* maxWinding, int* sumWinding, int* oppMaxWinding, int* oppSumWinding);
+    void sortAngles();
 
-    const SkOpAngle* spanToAngle(int tStart, int tEnd) const {
-        SkASSERT(tStart != tEnd);
-        const SkOpSpan& span = fTs[tStart];
-        return tStart < tEnd ? span.fToAngle : span.fFromAngle;
-    }
-
-    // FIXME: create some sort of macro or template that avoids casting
-    SkOpAngle* spanToAngle(int tStart, int tEnd) {
-        const SkOpAngle* cAngle = (const_cast<const SkOpSegment*>(this))->spanToAngle(tStart, tEnd);
-        return const_cast<SkOpAngle*>(cAngle);
-    }
-
-    int spanSign(const SkOpAngle* angle) const {
-        SkASSERT(angle->segment() == this);
-        return spanSign(angle->start(), angle->end());
-    }
-
-    int spanSign(int startIndex, int endIndex) const {
-        int result = startIndex < endIndex ? -fTs[startIndex].fWindValue : fTs[endIndex].fWindValue;
-#if DEBUG_WIND_BUMP
-        SkDebugf("%s spanSign=%d\n", __FUNCTION__, result);
-#endif
+    static int SpanSign(const SkOpSpanBase* start, const SkOpSpanBase* end) {
+        int result = start->t() < end->t() ? -start->upCast()->windValue()
+                : end->upCast()->windValue();
         return result;
     }
 
-    double t(int tIndex) const {
-        return fTs[tIndex].fT;
+    SkOpAngle* spanToAngle(SkOpSpanBase* start, SkOpSpanBase* end) {
+        SkASSERT(start != end);
+        return start->t() < end->t() ? start->upCast()->toAngle() : start->fromAngle();
     }
 
-    double tAtMid(int start, int end, double mid) const {
-        return fTs[start].fT * (1 - mid) + fTs[end].fT * mid;
+    bool subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end, SkPoint edge[4]) const;
+    bool subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end, SkDCubic* result) const;
+    void subDivideBounds(const SkOpSpanBase* start, const SkOpSpanBase* end,
+                         SkPathOpsBounds* bounds) const;
+
+    const SkOpSpanBase* tail() const {
+        return &fTail;
     }
 
-    void updatePts(const SkPoint pts[]) {
-        fPts = pts;
+    SkOpSpanBase* tail() {
+        return &fTail;
     }
 
+    static double TAtMid(const SkOpSpanBase* start, const SkOpSpanBase* end, double mid) {
+        return start->t() * (1 - mid) + end->t() * mid;
+    }
+
+    void undoneSpan(SkOpSpanBase** start, SkOpSpanBase** end);
+    int updateOppWinding(const SkOpSpanBase* start, const SkOpSpanBase* end) const;
+    int updateOppWinding(const SkOpAngle* angle) const;
+    int updateOppWindingReverse(const SkOpAngle* angle) const;
+    int updateWinding(const SkOpSpanBase* start, const SkOpSpanBase* end) const;
+    int updateWinding(const SkOpAngle* angle) const;
+    int updateWindingReverse(const SkOpAngle* angle) const;
+
+    static bool UseInnerWinding(int outerWinding, int innerWinding);
+
     SkPath::Verb verb() const {
         return fVerb;
     }
 
-    int windSum(int tIndex) const {
-        return fTs[tIndex].fWindSum;
-    }
-
-    int windValue(int tIndex) const {
-        return fTs[tIndex].fWindValue;
-    }
-
-#if defined(SK_DEBUG) || DEBUG_WINDING
-    SkScalar xAtT(int index) const {
-        return xAtT(&fTs[index]);
-    }
-#endif
-
-#if DEBUG_VALIDATE
-    bool _xor() const {  // FIXME: used only by SkOpAngle::debugValidateLoop()
-        return fXor;
-    }
-#endif
-
-    const SkPoint& xyAtT(const SkOpSpan* span) const {
-        return span->fPt;
-    }
-
-    const SkPoint& xyAtT(int index) const {
-        return xyAtT(&fTs[index]);
-    }
-
-#if defined(SK_DEBUG) || DEBUG_WINDING
-    SkScalar yAtT(int index) const {
-        return yAtT(&fTs[index]);
-    }
-#endif
-
-    const SkOpAngle* activeAngle(int index, int* start, int* end, bool* done,
-                                 bool* sortable) const;
-    SkPoint activeLeftTop(int* firstT) const;
-    bool activeOp(int index, int endIndex, int xorMiMask, int xorSuMask, SkPathOp op);
-    bool activeWinding(int index, int endIndex);
-    void addCubic(const SkPoint pts[4], bool operand, bool evenOdd);
-    void addCurveTo(int start, int end, SkPathWriter* path, bool active) const;
-    void addEndSpan(int endIndex);
-    void addLine(const SkPoint pts[2], bool operand, bool evenOdd);
-    void addOtherT(int index, double otherT, int otherIndex);
-    void addQuad(const SkPoint pts[3], bool operand, bool evenOdd);
-    void addSimpleAngle(int endIndex);
-    int addSelfT(const SkPoint& pt, double newT);
-    void addStartSpan(int endIndex);
-    int addT(SkOpSegment* other, const SkPoint& pt, double newT);
-    void addTCancel(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other);
-    bool addTCoincident(const SkPoint& startPt, const SkPoint& endPt, double endT,
-                        SkOpSegment* other);
-    const SkOpSpan* addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind,
-                             const SkPoint& pt);
-    const SkOpSpan* addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind,
-                             const SkPoint& pt, const SkPoint& oPt);
-    void alignMultiples(SkTDArray<AlignedSpan>* aligned);
-    bool alignSpan(int index, double thisT, const SkPoint& thisPt);
-    void alignSpanState(int start, int end);
-    bool betweenTs(int lesser, double testT, int greater) const;
-    void blindCancel(const SkCoincidence& coincidence, SkOpSegment* other);
-    void blindCoincident(const SkCoincidence& coincidence, SkOpSegment* other);
-    bool calcAngles();
-    double calcMissingTEnd(const SkOpSegment* ref, double loEnd, double min, double max,
-                           double hiEnd, const SkOpSegment* other, int thisEnd);
-    double calcMissingTStart(const SkOpSegment* ref, double loEnd, double min, double max,
-                             double hiEnd, const SkOpSegment* other, int thisEnd);
-    void checkDuplicates();
-    bool checkEnds();
-    void checkMultiples();
-    void checkSmall();
-    bool checkSmall(int index) const;
-    void checkTiny();
-    int computeSum(int startIndex, int endIndex, SkOpAngle::IncludeType includeType);
-    bool containsPt(const SkPoint& , int index, int endIndex) const;
-    int crossedSpanY(const SkPoint& basePt, SkScalar* bestY, double* hitT, bool* hitSomething,
-                     double mid, bool opp, bool current) const;
-    bool findCoincidentMatch(const SkOpSpan* span, const SkOpSegment* other, int oStart, int oEnd,
-                             int step, SkPoint* startPt, SkPoint* endPt, double* endT) const;
-    SkOpSegment* findNextOp(SkTDArray<SkOpSpan*>* chase, int* nextStart, int* nextEnd,
-                            bool* unsortable, SkPathOp op, int xorMiMask, int xorSuMask);
-    SkOpSegment* findNextWinding(SkTDArray<SkOpSpan*>* chase, int* nextStart, int* nextEnd,
-                                 bool* unsortable);
-    SkOpSegment* findNextXor(int* nextStart, int* nextEnd, bool* unsortable);
-    int findExactT(double t, const SkOpSegment* ) const;
-    int findOtherT(double t, const SkOpSegment* ) const;
-    int findT(double t, const SkPoint& , const SkOpSegment* ) const;
-    SkOpSegment* findTop(int* tIndex, int* endIndex, bool* unsortable, bool firstPass);
-    void fixOtherTIndex();
-    bool inconsistentAngle(int maxWinding, int sumWinding, int oppMaxWinding, int oppSumWinding,
-                        const SkOpAngle* angle) const;
-    void initWinding(int start, int end, SkOpAngle::IncludeType angleIncludeType);
-    bool initWinding(int start, int end, double tHit, int winding, SkScalar hitDx, int oppWind,
-                     SkScalar hitOppDx);
-    bool isMissing(double startT, const SkPoint& pt) const;
-    bool isTiny(const SkOpAngle* angle) const;
-    bool joinCoincidence(SkOpSegment* other, double otherT, const SkPoint& otherPt, int step,
-                         bool cancel);
-    SkOpSpan* markAndChaseDoneBinary(int index, int endIndex);
-    SkOpSpan* markAndChaseDoneUnary(int index, int endIndex);
-    bool markAndChaseWinding(const SkOpAngle* angle, int winding, int oppWinding,
-                             SkOpSpan** lastPtr);
-    SkOpSpan* markAngle(int maxWinding, int sumWinding, int oppMaxWinding, int oppSumWinding,
-                        const SkOpAngle* angle);
-    void markDone(int index, int winding);
-    void markDoneBinary(int index);
-    void markDoneFinal(int index);
-    void markDoneUnary(int index);
-    bool nextCandidate(int* start, int* end) const;
-    int nextSpan(int from, int step) const;
-    void pinT(const SkPoint& pt, double* t);
-    void setUpWindings(int index, int endIndex, int* sumMiWinding, int* sumSuWinding,
-            int* maxWinding, int* sumWinding, int* oppMaxWinding, int* oppSumWinding);
-    void sortAngles();
-    bool subDivide(int start, int end, SkPoint edge[4]) const;
-    bool subDivide(int start, int end, SkDCubic* result) const;
-    void undoneSpan(int* start, int* end);
-    int updateOppWindingReverse(const SkOpAngle* angle) const;
-    int updateWindingReverse(const SkOpAngle* angle) const;
-    static bool UseInnerWinding(int outerWinding, int innerWinding);
-    static bool UseInnerWindingReverse(int outerWinding, int innerWinding);
-    int windingAtT(double tHit, int tIndex, bool crossOpp, SkScalar* dx) const;
+    int windingAtT(double tHit, const SkOpSpan* span, bool crossOpp, SkScalar* dx) const;
     int windSum(const SkOpAngle* angle) const;
-// available for testing only
-#if defined(SK_DEBUG) || !FORCE_RELEASE
-    int debugID() const {
-        return fID;
+
+    SkPoint* writablePt(bool end) {
+        return &fPts[end ? SkPathOpsVerbToPoints(fVerb) : 0];
     }
-#else
-    int debugID() const {
-        return -1;
-    }
-#endif
-#if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
-    void debugShowActiveSpans() const;
-#endif
-#if DEBUG_CONCIDENT
-    void debugShowTs(const char* prefix) const;
-#endif
-#if DEBUG_SHOW_WINDING
-    int debugShowWindingValues(int slotCount, int ofInterest) const;
-#endif
-    const SkTDArray<SkOpSpan>& debugSpans() const;
-    void debugValidate() const;
-    // available to testing only
-    const SkOpAngle* debugLastAngle() const;
-    void dumpAngles() const;
-    void dumpContour(int firstID, int lastID) const;
-    void dumpPts() const;
-    void dumpSpans() const;
 
 private:
-    struct MissingSpan  {
-        double fT;
-        double fEndT;
-        SkOpSegment* fSegment;
-        SkOpSegment* fOther;
-        double fOtherT;
-        SkPoint fPt;
-    };
-
-    const SkOpAngle* activeAngleInner(int index, int* start, int* end, bool* done,
-                                      bool* sortable) const;
-    const SkOpAngle* activeAngleOther(int index, int* start, int* end, bool* done,
-                                      bool* sortable) const;
-    bool activeOp(int xorMiMask, int xorSuMask, int index, int endIndex, SkPathOp op,
-                  int* sumMiWinding, int* sumSuWinding);
-    bool activeWinding(int index, int endIndex, int* sumWinding);
-    void addCancelOutsides(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other);
-    void addCoinOutsides(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other);
-    SkOpAngle* addSingletonAngleDown(SkOpSegment** otherPtr, SkOpAngle** );
-    SkOpAngle* addSingletonAngleUp(SkOpSegment** otherPtr, SkOpAngle** );
-    SkOpAngle* addSingletonAngles(int step);
-    void alignRange(int lower, int upper, const SkOpSegment* other, int oLower, int oUpper);
-    void alignSpan(const SkPoint& newPt, double newT, const SkOpSegment* other, double otherT,
-                   const SkOpSegment* other2, SkOpSpan* oSpan, SkTDArray<AlignedSpan>* );
-    bool betweenPoints(double midT, const SkPoint& pt1, const SkPoint& pt2) const;
-    void bumpCoincidentBlind(bool binary, int index, int last);
-    bool bumpCoincidentThis(const SkOpSpan& oTest, bool binary, int* index,
-                            SkTArray<SkPoint, true>* outsideTs);
-    void bumpCoincidentOBlind(int index, int last);
-    bool bumpCoincidentOther(const SkOpSpan& oTest, int* index,
-                             SkTArray<SkPoint, true>* outsideTs, const SkPoint& endPt);
-    bool bumpSpan(SkOpSpan* span, int windDelta, int oppDelta);
-    bool calcLoopSpanCount(const SkOpSpan& thisSpan, int* smallCounts);
-    bool checkForSmall(const SkOpSpan* span, const SkPoint& pt, double newT,
-                       int* less, int* more) const;
-    void checkLinks(const SkOpSpan* ,
-                    SkTArray<MissingSpan, true>* missingSpans) const;
-    static void CheckOneLink(const SkOpSpan* test, const SkOpSpan* oSpan,
-                             const SkOpSpan* oFirst, const SkOpSpan* oLast,
-                             const SkOpSpan** missingPtr,
-                             SkTArray<MissingSpan, true>* missingSpans);
-    int checkSetAngle(int tIndex) const;
-    void checkSmallCoincidence(const SkOpSpan& span, SkTArray<MissingSpan, true>* );
-    bool coincidentSmall(const SkPoint& pt, double t, const SkOpSegment* other) const;
-    bool clockwise(int tStart, int tEnd, bool* swap) const;
-    static void ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
-                              SkOpAngle::IncludeType );
-    static void ComputeOneSumReverse(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
-                                     SkOpAngle::IncludeType );
-    bool containsT(double t, const SkOpSegment* other, double otherT) const;
-    bool decrementSpan(SkOpSpan* span);
-    int findEndSpan(int endIndex) const;
-    int findStartSpan(int startIndex) const;
-    int firstActive(int tIndex) const;
-    const SkOpSpan& firstSpan(const SkOpSpan& thisSpan) const;
-    void init(const SkPoint pts[], SkPath::Verb verb, bool operand, bool evenOdd);
-    bool inCoincidentSpan(double t, const SkOpSegment* other) const;
-    bool inconsistentWinding(const SkOpAngle* , int maxWinding, int oppMaxWinding) const;
-    bool inconsistentWinding(int min, int maxWinding, int oppMaxWinding) const;
-    bool inconsistentWinding(const char* funName, int tIndex, int winding, int oppWinding) const;
-    bool inLoop(const SkOpAngle* baseAngle, int spanCount, int* indexPtr) const;
-#if OLD_CHASE
-    bool isSimple(int end) const;
-#else
-    SkOpSegment* isSimple(int* end, int* step);
-#endif
-    bool isTiny(int index) const;
-    const SkOpSpan& lastSpan(const SkOpSpan& thisSpan) const;
-    void matchWindingValue(int tIndex, double t, bool borrowWind);
-    SkOpSpan* markAndChaseDone(int index, int endIndex, int winding);
-    SkOpSpan* markAndChaseDoneBinary(const SkOpAngle* angle, int winding, int oppWinding);
-    bool markAndChaseWinding(const SkOpAngle* angle, int winding, SkOpSpan** lastPtr);
-    bool markAndChaseWinding(int index, int endIndex, int winding, SkOpSpan** lastPtr);
-    bool markAndChaseWinding(int index, int endIndex, int winding, int oppWinding,
-                             SkOpSpan** lastPtr);
-    SkOpSpan* markAngle(int maxWinding, int sumWinding, const SkOpAngle* angle);
-    void markDoneBinary(int index, int winding, int oppWinding);
-    SkOpSpan* markAndChaseDoneUnary(const SkOpAngle* angle, int winding);
-    void markOneDone(const char* funName, int tIndex, int winding);
-    void markOneDoneBinary(const char* funName, int tIndex);
-    void markOneDoneBinary(const char* funName, int tIndex, int winding, int oppWinding);
-    void markOneDoneFinal(const char* funName, int tIndex);
-    void markOneDoneUnary(const char* funName, int tIndex);
-    bool markOneWinding(const char* funName, int tIndex, int winding, SkOpSpan** lastPtr);
-    bool markOneWinding(const char* funName, int tIndex, int winding, int oppWinding,
-                        SkOpSpan** lastPtr);
-    bool markWinding(int index, int winding);
-    bool markWinding(int index, int winding, int oppWinding);
-    bool monotonicInY(int tStart, int tEnd) const;
-
-    bool multipleEnds() const { return fTs[count() - 2].fT == 1; }
-    bool multipleStarts() const { return fTs[1].fT == 0; }
-
-    SkOpSegment* nextChase(int* index, int* step, int* min, SkOpSpan** last) const;
-    int nextExactSpan(int from, int step) const;
-    void resetSpanFlags();
-    bool serpentine(int tStart, int tEnd) const;
-    void setCoincidentRange(const SkPoint& startPt, const SkPoint& endPt,  SkOpSegment* other);
-    void setFromAngle(int endIndex, SkOpAngle* );
-    void setSpanFlags(const SkPoint& pt, double newT, SkOpSpan* span);
-    void setToAngle(int endIndex, SkOpAngle* );
-    void setUpWindings(int index, int endIndex, int* sumMiWinding,
-            int* maxWinding, int* sumWinding);
-    void subDivideBounds(int start, int end, SkPathOpsBounds* bounds) const;
-    static void TrackOutsidePair(SkTArray<SkPoint, true>* outsideTs, const SkPoint& endPt,
-            const SkPoint& startPt);
-    static void TrackOutside(SkTArray<SkPoint, true>* outsideTs, const SkPoint& startPt);
-    int updateOppWinding(int index, int endIndex) const;
-    int updateOppWinding(const SkOpAngle* angle) const;
-    int updateWinding(int index, int endIndex) const;
-    int updateWinding(const SkOpAngle* angle) const;
-    int updateWindingReverse(int index, int endIndex) const;
-    SkOpSpan* verifyOneWinding(const char* funName, int tIndex);
-    SkOpSpan* verifyOneWindingU(const char* funName, int tIndex);
-
-    SkScalar xAtT(const SkOpSpan* span) const {
-        return xyAtT(span).fX;
-    }
-
-    SkScalar yAtT(const SkOpSpan* span) const {
-        return xyAtT(span).fY;
-    }
-
-    void zeroSpan(SkOpSpan* span);
-
-#if DEBUG_SWAP_TOP
-    bool controlsContainedByEnds(int tStart, int tEnd) const;
-#endif
-    void debugAddAngle(int start, int end);
-#if DEBUG_CONCIDENT
-    void debugAddTPair(double t, const SkOpSegment& other, double otherT) const;
-#endif
-#if DEBUG_ANGLE
-    void debugCheckPointsEqualish(int tStart, int tEnd) const;
-#endif
-#if DEBUG_SWAP_TOP
-    int debugInflections(int index, int endIndex) const;
-#endif
-#if DEBUG_MARK_DONE || DEBUG_UNSORTABLE
-    void debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding);
-    void debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding, int oppWinding);
-#endif
-#if DEBUG_WINDING
-    static char as_digit(int value) {
-        return value < 0 ? '?' : value <= 9 ? '0' + value : '+';
-    }
-#endif
-    // available to testing only
-    void debugConstruct();
-    void debugConstructCubic(SkPoint shortQuad[4]);
-    void debugConstructLine(SkPoint shortQuad[2]);
-    void debugConstructQuad(SkPoint shortQuad[3]);
-    void debugReset();
-    void dumpDPts() const;
-    void dumpHexPts() const;
-    void dumpSpan(int index) const;
-
-    const SkPoint* fPts;
-    SkPathOpsBounds fBounds;
-    // FIXME: can't convert to SkTArray because it uses insert
-    SkTDArray<SkOpSpan> fTs;  // 2+ (always includes t=0 t=1) -- at least (number of spans) + 1
-    SkOpAngleSet fAngles;  // empty or 2+ -- (number of non-zero spans) * 2
-    // OPTIMIZATION: could pack donespans, verb, operand, xor into 1 int-sized value
-    int fDoneSpans;  // quick check that segment is finished
-    // OPTIMIZATION: force the following to be byte-sized
+    SkOpSpan fHead;  // the head span always has its t set to zero
+    SkOpSpanBase fTail;  // the tail span always has its t set to one
+    SkOpContour* fContour;
+    SkOpSegment* fNext;  // forward-only linked list used by contour to walk the segments
+    const SkOpSegment* fPrev;
+    SkPoint* fPts;  // pointer into array of points owned by edge builder that may be tweaked
+    SkPathOpsBounds fBounds;  // tight bounds
+    int fCount;  // number of spans (one for a non-intersecting segment)
+    int fDoneCount;  // number of processed spans (zero initially)
     SkPath::Verb fVerb;
-    bool fLoop;   // set if cubic intersects itself
-    bool fMultiples;  // set if curve intersects multiple other curves at one interior point
-    bool fOperand;
-    bool fXor;  // set if original contour had even-odd fill
-    bool fOppXor;  // set if opposite operand had even-odd fill
-    bool fSmall;  // set if some span is small
-    bool fTiny;  // set if some span is tiny
-#if defined(SK_DEBUG) || !FORCE_RELEASE
-    int fID;
-#endif
-
-    friend class PathOpsSegmentTester;
+    bool fVisited;  // used by missing coincidence check
+    PATH_OPS_DEBUG_CODE(int fID);
 };
 
 #endif
diff --git a/src/pathops/SkOpSpan.cpp b/src/pathops/SkOpSpan.cpp
new file mode 100755
index 0000000..37d5120
--- /dev/null
+++ b/src/pathops/SkOpSpan.cpp
@@ -0,0 +1,355 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkOpCoincidence.h"
+#include "SkOpContour.h"
+#include "SkOpSegment.h"
+#include "SkPathWriter.h"
+
+bool SkOpPtT::alias() const {
+    return this->span()->ptT() != this;
+}
+
+SkOpContour* SkOpPtT::contour() const {
+    return segment()->contour();
+}
+
+SkOpGlobalState* SkOpPtT::globalState() const {
+    return contour()->globalState(); 
+}
+
+void SkOpPtT::init(SkOpSpanBase* span, double t, const SkPoint& pt, bool duplicate) {
+    fT = t;
+    fPt = pt;
+    fSpan = span;
+    fNext = this;
+    fDuplicatePt = duplicate;
+    fDeleted = false;
+    PATH_OPS_DEBUG_CODE(fID = span->globalState()->nextPtTID());
+}
+
+bool SkOpPtT::onEnd() const {
+    const SkOpSpanBase* span = this->span();
+    if (span->ptT() != this) {
+        return false;
+    }
+    const SkOpSegment* segment = this->segment();
+    return span == segment->head() || span == segment->tail();
+}
+
+SkOpPtT* SkOpPtT::prev() {
+    SkOpPtT* result = this;
+    SkOpPtT* next = this;
+    while ((next = next->fNext) != this) {
+        result = next;
+    }
+    SkASSERT(result->fNext == this);
+    return result;
+}
+
+SkOpPtT* SkOpPtT::remove() {
+    SkOpPtT* prev = this;
+    do {
+        SkOpPtT* next = prev->fNext;
+        if (next == this) {
+            prev->removeNext(this);
+            SkASSERT(prev->fNext != prev);
+            fDeleted = true;
+            return prev;
+        }
+        prev = next;
+    } while (prev != this);
+    SkASSERT(0);
+    return NULL;
+}
+
+void SkOpPtT::removeNext(SkOpPtT* kept) {
+    SkASSERT(this->fNext);
+    SkOpPtT* next = this->fNext;
+    SkASSERT(this != next->fNext);
+    this->fNext = next->fNext;
+    SkOpSpanBase* span = next->span();
+    next->setDeleted();
+    if (span->ptT() == next) {
+        span->upCast()->detach(kept);
+    }
+}
+
+const SkOpSegment* SkOpPtT::segment() const {
+    return span()->segment();
+}
+
+SkOpSegment* SkOpPtT::segment() {
+    return span()->segment();
+}
+
+// find the starting or ending span with an existing loop of angles
+// OPTIMIZE? remove the spans pointing to windValue==0 here or earlier?
+// FIXME? assert that only one other span has a valid windValue or oppValue
+void SkOpSpanBase::addSimpleAngle(bool checkFrom, SkChunkAlloc* allocator) {
+    SkOpAngle* angle;
+    if (checkFrom) {
+        SkASSERT(this->final());
+        if (this->fromAngle()) {
+            SkASSERT(this->fromAngle()->loopCount() == 2);
+            return;
+        }
+        angle = this->segment()->addEndSpan(allocator);
+    } else {
+        SkASSERT(this->t() == 0);
+        SkOpSpan* span = this->upCast();
+        if (span->toAngle()) {
+            SkASSERT(span->toAngle()->loopCount() == 2);
+            SkASSERT(!span->fromAngle());
+            span->setFromAngle(span->toAngle()->next());
+            return;
+        }
+        angle = this->segment()->addStartSpan(allocator);
+    }
+    SkOpPtT* ptT = this->ptT();
+    SkOpSpanBase* oSpanBase;
+    SkOpSpan* oSpan;
+    SkOpSegment* other;
+    do {
+        ptT = ptT->next();
+        oSpanBase = ptT->span();
+        oSpan = oSpanBase->upCastable();
+        other = oSpanBase->segment();
+        if (oSpan && oSpan->windValue()) {
+            break;
+        }
+        if (oSpanBase->t() == 0) {
+            continue;
+        }
+        SkOpSpan* oFromSpan = oSpanBase->prev();
+        SkASSERT(oFromSpan->t() < 1);
+        if (oFromSpan->windValue()) {
+            break;
+        }
+    } while (ptT != this->ptT());
+    SkOpAngle* oAngle;
+    if (checkFrom) {
+        oAngle = other->addStartSpan(allocator);
+        SkASSERT(oSpan && !oSpan->final());
+        SkASSERT(oAngle == oSpan->toAngle());
+    } else {
+        oAngle = other->addEndSpan(allocator);
+        SkASSERT(oAngle == oSpanBase->fromAngle());
+    }
+    angle->insert(oAngle);
+}
+
+void SkOpSpanBase::align() {
+    if (this->fAligned) {
+        return;
+    }
+    SkASSERT(!zero_or_one(this->fPtT.fT));
+    SkASSERT(this->fPtT.next());
+    // if a linked pt/t pair has a t of zero or one, use it as the base for alignment
+    SkOpPtT* ptT = &this->fPtT, * stopPtT = ptT;
+    while ((ptT = ptT->next()) != stopPtT) {
+        if (zero_or_one(ptT->fT)) {
+            SkOpSegment* segment = ptT->segment();
+            SkASSERT(this->segment() != segment);
+            SkASSERT(segment->head()->ptT() == ptT || segment->tail()->ptT() == ptT);
+            if (ptT->fT) {
+                segment->tail()->alignEnd(1, segment->lastPt());
+            } else {
+                segment->head()->alignEnd(0, segment->pts()[0]);
+            }
+            return;
+        }
+    }
+    alignInner();
+    this->fAligned = true;
+}
+
+
+// FIXME: delete spans that collapse
+// delete segments that collapse
+// delete contours that collapse
+void SkOpSpanBase::alignEnd(double t, const SkPoint& pt) {
+    SkASSERT(zero_or_one(t));
+    SkOpSegment* segment = this->segment();
+    SkASSERT(t ? segment->lastPt() == pt : segment->pts()[0] == pt);
+    alignInner();
+    *segment->writablePt(!!t) = pt;
+    SkOpPtT* ptT = &this->fPtT;
+    SkASSERT(t == ptT->fT);
+    SkASSERT(pt == ptT->fPt);
+    SkOpPtT* test = ptT, * stopPtT = ptT;
+    while ((test = test->next()) != stopPtT) {
+        SkOpSegment* other = test->segment();
+        if (other == this->segment()) {
+            continue;
+        }
+        if (!zero_or_one(test->fT)) {
+            continue;
+        }
+        *other->writablePt(!!test->fT) = pt;
+    }
+    this->fAligned = true;
+}
+
+void SkOpSpanBase::alignInner() {
+    // force the spans to share points and t values
+    SkOpPtT* ptT = &this->fPtT, * stopPtT = ptT;
+    const SkPoint& pt = ptT->fPt;
+    do {
+        ptT->fPt = pt;
+        const SkOpSpanBase* span = ptT->span();
+        SkOpPtT* test = ptT;
+        do {
+            SkOpPtT* prev = test;
+            if ((test = test->next()) == stopPtT) {
+                break;
+            }
+            if (span == test->span() && !span->segment()->ptsDisjoint(*ptT, *test)) {
+                // omit aliases that alignment makes redundant
+                if ((!ptT->alias() || test->alias()) && (ptT->onEnd() || !test->onEnd())) {
+                    SkASSERT(test->alias());
+                    prev->removeNext(ptT);
+                    test = prev;
+                } else {
+                    SkASSERT(ptT->alias());
+                    stopPtT = ptT = ptT->remove();
+                    break;
+                }
+            }
+        } while (true);
+    } while ((ptT = ptT->next()) != stopPtT);
+}
+
+bool SkOpSpanBase::contains(const SkOpSpanBase* span) const {
+    const SkOpPtT* start = &fPtT;
+    const SkOpPtT* check = &span->fPtT;
+    SkASSERT(start != check);
+    const SkOpPtT* walk = start;
+    while ((walk = walk->next()) != start) {
+        if (walk == check) {
+            return true;
+        }
+    }
+    return false;
+}
+
+SkOpPtT* SkOpSpanBase::contains(const SkOpSegment* segment) {
+    SkOpPtT* start = &fPtT;
+    SkOpPtT* walk = start;
+    while ((walk = walk->next()) != start) {
+        if (walk->segment() == segment) {
+            return walk;
+        }
+    }
+    return NULL;
+}
+
+bool SkOpSpanBase::containsCoinEnd(const SkOpSegment* segment) const {
+    SkASSERT(this->segment() != segment);
+    const SkOpSpanBase* next = this;
+    while ((next = next->fCoinEnd) != this) {
+        if (next->segment() == segment) {
+            return true;
+        }
+    }
+    return false;
+}
+
+SkOpContour* SkOpSpanBase::contour() const {
+    return segment()->contour();
+}
+
+SkOpGlobalState* SkOpSpanBase::globalState() const {
+    return contour()->globalState(); 
+}
+
+void SkOpSpanBase::initBase(SkOpSegment* segment, SkOpSpan* prev, double t, const SkPoint& pt) {
+    fSegment = segment;
+    fPtT.init(this, t, pt, false);
+    fCoinEnd = this;
+    fFromAngle = NULL;
+    fPrev = prev;
+    fAligned = true;
+    fChased = false;
+    PATH_OPS_DEBUG_CODE(fCount = 1);
+    PATH_OPS_DEBUG_CODE(fID = globalState()->nextSpanID());
+}
+
+// this pair of spans share a common t value or point; merge them and eliminate duplicates
+// this does not compute the best t or pt value; this merely moves all data into a single list
+void SkOpSpanBase::merge(SkOpSpan* span) {
+    SkOpPtT* spanPtT = span->ptT();
+    SkASSERT(this->t() != spanPtT->fT);
+    SkASSERT(!zero_or_one(spanPtT->fT));
+    span->detach(this->ptT());
+    SkOpPtT* remainder = spanPtT->next();
+    ptT()->insert(spanPtT);
+    while (remainder != spanPtT) {
+        SkOpPtT* next = remainder->next();
+        SkOpPtT* compare = spanPtT->next();
+        while (compare != spanPtT) {
+            SkOpPtT* nextC = compare->next();
+            if (nextC->span() == remainder->span() && nextC->fT == remainder->fT) {
+                goto tryNextRemainder;
+            }
+            compare = nextC;
+        }
+        spanPtT->insert(remainder);
+tryNextRemainder:
+        remainder = next;
+    }
+}
+
+void SkOpSpan::applyCoincidence(SkOpSpan* opp) {
+    SkASSERT(!final());
+    SkASSERT(0);  // incomplete
+}
+
+bool SkOpSpan::containsCoincidence(const SkOpSegment* segment) const {
+    SkASSERT(this->segment() != segment);
+    const SkOpSpan* next = fCoincident;
+    do {
+        if (next->segment() == segment) {
+            return true;
+        }
+    } while ((next = next->fCoincident) != this);
+    return false;
+}
+
+void SkOpSpan::detach(SkOpPtT* kept) {
+    SkASSERT(!final());
+    SkOpSpan* prev = this->prev();
+    SkASSERT(prev);
+    SkOpSpanBase* next = this->next();
+    SkASSERT(next);
+    prev->setNext(next);
+    next->setPrev(prev);
+    this->segment()->detach(this);
+    this->globalState()->coincidence()->fixUp(this->ptT(), kept);
+    this->ptT()->setDeleted();
+}
+
+void SkOpSpan::init(SkOpSegment* segment, SkOpSpan* prev, double t, const SkPoint& pt) {
+    SkASSERT(t != 1);
+    initBase(segment, prev, t, pt);
+    fCoincident = this;
+    fToAngle = NULL;
+    fWindSum = fOppSum = SK_MinS32;
+    fWindValue = 1;
+    fOppValue = 0;
+    fChased = fDone = false;
+    segment->bumpCount();
+}
+
+void SkOpSpan::setOppSum(int oppSum) {
+    SkASSERT(!final());
+    if (fOppSum != SK_MinS32 && fOppSum != oppSum) {
+        this->globalState()->setWindingFailed();
+        return;
+    }
+    SkASSERT(!DEBUG_LIMIT_WIND_SUM || abs(oppSum) <= DEBUG_LIMIT_WIND_SUM);
+    fOppSum = oppSum;
+}
diff --git a/src/pathops/SkOpSpan.h b/src/pathops/SkOpSpan.h
index d9ce44e..9e5939a 100644
--- a/src/pathops/SkOpSpan.h
+++ b/src/pathops/SkOpSpan.h
@@ -7,36 +7,460 @@
 #ifndef SkOpSpan_DEFINED
 #define SkOpSpan_DEFINED
 
+#include "SkPathOpsDebug.h"
 #include "SkPoint.h"
 
-class SkOpAngle;
+class SkChunkAlloc;
+struct SkOpAngle;
+class SkOpContour;
+class SkOpGlobalState;
 class SkOpSegment;
+class SkOpSpanBase;
+class SkOpSpan;
 
-struct SkOpSpan {
-    SkPoint fPt;  // computed when the curves are intersected
-    double fT;
-    double fOtherT;  // value at fOther[fOtherIndex].fT
-    SkOpSegment* fOther;
-    SkOpAngle* fFromAngle;  // (if t > 0) index into segment's angle array going negative in t
-    SkOpAngle* fToAngle;  // (if t < 1) index into segment's angle array going positive in t
-    int fOtherIndex;  // can't be used during intersection
+// subset of op span used by terminal span (when t is equal to one)
+class SkOpPtT {
+public:
+    enum {
+        kIsAlias = 1,
+        kIsDuplicate = 1
+    };
+
+    void addOpp(SkOpPtT* opp) {
+        // find the fOpp ptr to opp
+        SkOpPtT* oppPrev = opp->fNext;
+        if (oppPrev == this) {
+            return;
+        }
+        while (oppPrev->fNext != opp) {
+            oppPrev = oppPrev->fNext;
+             if (oppPrev == this) {
+                 return;
+             }
+        }
+        
+        SkOpPtT* oldNext = this->fNext;
+        SkASSERT(this != opp);
+        this->fNext = opp;
+        SkASSERT(oppPrev != oldNext);
+        oppPrev->fNext = oldNext;
+    }
+
+    bool alias() const;
+    SkOpContour* contour() const;
+
+    int debugID() const {
+        return PATH_OPS_DEBUG_RELEASE(fID, -1);
+    }
+
+    const SkOpAngle* debugAngle(int id) const;
+    SkOpContour* debugContour(int id);
+    int debugLoopLimit(bool report) const;
+    bool debugMatchID(int id) const;
+    const SkOpPtT* debugPtT(int id) const;
+    const SkOpSegment* debugSegment(int id) const;
+    const SkOpSpanBase* debugSpan(int id) const;
+    SkOpGlobalState* globalState() const;
+    void debugValidate() const;
+
+    bool deleted() const {
+        return fDeleted;
+    }
+
+    bool duplicate() const {
+        return fDuplicatePt;
+    }
+
+    void dump() const;  // available to testing only
+    void dumpAll() const;
+    void dumpBase() const;
+
+    void init(SkOpSpanBase* , double t, const SkPoint& , bool dup);
+
+    void insert(SkOpPtT* span) {
+        SkASSERT(span != this);
+        span->fNext = fNext;
+        fNext = span;
+    }
+
+    const SkOpPtT* next() const {
+        return fNext;
+    }
+
+    SkOpPtT* next() {
+        return fNext;
+    }
+
+    bool onEnd() const;
+    SkOpPtT* prev();
+    SkOpPtT* remove();
+    void removeNext(SkOpPtT* kept);
+
+    const SkOpSegment* segment() const;
+    SkOpSegment* segment();
+
+    void setDeleted() {
+        SkASSERT(!fDeleted);
+        fDeleted = true;
+    }
+
+    const SkOpSpanBase* span() const {
+        return fSpan;
+    }
+
+    SkOpSpanBase* span() {
+        return fSpan;
+    }
+
+    double fT; 
+    SkPoint fPt;   // cache of point value at this t
+protected:
+    SkOpSpanBase* fSpan;  // contains winding data
+    SkOpPtT* fNext;  // intersection on opposite curve or alias on this curve
+    bool fDeleted;  // set if removed from span list 
+    bool fDuplicatePt;  // set if identical pt is somewhere in the next loop
+    PATH_OPS_DEBUG_CODE(int fID);
+};
+
+class SkOpSpanBase {
+public:
+    void addSimpleAngle(bool checkFrom , SkChunkAlloc* );
+    void align();
+
+    bool aligned() const {
+        return fAligned;
+    }
+
+    void alignEnd(double t, const SkPoint& pt);
+
+    bool chased() const {
+        return fChased;
+    }
+
+    void clearCoinEnd() {
+        SkASSERT(fCoinEnd != this);
+        fCoinEnd = this;
+    }
+
+    const SkOpSpanBase* coinEnd() const {
+        return fCoinEnd;
+    }
+
+    bool contains(const SkOpSpanBase* ) const;
+    SkOpPtT* contains(const SkOpSegment* );
+
+    bool containsCoinEnd(const SkOpSpanBase* coin) const {
+        SkASSERT(this != coin);
+        const SkOpSpanBase* next = this;
+        while ((next = next->fCoinEnd) != this) {
+            if (next == coin) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    bool containsCoinEnd(const SkOpSegment* ) const;
+    SkOpContour* contour() const;
+
+    int debugBumpCount() {
+        return PATH_OPS_DEBUG_RELEASE(++fCount, -1);
+    }
+
+    int debugID() const {
+        return PATH_OPS_DEBUG_RELEASE(fID, -1);
+    }
+
+    const SkOpAngle* debugAngle(int id) const;
+    bool debugCoinEndLoopCheck() const;
+    SkOpContour* debugContour(int id);
+    const SkOpPtT* debugPtT(int id) const;
+    const SkOpSegment* debugSegment(int id) const;
+    const SkOpSpanBase* debugSpan(int id) const;
+    SkOpGlobalState* globalState() const;
+    void debugValidate() const;
+
+    bool deleted() const {
+        return fPtT.deleted();
+    }
+
+    void dump() const;  // available to testing only
+    void dumpCoin() const;
+    void dumpAll() const;
+    void dumpBase() const;
+
+    bool final() const {
+        return fPtT.fT == 1;
+    }
+
+    SkOpAngle* fromAngle() const {
+        return fFromAngle;
+    }
+
+    void initBase(SkOpSegment* parent, SkOpSpan* prev, double t, const SkPoint& pt);
+
+    void insertCoinEnd(SkOpSpanBase* coin) {
+        if (containsCoinEnd(coin)) {
+            SkASSERT(coin->containsCoinEnd(this));
+            return;
+        }
+        debugValidate();
+        SkASSERT(this != coin);
+        SkOpSpanBase* coinNext = coin->fCoinEnd;
+        coin->fCoinEnd = this->fCoinEnd;
+        this->fCoinEnd = coinNext;
+        debugValidate();
+    }
+
+    void merge(SkOpSpan* span);
+
+    SkOpSpan* prev() const {
+        return fPrev;
+    }
+
+    const SkPoint& pt() const {
+        return fPtT.fPt;
+    }
+
+    const SkOpPtT* ptT() const {
+        return &fPtT;
+    }
+
+    SkOpPtT* ptT() {
+        return &fPtT;
+    }
+
+    SkOpSegment* segment() const {
+        return fSegment;
+    }
+
+    void setChased(bool chased) {
+        fChased = chased;
+    }
+
+    SkOpPtT* setCoinEnd(SkOpSpanBase* oldCoinEnd, SkOpSegment* oppSegment);
+
+    void setFromAngle(SkOpAngle* angle) {
+        fFromAngle = angle;
+    }
+
+    void setPrev(SkOpSpan* prev) {
+        fPrev = prev;
+    }
+
+    bool simple() const {
+        fPtT.debugValidate();
+        return fPtT.next()->next() == &fPtT; 
+    }
+
+    const SkOpSpan* starter(const SkOpSpanBase* end) const {
+        const SkOpSpanBase* result = t() < end->t() ? this : end;
+        return result->upCast();
+    }
+
+    SkOpSpan* starter(SkOpSpanBase* end) {
+        SkASSERT(this->segment() == end->segment());
+        SkOpSpanBase* result = t() < end->t() ? this : end;
+        return result->upCast();
+    }
+
+    SkOpSpan* starter(SkOpSpanBase** endPtr) {
+        SkOpSpanBase* end = *endPtr;
+        SkASSERT(this->segment() == end->segment());
+        SkOpSpanBase* result;
+        if (t() < end->t()) {
+            result = this;
+        } else {
+            result = end;
+            *endPtr = this;
+        }
+        return result->upCast();
+    }
+
+    int step(const SkOpSpanBase* end) const {
+        return t() < end->t() ? 1 : -1;
+    }
+
+    double t() const {
+        return fPtT.fT;
+    }
+
+    void unaligned() {
+        fAligned = false;
+    }
+
+    SkOpSpan* upCast() {
+        SkASSERT(!final());
+        return (SkOpSpan*) this;
+    }
+
+    const SkOpSpan* upCast() const {
+        SkASSERT(!final());
+        return (const SkOpSpan*) this;
+    }
+
+    SkOpSpan* upCastable() {
+        return final() ? NULL : upCast();
+    }
+
+    const SkOpSpan* upCastable() const {
+        return final() ? NULL : upCast();
+    }
+
+private:
+    void alignInner();
+
+protected:  // no direct access to internals to avoid treating a span base as a span
+    SkOpPtT fPtT;  // list of points and t values associated with the start of this span
+    SkOpSegment* fSegment;  // segment that contains this span
+    SkOpSpanBase* fCoinEnd;  // linked list of coincident spans that end here (may point to itself)
+    SkOpAngle* fFromAngle;  // points to next angle from span start to end
+    SkOpSpan* fPrev;  // previous intersection point
+    bool fAligned;
+    bool fChased;  // set after span has been added to chase array
+    PATH_OPS_DEBUG_CODE(int fCount);  // number of pt/t pairs added
+    PATH_OPS_DEBUG_CODE(int fID);
+};
+
+class SkOpSpan : public SkOpSpanBase {
+public:
+    void applyCoincidence(SkOpSpan* opp);
+
+    bool clearCoincident() {
+        SkASSERT(!final());
+        if (fCoincident == this) {
+            return false;
+        }
+        fCoincident = this;
+        return true;
+    }
+
+    bool containsCoincidence(const SkOpSegment* ) const;
+
+    bool containsCoincidence(const SkOpSpan* coin) const {
+        SkASSERT(this != coin);
+        const SkOpSpan* next = this;
+        while ((next = next->fCoincident) != this) {
+            if (next == coin) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    bool debugCoinLoopCheck() const;
+    void detach(SkOpPtT* );
+
+    bool done() const {
+        SkASSERT(!final());
+        return fDone;
+    }
+
+    void dumpCoin() const;
+    bool dumpSpan() const;
+    void init(SkOpSegment* parent, SkOpSpan* prev, double t, const SkPoint& pt);
+
+    void insertCoincidence(SkOpSpan* coin) {
+        if (containsCoincidence(coin)) {
+            SkASSERT(coin->containsCoincidence(this));
+            return;
+        }
+        debugValidate();
+        SkASSERT(this != coin);
+        SkOpSpan* coinNext = coin->fCoincident;
+        coin->fCoincident = this->fCoincident;
+        this->fCoincident = coinNext;
+        debugValidate();
+    }
+
+    bool isCanceled() const {
+        SkASSERT(!final());
+        return fWindValue == 0 && fOppValue == 0;
+    }
+
+    bool isCoincident() const {
+        SkASSERT(!final());
+        return fCoincident != this;
+    }
+
+    SkOpSpanBase* next() const {
+        SkASSERT(!final());
+        return fNext;
+    }
+
+    int oppSum() const {
+        SkASSERT(!final());
+        return fOppSum;
+    }
+
+    int oppValue() const {
+        SkASSERT(!final());
+        return fOppValue;
+    }
+
+    SkOpPtT* setCoinStart(SkOpSpan* oldCoinStart, SkOpSegment* oppSegment);
+
+    void setDone(bool done) {
+        SkASSERT(!final());
+        fDone = done;
+    }
+
+    void setNext(SkOpSpanBase* nextT) {
+        SkASSERT(!final());
+        fNext = nextT;
+    }
+
+    void setOppSum(int oppSum);
+
+    void setOppValue(int oppValue) {
+        SkASSERT(!final());
+        SkASSERT(fOppSum == SK_MinS32);
+        fOppValue = oppValue;
+    }
+
+    void setToAngle(SkOpAngle* angle) {
+        SkASSERT(!final());
+        fToAngle = angle;
+    }
+
+    void setWindSum(int windSum) {
+        SkASSERT(!final());
+        SkASSERT(fWindSum == SK_MinS32 || fWindSum == windSum);
+        SkASSERT(!DEBUG_LIMIT_WIND_SUM || abs(windSum) <= DEBUG_LIMIT_WIND_SUM);
+        fWindSum = windSum;
+    }
+
+    void setWindValue(int windValue) {
+        SkASSERT(!final());
+        SkASSERT(windValue >= 0);
+        SkASSERT(fWindSum == SK_MinS32);
+        fWindValue = windValue;
+    }
+
+    SkOpAngle* toAngle() const {
+        SkASSERT(!final());
+        return fToAngle;
+    }
+
+    int windSum() const {
+        SkASSERT(!final());
+        return fWindSum;
+    }
+
+    int windValue() const {
+        SkASSERT(!final());
+        return fWindValue;
+    }
+
+private:  // no direct access to internals to avoid treating a span base as a span
+    SkOpSpan* fCoincident;  // linked list of spans coincident with this one (may point to itself)
+    SkOpAngle* fToAngle;  // points to next angle from span start to end
+    SkOpSpanBase* fNext;  // next intersection point
     int fWindSum;  // accumulated from contours surrounding this one.
     int fOppSum;  // for binary operators: the opposite winding sum
     int fWindValue;  // 0 == canceled; 1 == normal; >1 == coincident
     int fOppValue;  // normally 0 -- when binary coincident edges combine, opp value goes here
-    bool fChased;  // set after span has been added to chase array
-    bool fCoincident;  // set if span is bumped -- if set additional points aren't inserted
     bool fDone;  // if set, this span to next higher T has been processed
-    bool fLoop;  // set when a cubic loops back to this point
-    bool fMultiple;  // set if this is one of mutiple spans with identical t and pt values
-    bool fNear;  // set if opposite end point is near but not equal to this one
-    bool fSmall;   // if set, consecutive points are almost equal
-    bool fTiny;  // if set, consecutive points are equal but consecutive ts are not precisely equal
-
-    // available to testing only
-    const SkOpSegment* debugToSegment(ptrdiff_t* ) const;
-    void dump() const;
-    void dumpOne() const;
 };
 
 #endif
diff --git a/src/pathops/SkOpTAllocator.h b/src/pathops/SkOpTAllocator.h
index c80c12f..e8835f0 100644
--- a/src/pathops/SkOpTAllocator.h
+++ b/src/pathops/SkOpTAllocator.h
@@ -19,6 +19,12 @@
         return record;
     }
 
+    static T* AllocateArray(SkChunkAlloc* allocator, int count) {
+        void* ptr = allocator->allocThrow(sizeof(T) * count);
+        T* record = (T*) ptr;
+        return record;
+    }
+
     static T* New(SkChunkAlloc* allocator) {
         return new (Allocate(allocator)) T();
     }
diff --git a/src/pathops/SkPathOpsCommon.cpp b/src/pathops/SkPathOpsCommon.cpp
index 1a5bfc1..b0fd822 100644
--- a/src/pathops/SkPathOpsCommon.cpp
+++ b/src/pathops/SkPathOpsCommon.cpp
@@ -5,47 +5,25 @@
  * found in the LICENSE file.
  */
 #include "SkAddIntersections.h"
+#include "SkOpCoincidence.h"
 #include "SkOpEdgeBuilder.h"
 #include "SkPathOpsCommon.h"
 #include "SkPathWriter.h"
 #include "SkTSort.h"
 
-static void alignMultiples(SkTArray<SkOpContour*, true>* contourList,
-        SkTDArray<SkOpSegment::AlignedSpan>* aligned) {
-    int contourCount = (*contourList).count();
-    for (int cTest = 0; cTest < contourCount; ++cTest) {
-        SkOpContour* contour = (*contourList)[cTest];
-        if (contour->hasMultiples()) {
-            contour->alignMultiples(aligned);
-        }
-    }
-}
-
-static void alignCoincidence(SkTArray<SkOpContour*, true>* contourList,
-        const SkTDArray<SkOpSegment::AlignedSpan>& aligned) {
-    int contourCount = (*contourList).count();
-    for (int cTest = 0; cTest < contourCount; ++cTest) {
-        SkOpContour* contour = (*contourList)[cTest];
-        int count = aligned.count();
-        for (int index = 0; index < count; ++index) {
-            contour->alignCoincidence(aligned[index]);
-        }
-    }    
-}
-
-static int contourRangeCheckY(const SkTArray<SkOpContour*, true>& contourList, SkOpSegment** currentPtr,
-                              int* indexPtr, int* endIndexPtr, double* bestHit, SkScalar* bestDx,
-                              bool* tryAgain, double* midPtr, bool opp) {
-    const int index = *indexPtr;
-    const int endIndex = *endIndexPtr;
+static int contourRangeCheckY(const SkTDArray<SkOpContour* >& contourList,
+        SkOpSegment** currentPtr, SkOpSpanBase** startPtr, SkOpSpanBase** endPtr,
+        double* bestHit, SkScalar* bestDx, bool* tryAgain, double* midPtr, bool opp) {
+    SkOpSpanBase* start = *startPtr;
+    SkOpSpanBase* end = *endPtr;
     const double mid = *midPtr;
     const SkOpSegment* current = *currentPtr;
-    double tAtMid = current->tAtMid(index, endIndex, mid);
+    double tAtMid = SkOpSegment::TAtMid(start, end, mid);
     SkPoint basePt = current->ptAtT(tAtMid);
     int contourCount = contourList.count();
     SkScalar bestY = SK_ScalarMin;
     SkOpSegment* bestSeg = NULL;
-    int bestTIndex = 0;
+    SkOpSpan* bestTSpan = NULL;
     bool bestOpp;
     bool hitSomething = false;
     for (int cTest = 0; cTest < contourCount; ++cTest) {
@@ -57,37 +35,38 @@
         if (bestY > contour->bounds().fBottom) {
             continue;
         }
-        int segmentCount = contour->segments().count();
-        for (int test = 0; test < segmentCount; ++test) {
-            SkOpSegment* testSeg = &contour->segments()[test];
+        SkOpSegment* testSeg = contour->first();
+        SkASSERT(testSeg);
+        do {
             SkScalar testY = bestY;
             double testHit;
-            int testTIndex = testSeg->crossedSpanY(basePt, &testY, &testHit, &hitSomething, tAtMid,
-                    testOpp, testSeg == current);
-            if (testTIndex < 0) {
-                if (testTIndex == SK_MinS32) {
+            bool vertical;
+            SkOpSpan* testTSpan = testSeg->crossedSpanY(basePt, tAtMid, testOpp,
+                    testSeg == current, &testY, &testHit, &hitSomething, &vertical);
+            if (!testTSpan) {
+                if (vertical) {
                     hitSomething = true;
                     bestSeg = NULL;
                     goto abortContours;  // vertical encountered, return and try different point
                 }
                 continue;
             }
-            if (testSeg == current && current->betweenTs(index, testHit, endIndex)) {
-                double baseT = current->t(index);
-                double endT = current->t(endIndex);
+            if (testSeg == current && SkOpSegment::BetweenTs(start, testHit, end)) {
+                double baseT = start->t();
+                double endT = end->t();
                 double newMid = (testHit - baseT) / (endT - baseT);
 #if DEBUG_WINDING
-                double midT = current->tAtMid(index, endIndex, mid);
-                SkPoint midXY = current->xyAtT(midT);
-                double newMidT = current->tAtMid(index, endIndex, newMid);
-                SkPoint newXY = current->xyAtT(newMidT);
+                double midT = SkOpSegment::TAtMid(start, end, mid);
+                SkPoint midXY = current->ptAtT(midT);
+                double newMidT = SkOpSegment::TAtMid(start, end, newMid);
+                SkPoint newXY = current->ptAtT(newMidT);
                 SkDebugf("%s [%d] mid=%1.9g->%1.9g s=%1.9g (%1.9g,%1.9g) m=%1.9g (%1.9g,%1.9g)"
                         " n=%1.9g (%1.9g,%1.9g) e=%1.9g (%1.9g,%1.9g)\n", __FUNCTION__,
                         current->debugID(), mid, newMid,
-                        baseT, current->xAtT(index), current->yAtT(index),
+                        baseT, start->pt().fX, start->pt().fY,
                         baseT + mid * (endT - baseT), midXY.fX, midXY.fY,
                         baseT + newMid * (endT - baseT), newXY.fX, newXY.fY,
-                        endT, current->xAtT(endIndex), current->yAtT(endIndex));
+                        endT, end->pt().fX, end->pt().fY);
 #endif
                 *midPtr = newMid * 2;  // calling loop with divide by 2 before continuing
                 return SK_MinS32;
@@ -95,38 +74,39 @@
             bestSeg = testSeg;
             *bestHit = testHit;
             bestOpp = testOpp;
-            bestTIndex = testTIndex;
+            bestTSpan = testTSpan;
             bestY = testY;
-        }
+        } while ((testSeg = testSeg->next()));
     }
 abortContours:
     int result;
     if (!bestSeg) {
         result = hitSomething ? SK_MinS32 : 0;
     } else {
-        if (bestSeg->windSum(bestTIndex) == SK_MinS32) {
+        if (bestTSpan->windSum() == SK_MinS32) {
             *currentPtr = bestSeg;
-            *indexPtr = bestTIndex;
-            *endIndexPtr = bestSeg->nextSpan(bestTIndex, 1);
-            SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0);
+            *startPtr = bestTSpan;
+            *endPtr = bestTSpan->next();
+            SkASSERT(*startPtr != *endPtr && *startPtr && *endPtr);
             *tryAgain = true;
             return 0;
         }
-        result = bestSeg->windingAtT(*bestHit, bestTIndex, bestOpp, bestDx);
+        result = bestSeg->windingAtT(*bestHit, bestTSpan, bestOpp, bestDx);
         SkASSERT(result == SK_MinS32 || *bestDx);
     }
-    double baseT = current->t(index);
-    double endT = current->t(endIndex);
+    double baseT = (*startPtr)->t();
+    double endT = (*endPtr)->t();
     *bestHit = baseT + mid * (endT - baseT);
     return result;
 }
 
-SkOpSegment* FindUndone(SkTArray<SkOpContour*, true>& contourList, int* start, int* end) {
+SkOpSegment* FindUndone(SkTDArray<SkOpContour* >& contourList, SkOpSpanBase** startPtr,
+         SkOpSpanBase** endPtr) {
     int contourCount = contourList.count();
     SkOpSegment* result;
     for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
         SkOpContour* contour = contourList[cIndex];
-        result = contour->undoneSegment(start, end);
+        result = contour->undoneSegment(startPtr, endPtr);
         if (result) {
             return result;
         }
@@ -134,20 +114,23 @@
     return NULL;
 }
 
-SkOpSegment* FindChase(SkTDArray<SkOpSpan*>* chase, int* tIndex, int* endIndex) {
+SkOpSegment* FindChase(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** startPtr,
+        SkOpSpanBase** endPtr) {
     while (chase->count()) {
-        SkOpSpan* span;
+        SkOpSpanBase* span;
         chase->pop(&span);
-        const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex);
-        SkOpSegment* segment = backPtr.fOther;
-        *tIndex = backPtr.fOtherIndex;
+        SkOpSegment* segment = span->segment();
+        *startPtr = span->ptT()->next()->span();
         bool sortable = true;
         bool done = true;
-        *endIndex = -1;
-        if (const SkOpAngle* last = segment->activeAngle(*tIndex, tIndex, endIndex, &done,
+        *endPtr = NULL;
+        if (SkOpAngle* last = segment->activeAngle(*startPtr, startPtr, endPtr, &done,
                 &sortable)) {
-            *tIndex = last->start();
-            *endIndex = last->end();
+            if (last->unorderable()) {
+                continue;
+            }
+            *startPtr = last->start();
+            *endPtr = last->end();
     #if TRY_ROTATE
             *chase->insert(0) = span;
     #else
@@ -162,65 +145,58 @@
             continue;
         }
         // find first angle, initialize winding to computed wind sum
-        const SkOpAngle* angle = segment->spanToAngle(*tIndex, *endIndex);
-        const SkOpAngle* firstAngle;
-        SkDEBUGCODE(firstAngle = angle);
-        SkDEBUGCODE(bool loop = false);
-        int winding;
+        const SkOpAngle* angle = segment->spanToAngle(*startPtr, *endPtr);
+        if (!angle) {
+            continue;
+        }
+        const SkOpAngle* firstAngle = angle;
+        bool loop = false;
+        int winding = SK_MinS32;
         do {
             angle = angle->next();
-            SkASSERT(angle != firstAngle || !loop);
-            SkDEBUGCODE(loop |= angle == firstAngle);
+            if (angle == firstAngle && loop) {
+                break;    // if we get here, there's no winding, loop is unorderable
+            }
+            loop |= angle == firstAngle;
             segment = angle->segment();
             winding = segment->windSum(angle);
         } while (winding == SK_MinS32);
-        int spanWinding = segment->spanSign(angle->start(), angle->end());
-    #if DEBUG_WINDING
-        SkDebugf("%s winding=%d spanWinding=%d\n", __FUNCTION__, winding, spanWinding);
-    #endif
-        // turn span winding into contour winding
-        if (spanWinding * winding < 0) {
-            winding += spanWinding;
+        if (winding == SK_MinS32) {
+            continue;
         }
-        // we care about first sign and whether wind sum indicates this
-        // edge is inside or outside. Maybe need to pass span winding
-        // or first winding or something into this function?
-        // advance to first undone angle, then return it and winding
-        // (to set whether edges are active or not)
+        int sumWinding = segment->updateWindingReverse(angle);
+        SkOpSegment* first = NULL;
         firstAngle = angle;
-        winding -= firstAngle->segment()->spanSign(firstAngle);
         while ((angle = angle->next()) != firstAngle) {
             segment = angle->segment();
-            int maxWinding = winding;
-            winding -= segment->spanSign(angle);
-    #if DEBUG_SORT
-            SkDebugf("%s id=%d maxWinding=%d winding=%d sign=%d\n", __FUNCTION__,
-                    segment->debugID(), maxWinding, winding, angle->sign());
-    #endif
-            *tIndex = angle->start();
-            *endIndex = angle->end();
-            int lesser = SkMin32(*tIndex, *endIndex);
-            const SkOpSpan& nextSpan = segment->span(lesser);
-            if (!nextSpan.fDone) {
-            // FIXME: this be wrong? assign startWinding if edge is in
-            // same direction. If the direction is opposite, winding to
-            // assign is flipped sign or +/- 1?
-                if (SkOpSegment::UseInnerWinding(maxWinding, winding)) {
-                    maxWinding = winding;
+            SkOpSpanBase* start = angle->start();
+            SkOpSpanBase* end = angle->end();
+            int maxWinding;
+            segment->setUpWinding(start, end, &maxWinding, &sumWinding);
+            if (!segment->done(angle)) {
+                if (!first) {
+                    first = segment;
+                    *startPtr = start;
+                    *endPtr = end;
                 }
-                // allowed to do nothing
-                (void) segment->markAndChaseWinding(angle, maxWinding, 0, NULL);
-                break;
+                // OPTIMIZATION: should this also add to the chase?
+                (void) segment->markAngle(maxWinding, sumWinding, angle);
             }
         }
-        *chase->insert(0) = span;
-        return segment;
+        if (first) {
+       #if TRY_ROTATE
+            *chase->insert(0) = span;
+       #else
+            *chase->append() = span;
+       #endif
+            return first;
+        }
     }
     return NULL;
 }
 
-#if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
-void DebugShowActiveSpans(SkTArray<SkOpContour*, true>& contourList) {
+#if DEBUG_ACTIVE_SPANS
+void DebugShowActiveSpans(SkTDArray<SkOpContour* >& contourList) {
     int index;
     for (index = 0; index < contourList.count(); ++ index) {
         contourList[index]->debugShowActiveSpans();
@@ -228,11 +204,12 @@
 }
 #endif
 
-static SkOpSegment* findTopSegment(const SkTArray<SkOpContour*, true>& contourList, int* index,
-        int* endIndex, SkPoint* topLeft, bool* unsortable, bool* done, bool firstPass) {
+static SkOpSegment* findTopSegment(const SkTDArray<SkOpContour* >& contourList,
+        bool firstPass, SkOpSpanBase** start, SkOpSpanBase** end, SkPoint* topLeft,
+        bool* unsortable, bool* done, SkChunkAlloc* allocator) {
     SkOpSegment* result;
     const SkOpSegment* lastTopStart = NULL;
-    int lastIndex = -1, lastEndIndex = -1;
+    SkOpSpanBase* lastStart = NULL, * lastEnd = NULL;
     do {
         SkPoint bestXY = {SK_ScalarMax, SK_ScalarMax};
         int contourCount = contourList.count();
@@ -261,27 +238,27 @@
             return NULL;
         }
         *topLeft = bestXY;
-        result = topStart->findTop(index, endIndex, unsortable, firstPass);
+        result = topStart->findTop(firstPass, start, end, unsortable, allocator);
         if (!result) {
-            if (lastTopStart == topStart && lastIndex == *index && lastEndIndex == *endIndex) {
+            if (lastTopStart == topStart && lastStart == *start && lastEnd == *end) {
                 *done = true;
                 return NULL;
             }
             lastTopStart = topStart;
-            lastIndex = *index;
-            lastEndIndex = *endIndex;
+            lastStart = *start;
+            lastEnd = *end;
         }
     } while (!result);
     return result;
 }
 
-static int rightAngleWinding(const SkTArray<SkOpContour*, true>& contourList,
-        SkOpSegment** currentPtr, int* indexPtr, int* endIndexPtr, double* tHit,
+static int rightAngleWinding(const SkTDArray<SkOpContour* >& contourList,
+        SkOpSegment** currentPtr, SkOpSpanBase** start, SkOpSpanBase** end, double* tHit,
         SkScalar* hitDx, bool* tryAgain, bool* onlyVertical, bool opp) {
     double test = 0.9;
     int contourWinding;
     do {
-        contourWinding = contourRangeCheckY(contourList, currentPtr, indexPtr, endIndexPtr,
+        contourWinding = contourRangeCheckY(contourList, currentPtr, start, end,
                 tHit, hitDx, tryAgain, &test, opp);
         if (contourWinding != SK_MinS32 || *tryAgain) {
             return contourWinding;
@@ -296,9 +273,9 @@
     return contourWinding;
 }
 
-static void skipVertical(const SkTArray<SkOpContour*, true>& contourList,
-        SkOpSegment** current, int* index, int* endIndex) {
-    if (!(*current)->isVertical(*index, *endIndex)) {
+static void skipVertical(const SkTDArray<SkOpContour* >& contourList,
+        SkOpSegment** current, SkOpSpanBase** start, SkOpSpanBase** end) {
+    if (!(*current)->isVertical(*start, *end)) {
         return;
     }
     int contourCount = contourList.count();
@@ -307,7 +284,7 @@
         if (contour->done()) {
             continue;
         }
-        SkOpSegment* nonVertical = contour->nonVerticalSegment(index, endIndex);
+        SkOpSegment* nonVertical = contour->nonVerticalSegment(start, end);
         if (nonVertical) {
             *current = nonVertical;
             return;
@@ -316,41 +293,41 @@
     return;
 }
 
-struct SortableTop {  // error if local in pre-C++11
-    SkOpSegment* fSegment;
-    int fIndex;
-    int fEndIndex;
+struct SortableTop2 {  // error if local in pre-C++11
+    SkOpSpanBase* fStart;
+    SkOpSpanBase* fEnd;
 };
 
-SkOpSegment* FindSortableTop(const SkTArray<SkOpContour*, true>& contourList,
-        SkOpAngle::IncludeType angleIncludeType, bool* firstContour, int* indexPtr,
-        int* endIndexPtr, SkPoint* topLeft, bool* unsortable, bool* done, bool* onlyVertical,
-        bool firstPass) {
-    SkOpSegment* current = findTopSegment(contourList, indexPtr, endIndexPtr, topLeft, unsortable,
-            done, firstPass);
+SkOpSegment* FindSortableTop(const SkTDArray<SkOpContour* >& contourList, bool firstPass,
+        SkOpAngle::IncludeType angleIncludeType, bool* firstContour, SkOpSpanBase** startPtr,
+        SkOpSpanBase** endPtr, SkPoint* topLeft, bool* unsortable, bool* done, bool* onlyVertical,
+        SkChunkAlloc* allocator) {
+    SkOpSegment* current = findTopSegment(contourList, firstPass, startPtr, endPtr, topLeft,
+            unsortable, done, allocator);
     if (!current) {
         return NULL;
     }
-    const int startIndex = *indexPtr;
-    const int endIndex = *endIndexPtr;
+    SkOpSpanBase* start = *startPtr;
+    SkOpSpanBase* end = *endPtr;
+    SkASSERT(current == start->segment());
     if (*firstContour) {
-        current->initWinding(startIndex, endIndex, angleIncludeType);
+        current->initWinding(start, end, angleIncludeType);
         *firstContour = false;
         return current;
     }
-    int minIndex = SkMin32(startIndex, endIndex);
-    int sumWinding = current->windSum(minIndex);
+    SkOpSpan* minSpan = start->starter(end);
+    int sumWinding = minSpan->windSum();
     if (sumWinding == SK_MinS32) {
-        int index = endIndex;
-        int oIndex = startIndex;
-        do { 
-            const SkOpSpan& span = current->span(index);
-            if ((oIndex < index ? span.fFromAngle : span.fToAngle) == NULL) {
-                current->addSimpleAngle(index);
+        SkOpSpanBase* iSpan = end;
+        SkOpSpanBase* oSpan = start;
+        do {
+            bool checkFrom = oSpan->t() < iSpan->t();
+            if ((checkFrom ? iSpan->fromAngle() : iSpan->upCast()->toAngle()) == NULL) {
+                iSpan->addSimpleAngle(checkFrom, allocator);
             }
-            sumWinding = current->computeSum(oIndex, index, angleIncludeType);
-            SkTSwap(index, oIndex);
-        } while (sumWinding == SK_MinS32 && index == startIndex);
+            sumWinding = current->computeSum(oSpan, iSpan, angleIncludeType);
+            SkTSwap(iSpan, oSpan);
+        } while (sumWinding == SK_MinS32 && iSpan == start);
     }
     if (sumWinding != SK_MinS32 && sumWinding != SK_NaN32) {
         return current;
@@ -364,26 +341,28 @@
     SkScalar hitDx = 0;
     SkScalar hitOppDx = 0;
     // keep track of subsequent returns to detect infinite loops
-    SkTDArray<SortableTop> sortableTops;
+    SkTDArray<SortableTop2> sortableTops;
     do {
         // if current is vertical, find another candidate which is not
         // if only remaining candidates are vertical, then they can be marked done
-        SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0);
-        skipVertical(contourList, &current, indexPtr, endIndexPtr);
+        SkASSERT(*startPtr != *endPtr && *startPtr && *endPtr);
+        SkASSERT(current == (*startPtr)->segment());
+        skipVertical(contourList, &current, startPtr, endPtr);
         SkASSERT(current);  // FIXME: if null, all remaining are vertical
-        SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0);
+        SkASSERT(*startPtr != *endPtr && *startPtr && *endPtr);
+        SkASSERT(current == (*startPtr)->segment());
         tryAgain = false;
-        contourWinding = rightAngleWinding(contourList, &current, indexPtr, endIndexPtr, &tHit,
+        contourWinding = rightAngleWinding(contourList, &current, startPtr, endPtr, &tHit,
                 &hitDx, &tryAgain, onlyVertical, false);
+        SkASSERT(current == (*startPtr)->segment());
         if (tryAgain) {
             bool giveUp = false;
             int count = sortableTops.count();
             for (int index = 0; index < count; ++index) {
-                const SortableTop& prev = sortableTops[index];
+                const SortableTop2& prev = sortableTops[index];
                 if (giveUp) {
-                    prev.fSegment->markDoneFinal(prev.fIndex);
-                } else if (prev.fSegment == current
-                        && (prev.fIndex == *indexPtr || prev.fEndIndex == *endIndexPtr)) {
+                    prev.fStart->segment()->markDone(prev.fStart->starter(prev.fEnd));
+                } else if (prev.fStart == *startPtr || prev.fEnd == *endPtr) {
                     // remaining edges are non-vertical and cannot have their winding computed
                     // mark them as done and return, and hope that assembly can fill the holes
                     giveUp = true;
@@ -395,14 +374,13 @@
                 return NULL;
             }
         }
-        SortableTop* sortableTop = sortableTops.append();
-        sortableTop->fSegment = current;
-        sortableTop->fIndex = *indexPtr;
-        sortableTop->fEndIndex = *endIndexPtr;
+        SortableTop2* sortableTop = sortableTops.append();
+        sortableTop->fStart = *startPtr;
+        sortableTop->fEnd = *endPtr;
 #if DEBUG_SORT
         SkDebugf("%s current=%d index=%d endIndex=%d tHit=%1.9g hitDx=%1.9g try=%d vert=%d\n",
-                __FUNCTION__, current->debugID(), *indexPtr, *endIndexPtr, tHit, hitDx, tryAgain,
-                *onlyVertical);
+                __FUNCTION__, current->debugID(), (*startPtr)->debugID(), (*endPtr)->debugID(),
+                tHit, hitDx, tryAgain, *onlyVertical);
 #endif
         if (*onlyVertical) {
             return current;
@@ -413,127 +391,35 @@
         if (angleIncludeType < SkOpAngle::kBinarySingle) {
             break;
         }
-        oppContourWinding = rightAngleWinding(contourList, &current, indexPtr, endIndexPtr, &tHit,
+        oppContourWinding = rightAngleWinding(contourList, &current, startPtr, endPtr, &tHit,
                 &hitOppDx, &tryAgain, NULL, true);
+        SkASSERT(current == (*startPtr)->segment());
     } while (tryAgain);
-    bool success = current->initWinding(*indexPtr, *endIndexPtr, tHit, contourWinding, hitDx,
+    bool success = current->initWinding(*startPtr, *endPtr, tHit, contourWinding, hitDx,
             oppContourWinding, hitOppDx);
     if (current->done()) {
         return NULL;
     } else if (!success) {  // check if the span has a valid winding
-        int min = SkTMin(*indexPtr, *endIndexPtr);
-        const SkOpSpan& span = current->span(min);
-        if (span.fWindSum == SK_MinS32) {
+        SkOpSpan* minSpan = (*startPtr)->t() < (*endPtr)->t() ? (*startPtr)->upCast()
+            : (*endPtr)->upCast();
+        if (minSpan->windSum() == SK_MinS32) {
             return NULL;
         }
     }
     return current;
 }
 
-static bool calcAngles(SkTArray<SkOpContour*, true>* contourList) {
-    int contourCount = (*contourList).count();
-    for (int cTest = 0; cTest < contourCount; ++cTest) {
-        SkOpContour* contour = (*contourList)[cTest];
-        if (!contour->calcAngles()) {
-            return false;
-        }
-    }
-    return true;
-}
-
-static void checkDuplicates(SkTArray<SkOpContour*, true>* contourList) {
-    int contourCount = (*contourList).count();
-    for (int cTest = 0; cTest < contourCount; ++cTest) {
-        SkOpContour* contour = (*contourList)[cTest];
-        contour->checkDuplicates();
-    }
-}
-
-static bool checkEnds(SkTArray<SkOpContour*, true>* contourList) {
-    // it's hard to determine if the end of a cubic or conic nearly intersects another curve.
-    // instead, look to see if the connecting curve intersected at that same end.
-    int contourCount = (*contourList).count();
-    for (int cTest = 0; cTest < contourCount; ++cTest) {
-        SkOpContour* contour = (*contourList)[cTest];
-        if (!contour->checkEnds()) {
-            return false;
-        }
-    }
-    return true;
-}
-
-static bool checkMultiples(SkTArray<SkOpContour*, true>* contourList) {
-    bool hasMultiples = false;
-    int contourCount = (*contourList).count();
-    for (int cTest = 0; cTest < contourCount; ++cTest) {
-        SkOpContour* contour = (*contourList)[cTest];
-        contour->checkMultiples();
-        hasMultiples |= contour->hasMultiples();
-    }
-    return hasMultiples;
-}
-
-// A small interval of a pair of curves may collapse to lines for each, triggering coincidence
-static void checkSmall(SkTArray<SkOpContour*, true>* contourList) {
-    int contourCount = (*contourList).count();
-    for (int cTest = 0; cTest < contourCount; ++cTest) {
-        SkOpContour* contour = (*contourList)[cTest];
-        contour->checkSmall();
-    }
-}
-
-// A tiny interval may indicate an undiscovered coincidence. Find and fix.
-static void checkTiny(SkTArray<SkOpContour*, true>* contourList) {
-    int contourCount = (*contourList).count();
-    for (int cTest = 0; cTest < contourCount; ++cTest) {
-        SkOpContour* contour = (*contourList)[cTest];
-        contour->checkTiny();
-    }
-}
-
-static void fixOtherTIndex(SkTArray<SkOpContour*, true>* contourList) {
-    int contourCount = (*contourList).count();
-    for (int cTest = 0; cTest < contourCount; ++cTest) {
-        SkOpContour* contour = (*contourList)[cTest];
-        contour->fixOtherTIndex();
-    }
-}
-
-static void joinCoincidence(SkTArray<SkOpContour*, true>* contourList) {
-    int contourCount = (*contourList).count();
-    for (int cTest = 0; cTest < contourCount; ++cTest) {
-        SkOpContour* contour = (*contourList)[cTest];
-        contour->joinCoincidence();
-    }
-}
-
-static void sortAngles(SkTArray<SkOpContour*, true>* contourList) {
-    int contourCount = (*contourList).count();
-    for (int cTest = 0; cTest < contourCount; ++cTest) {
-        SkOpContour* contour = (*contourList)[cTest];
-        contour->sortAngles();
-    }
-}
-
-static void sortSegments(SkTArray<SkOpContour*, true>* contourList) {
-    int contourCount = (*contourList).count();
-    for (int cTest = 0; cTest < contourCount; ++cTest) {
-        SkOpContour* contour = (*contourList)[cTest];
-        contour->sortSegments();
-    }
-}
-
-void MakeContourList(SkTArray<SkOpContour>& contours, SkTArray<SkOpContour*, true>& list,
+void MakeContourList(SkOpContour* contour, SkTDArray<SkOpContour* >& list,
                      bool evenOdd, bool oppEvenOdd) {
-    int count = contours.count();
-    if (count == 0) {
+    do {
+        if (contour->count()) {
+            contour->setOppXor(contour->operand() ? evenOdd : oppEvenOdd);
+            *list.append() = contour;
+        }
+    } while ((contour = contour->next()));
+    if (list.count() < 2) {
         return;
     }
-    for (int index = 0; index < count; ++index) {
-        SkOpContour& contour = contours[index];
-        contour.setOppXor(contour.operand() ? evenOdd : oppEvenOdd);
-        list.push_back(&contour);
-    }
     SkTQSort<SkOpContour>(list.begin(), list.end() - 1);
 }
 
@@ -554,19 +440,22 @@
         reassemble contour pieces into new path
     */
 void Assemble(const SkPathWriter& path, SkPathWriter* simple) {
+    SkOpContour contour;
+    SkOpGlobalState globalState(NULL  PATH_OPS_DEBUG_PARAMS(&contour));
 #if DEBUG_PATH_CONSTRUCTION
     SkDebugf("%s\n", __FUNCTION__);
 #endif
-    SkTArray<SkOpContour> contours;
-    SkOpEdgeBuilder builder(path, contours);
-    builder.finish();
-    int count = contours.count();
-    int outer;
-    SkTArray<int, true> runs(count);  // indices of partial contours
-    for (outer = 0; outer < count; ++outer) {
-        const SkOpContour& eContour = contours[outer];
-        const SkPoint& eStart = eContour.start();
-        const SkPoint& eEnd = eContour.end();
+    SkChunkAlloc allocator(4096);  // FIXME: constant-ize, tune
+    SkOpEdgeBuilder builder(path, &contour, &allocator, &globalState);
+    builder.finish(&allocator);
+    SkTDArray<const SkOpContour* > runs;  // indices of partial contours
+    const SkOpContour* eContour = builder.head();
+    do {
+        if (!eContour->count()) {
+            continue;
+        }
+        const SkPoint& eStart = eContour->start();
+        const SkPoint& eEnd = eContour->end();
 #if DEBUG_ASSEMBLE
         SkDebugf("%s contour", __FUNCTION__);
         if (!SkDPoint::ApproximatelyEqual(eStart, eEnd)) {
@@ -578,44 +467,42 @@
                 eStart.fX, eStart.fY, eEnd.fX, eEnd.fY);
 #endif
         if (SkDPoint::ApproximatelyEqual(eStart, eEnd)) {
-            eContour.toPath(simple);
+            eContour->toPath(simple);
             continue;
         }
-        runs.push_back(outer);
-    }
-    count = runs.count();
+        *runs.append() = eContour;
+    } while ((eContour = eContour->next()));
+    int count = runs.count();
     if (count == 0) {
         return;
     }
-    SkTArray<int, true> sLink, eLink;
-    sLink.push_back_n(count);
-    eLink.push_back_n(count);
+    SkTDArray<int> sLink, eLink;
+    sLink.append(count);
+    eLink.append(count);
     int rIndex, iIndex;
     for (rIndex = 0; rIndex < count; ++rIndex) {
         sLink[rIndex] = eLink[rIndex] = SK_MaxS32;
     }
     const int ends = count * 2;  // all starts and ends
     const int entries = (ends - 1) * count;  // folded triangle : n * (n - 1) / 2
-    SkTArray<double, true> distances;
-    distances.push_back_n(entries);
+    SkTDArray<double> distances;
+    distances.append(entries);
     for (rIndex = 0; rIndex < ends - 1; ++rIndex) {
-        outer = runs[rIndex >> 1];
-        const SkOpContour& oContour = contours[outer];
-        const SkPoint& oPt = rIndex & 1 ? oContour.end() : oContour.start();
+        const SkOpContour* oContour = runs[rIndex >> 1];
+        const SkPoint& oPt = rIndex & 1 ? oContour->end() : oContour->start();
         const int row = rIndex < count - 1 ? rIndex * ends : (ends - rIndex - 2)
                 * ends - rIndex - 1;
         for (iIndex = rIndex + 1; iIndex < ends; ++iIndex) {
-            int inner = runs[iIndex >> 1];
-            const SkOpContour& iContour = contours[inner];
-            const SkPoint& iPt = iIndex & 1 ? iContour.end() : iContour.start();
+            const SkOpContour* iContour = runs[iIndex >> 1];
+            const SkPoint& iPt = iIndex & 1 ? iContour->end() : iContour->start();
             double dx = iPt.fX - oPt.fX;
             double dy = iPt.fY - oPt.fY;
             double dist = dx * dx + dy * dy;
             distances[row + iIndex] = dist;  // oStart distance from iStart
         }
     }
-    SkTArray<int, true> sortedDist;
-    sortedDist.push_back_n(entries);
+    SkTDArray<int> sortedDist;
+    sortedDist.append(entries);
     for (rIndex = 0; rIndex < entries; ++rIndex) {
         sortedDist[rIndex] = rIndex;
     }
@@ -678,17 +565,16 @@
                     eIndex < 0 ? ~eIndex : eIndex);
 #endif
         do {
-            outer = runs[rIndex];
-            const SkOpContour& contour = contours[outer];
+            const SkOpContour* contour = runs[rIndex];
             if (first) {
                 first = false;
-                const SkPoint* startPtr = &contour.start();
+                const SkPoint* startPtr = &contour->start();
                 simple->deferredMove(startPtr[0]);
             }
             if (forward) {
-                contour.toPartialForward(simple);
+                contour->toPartialForward(simple);
             } else {
-                contour.toPartialBackward(simple);
+                contour->toPartialBackward(simple);
             }
 #if DEBUG_ASSEMBLE
             SkDebugf("%s rIndex=%d eIndex=%s%d close=%d\n", __FUNCTION__, rIndex,
@@ -742,36 +628,88 @@
 #endif
 }
 
-bool HandleCoincidence(SkTArray<SkOpContour*, true>* contourList, int total) {
-#if DEBUG_SHOW_WINDING
-    SkOpContour::debugShowWindingValues(contourList);
-#endif
-    if (!CoincidenceCheck(contourList, total)) {
+static void align(SkTDArray<SkOpContour* >* contourList) {
+    int contourCount = (*contourList).count();
+    for (int cTest = 0; cTest < contourCount; ++cTest) {
+        SkOpContour* contour = (*contourList)[cTest];
+        contour->align();
+    }
+}
+
+static void calcAngles(SkTDArray<SkOpContour* >* contourList, SkChunkAlloc* allocator) {
+    int contourCount = (*contourList).count();
+    for (int cTest = 0; cTest < contourCount; ++cTest) {
+        SkOpContour* contour = (*contourList)[cTest];
+        contour->calcAngles(allocator);
+    }
+}
+
+static void missingCoincidence(SkTDArray<SkOpContour* >* contourList,
+        SkOpCoincidence* coincidence, SkChunkAlloc* allocator) {
+    int contourCount = (*contourList).count();
+    for (int cTest = 0; cTest < contourCount; ++cTest) {
+        SkOpContour* contour = (*contourList)[cTest];
+        contour->missingCoincidence(coincidence, allocator);
+    }
+}
+
+static bool moveNearby(SkTDArray<SkOpContour* >* contourList) {
+    int contourCount = (*contourList).count();
+    for (int cTest = 0; cTest < contourCount; ++cTest) {
+        SkOpContour* contour = (*contourList)[cTest];
+        if (!contour->moveNearby()) {
+            return false;
+        }
+    }
+    return true;
+}
+
+static void sortAngles(SkTDArray<SkOpContour* >* contourList) {
+    int contourCount = (*contourList).count();
+    for (int cTest = 0; cTest < contourCount; ++cTest) {
+        SkOpContour* contour = (*contourList)[cTest];
+        contour->sortAngles();
+    }
+}
+
+static void sortSegments(SkTDArray<SkOpContour* >* contourList) {
+    int contourCount = (*contourList).count();
+    for (int cTest = 0; cTest < contourCount; ++cTest) {
+        SkOpContour* contour = (*contourList)[cTest];
+        contour->sortSegments();
+    }
+}
+
+bool HandleCoincidence(SkTDArray<SkOpContour* >* contourList, SkOpCoincidence* coincidence,
+        SkChunkAlloc* allocator, SkOpGlobalState* globalState) {
+    // move t values and points together to eliminate small/tiny gaps
+    if (!moveNearby(contourList)) {
         return false;
     }
-#if DEBUG_SHOW_WINDING
-    SkOpContour::debugShowWindingValues(contourList);
+    align(contourList);  // give all span members common values
+#if DEBUG_VALIDATE
+    globalState->setPhase(SkOpGlobalState::kIntersecting);
 #endif
-    fixOtherTIndex(contourList);
-    if (!checkEnds(contourList)) {  // check if connecting curve intersected at the same end
+    coincidence->addMissing(allocator);
+#if DEBUG_VALIDATE
+    globalState->setPhase(SkOpGlobalState::kWalking);
+#endif
+    coincidence->expand();  // check to see if, loosely, coincident ranges may be expanded
+    coincidence->mark();  // mark spans of coincident segments as coincident
+    missingCoincidence(contourList, coincidence, allocator);  // look for coincidence missed earlier
+    if (!coincidence->apply()) {  // adjust the winding value to account for coincident edges
         return false;
     }
-    bool hasM = checkMultiples(contourList);  // check if intersections agree on t and point values
-    SkTDArray<SkOpSegment::AlignedSpan> aligned;
-    if (hasM) {
-        alignMultiples(contourList, &aligned);  // align pairs of identical points
-        alignCoincidence(contourList, aligned);
-    }
-    checkDuplicates(contourList);  // check if spans have the same number on the other end
-    checkTiny(contourList);  // if pair have the same end points, mark them as parallel
-    checkSmall(contourList);  // a pair of curves with a small span may turn into coincident lines
-    joinCoincidence(contourList);  // join curves that connect to a coincident pair
     sortSegments(contourList);
-    if (!calcAngles(contourList)) {
-        return false;
-    }
+    calcAngles(contourList, allocator);
     sortAngles(contourList);
-#if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
+    if (globalState->angleCoincidence()) {
+        missingCoincidence(contourList, coincidence, allocator);
+        if (!coincidence->apply()) {
+            return false;
+        }
+    }
+#if DEBUG_ACTIVE_SPANS
     DebugShowActiveSpans(*contourList);
 #endif
     return true;
diff --git a/src/pathops/SkPathOpsCommon.h b/src/pathops/SkPathOpsCommon.h
index 0d8cfc4..1bf1791 100644
--- a/src/pathops/SkPathOpsCommon.h
+++ b/src/pathops/SkPathOpsCommon.h
@@ -8,24 +8,28 @@
 #define SkPathOpsCommon_DEFINED
 
 #include "SkOpAngle.h"
-#include "SkOpContour.h"
 #include "SkTDArray.h"
 
+class SkOpCoincidence;
+class SkOpContour;
 class SkPathWriter;
 
 void Assemble(const SkPathWriter& path, SkPathWriter* simple);
-// FIXME: find chase uses insert, so it can't be converted to SkTArray yet
-SkOpSegment* FindChase(SkTDArray<SkOpSpan*>* chase, int* tIndex, int* endIndex);
-SkOpSegment* FindSortableTop(const SkTArray<SkOpContour*, true>& , SkOpAngle::IncludeType ,
-                             bool* firstContour, int* index, int* endIndex, SkPoint* topLeft,
-                             bool* unsortable, bool* done, bool* onlyVertical, bool firstPass);
-SkOpSegment* FindUndone(SkTArray<SkOpContour*, true>& contourList, int* start, int* end);
-void MakeContourList(SkTArray<SkOpContour>& contours, SkTArray<SkOpContour*, true>& list,
+SkOpSegment* FindChase(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** startPtr,
+                       SkOpSpanBase** endPtr);
+SkOpSegment* FindSortableTop(const SkTDArray<SkOpContour*>& , bool firstPass,
+                              SkOpAngle::IncludeType , bool* firstContour, SkOpSpanBase** index,
+                              SkOpSpanBase** endIndex, SkPoint* topLeft, bool* unsortable,
+                              bool* done, bool* onlyVertical, SkChunkAlloc* );
+SkOpSegment* FindUndone(SkTDArray<SkOpContour*>& contourList, SkOpSpanBase** startPtr,
+                         SkOpSpanBase** endPtr);
+void MakeContourList(SkOpContour* , SkTDArray<SkOpContour*>& list,
                      bool evenOdd, bool oppEvenOdd);
-bool HandleCoincidence(SkTArray<SkOpContour*, true>* , int );
+bool HandleCoincidence(SkTDArray<SkOpContour*>* , SkOpCoincidence* , SkChunkAlloc* ,
+                       SkOpGlobalState* );
 
-#if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
-void DebugShowActiveSpans(SkTArray<SkOpContour*, true>& contourList);
+#if DEBUG_ACTIVE_SPANS
+void DebugShowActiveSpans(SkTDArray<SkOpContour*>& contourList);
 #endif
 
 #endif
diff --git a/src/pathops/SkPathOpsCubic.cpp b/src/pathops/SkPathOpsCubic.cpp
index 9d70d58..d4a5898 100644
--- a/src/pathops/SkPathOpsCubic.cpp
+++ b/src/pathops/SkPathOpsCubic.cpp
@@ -4,6 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+#include "SkGeometry.h"
 #include "SkLineParameters.h"
 #include "SkPathOpsCubic.h"
 #include "SkPathOpsLine.h"
@@ -26,8 +27,8 @@
         double priorT = t - step;
         SkASSERT(priorT >= min);
         SkDPoint lessPt = ptAtT(priorT);
-        if (approximately_equal(lessPt.fX, cubicAtT.fX)
-                && approximately_equal(lessPt.fY, cubicAtT.fY)) {
+        if (approximately_equal_half(lessPt.fX, cubicAtT.fX)
+                && approximately_equal_half(lessPt.fY, cubicAtT.fY)) {
             return -1;  // binary search found no point at this axis intercept
         }
         double lessDist = (&lessPt.fX)[xAxis] - axisIntercept;
@@ -41,10 +42,12 @@
             t = priorT;
         } else {
             double nextT = t + lastStep;
-            SkASSERT(nextT <= max);
+            if (nextT > max) {
+                return -1;
+            }
             SkDPoint morePt = ptAtT(nextT);
-            if (approximately_equal(morePt.fX, cubicAtT.fX)
-                    && approximately_equal(morePt.fY, cubicAtT.fY)) {
+            if (approximately_equal_half(morePt.fX, cubicAtT.fX)
+                    && approximately_equal_half(morePt.fY, cubicAtT.fY)) {
                 return -1;  // binary search found no point at this axis intercept
             }
             double moreDist = (&morePt.fX)[xAxis] - axisIntercept;
@@ -88,35 +91,6 @@
     *C -= 3 * *D;           // C = -3*a + 3*b
 }
 
-bool SkDCubic::controlsContainedByEnds() const {
-    SkDVector startTan = fPts[1] - fPts[0];
-    if (startTan.fX == 0 && startTan.fY == 0) {
-        startTan = fPts[2] - fPts[0];
-    }
-    SkDVector endTan = fPts[2] - fPts[3];
-    if (endTan.fX == 0 && endTan.fY == 0) {
-        endTan = fPts[1] - fPts[3];
-    }
-    if (startTan.dot(endTan) >= 0) {
-        return false;
-    }
-    SkDLine startEdge = {{fPts[0], fPts[0]}};
-    startEdge[1].fX -= startTan.fY;
-    startEdge[1].fY += startTan.fX;
-    SkDLine endEdge = {{fPts[3], fPts[3]}};
-    endEdge[1].fX -= endTan.fY;
-    endEdge[1].fY += endTan.fX;
-    double leftStart1 = startEdge.isLeft(fPts[1]);
-    if (leftStart1 * startEdge.isLeft(fPts[2]) < 0) {
-        return false;
-    }
-    double leftEnd1 = endEdge.isLeft(fPts[1]);
-    if (leftEnd1 * endEdge.isLeft(fPts[2]) < 0) {
-        return false;
-    }
-    return leftStart1 * leftEnd1 >= 0;
-}
-
 bool SkDCubic::endsAreExtremaInXOrY() const {
     return (between(fPts[0].fX, fPts[1].fX, fPts[3].fX)
             && between(fPts[0].fX, fPts[2].fX, fPts[3].fX))
@@ -124,17 +98,120 @@
             && between(fPts[0].fY, fPts[2].fY, fPts[3].fY));
 }
 
+// Do a quick reject by rotating all points relative to a line formed by
+// a pair of one cubic's points. If the 2nd cubic's points
+// are on the line or on the opposite side from the 1st cubic's 'odd man', the
+// curves at most intersect at the endpoints.
+/* if returning true, check contains true if cubic's hull collapsed, making the cubic linear
+   if returning false, check contains true if the the cubic pair have only the end point in common
+*/
+bool SkDCubic::hullIntersects(const SkDCubic& c2, bool* isLinear) const {
+    bool linear = true;
+    char hullOrder[4];
+    int hullCount = convexHull(hullOrder);
+    int end1 = hullOrder[0];
+    int hullIndex = 0;
+    const SkDPoint* endPt[2];
+    endPt[0] = &fPts[end1];
+    do {
+        hullIndex = (hullIndex + 1) % hullCount;
+        int end2 = hullOrder[hullIndex];
+        endPt[1] = &fPts[end2];
+        double origX = endPt[0]->fX;
+        double origY = endPt[0]->fY;
+        double adj = endPt[1]->fX - origX;
+        double opp = endPt[1]->fY - origY;
+        int oddManMask = other_two(end1, end2);
+        int oddMan = end1 ^ oddManMask;
+        double sign = (fPts[oddMan].fY - origY) * adj - (fPts[oddMan].fX - origX) * opp;
+        int oddMan2 = end2 ^ oddManMask;
+        double sign2 = (fPts[oddMan2].fY - origY) * adj - (fPts[oddMan2].fX - origX) * opp;
+        if (sign * sign2 < 0) {
+            continue;
+        }
+        if (approximately_zero(sign)) {
+            sign = sign2;
+            if (approximately_zero(sign)) {
+                continue;
+            }
+        }
+        linear = false;
+        bool foundOutlier = false;
+        for (int n = 0; n < kPointCount; ++n) {
+            double test = (c2[n].fY - origY) * adj - (c2[n].fX - origX) * opp;
+            if (test * sign > 0 && !precisely_zero(test)) {
+                foundOutlier = true;
+                break;
+            }
+        }
+        if (!foundOutlier) {
+            return false;
+        }
+        endPt[0] = endPt[1];
+        end1 = end2;
+    } while (hullIndex);
+    *isLinear = linear;
+    return true;
+}
+
 bool SkDCubic::isLinear(int startIndex, int endIndex) const {
     SkLineParameters lineParameters;
     lineParameters.cubicEndPoints(*this, startIndex, endIndex);
     // FIXME: maybe it's possible to avoid this and compare non-normalized
     lineParameters.normalize();
+    double tiniest = SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY),
+            fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY), fPts[3].fX), fPts[3].fY);
+    double largest = SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY),
+            fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY), fPts[3].fX), fPts[3].fY);
+    largest = SkTMax(largest, -tiniest);
     double distance = lineParameters.controlPtDistance(*this, 1);
-    if (!approximately_zero(distance)) {
+    if (!approximately_zero_when_compared_to(distance, largest)) {
         return false;
     }
     distance = lineParameters.controlPtDistance(*this, 2);
-    return approximately_zero(distance);
+    return approximately_zero_when_compared_to(distance, largest);
+}
+
+bool SkDCubic::ComplexBreak(const SkPoint pointsPtr[4], SkScalar* t) {
+    SkScalar d[3];
+    SkCubicType cubicType = SkClassifyCubic(pointsPtr, d);
+    if (cubicType == kLoop_SkCubicType) {
+        // crib code from gpu path utils that finds t values where loop self-intersects
+        // use it to find mid of t values which should be a friendly place to chop
+        SkScalar tempSqrt = SkScalarSqrt(4.f * d[0] * d[2] - 3.f * d[1] * d[1]);
+        SkScalar ls = d[1] - tempSqrt;
+        SkScalar lt = 2.f * d[0];
+        SkScalar ms = d[1] + tempSqrt;
+        SkScalar mt = 2.f * d[0];
+        if (between(0, ls, lt) || between(0, ms, mt)) {
+            ls = ls / lt;
+            ms = ms / mt;
+            SkScalar smaller = SkTMax(0.f, SkTMin(ls, ms));
+            SkScalar larger = SkTMin(1.f, SkTMax(ls, ms));
+            *t = (smaller + larger) / 2;
+            return *t > 0 && *t < 1;
+        }
+    } else if (cubicType == kSerpentine_SkCubicType) {
+        SkDCubic cubic;
+        cubic.set(pointsPtr);
+        double inflectionTs[2];
+        int infTCount = cubic.findInflections(inflectionTs);
+        if (infTCount == 2) {
+            double maxCurvature[3];
+            int roots = cubic.findMaxCurvature(maxCurvature);
+            for (int index = 0; index < roots; ++index) {
+                if (between(inflectionTs[0], maxCurvature[index], inflectionTs[1])) {
+                    *t = maxCurvature[index];
+                    return true;
+                }
+            }
+        } else if (infTCount == 1) {
+            *t = inflectionTs[0];
+            return *t > 0 && *t < 1;
+        }
+        return false;
+    }
+    return false;
 }
 
 bool SkDCubic::monotonicInY() const {
@@ -142,6 +219,13 @@
             && between(fPts[0].fY, fPts[2].fY, fPts[3].fY);
 }
 
+void SkDCubic::otherPts(int index, const SkDPoint* o1Pts[kPointCount - 1]) const {
+    int offset = (int) !SkToBool(index);
+    o1Pts[0] = &fPts[offset];
+    o1Pts[1] = &fPts[++offset];
+    o1Pts[2] = &fPts[++offset];
+}
+
 int SkDCubic::searchRoots(double extremeTs[6], int extrema, double axisIntercept,
         SearchAxis xAxis, double* validRoots) const {
     extrema += findInflections(&extremeTs[extrema]);
@@ -163,26 +247,6 @@
     return validCount;
 }
 
-bool SkDCubic::serpentine() const {
-#if 0  // FIXME: enabling this fixes cubicOp114 but breaks cubicOp58d and cubicOp53d
-    double tValues[2];
-    // OPTIMIZATION : another case where caching the present of cubic inflections would be useful
-    return findInflections(tValues) > 1;
-#endif
-    if (!controlsContainedByEnds()) {
-        return false;
-    }
-    double wiggle = (fPts[0].fX - fPts[2].fX) * (fPts[0].fY + fPts[2].fY);
-    for (int idx = 0; idx < 2; ++idx) {
-        wiggle += (fPts[idx + 1].fX - fPts[idx].fX) * (fPts[idx + 1].fY + fPts[idx].fY);
-    }
-    double waggle = (fPts[1].fX - fPts[3].fX) * (fPts[1].fY + fPts[3].fY);
-    for (int idx = 1; idx < 3; ++idx) {
-        waggle += (fPts[idx + 1].fX - fPts[idx].fX) * (fPts[idx + 1].fY + fPts[idx].fY);
-    }
-    return wiggle * waggle < 0;
-}
-
 // cubic roots
 
 static const double PI = 3.141592653589793;
@@ -505,25 +569,10 @@
 void SkDCubic::subDivide(const SkDPoint& a, const SkDPoint& d,
                          double t1, double t2, SkDPoint dst[2]) const {
     SkASSERT(t1 != t2);
-#if 0
-    double ex = interp_cubic_coords(&fPts[0].fX, (t1 * 2 + t2) / 3);
-    double ey = interp_cubic_coords(&fPts[0].fY, (t1 * 2 + t2) / 3);
-    double fx = interp_cubic_coords(&fPts[0].fX, (t1 + t2 * 2) / 3);
-    double fy = interp_cubic_coords(&fPts[0].fY, (t1 + t2 * 2) / 3);
-    double mx = ex * 27 - a.fX * 8 - d.fX;
-    double my = ey * 27 - a.fY * 8 - d.fY;
-    double nx = fx * 27 - a.fX - d.fX * 8;
-    double ny = fy * 27 - a.fY - d.fY * 8;
-    /* bx = */ dst[0].fX = (mx * 2 - nx) / 18;
-    /* by = */ dst[0].fY = (my * 2 - ny) / 18;
-    /* cx = */ dst[1].fX = (nx * 2 - mx) / 18;
-    /* cy = */ dst[1].fY = (ny * 2 - my) / 18;
-#else
     // this approach assumes that the control points computed directly are accurate enough
     SkDCubic sub = subDivide(t1, t2);
     dst[0] = sub[1] + (a - sub[0]);
     dst[1] = sub[2] + (d - sub[3]);
-#endif
     if (t1 == 0 || t2 == 0) {
         align(0, 1, t1 == 0 ? &dst[0] : &dst[1]);
     }
diff --git a/src/pathops/SkPathOpsCubic.h b/src/pathops/SkPathOpsCubic.h
index 1037cae..9932e1d 100644
--- a/src/pathops/SkPathOpsCubic.h
+++ b/src/pathops/SkPathOpsCubic.h
@@ -10,7 +10,6 @@
 
 #include "SkPath.h"
 #include "SkPathOpsPoint.h"
-#include "SkTArray.h"
 
 struct SkDCubicPair {
     const SkDCubic& first() const { return (const SkDCubic&) pts[0]; }
@@ -19,13 +18,33 @@
 };
 
 struct SkDCubic {
+    static const int kPointCount = 4;
+    static const int kPointLast = kPointCount - 1;
+    static const int kMaxIntersections = 9;
+
     enum SearchAxis {
         kXAxis,
         kYAxis
     };
 
-    const SkDPoint& operator[](int n) const { SkASSERT(n >= 0 && n < 4); return fPts[n]; }
-    SkDPoint& operator[](int n) { SkASSERT(n >= 0 && n < 4); return fPts[n]; }
+    bool collapsed() const {
+        return fPts[0].approximatelyEqual(fPts[1]) && fPts[0].approximatelyEqual(fPts[2])
+                && fPts[0].approximatelyEqual(fPts[3]);
+    }
+
+    bool controlsInside() const {
+        SkDVector v01 = fPts[0] - fPts[1];
+        SkDVector v02 = fPts[0] - fPts[2];
+        SkDVector v03 = fPts[0] - fPts[3];
+        SkDVector v13 = fPts[1] - fPts[3];
+        SkDVector v23 = fPts[2] - fPts[3];
+        return v03.dot(v01) > 0 && v03.dot(v02) > 0 && v03.dot(v13) > 0 && v03.dot(v23) > 0;
+    }
+
+    static bool IsCubic() { return true; }
+
+    const SkDPoint& operator[](int n) const { SkASSERT(n >= 0 && n < kPointCount); return fPts[n]; }
+    SkDPoint& operator[](int n) { SkASSERT(n >= 0 && n < kPointCount); return fPts[n]; }
 
     void align(int endIndex, int ctrlIndex, SkDPoint* dstPt) const;
     double binarySearch(double min, double max, double axisIntercept, SearchAxis xAxis) const;
@@ -33,30 +52,35 @@
     SkDCubicPair chopAt(double t) const;
     bool clockwise() const;
     static void Coefficients(const double* cubic, double* A, double* B, double* C, double* D);
-    bool controlsContainedByEnds() const;
+    static bool ComplexBreak(const SkPoint pts[4], SkScalar* t);
+    int convexHull(char order[kPointCount]) const;
+    void dump() const;  // callable from the debugger when the implementation code is linked in
+    void dumpID(int id) const;
+    void dumpInner() const;
     SkDVector dxdyAtT(double t) const;
     bool endsAreExtremaInXOrY() const;
     static int FindExtrema(double a, double b, double c, double d, double tValue[2]);
     int findInflections(double tValues[2]) const;
 
-    static int FindInflections(const SkPoint a[4], double tValues[2]) {
+    static int FindInflections(const SkPoint a[kPointCount], double tValues[2]) {
         SkDCubic cubic;
         cubic.set(a);
         return cubic.findInflections(tValues);
     }
 
     int findMaxCurvature(double tValues[]) const;
+    bool hullIntersects(const SkDCubic& c2, bool* isLinear) const;
     bool isLinear(int startIndex, int endIndex) const;
     bool monotonicInY() const;
+    void otherPts(int index, const SkDPoint* o1Pts[kPointCount - 1]) const;
     SkDPoint ptAtT(double t) const;
     static int RootsReal(double A, double B, double C, double D, double t[3]);
     static int RootsValidT(const double A, const double B, const double C, double D, double s[3]);
 
     int searchRoots(double extremes[6], int extrema, double axisIntercept,
                     SearchAxis xAxis, double* validRoots) const;
-    bool serpentine() const;
 
-    void set(const SkPoint pts[4]) {
+    void set(const SkPoint pts[kPointCount]) {
         fPts[0] = pts[0];
         fPts[1] = pts[1];
         fPts[2] = pts[2];
@@ -65,7 +89,7 @@
 
     SkDCubic subDivide(double t1, double t2) const;
 
-    static SkDCubic SubDivide(const SkPoint a[4], double t1, double t2) {
+    static SkDCubic SubDivide(const SkPoint a[kPointCount], double t1, double t2) {
         SkDCubic cubic;
         cubic.set(a);
         return cubic.subDivide(t1, t2);
@@ -73,7 +97,7 @@
 
     void subDivide(const SkDPoint& a, const SkDPoint& d, double t1, double t2, SkDPoint p[2]) const;
 
-    static void SubDivide(const SkPoint pts[4], const SkDPoint& a, const SkDPoint& d, double t1,
+    static void SubDivide(const SkPoint pts[kPointCount], const SkDPoint& a, const SkDPoint& d, double t1,
                           double t2, SkDPoint p[2]) {
         SkDCubic cubic;
         cubic.set(pts);
@@ -81,16 +105,29 @@
     }
 
     SkDPoint top(double startT, double endT) const;
-    void toQuadraticTs(double precision, SkTArray<double, true>* ts) const;
     SkDQuad toQuad() const;
 
-    // utilities callable by the user from the debugger when the implementation code is linked in
-    void dump() const;
-    void dumpNumber() const;
-
     static const int gPrecisionUnit;
 
-    SkDPoint fPts[4];
+    SkDPoint fPts[kPointCount];
 };
 
+/* Given the set [0, 1, 2, 3], and two of the four members, compute an XOR mask
+   that computes the other two. Note that:
+
+   one ^ two == 3 for (0, 3), (1, 2)
+   one ^ two <  3 for (0, 1), (0, 2), (1, 3), (2, 3)
+   3 - (one ^ two) is either 0, 1, or 2
+   1 >> (3 - (one ^ two)) is either 0 or 1
+thus:
+   returned == 2 for (0, 3), (1, 2)
+   returned == 3 for (0, 1), (0, 2), (1, 3), (2, 3)
+given that:
+   (0, 3) ^ 2 -> (2, 1)  (1, 2) ^ 2 -> (3, 0)
+   (0, 1) ^ 3 -> (3, 2)  (0, 2) ^ 3 -> (3, 1)  (1, 3) ^ 3 -> (2, 0)  (2, 3) ^ 3 -> (1, 0)
+*/
+inline int other_two(int one, int two) {
+    return 1 >> (3 - (one ^ two)) ^ 3;
+}
+
 #endif
diff --git a/src/pathops/SkPathOpsCubicSect.h b/src/pathops/SkPathOpsCubicSect.h
deleted file mode 100644
index d763444..0000000
--- a/src/pathops/SkPathOpsCubicSect.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef SkCubicSpan_DEFINE
-#define SkCubicSpan_DEFINE
-
-#include "SkChunkAlloc.h"
-#include "SkPathOpsRect.h"
-#include "SkPathOpsCubic.h"
-#include "SkTArray.h"
-
-class SkIntersections;
-
-class SkCubicCoincident {
-public:
-    bool isCoincident() const {
-        return fCoincident;
-    }
-
-    void init() {
-        fCoincident = false;
-        SkDEBUGCODE(fPerpPt.fX = fPerpPt.fY = SK_ScalarNaN);
-        SkDEBUGCODE(fPerpT = SK_ScalarNaN);
-    }
-
-    void markCoincident() {
-        if (!fCoincident) {
-            fPerpT = -1;
-        }
-        fCoincident = true;
-    }
-
-    const SkDPoint& perpPt() const {
-        return fPerpPt;
-    }
-
-    double perpT() const {
-        return fPerpT;
-    }
-
-    void setPerp(const SkDCubic& cubic1, double t, const SkDPoint& qPt, const SkDCubic& cubic2);
-
-private:
-    SkDPoint fPerpPt;
-    double fPerpT;  // perpendicular intersection on opposite Cubic
-    bool fCoincident;
-};
-
-class SkCubicSect;  // used only by debug id
-
-class SkCubicSpan {
-public:
-    void init(const SkDCubic& Cubic);
-    void initBounds(const SkDCubic& Cubic);
-
-    bool contains(double t) const {
-        return !! const_cast<SkCubicSpan*>(this)->innerFind(t);
-    }
-
-    bool contains(const SkCubicSpan* span) const;
-
-    SkCubicSpan* find(double t) {
-        SkCubicSpan* result = innerFind(t);
-        SkASSERT(result);
-        return result;
-    }
-
-    bool intersects(const SkCubicSpan* span) const;
-
-    const SkCubicSpan* next() const {
-        return fNext;
-    }
-
-    void reset() {
-        fBounded.reset();
-    }
-
-    bool split(SkCubicSpan* work) {
-        return splitAt(work, (work->fStartT + work->fEndT) * 0.5);
-    }
-
-    bool splitAt(SkCubicSpan* work, double t);
-    bool tightBoundsIntersects(const SkCubicSpan* span) const;
-
-    // implementation is for testing only
-    void dump() const;
-
-private:
-    bool hullIntersects(const SkDCubic& ) const;
-    SkCubicSpan* innerFind(double t);
-    bool linearIntersects(const SkDCubic& ) const;
-
-    // implementation is for testing only
-#if DEBUG_BINARY_CUBIC
-    int debugID(const SkCubicSect* ) const { return fDebugID; }
-#else
-    int debugID(const SkCubicSect* ) const;
-#endif
-    void dump(const SkCubicSect* ) const;
-    void dumpID(const SkCubicSect* ) const;
-
-#if DEBUG_BINARY_CUBIC
-    void validate() const;
-#endif
-
-    SkDCubic fPart;
-    SkCubicCoincident fCoinStart;
-    SkCubicCoincident fCoinEnd;
-    SkSTArray<4, SkCubicSpan*, true> fBounded;
-    SkCubicSpan* fPrev;
-    SkCubicSpan* fNext;
-    SkDRect fBounds;
-    double fStartT;
-    double fEndT;
-    double fBoundsMax;
-    bool fCollapsed;
-    bool fHasPerp;
-    mutable bool fIsLinear;
-#if DEBUG_BINARY_CUBIC
-    int fDebugID;
-    bool fDebugDeleted;
-#endif
-    friend class SkCubicSect;
-};
-
-class SkCubicSect {
-public:
-    SkCubicSect(const SkDCubic& Cubic PATH_OPS_DEBUG_PARAMS(int id));
-    static void BinarySearch(SkCubicSect* sect1, SkCubicSect* sect2, SkIntersections* intersections);
-
-    // for testing only
-    void dumpCubics() const;
-private:
-    SkCubicSpan* addOne();
-    bool binarySearchCoin(const SkCubicSect& , double tStart, double tStep, double* t,
-            double* oppT);
-    SkCubicSpan* boundsMax() const;
-    void coincidentCheck(SkCubicSect* sect2);
-    bool intersects(const SkCubicSpan* span, const SkCubicSect* opp, const SkCubicSpan* oppSpan) const;
-    void onCurveCheck(SkCubicSect* sect2, SkCubicSpan* first, SkCubicSpan* last);
-    void recoverCollapsed();
-    void removeSpan(SkCubicSpan* span);
-    void removeOne(const SkCubicSpan* test, SkCubicSpan* span);
-    void removeSpans(SkCubicSpan* span, SkCubicSect* opp);
-    void setPerp(const SkDCubic& opp, SkCubicSpan* first, SkCubicSpan* last);
-    void trim(SkCubicSpan* span, SkCubicSect* opp);
-
-    // for testing only
-    void dump() const;
-    void dumpBoth(const SkCubicSect& opp) const;
-    void dumpBoth(const SkCubicSect* opp) const;
-
-#if DEBUG_BINARY_CUBIC
-    int debugID() const { return fDebugID; }
-    void validate() const;
-#else
-    int debugID() const { return 0; }
-#endif
-    const SkDCubic& fCubic;
-    SkChunkAlloc fHeap;
-    SkCubicSpan* fHead;
-    SkCubicSpan* fDeleted;
-    int fActiveCount;
-#if DEBUG_BINARY_CUBIC
-    int fDebugID;
-    int fDebugCount;
-    int fDebugAllocatedCount;
-#endif
-    friend class SkCubicSpan;  // only used by debug id
-};
-
-#endif
diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp
index 7db93f5..0331f34 100644
--- a/src/pathops/SkPathOpsDebug.cpp
+++ b/src/pathops/SkPathOpsDebug.cpp
@@ -7,6 +7,13 @@
 
 #include "SkPathOpsDebug.h"
 #include "SkPath.h"
+#if DEBUG_ANGLE
+#include "SkString.h"
+#endif
+
+#if DEBUG_VALIDATE
+extern bool FLAGS_runFail;
+#endif
 
 #if defined SK_DEBUG || !FORCE_RELEASE
 
@@ -26,10 +33,10 @@
 const char* SkPathOpsDebug::kPathOpStr[] = {"diff", "sect", "union", "xor"};
 #endif
 
-bool SkPathOpsDebug::ChaseContains(const SkTDArray<SkOpSpan *>& chaseArray,
-        const SkOpSpan* span) {
+bool SkPathOpsDebug::ChaseContains(const SkTDArray<SkOpSpanBase* >& chaseArray,
+        const SkOpSpanBase* span) {
     for (int index = 0; index < chaseArray.count(); ++index) {
-        const SkOpSpan* entry = chaseArray[index];
+        const SkOpSpanBase* entry = chaseArray[index];
         if (entry == span) {
             return true;
         }
@@ -65,6 +72,8 @@
         SkDebugf("%d", wind);
     }
 }
+#endif //  defined SK_DEBUG || !FORCE_RELEASE
+
 
 #if DEBUG_SHOW_TEST_NAME
 void* SkPathOpsDebug::CreateNameStr() {
@@ -97,11 +106,160 @@
 }
 #endif
 
-#endif //  defined SK_DEBUG || !FORCE_RELEASE
-
 #include "SkOpAngle.h"
 #include "SkOpSegment.h"
 
+#if DEBUG_SWAP_TOP
+int SkOpSegment::debugInflections(const SkOpSpanBase* start, const SkOpSpanBase* end) const {
+    if (fVerb != SkPath::kCubic_Verb) {
+        return false;
+    }
+    SkDCubic dst = SkDCubic::SubDivide(fPts, start->t(), end->t());
+    double inflections[2];
+    return dst.findInflections(inflections);
+}
+#endif
+
+SkOpAngle* SkOpSegment::debugLastAngle() {
+    SkOpAngle* result = NULL;
+    SkOpSpan* span = this->head();
+    do {
+        if (span->toAngle()) {
+            SkASSERT(!result);
+            result = span->toAngle();
+        }
+    } while ((span = span->next()->upCastable()));
+    SkASSERT(result);
+    return result;
+}
+
+void SkOpSegment::debugReset() {
+    this->init(this->fPts, this->contour(), this->verb());
+}
+
+#if DEBUG_ACTIVE_SPANS
+void SkOpSegment::debugShowActiveSpans() const {
+    debugValidate();
+    if (done()) {
+        return;
+    }
+    int lastId = -1;
+    double lastT = -1;
+    const SkOpSpan* span = &fHead;
+    do {
+        if (span->done()) {
+            continue;
+        }
+        if (lastId == fID && lastT == span->t()) {
+            continue;
+        }
+        lastId = fID;
+        lastT = span->t();
+        SkDebugf("%s id=%d", __FUNCTION__, fID);
+        SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
+        for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
+            SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
+        }
+        const SkOpPtT* ptT = span->ptT();
+        SkDebugf(") t=%1.9g (%1.9g,%1.9g)", ptT->fT, ptT->fPt.fX, ptT->fPt.fY);
+        SkDebugf(" tEnd=%1.9g", span->next()->t());
+        SkDebugf(" windSum=");
+        if (span->windSum() == SK_MinS32) {
+            SkDebugf("?");
+        } else {
+            SkDebugf("%d", span->windSum());
+        }
+        SkDebugf(" windValue=%d oppValue=%d", span->windValue(), span->oppValue());
+        SkDebugf("\n");
+   } while ((span = span->next()->upCastable()));
+}
+#endif
+
+#if DEBUG_MARK_DONE
+void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding) {
+    const SkPoint& pt = span->ptT()->fPt;
+    SkDebugf("%s id=%d", fun, fID);
+    SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
+    for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
+        SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
+    }
+    SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=",
+            span->t(), span->debugID(), pt.fX, pt.fY, span->next()->t());
+    if (winding == SK_MinS32) {
+        SkDebugf("?");
+    } else {
+        SkDebugf("%d", winding);
+    }
+    SkDebugf(" windSum=");
+    if (span->windSum() == SK_MinS32) {
+        SkDebugf("?");
+    } else {
+        SkDebugf("%d", span->windSum());
+    }
+    SkDebugf(" windValue=%d\n", span->windValue());
+}
+
+void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding,
+                                      int oppWinding) {
+    const SkPoint& pt = span->ptT()->fPt;
+    SkDebugf("%s id=%d", fun, fID);
+    SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
+    for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
+        SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
+    }
+    SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=",
+            span->t(), span->debugID(), pt.fX, pt.fY, span->next()->t(), winding, oppWinding);
+    if (winding == SK_MinS32) {
+        SkDebugf("?");
+    } else {
+        SkDebugf("%d", winding);
+    }
+    SkDebugf(" newOppSum=");
+    if (oppWinding == SK_MinS32) {
+        SkDebugf("?");
+    } else {
+        SkDebugf("%d", oppWinding);
+    }
+    SkDebugf(" oppSum=");
+    if (span->oppSum() == SK_MinS32) {
+        SkDebugf("?");
+    } else {
+        SkDebugf("%d", span->oppSum());
+    }
+    SkDebugf(" windSum=");
+    if (span->windSum() == SK_MinS32) {
+        SkDebugf("?");
+    } else {
+        SkDebugf("%d", span->windSum());
+    }
+    SkDebugf(" windValue=%d oppValue=%d\n", span->windValue(), span->oppValue());
+}
+
+#endif
+
+#if DEBUG_ANGLE
+SkString SkOpAngle::debugPart() const {
+    SkString result;
+    switch (this->segment()->verb()) {
+        case SkPath::kLine_Verb:
+            result.printf(LINE_DEBUG_STR " id=%d", LINE_DEBUG_DATA(fCurvePart),
+                    this->segment()->debugID());
+            break;
+        case SkPath::kQuad_Verb:
+            result.printf(QUAD_DEBUG_STR " id=%d", QUAD_DEBUG_DATA(fCurvePart),
+                    this->segment()->debugID());
+            break;
+        case SkPath::kCubic_Verb:
+            result.printf(CUBIC_DEBUG_STR " id=%d", CUBIC_DEBUG_DATA(fCurvePart),
+                    this->segment()->debugID());
+            break;
+        default:
+            SkASSERT(0);
+    } 
+    return result;
+}
+#endif
+
 #if DEBUG_SORT
 void SkOpAngle::debugLoop() const {
     const SkOpAngle* first = this;
@@ -111,25 +269,59 @@
         SkDebugf("\n");
         next = next->fNext;
     } while (next && next != first);
+    next = first;
+    do {
+        next->debugValidate();
+        next = next->fNext;
+    } while (next && next != first);
 }
 #endif
 
-#if DEBUG_ANGLE
-void SkOpAngle::debugSameAs(const SkOpAngle* compare) const {
-    SK_ALWAYSBREAK(fSegment == compare->fSegment);
-    const SkOpSpan& startSpan = fSegment->span(fStart);
-    const SkOpSpan& oStartSpan = fSegment->span(compare->fStart);
-    SK_ALWAYSBREAK(startSpan.fToAngle == oStartSpan.fToAngle);
-    SK_ALWAYSBREAK(startSpan.fFromAngle == oStartSpan.fFromAngle);
-    const SkOpSpan& endSpan = fSegment->span(fEnd);
-    const SkOpSpan& oEndSpan = fSegment->span(compare->fEnd);
-    SK_ALWAYSBREAK(endSpan.fToAngle == oEndSpan.fToAngle);
-    SK_ALWAYSBREAK(endSpan.fFromAngle == oEndSpan.fFromAngle);
-}
-#endif
-
+void SkOpAngle::debugValidate() const {
 #if DEBUG_VALIDATE
+    const SkOpAngle* first = this;
+    const SkOpAngle* next = this;
+    int wind = 0;
+    int opp = 0;
+    int lastXor = -1;
+    int lastOppXor = -1;
+    do {
+        if (next->unorderable()) {
+            return;
+        }
+        const SkOpSpan* minSpan = next->start()->starter(next->end());
+        if (minSpan->windValue() == SK_MinS32) {
+            return;
+        }
+        bool op = next->segment()->operand();
+        bool isXor = next->segment()->isXor();
+        bool oppXor = next->segment()->oppXor();
+        SkASSERT(!DEBUG_LIMIT_WIND_SUM || between(0, minSpan->windValue(), DEBUG_LIMIT_WIND_SUM));
+        SkASSERT(!DEBUG_LIMIT_WIND_SUM
+                || between(-DEBUG_LIMIT_WIND_SUM, minSpan->oppValue(), DEBUG_LIMIT_WIND_SUM));
+        bool useXor = op ? oppXor : isXor;
+        SkASSERT(lastXor == -1 || lastXor == (int) useXor);
+        lastXor = (int) useXor;
+        wind += next->sign() * (op ? minSpan->oppValue() : minSpan->windValue());
+        if (useXor) {
+            wind &= 1;
+        }
+        useXor = op ? isXor : oppXor;
+        SkASSERT(lastOppXor == -1 || lastOppXor == (int) useXor);
+        lastOppXor = (int) useXor;
+        opp += next->sign() * (op ? minSpan->windValue() : minSpan->oppValue());
+        if (useXor) {
+            opp &= 1;
+        }
+        next = next->fNext;
+    } while (next && next != first);
+    SkASSERT(wind == 0);
+    SkASSERT(opp == 0 || !FLAGS_runFail);
+#endif
+}
+
 void SkOpAngle::debugValidateNext() const {
+#if !FORCE_RELEASE
     const SkOpAngle* first = this;
     const SkOpAngle* next = first;
     SkTDArray<const SkOpAngle*>(angles);
@@ -145,422 +337,137 @@
             return;
         }
     } while (true);
-}
-
-void SkOpAngle::debugValidateLoop() const {
-    const SkOpAngle* first = this;
-    const SkOpAngle* next = first;
-    SK_ALWAYSBREAK(first->next() != first);
-    int signSum = 0;
-    int oppSum = 0;
-    bool firstOperand = fSegment->operand();
-    bool unorderable = false;
-    do {
-        unorderable |= next->fUnorderable;
-        const SkOpSegment* segment = next->fSegment;
-        bool operandsMatch = firstOperand == segment->operand();
-        signSum += operandsMatch ? segment->spanSign(next) : segment->oppSign(next);
-        oppSum += operandsMatch ? segment->oppSign(next) : segment->spanSign(next);
-        const SkOpSpan& span = segment->span(SkMin32(next->fStart, next->fEnd));
-        if (segment->_xor()) {
-//            SK_ALWAYSBREAK(span.fWindValue == 1);
-//            SK_ALWAYSBREAK(span.fWindSum == SK_MinS32 || span.fWindSum == 1);
-        }
-        if (segment->oppXor()) {
-            SK_ALWAYSBREAK(span.fOppValue == 0 || abs(span.fOppValue) == 1);
-//            SK_ALWAYSBREAK(span.fOppSum == SK_MinS32 || span.fOppSum == 0 || abs(span.fOppSum) == 1);
-        }
-        next = next->next();
-        if (!next) {
-            return;
-        }
-    } while (next != first);
-    if (unorderable) {
-        return;
-    }
-    SK_ALWAYSBREAK(!signSum || fSegment->_xor());
-    SK_ALWAYSBREAK(!oppSum || fSegment->oppXor());
-    int lastWinding;
-    int lastOppWinding;
-    int winding;
-    int oppWinding;
-    do {
-        const SkOpSegment* segment = next->fSegment;
-        const SkOpSpan& span = segment->span(SkMin32(next->fStart, next->fEnd));
-        winding = span.fWindSum;
-        if (winding != SK_MinS32) {
-//            SK_ALWAYSBREAK(winding != 0);
-            SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(winding));
-            lastWinding = winding;
-            int diffWinding = segment->spanSign(next);
-            if (!segment->_xor()) {
-                SK_ALWAYSBREAK(diffWinding != 0);
-                bool sameSign = (winding > 0) == (diffWinding > 0);
-                winding -= sameSign ? diffWinding : -diffWinding;
-                SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(winding));
-                SK_ALWAYSBREAK(abs(winding) <= abs(lastWinding));
-                if (!sameSign) {
-                    SkTSwap(winding, lastWinding);
-                }
-            }
-            lastOppWinding = oppWinding = span.fOppSum;
-            if (oppWinding != SK_MinS32 && !segment->oppXor()) {
-                int oppDiffWinding = segment->oppSign(next);
-//                SK_ALWAYSBREAK(abs(oppDiffWinding) <= abs(diffWinding) || segment->_xor());
-                if (oppDiffWinding) {
-                    bool oppSameSign = (oppWinding > 0) == (oppDiffWinding > 0);
-                    oppWinding -= oppSameSign ? oppDiffWinding : -oppDiffWinding;
-                    SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(oppWinding));
-                    SK_ALWAYSBREAK(abs(oppWinding) <= abs(lastOppWinding));
-                    if (!oppSameSign) {
-                        SkTSwap(oppWinding, lastOppWinding);
-                    }
-                }
-            }
-            firstOperand = segment->operand();
-            break;
-        }
-        SK_ALWAYSBREAK(span.fOppSum == SK_MinS32);
-        next = next->next();
-    } while (next != first);
-    if (winding == SK_MinS32) {
-        return;
-    }
-    SK_ALWAYSBREAK(oppWinding == SK_MinS32 || SkPathOpsDebug::ValidWind(oppWinding));
-    first = next;
-    next = next->next();
-    do {
-        const SkOpSegment* segment = next->fSegment;
-        lastWinding = winding;
-        lastOppWinding = oppWinding;
-        bool operandsMatch = firstOperand == segment->operand();
-        if (operandsMatch) {
-            if (!segment->_xor()) {
-                winding -= segment->spanSign(next);
-                SK_ALWAYSBREAK(winding != lastWinding);
-                SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(winding));
-            }
-            if (!segment->oppXor()) {
-                int oppDiffWinding = segment->oppSign(next);
-                if (oppWinding != SK_MinS32) {
-                    oppWinding -= oppDiffWinding;
-                    SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(oppWinding));
-                } else {
-                    SK_ALWAYSBREAK(oppDiffWinding == 0);
-                }
-            }
-        } else {
-            if (!segment->oppXor()) {
-                winding -= segment->oppSign(next);
-                SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(winding));
-            }
-            if (!segment->_xor()) {
-                oppWinding -= segment->spanSign(next);
-                SK_ALWAYSBREAK(oppWinding != lastOppWinding);
-                SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(oppWinding));
-            }
-        }
-        bool useInner = SkOpSegment::UseInnerWinding(lastWinding, winding);
-        int sumWinding = useInner ? winding : lastWinding;
-        bool oppUseInner = SkOpSegment::UseInnerWinding(lastOppWinding, oppWinding);
-        int oppSumWinding = oppUseInner ? oppWinding : lastOppWinding;
-        if (!operandsMatch) {
-            SkTSwap(useInner, oppUseInner);
-            SkTSwap(sumWinding, oppSumWinding);
-        }
-        const SkOpSpan& span = segment->span(SkMin32(next->fStart, next->fEnd));
-        if (winding == -lastWinding) {
-            if (span.fWindSum != SK_MinS32) {
-                SkDebugf("%s useInner=%d spanSign=%d lastWinding=%d winding=%d windSum=%d\n",
-                        __FUNCTION__,
-                        useInner, segment->spanSign(next), lastWinding, winding, span.fWindSum);
-            }
-        }
-        if (oppWinding != SK_MinS32) {
-            if (span.fOppSum != SK_MinS32) {
-                SK_ALWAYSBREAK(span.fOppSum == oppSumWinding || segment->oppXor() || segment->_xor());
-            }
-        } else {
-            SK_ALWAYSBREAK(!firstOperand);
-            SK_ALWAYSBREAK(!segment->operand());
-            SK_ALWAYSBREAK(!span.fOppValue);
-        }
-        next = next->next();
-    } while (next != first);
-}
 #endif
-
-#if DEBUG_SWAP_TOP
-bool SkOpSegment::controlsContainedByEnds(int tStart, int tEnd) const {
-    if (fVerb != SkPath::kCubic_Verb) {
-        return false;
-    }
-    SkDCubic dst = SkDCubic::SubDivide(fPts, fTs[tStart].fT, fTs[tEnd].fT);
-    return dst.controlsContainedByEnds();
 }
-#endif
-
-#if DEBUG_CONCIDENT
-// SK_ALWAYSBREAK if pair has not already been added
-void SkOpSegment::debugAddTPair(double t, const SkOpSegment& other, double otherT) const {
-    for (int i = 0; i < fTs.count(); ++i) {
-        if (fTs[i].fT == t && fTs[i].fOther == &other && fTs[i].fOtherT == otherT) {
-            return;
-        }
-    }
-    SK_ALWAYSBREAK(0);
-}
-#endif
-
-#if DEBUG_ANGLE
-void SkOpSegment::debugCheckPointsEqualish(int tStart, int tEnd) const {
-    const SkPoint& basePt = fTs[tStart].fPt;
-    while (++tStart < tEnd) {
-       const SkPoint& cmpPt = fTs[tStart].fPt;
-       SK_ALWAYSBREAK(SkDPoint::ApproximatelyEqual(basePt, cmpPt));
-    }
-}
-#endif
-
-#if DEBUG_SWAP_TOP
-int SkOpSegment::debugInflections(int tStart, int tEnd) const {
-    if (fVerb != SkPath::kCubic_Verb) {
-        return false;
-    }
-    SkDCubic dst = SkDCubic::SubDivide(fPts, fTs[tStart].fT, fTs[tEnd].fT);
-    double inflections[2];
-    return dst.findInflections(inflections);
-}
-#endif
-
-const SkOpAngle* SkOpSegment::debugLastAngle() const {
-    const SkOpAngle* result = NULL;
-    for (int index = 0; index < count(); ++index) {
-        const SkOpSpan& span = this->span(index);
-        if (span.fToAngle) {
-            SkASSERT(!result);
-            result = span.fToAngle;
-        }
-    }
-    SkASSERT(result);
-    return result;
-}
-
-void SkOpSegment::debugReset() {
-    fTs.reset();
-    fAngles.reset();
-}
-
-#if DEBUG_CONCIDENT
-void SkOpSegment::debugShowTs(const char* prefix) const {
-    SkDebugf("%s %s id=%d", __FUNCTION__, prefix, fID);
-    int lastWind = -1;
-    int lastOpp = -1;
-    double lastT = -1;
-    int i;
-    for (i = 0; i < fTs.count(); ++i) {
-        bool change = lastT != fTs[i].fT || lastWind != fTs[i].fWindValue
-                || lastOpp != fTs[i].fOppValue;
-        if (change && lastWind >= 0) {
-            SkDebugf(" t=%1.3g %1.9g,%1.9g w=%d o=%d]",
-                    lastT, xyAtT(i - 1).fX, xyAtT(i - 1).fY, lastWind, lastOpp);
-        }
-        if (change) {
-            SkDebugf(" [o=%d", fTs[i].fOther->fID);
-            lastWind = fTs[i].fWindValue;
-            lastOpp = fTs[i].fOppValue;
-            lastT = fTs[i].fT;
-        } else {
-            SkDebugf(",%d", fTs[i].fOther->fID);
-        }
-    }
-    if (i <= 0) {
-        return;
-    }
-    SkDebugf(" t=%1.3g %1.9g,%1.9g w=%d o=%d]",
-            lastT, xyAtT(i - 1).fX, xyAtT(i - 1).fY, lastWind, lastOpp);
-    if (fOperand) {
-        SkDebugf(" operand");
-    }
-    if (done()) {
-        SkDebugf(" done");
-    }
-    SkDebugf("\n");
-}
-#endif
-
-#if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
-void SkOpSegment::debugShowActiveSpans() const {
-    debugValidate();
-    if (done()) {
-        return;
-    }
-#if DEBUG_ACTIVE_SPANS_SHORT_FORM
-    int lastId = -1;
-    double lastT = -1;
-#endif
-    for (int i = 0; i < fTs.count(); ++i) {
-        if (fTs[i].fDone) {
-            continue;
-        }
-        SK_ALWAYSBREAK(i < fTs.count() - 1);
-#if DEBUG_ACTIVE_SPANS_SHORT_FORM
-        if (lastId == fID && lastT == fTs[i].fT) {
-            continue;
-        }
-        lastId = fID;
-        lastT = fTs[i].fT;
-#endif
-        SkDebugf("%s id=%d", __FUNCTION__, fID);
-        SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
-        for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
-            SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
-        }
-        const SkOpSpan* span = &fTs[i];
-        SkDebugf(") t=%1.9g (%1.9g,%1.9g)", span->fT, xAtT(span), yAtT(span));
-        int iEnd = i + 1;
-        while (fTs[iEnd].fT < 1 && approximately_equal(fTs[i].fT, fTs[iEnd].fT)) {
-            ++iEnd;
-        }
-        SkDebugf(" tEnd=%1.9g", fTs[iEnd].fT);
-        const SkOpSegment* other = fTs[i].fOther;
-        SkDebugf(" other=%d otherT=%1.9g otherIndex=%d windSum=",
-                other->fID, fTs[i].fOtherT, fTs[i].fOtherIndex);
-        if (fTs[i].fWindSum == SK_MinS32) {
-            SkDebugf("?");
-        } else {
-            SkDebugf("%d", fTs[i].fWindSum);
-        }
-        SkDebugf(" windValue=%d oppValue=%d\n", fTs[i].fWindValue, fTs[i].fOppValue);
-    }
-}
-#endif
-
-#if DEBUG_MARK_DONE || DEBUG_UNSORTABLE
-void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding) {
-    const SkPoint& pt = xyAtT(&span);
-    SkDebugf("%s id=%d", fun, fID);
-    SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
-    for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
-        SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
-    }
-    SK_ALWAYSBREAK(&span == &span.fOther->fTs[span.fOtherIndex].fOther->
-            fTs[span.fOther->fTs[span.fOtherIndex].fOtherIndex]);
-    SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=%d windSum=",
-            span.fT, span.fOther->fTs[span.fOtherIndex].fOtherIndex, pt.fX, pt.fY,
-            (&span)[1].fT, winding);
-    if (span.fWindSum == SK_MinS32) {
-        SkDebugf("?");
-    } else {
-        SkDebugf("%d", span.fWindSum);
-    }
-    SkDebugf(" windValue=%d\n", span.fWindValue);
-}
-
-void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding,
-                                      int oppWinding) {
-    const SkPoint& pt = xyAtT(&span);
-    SkDebugf("%s id=%d", fun, fID);
-    SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
-    for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
-        SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
-    }
-    SK_ALWAYSBREAK(&span == &span.fOther->fTs[span.fOtherIndex].fOther->
-            fTs[span.fOther->fTs[span.fOtherIndex].fOtherIndex]);
-    SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=%d newOppSum=%d oppSum=",
-            span.fT, span.fOther->fTs[span.fOtherIndex].fOtherIndex, pt.fX, pt.fY,
-            (&span)[1].fT, winding, oppWinding);
-    if (span.fOppSum == SK_MinS32) {
-        SkDebugf("?");
-    } else {
-        SkDebugf("%d", span.fOppSum);
-    }
-    SkDebugf(" windSum=");
-    if (span.fWindSum == SK_MinS32) {
-        SkDebugf("?");
-    } else {
-        SkDebugf("%d", span.fWindSum);
-    }
-    SkDebugf(" windValue=%d oppValue=%d\n", span.fWindValue, span.fOppValue);
-}
-#endif
-
-#if DEBUG_SHOW_WINDING
-int SkOpSegment::debugShowWindingValues(int slotCount, int ofInterest) const {
-    if (!(1 << fID & ofInterest)) {
-        return 0;
-    }
-    int sum = 0;
-    SkTArray<char, true> slots(slotCount * 2);
-    memset(slots.begin(), ' ', slotCount * 2);
-    for (int i = 0; i < fTs.count(); ++i) {
-   //     if (!(1 << fTs[i].fOther->fID & ofInterest)) {
-   //         continue;
-   //     }
-        sum += fTs[i].fWindValue;
-        slots[fTs[i].fOther->fID - 1] = as_digit(fTs[i].fWindValue);
-        sum += fTs[i].fOppValue;
-        slots[slotCount + fTs[i].fOther->fID - 1] = as_digit(fTs[i].fOppValue);
-    }
-    SkDebugf("%s id=%2d %.*s | %.*s\n", __FUNCTION__, fID, slotCount, slots.begin(), slotCount,
-            slots.begin() + slotCount);
-    return sum;
-}
-#endif
 
 void SkOpSegment::debugValidate() const {
 #if DEBUG_VALIDATE
-    int count = fTs.count();
-    SK_ALWAYSBREAK(count >= 2);
-    SK_ALWAYSBREAK(fTs[0].fT == 0);
-    SK_ALWAYSBREAK(fTs[count - 1].fT == 1);
+    const SkOpSpanBase* span = &fHead;
+    double lastT = -1;
+    const SkOpSpanBase* prev = NULL;
+    int count = 0;
     int done = 0;
-    double t = -1;
-    const SkOpSpan* last = NULL;
-    bool tinyTFound = false;
-    bool hasLoop = false;
-    for (int i = 0; i < count; ++i) {
-        const SkOpSpan& span = fTs[i];
-        SK_ALWAYSBREAK(t <= span.fT);
-        t = span.fT;
-        int otherIndex = span.fOtherIndex;
-        const SkOpSegment* other = span.fOther;
-        SK_ALWAYSBREAK(other != this || fVerb == SkPath::kCubic_Verb);
-        const SkOpSpan& otherSpan = other->fTs[otherIndex];
-        SK_ALWAYSBREAK(otherSpan.fPt == span.fPt);
-        SK_ALWAYSBREAK(otherSpan.fOtherT == t);
-        SK_ALWAYSBREAK(&fTs[i] == &otherSpan.fOther->fTs[otherSpan.fOtherIndex]);
-        done += span.fDone;
-        if (last) {
-            SK_ALWAYSBREAK(last->fT != span.fT || last->fOther != span.fOther);
-            bool tsEqual = last->fT == span.fT;
-            bool tsPreciselyEqual = precisely_equal(last->fT, span.fT);
-            SK_ALWAYSBREAK(!tsEqual || tsPreciselyEqual);
-            bool pointsEqual = last->fPt == span.fPt;
-            bool pointsNearlyEqual = AlmostEqualUlps(last->fPt, span.fPt);
-#if 0  // bufferOverflow test triggers this
-            SK_ALWAYSBREAK(!tsPreciselyEqual || pointsNearlyEqual);
+    do {
+        if (!span->final()) {
+            ++count;
+            done += span->upCast()->done() ? 1 : 0;
+        }
+        SkASSERT(span->segment() == this);
+        SkASSERT(!prev || prev->upCast()->next() == span);
+        SkASSERT(!prev || prev == span->prev());
+        prev = span;
+        double t = span->ptT()->fT;
+        SkASSERT(lastT < t);
+        lastT = t;
+        span->debugValidate();
+    } while (!span->final() && (span = span->upCast()->next()));
+    SkASSERT(count == fCount);
+    SkASSERT(done == fDoneCount);
+    SkASSERT(span->final());
+    span->debugValidate();
 #endif
-//            SK_ALWAYSBREAK(!last->fTiny || !tsPreciselyEqual || span.fTiny || tinyTFound);
-            SK_ALWAYSBREAK(last->fTiny || tsPreciselyEqual || !pointsEqual || hasLoop);
-            SK_ALWAYSBREAK(!last->fTiny || pointsEqual);
-            SK_ALWAYSBREAK(!last->fTiny || last->fDone);
-            SK_ALWAYSBREAK(!last->fSmall || pointsNearlyEqual);
-            SK_ALWAYSBREAK(!last->fSmall || last->fDone);
-//            SK_ALWAYSBREAK(!last->fSmall || last->fTiny);
-//            SK_ALWAYSBREAK(last->fTiny || !pointsEqual || last->fDone == span.fDone);
-            if (last->fTiny) {
-                tinyTFound |= !tsPreciselyEqual;
-            } else {
-                tinyTFound = false;
+}
+
+bool SkOpSpanBase::debugCoinEndLoopCheck() const {
+    int loop = 0;
+    const SkOpSpanBase* next = this;
+    SkOpSpanBase* nextCoin;
+    do {
+        nextCoin = next->fCoinEnd;
+        SkASSERT(nextCoin == this || nextCoin->fCoinEnd != nextCoin);
+        for (int check = 1; check < loop - 1; ++check) {
+            const SkOpSpanBase* checkCoin = this->fCoinEnd;
+            const SkOpSpanBase* innerCoin = checkCoin;
+            for (int inner = check + 1; inner < loop; ++inner) {
+                innerCoin = innerCoin->fCoinEnd;
+                if (checkCoin == innerCoin) {
+                    SkDebugf("*** bad coincident end loop ***\n");
+                    return false;
+                }
             }
         }
-        last = &span;
-        hasLoop |= last->fLoop;
+        ++loop;
+    } while ((next = nextCoin) && next != this);
+    return true;
+}
+
+void SkOpSpanBase::debugValidate() const {
+#if DEBUG_VALIDATE
+    const SkOpPtT* ptT = &fPtT;
+    SkASSERT(ptT->span() == this);
+    do {
+//        SkASSERT(SkDPoint::RoughlyEqual(fPtT.fPt, ptT->fPt));
+        ptT->debugValidate();
+        ptT = ptT->next();
+    } while (ptT != &fPtT);
+    SkASSERT(this->debugCoinEndLoopCheck());
+    if (!this->final()) {
+        SkASSERT(this->upCast()->debugCoinLoopCheck());
     }
-    SK_ALWAYSBREAK(done == fDoneSpans);
-//    if (fAngles.count() ) {
-//        fAngles.begin()->debugValidateLoop();
-//    }
+    if (fFromAngle) {
+        fFromAngle->debugValidate();
+    }
+    if (!this->final() && this->upCast()->toAngle()) {
+        this->upCast()->toAngle()->debugValidate();
+    }
+#endif
+}
+
+bool SkOpSpan::debugCoinLoopCheck() const {
+    int loop = 0;
+    const SkOpSpan* next = this;
+    SkOpSpan* nextCoin;
+    do {
+        nextCoin = next->fCoincident;
+        SkASSERT(nextCoin == this || nextCoin->fCoincident != nextCoin);
+        for (int check = 1; check < loop - 1; ++check) {
+            const SkOpSpan* checkCoin = this->fCoincident;
+            const SkOpSpan* innerCoin = checkCoin;
+            for (int inner = check + 1; inner < loop; ++inner) {
+                innerCoin = innerCoin->fCoincident;
+                if (checkCoin == innerCoin) {
+                    SkDebugf("*** bad coincident loop ***\n");
+                    return false;
+                }
+            }
+        }
+        ++loop;
+    } while ((next = nextCoin) && next != this);
+    return true;
+}
+
+#include "SkOpContour.h"
+
+int SkOpPtT::debugLoopLimit(bool report) const {
+    int loop = 0;
+    const SkOpPtT* next = this;
+    do {
+        for (int check = 1; check < loop - 1; ++check) {
+            const SkOpPtT* checkPtT = this->fNext;
+            const SkOpPtT* innerPtT = checkPtT;
+            for (int inner = check + 1; inner < loop; ++inner) {
+                innerPtT = innerPtT->fNext;
+                if (checkPtT == innerPtT) {
+                    if (report) {
+                        SkDebugf("*** bad ptT loop ***\n");
+                    }
+                    return loop;
+                }
+            }
+        }
+        ++loop;
+    } while ((next = next->fNext) && next != this);
+    return 0;
+}
+
+void SkOpPtT::debugValidate() const {
+#if DEBUG_VALIDATE
+    if (contour()->globalState()->phase() == SkOpGlobalState::kIntersecting) {
+        return;
+    }
+    SkASSERT(fNext);
+    SkASSERT(fNext != this);
+    SkASSERT(fNext->fNext);
+    SkASSERT(debugLoopLimit(false) == 0);
 #endif
 }
diff --git a/src/pathops/SkPathOpsDebug.h b/src/pathops/SkPathOpsDebug.h
index 5770aef..72a9ea5 100644
--- a/src/pathops/SkPathOpsDebug.h
+++ b/src/pathops/SkPathOpsDebug.h
@@ -39,35 +39,22 @@
 
 #define DEBUG_ACTIVE_OP 0
 #define DEBUG_ACTIVE_SPANS 0
-#define DEBUG_ACTIVE_SPANS_FIRST_ONLY 0
-#define DEBUG_ACTIVE_SPANS_SHORT_FORM 1
 #define DEBUG_ADD_INTERSECTING_TS 0
-#define DEBUG_ADD_T_PAIR 0
+#define DEBUG_ADD_T 0
 #define DEBUG_ANGLE 0
-#define DEBUG_AS_C_CODE 1
 #define DEBUG_ASSEMBLE 0
-#define DEBUG_CHECK_ALIGN 0
-#define DEBUG_CHECK_TINY 0
-#define DEBUG_CONCIDENT 0
-#define DEBUG_CROSS 0
 #define DEBUG_CUBIC_BINARY_SEARCH 0
-#define DEBUG_DUPLICATES 0
-#define DEBUG_FLAT_QUADS 0
 #define DEBUG_FLOW 0
 #define DEBUG_LIMIT_WIND_SUM 0
 #define DEBUG_MARK_DONE 0
 #define DEBUG_PATH_CONSTRUCTION 0
+#define DEBUG_PERP 0
 #define DEBUG_SHOW_TEST_NAME 0
-#define DEBUG_SHOW_TEST_PROGRESS 0
-#define DEBUG_SHOW_WINDING 0
 #define DEBUG_SORT 0
-#define DEBUG_SORT_COMPACT 0
-#define DEBUG_SORT_RAW 0
-#define DEBUG_SORT_SINGLE 0
 #define DEBUG_SWAP_TOP 0
-#define DEBUG_UNSORTABLE 0
+#define DEBUG_T_SECT 0
+#define DEBUG_T_SECT_DUMP 0
 #define DEBUG_VALIDATE 0
-#define DEBUG_WIND_BUMP 0
 #define DEBUG_WINDING 0
 #define DEBUG_WINDING_AT_T 0
 
@@ -75,51 +62,56 @@
 
 #define DEBUG_ACTIVE_OP 1
 #define DEBUG_ACTIVE_SPANS 1
-#define DEBUG_ACTIVE_SPANS_FIRST_ONLY 0
-#define DEBUG_ACTIVE_SPANS_SHORT_FORM 1
 #define DEBUG_ADD_INTERSECTING_TS 1
-#define DEBUG_ADD_T_PAIR 1
+#define DEBUG_ADD_T 1
 #define DEBUG_ANGLE 1
-#define DEBUG_AS_C_CODE 1
 #define DEBUG_ASSEMBLE 1
-#define DEBUG_CHECK_ALIGN 1
-#define DEBUG_CHECK_TINY 1
-#define DEBUG_CONCIDENT 1
-#define DEBUG_CROSS 01
 #define DEBUG_CUBIC_BINARY_SEARCH 0
-#define DEBUG_DUPLICATES 1
-#define DEBUG_FLAT_QUADS 0
 #define DEBUG_FLOW 1
-#define DEBUG_LIMIT_WIND_SUM 4
+#define DEBUG_LIMIT_WIND_SUM 5
 #define DEBUG_MARK_DONE 1
 #define DEBUG_PATH_CONSTRUCTION 1
+#define DEBUG_PERP 0
 #define DEBUG_SHOW_TEST_NAME 1
-#define DEBUG_SHOW_TEST_PROGRESS 1
-#define DEBUG_SHOW_WINDING 0
 #define DEBUG_SORT 1
-#define DEBUG_SORT_COMPACT 0
-#define DEBUG_SORT_RAW 0
-#define DEBUG_SORT_SINGLE 0
 #define DEBUG_SWAP_TOP 1
-#define DEBUG_UNSORTABLE 1
-#define DEBUG_VALIDATE 0
-#define DEBUG_WIND_BUMP 0
+#define DEBUG_T_SECT 1
+#define DEBUG_T_SECT_DUMP 02
+#define DEBUG_VALIDATE 1
 #define DEBUG_WINDING 1
 #define DEBUG_WINDING_AT_T 1
 
 #endif
 
-#if DEBUG_AS_C_CODE
-#define CUBIC_DEBUG_STR "{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}"
-#define QUAD_DEBUG_STR  "{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}"
-#define LINE_DEBUG_STR  "{{%1.9g,%1.9g}, {%1.9g,%1.9g}}"
-#define PT_DEBUG_STR "{{%1.9g,%1.9g}}"
+#ifdef SK_RELEASE
+    #define PATH_OPS_DEBUG_RELEASE(a, b) b
+    #define PATH_OPS_DEBUG_CODE(...)
+    #define PATH_OPS_DEBUG_PARAMS(...)
 #else
-#define CUBIC_DEBUG_STR "(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)"
-#define QUAD_DEBUG_STR  "(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)"
-#define LINE_DEBUG_STR  "(%1.9g,%1.9g %1.9g,%1.9g)"
-#define PT_DEBUG_STR "(%1.9g,%1.9g)"
+    #define PATH_OPS_DEBUG_RELEASE(a, b) a
+    #define PATH_OPS_DEBUG_CODE(...) __VA_ARGS__
+    #define PATH_OPS_DEBUG_PARAMS(...) , __VA_ARGS__
 #endif
+
+#if DEBUG_T_SECT == 0
+    #define PATH_OPS_DEBUG_T_SECT_RELEASE(a, b) b
+    #define PATH_OPS_DEBUG_T_SECT_PARAMS(...)
+    #define PATH_OPS_DEBUG_T_SECT_CODE(...)
+#else
+    #define PATH_OPS_DEBUG_T_SECT_RELEASE(a, b) a
+    #define PATH_OPS_DEBUG_T_SECT_PARAMS(...) , __VA_ARGS__
+    #define PATH_OPS_DEBUG_T_SECT_CODE(...) __VA_ARGS__
+#endif
+
+#if DEBUG_T_SECT_DUMP > 1
+    extern int gDumpTSectNum;
+#endif
+
+#define CUBIC_DEBUG_STR "{{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}}"
+#define QUAD_DEBUG_STR  "{{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}}"
+#define LINE_DEBUG_STR  "{{{%1.9g,%1.9g}, {%1.9g,%1.9g}}}"
+#define PT_DEBUG_STR "{{%1.9g,%1.9g}}"
+
 #define T_DEBUG_STR(t, n) #t "[" #n "]=%1.9g"
 #define TX_DEBUG_STR(t) #t "[%d]=%1.9g"
 #define CUBIC_DEBUG_DATA(c) c[0].fX, c[0].fY, c[1].fX, c[1].fY, c[2].fX, c[2].fY, c[3].fX, c[3].fY
@@ -135,7 +127,6 @@
 #include "SkTLS.h"
 #endif
 
-#include "SkTArray.h"
 #include "SkTDArray.h"
 
 class SkPathOpsDebug {
@@ -156,7 +147,6 @@
     static const char* kPathOpStr[];
 #endif
 
-    static bool ChaseContains(const SkTDArray<struct SkOpSpan *>& , const struct SkOpSpan * );
     static void MathematicaIze(char* str, size_t bufferSize);
     static bool ValidWind(int winding);
     static void WindingPrintf(int winding);
@@ -171,66 +161,96 @@
 #endif
     static void ShowOnePath(const SkPath& path, const char* name, bool includeDeclaration);
     static void ShowPath(const SkPath& one, const SkPath& two, SkPathOp op, const char* name);
-    static void DumpCoincidence(const SkTArray<class SkOpContour, true>& contours);
-    static void DumpCoincidence(const SkTArray<class SkOpContour* , true>& contours);
-    static void DumpContours(const SkTArray<class SkOpContour, true>& contours);
-    static void DumpContours(const SkTArray<class SkOpContour* , true>& contours);
-    static void DumpContourAngles(const SkTArray<class SkOpContour, true>& contours);
-    static void DumpContourAngles(const SkTArray<class SkOpContour* , true>& contours);
-    static void DumpContourPt(const SkTArray<class SkOpContour, true>& contours, int id);
-    static void DumpContourPt(const SkTArray<class SkOpContour* , true>& contours, int id);
-    static void DumpContourPts(const SkTArray<class SkOpContour, true>& contours);
-    static void DumpContourPts(const SkTArray<class SkOpContour* , true>& contours);
-    static void DumpContourSpan(const SkTArray<class SkOpContour, true>& contours, int id);
-    static void DumpContourSpan(const SkTArray<class SkOpContour* , true>& contours, int id);
-    static void DumpContourSpans(const SkTArray<class SkOpContour, true>& contours);
-    static void DumpContourSpans(const SkTArray<class SkOpContour* , true>& contours);
-    static void DumpSpans(const SkTDArray<struct SkOpSpan *>& );
-    static void DumpSpans(const SkTDArray<struct SkOpSpan *>* );
+
+    static bool ChaseContains(const SkTDArray<class SkOpSpanBase*>& , const class SkOpSpanBase* );
+
+    static const struct SkOpAngle* DebugAngleAngle(const struct SkOpAngle*, int id);
+    static class SkOpContour* DebugAngleContour(struct SkOpAngle*, int id);
+    static const class SkOpPtT* DebugAnglePtT(const struct SkOpAngle*, int id);
+    static const class SkOpSegment* DebugAngleSegment(const struct SkOpAngle*, int id);
+    static const class SkOpSpanBase* DebugAngleSpan(const struct SkOpAngle*, int id);
+
+    static const struct SkOpAngle* DebugContourAngle(class SkOpContour*, int id);
+    static class SkOpContour* DebugContourContour(class SkOpContour*, int id);
+    static const class SkOpPtT* DebugContourPtT(class SkOpContour*, int id);
+    static const class SkOpSegment* DebugContourSegment(class SkOpContour*, int id);
+    static const class SkOpSpanBase* DebugContourSpan(class SkOpContour*, int id);
+
+    static const struct SkOpAngle* DebugPtTAngle(const class SkOpPtT*, int id);
+    static class SkOpContour* DebugPtTContour(class SkOpPtT*, int id);
+    static const class SkOpPtT* DebugPtTPtT(const class SkOpPtT*, int id);
+    static const class SkOpSegment* DebugPtTSegment(const class SkOpPtT*, int id);
+    static const class SkOpSpanBase* DebugPtTSpan(const class SkOpPtT*, int id);
+
+    static const struct SkOpAngle* DebugSegmentAngle(const class SkOpSegment*, int id);
+    static class SkOpContour* DebugSegmentContour(class SkOpSegment*, int id);
+    static const class SkOpPtT* DebugSegmentPtT(const class SkOpSegment*, int id);
+    static const class SkOpSegment* DebugSegmentSegment(const class SkOpSegment*, int id);
+    static const class SkOpSpanBase* DebugSegmentSpan(const class SkOpSegment*, int id);
+
+    static const struct SkOpAngle* DebugSpanAngle(const class SkOpSpanBase*, int id);
+    static class SkOpContour* DebugSpanContour(class SkOpSpanBase*, int id);
+    static const class SkOpPtT* DebugSpanPtT(const class SkOpSpanBase*, int id);
+    static const class SkOpSegment* DebugSpanSegment(const class SkOpSpanBase*, int id);
+    static const class SkOpSpanBase* DebugSpanSpan(const class SkOpSpanBase*, int id);
+
+    static void DumpContours(SkTDArray<class SkOpContour* >* contours);
+    static void DumpContoursAll(SkTDArray<class SkOpContour* >* contours);
+    static void DumpContoursAngles(const SkTDArray<class SkOpContour* >* contours);
+    static void DumpContoursPt(const SkTDArray<class SkOpContour* >* contours, int id);
+    static void DumpContoursPts(const SkTDArray<class SkOpContour* >* contours);
+    static void DumpContoursSegment(const SkTDArray<class SkOpContour* >* contours, int id);
+    static void DumpContoursSpan(const SkTDArray<class SkOpContour* >* contours, int id);
+    static void DumpContoursSpans(const SkTDArray<class SkOpContour* >* contours);
 };
 
 // shorthand for calling from debugger
-void Dump(const SkTArray<class SkOpContour, true>& contours);
-void Dump(const SkTArray<class SkOpContour* , true>& contours);
-void Dump(const SkTArray<class SkOpContour, true>* contours);
-void Dump(const SkTArray<class SkOpContour* , true>* contours);
+template<typename TCurve> class SkTSect;
+template<typename TCurve> class SkTSpan;
 
-void Dump(const SkTDArray<SkOpSpan* >& chase);
-void Dump(const SkTDArray<SkOpSpan* >* chase);
+struct SkDQuad;
+struct SkDCubic;
 
-void DumpAngles(const SkTArray<class SkOpContour, true>& contours);
-void DumpAngles(const SkTArray<class SkOpContour* , true>& contours);
-void DumpAngles(const SkTArray<class SkOpContour, true>* contours);
-void DumpAngles(const SkTArray<class SkOpContour* , true>* contours);
+const SkTSpan<SkDCubic>* DebugSpan(const SkTSect<SkDCubic>* , int id);
+const SkTSpan<SkDQuad>* DebugSpan(const SkTSect<SkDQuad>* , int id);
+const SkTSpan<SkDCubic>* DebugT(const SkTSect<SkDCubic>* , double t);
+const SkTSpan<SkDQuad>* DebugT(const SkTSect<SkDQuad>* , double t);
 
-void DumpCoin(const SkTArray<class SkOpContour, true>& contours);
-void DumpCoin(const SkTArray<class SkOpContour* , true>& contours);
-void DumpCoin(const SkTArray<class SkOpContour, true>* contours);
-void DumpCoin(const SkTArray<class SkOpContour* , true>* contours);
+const SkTSpan<SkDCubic>* DebugSpan(const SkTSpan<SkDCubic>* , int id);
+const SkTSpan<SkDQuad>* DebugSpan(const SkTSpan<SkDQuad>* , int id);
+const SkTSpan<SkDCubic>* DebugT(const SkTSpan<SkDCubic>* , double t);
+const SkTSpan<SkDQuad>* DebugT(const SkTSpan<SkDQuad>* , double t);
 
-void DumpPts(const SkTArray<class SkOpContour, true>& contours);
-void DumpPts(const SkTArray<class SkOpContour* , true>& contours);
-void DumpPts(const SkTArray<class SkOpContour, true>* contours);
-void DumpPts(const SkTArray<class SkOpContour* , true>* contours);
-
-void DumpPt(const SkTArray<class SkOpContour, true>& contours, int segmentID);
-void DumpPt(const SkTArray<class SkOpContour* , true>& contours, int segmentID);
-void DumpPt(const SkTArray<class SkOpContour, true>* contours, int segmentID);
-void DumpPt(const SkTArray<class SkOpContour* , true>* contours, int segmentID);
-
-void DumpSpans(const SkTArray<class SkOpContour, true>& contours);
-void DumpSpans(const SkTArray<class SkOpContour* , true>& contours);
-void DumpSpans(const SkTArray<class SkOpContour, true>* contours);
-void DumpSpans(const SkTArray<class SkOpContour* , true>* contours);
-
-void DumpSpan(const SkTArray<class SkOpContour, true>& contours, int segmentID);
-void DumpSpan(const SkTArray<class SkOpContour* , true>& contours, int segmentID);
-void DumpSpan(const SkTArray<class SkOpContour, true>* contours, int segmentID);
-void DumpSpan(const SkTArray<class SkOpContour* , true>* contours, int segmentID);
+void Dump(const SkTSect<SkDCubic>* );
+void Dump(const SkTSect<SkDQuad>* );
+void Dump(const SkTSpan<SkDCubic>* , const SkTSect<SkDCubic>* = NULL);
+void Dump(const SkTSpan<SkDQuad>* , const SkTSect<SkDQuad>* = NULL);
+void DumpBoth(SkTSect<SkDCubic>* sect1, SkTSect<SkDCubic>* sect2);
+void DumpBoth(SkTSect<SkDQuad>* sect1, SkTSect<SkDQuad>* sect2);
+void DumpCoin(SkTSect<SkDCubic>* sect1);
+void DumpCoin(SkTSect<SkDQuad>* sect1);
+void DumpCoinCurves(SkTSect<SkDCubic>* sect1);
+void DumpCoinCurves(SkTSect<SkDQuad>* sect1);
+void DumpCurves(const SkTSpan<SkDCubic>* );
+void DumpCurves(const SkTSpan<SkDQuad>* );
 
 // generates tools/path_sorter.htm and path_visualizer.htm compatible data
-void DumpQ(const struct SkDQuad& quad1, const struct SkDQuad& quad2, int testNo);
+void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo);
+void DumpT(const SkDQuad& quad, double t);
 
-void DumpT(const struct SkDQuad& quad, double t);
+const struct SkOpAngle* DebugAngle(const SkTDArray<class SkOpContour* >* contours, int id);
+class SkOpContour* DebugContour(const SkTDArray<class SkOpContour* >* contours, int id);
+const class SkOpPtT* DebugPtT(const SkTDArray<class SkOpContour* >* contours, int id);
+const class SkOpSegment* DebugSegment(const SkTDArray<class SkOpContour* >* contours, int id);
+const class SkOpSpanBase* DebugSpan(const SkTDArray<class SkOpContour* >* contours, int id);
 
+void Dump(const SkTDArray<class SkOpContour* >* contours);
+void DumpAll(SkTDArray<class SkOpContour* >* contours);
+void DumpAngles(const SkTDArray<class SkOpContour* >* contours);
+void DumpCoin(const SkTDArray<class SkOpContour* >* contours);
+void DumpPt(const SkTDArray<class SkOpContour* >* contours, int segmentID);
+void DumpPts(const SkTDArray<class SkOpContour* >* contours);
+void DumpSegment(const SkTDArray<class SkOpContour* >* contours, int segmentID);
+void DumpSpan(const SkTDArray<class SkOpContour* >* contours, int spanID);
+void DumpSpans(const SkTDArray<class SkOpContour* >* contours);
 #endif
diff --git a/src/pathops/SkPathOpsLine.cpp b/src/pathops/SkPathOpsLine.cpp
index e4fc97b..70f2e12 100644
--- a/src/pathops/SkPathOpsLine.cpp
+++ b/src/pathops/SkPathOpsLine.cpp
@@ -6,14 +6,6 @@
  */
 #include "SkPathOpsLine.h"
 
-SkDLine SkDLine::subDivide(double t1, double t2) const {
-    SkDVector delta = tangent();
-    SkDLine dst = {{{
-            fPts[0].fX - t1 * delta.fX, fPts[0].fY - t1 * delta.fY}, {
-            fPts[0].fX - t2 * delta.fX, fPts[0].fY - t2 * delta.fY}}};
-    return dst;
-}
-
 // may have this below somewhere else already:
 // copying here because I thought it was clever
 
@@ -28,6 +20,7 @@
 //    Point with coordinates {float x, y;}
 //===================================================================
 
+// (only used by testing)
 // isLeft(): tests if a point is Left|On|Right of an infinite line.
 //    Input:  three points P0, P1, and P2
 //    Return: >0 for P2 left of the line through P0 and P1
@@ -110,19 +103,6 @@
     return RoughlyEqualUlps(largest, largest + dist); // is the dist within ULPS tolerance?
 }
 
-// Returns true if a ray from (0,0) to (x1,y1) is coincident with a ray (0,0) to (x2,y2)
-// OPTIMIZE: a specialty routine could speed this up -- may not be called very often though
-bool SkDLine::NearRay(double x1, double y1, double x2, double y2) {
-    double denom1 = x1 * x1 + y1 * y1;
-    double denom2 = x2 * x2 + y2 * y2;
-    SkDLine line = {{{0, 0}, {x1, y1}}};
-    SkDPoint pt = {x2, y2};
-    if (denom2 > denom1) {
-        SkTSwap(line[1], pt);
-    }
-    return line.nearRay(pt);
-}
-
 double SkDLine::ExactPointH(const SkDPoint& xy, double left, double right, double y) {
     if (xy.fY == y) {
         if (xy.fX == left) {
diff --git a/src/pathops/SkPathOpsLine.h b/src/pathops/SkPathOpsLine.h
index 74eb615..bb25162 100644
--- a/src/pathops/SkPathOpsLine.h
+++ b/src/pathops/SkPathOpsLine.h
@@ -20,27 +20,20 @@
         fPts[1] = pts[1];
     }
 
-    static SkDLine SubDivide(const SkPoint a[2], double t1, double t2) {
-        SkDLine line;
-        line.set(a);
-        return line.subDivide(t1, t2);
-    }
-
     double exactPoint(const SkDPoint& xy) const;
     static double ExactPointH(const SkDPoint& xy, double left, double right, double y);
     static double ExactPointV(const SkDPoint& xy, double top, double bottom, double x);
+
+    // only used by testing
     double isLeft(const SkDPoint& pt) const;
+
     double nearPoint(const SkDPoint& xy, bool* unequal) const;
     bool nearRay(const SkDPoint& xy) const;
     static double NearPointH(const SkDPoint& xy, double left, double right, double y);
     static double NearPointV(const SkDPoint& xy, double top, double bottom, double x);
-    static bool NearRay(double dx1, double dy1, double dx2, double dy2);
     SkDPoint ptAtT(double t) const;
-    SkDLine subDivide(double t1, double t2) const;
 
     void dump() const;
-private:
-    SkDVector tangent() const { return fPts[0] - fPts[1]; }
 };
 
 #endif
diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp
index f2b25c0..77ae2de 100644
--- a/src/pathops/SkPathOpsOp.cpp
+++ b/src/pathops/SkPathOpsOp.cpp
@@ -5,27 +5,29 @@
  * found in the LICENSE file.
  */
 #include "SkAddIntersections.h"
+#include "SkOpCoincidence.h"
 #include "SkOpEdgeBuilder.h"
 #include "SkPathOpsCommon.h"
 #include "SkPathWriter.h"
 
-static SkOpSegment* findChaseOp(SkTDArray<SkOpSpan*>& chase, int* tIndex, int* endIndex) {
+static SkOpSegment* findChaseOp(SkTDArray<SkOpSpanBase*>& chase, SkOpSpanBase** startPtr,
+        SkOpSpanBase** endPtr) {
     while (chase.count()) {
-        SkOpSpan* span;
+        SkOpSpanBase* span;
         chase.pop(&span);
-        const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex);
-        SkOpSegment* segment = backPtr.fOther;
-        *tIndex = backPtr.fOtherIndex;
+        // OPTIMIZE: prev makes this compatible with old code -- but is it necessary?
+        *startPtr = span->ptT()->prev()->span();
+        SkOpSegment* segment = (*startPtr)->segment();
         bool sortable = true;
         bool done = true;
-        *endIndex = -1;
-        if (const SkOpAngle* last = segment->activeAngle(*tIndex, tIndex, endIndex, &done,
+        *endPtr = NULL;
+        if (SkOpAngle* last = segment->activeAngle(*startPtr, startPtr, endPtr, &done,
                 &sortable)) {
             if (last->unorderable()) {
                 continue;
             }
-            *tIndex = last->start();
-            *endIndex = last->end();
+            *startPtr = last->start();
+            *endPtr = last->end();
    #if TRY_ROTATE
             *chase.insert(0) = span;
    #else
@@ -40,7 +42,7 @@
             continue;
         }
         // find first angle, initialize winding to computed fWindSum
-        const SkOpAngle* angle = segment->spanToAngle(*tIndex, *endIndex);
+        const SkOpAngle* angle = segment->spanToAngle(*startPtr, *endPtr);
         if (!angle) {
             continue;
         }
@@ -65,33 +67,25 @@
             SkTSwap<int>(sumMiWinding, sumSuWinding);
         }
         SkOpSegment* first = NULL;
-        bool badData = false;
-        while ((angle = angle->next()) != firstAngle && !badData) {
+        firstAngle = angle;
+        while ((angle = angle->next()) != firstAngle) {
             segment = angle->segment();
-            int start = angle->start();
-            int end = angle->end();
+            SkOpSpanBase* start = angle->start();
+            SkOpSpanBase* end = angle->end();
             int maxWinding, sumWinding, oppMaxWinding, oppSumWinding;
             segment->setUpWindings(start, end, &sumMiWinding, &sumSuWinding,
                     &maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding);
             if (!segment->done(angle)) {
                 if (!first) {
                     first = segment;
-                    *tIndex = start;
-                    *endIndex = end;
-                }
-                if (segment->inconsistentAngle(maxWinding, sumWinding, oppMaxWinding,
-                        oppSumWinding, angle)) {
-                    badData = true;
-                    break;
+                    *startPtr = start;
+                    *endPtr = end;
                 }
                 // OPTIMIZATION: should this also add to the chase?
                 (void) segment->markAngle(maxWinding, sumWinding, oppMaxWinding,
                     oppSumWinding, angle);
             }
         }
-        if (badData) {
-            continue;
-        }
         if (first) {
        #if TRY_ROTATE
             *chase.insert(0) = span;
@@ -104,36 +98,8 @@
     return NULL;
 }
 
-/*
-static bool windingIsActive(int winding, int oppWinding, int spanWinding, int oppSpanWinding,
-        bool windingIsOp, PathOp op) {
-    bool active = windingIsActive(winding, spanWinding);
-    if (!active) {
-        return false;
-    }
-    if (oppSpanWinding && windingIsActive(oppWinding, oppSpanWinding)) {
-        switch (op) {
-            case kIntersect_Op:
-            case kUnion_Op:
-                return true;
-            case kDifference_Op: {
-                int absSpan = abs(spanWinding);
-                int absOpp = abs(oppSpanWinding);
-                return windingIsOp ? absSpan < absOpp : absSpan > absOpp;
-            }
-            case kXor_Op:
-                return spanWinding != oppSpanWinding;
-            default:
-                SkASSERT(0);
-        }
-    }
-    bool opActive = oppWinding != 0;
-    return gOpLookup[op][opActive][windingIsOp];
-}
-*/
-
-static bool bridgeOp(SkTArray<SkOpContour*, true>& contourList, const SkPathOp op,
-        const int xorMask, const int xorOpMask, SkPathWriter* simple) {
+static bool bridgeOp(SkTDArray<SkOpContour* >& contourList, const SkPathOp op,
+        const int xorMask, const int xorOpMask, SkPathWriter* simple, SkChunkAlloc* allocator) {
     bool firstContour = true;
     bool unsortable = false;
     bool topUnsortable = false;
@@ -141,12 +107,14 @@
     SkPoint lastTopLeft;
     SkPoint topLeft = {SK_ScalarMin, SK_ScalarMin};
     do {
-        int index, endIndex;
+        SkOpSpanBase* start;
+        SkOpSpanBase* end;
         bool topDone;
         bool onlyVertical = false;
         lastTopLeft = topLeft;
-        SkOpSegment* current = FindSortableTop(contourList, SkOpAngle::kBinarySingle, &firstContour,
-                &index, &endIndex, &topLeft, &topUnsortable, &topDone, &onlyVertical, firstPass);
+        SkOpSegment* current = FindSortableTop(contourList, firstPass, SkOpAngle::kBinarySingle,
+                &firstContour, &start, &end, &topLeft, &topUnsortable, &topDone, &onlyVertical,
+                allocator);
         if (!current) {
             if ((!topUnsortable || firstPass) && !topDone) {
                 SkASSERT(topLeft.fX != SK_ScalarMin && topLeft.fY != SK_ScalarMin);
@@ -165,69 +133,65 @@
             break;
         }
         firstPass = !topUnsortable || lastTopLeft != topLeft;
-        SkTDArray<SkOpSpan*> chase;
+        SkTDArray<SkOpSpanBase*> chase;
         do {
-            if (current->activeOp(index, endIndex, xorMask, xorOpMask, op)) {
+            if (current->activeOp(start, end, xorMask, xorOpMask, op)) {
                 do {
                     if (!unsortable && current->done()) {
                         break;
                     }
                     SkASSERT(unsortable || !current->done());
-                    int nextStart = index;
-                    int nextEnd = endIndex;
+                    SkOpSpanBase* nextStart = start;
+                    SkOpSpanBase* nextEnd = end;
                     SkOpSegment* next = current->findNextOp(&chase, &nextStart, &nextEnd,
                             &unsortable, op, xorMask, xorOpMask);
                     if (!next) {
                         if (!unsortable && simple->hasMove()
                                 && current->verb() != SkPath::kLine_Verb
                                 && !simple->isClosed()) {
-                            current->addCurveTo(index, endIndex, simple, true);
+                            current->addCurveTo(start, end, simple, true);
                     #if DEBUG_ACTIVE_SPANS
                             if (!simple->isClosed()) {
                                 DebugShowActiveSpans(contourList);
                             }
                     #endif
-//                            SkASSERT(simple->isClosed());
                         }
                         break;
                     }
         #if DEBUG_FLOW
-            SkDebugf("%s current id=%d from=(%1.9g,%1.9g) to=(%1.9g,%1.9g)\n", __FUNCTION__,
-                    current->debugID(), current->xyAtT(index).fX, current->xyAtT(index).fY,
-                    current->xyAtT(endIndex).fX, current->xyAtT(endIndex).fY);
+                    SkDebugf("%s current id=%d from=(%1.9g,%1.9g) to=(%1.9g,%1.9g)\n", __FUNCTION__,
+                            current->debugID(), start->pt().fX, start->pt().fY,
+                            end->pt().fX, end->pt().fY);
         #endif
-                    current->addCurveTo(index, endIndex, simple, true);
+                    current->addCurveTo(start, end, simple, true);
                     current = next;
-                    index = nextStart;
-                    endIndex = nextEnd;
-                } while (!simple->isClosed() && (!unsortable
-                        || !current->done(SkMin32(index, endIndex))));
-                if (current->activeWinding(index, endIndex) && !simple->isClosed()) {
-                    // FIXME : add to simplify, xor cpaths
-                    int min = SkMin32(index, endIndex);
-                    if (!unsortable && !simple->isEmpty()) {
-                        unsortable = current->checkSmall(min);
-                    }
-                    if (!current->done(min)) {
-                        current->addCurveTo(index, endIndex, simple, true);
-                        current->markDoneBinary(min);
+                    start = nextStart;
+                    end = nextEnd;
+                } while (!simple->isClosed() && (!unsortable || !start->starter(end)->done()));
+                if (current->activeWinding(start, end) && !simple->isClosed()) {
+                    SkOpSpan* spanStart = start->starter(end);
+                    if (!spanStart->done()) {
+                        current->addCurveTo(start, end, simple, true);
+                        current->markDone(spanStart);
                     }
                 }
                 simple->close();
             } else {
-                SkOpSpan* last = current->markAndChaseDoneBinary(index, endIndex);
-                if (last && !last->fChased && !last->fLoop) {
-                    last->fChased = true;
+                SkOpSpanBase* last = current->markAndChaseDone(start, end);
+                if (last && !last->chased()) {
+                    last->setChased(true);
                     SkASSERT(!SkPathOpsDebug::ChaseContains(chase, last));
                     *chase.append() = last;
 #if DEBUG_WINDING
-                    SkDebugf("%s chase.append id=%d windSum=%d small=%d\n", __FUNCTION__,
-                            last->fOther->span(last->fOtherIndex).fOther->debugID(), last->fWindSum,
-                            last->fSmall);
+                    SkDebugf("%s chase.append id=%d", __FUNCTION__, last->segment()->debugID());
+                    if (!last->final()) {
+                         SkDebugf(" windSum=%d", last->upCast()->windSum());
+                    }
+                    SkDebugf("\n");
 #endif
                 }
             }
-            current = findChaseOp(chase, &index, &endIndex);
+            current = findChaseOp(chase, &start, &end);
         #if DEBUG_ACTIVE_SPANS
             DebugShowActiveSpans(contourList);
         #endif
@@ -291,16 +255,19 @@
     dump_path(file, two, false, true);
     fprintf(file, "    SkPath path2(path);\n");
     fprintf(file, "    testPathOp(reporter, path1, path2, (SkPathOp) %d, filename);\n", op);
-    fprintf(file, "}\n");	
+    fprintf(file, "}\n");    
     fclose(file);
 }
 #endif
 
 bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) {
+    SkOpContour contour;
+    SkOpCoincidence coincidence;
+    SkOpGlobalState globalState(&coincidence  PATH_OPS_DEBUG_PARAMS(&contour));
 #if DEBUGGING_PATHOPS_FROM_HOST
     dump_op(one, two, op);
-#endif	
-#if DEBUG_SHOW_TEST_NAME
+#endif    
+#if 0 && DEBUG_SHOW_TEST_NAME
     char* debugName = DEBUG_FILENAME_STRING;
     if (debugName && debugName[0]) {
         SkPathOpsDebug::BumpTestName(debugName);
@@ -321,53 +288,54 @@
     SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault;
 #endif
     // turn path into list of segments
-    SkTArray<SkOpContour> contours;
-    // FIXME: add self-intersecting cubics' T values to segment
-    SkOpEdgeBuilder builder(*minuend, contours);
+    SkChunkAlloc allocator(4096);  // FIXME: add a constant expression here, tune
+    SkOpEdgeBuilder builder(*minuend, &contour, &allocator, &globalState);
     if (builder.unparseable()) {
         return false;
     }
     const int xorMask = builder.xorMask();
     builder.addOperand(*subtrahend);
-    if (!builder.finish()) {
+    if (!builder.finish(&allocator)) {
         return false;
     }
+#if !FORCE_RELEASE
+    contour.dumpSegments(op);
+#endif
+
     result->reset();
     result->setFillType(fillType);
     const int xorOpMask = builder.xorMask();
-    SkTArray<SkOpContour*, true> contourList;
-    MakeContourList(contours, contourList, xorMask == kEvenOdd_PathOpsMask,
+    SkTDArray<SkOpContour* > contourList;
+    MakeContourList(&contour, contourList, xorMask == kEvenOdd_PathOpsMask,
             xorOpMask == kEvenOdd_PathOpsMask);
     SkOpContour** currentPtr = contourList.begin();
     if (!currentPtr) {
         return true;
     }
+    if ((*currentPtr)->count() == 0) {
+        SkASSERT((*currentPtr)->next() == NULL);
+        return true;
+    }
     SkOpContour** listEnd = contourList.end();
     // find all intersections between segments
     do {
         SkOpContour** nextPtr = currentPtr;
         SkOpContour* current = *currentPtr++;
-        if (current->containsCubics()) {
-            AddSelfIntersectTs(current);
-        }
         SkOpContour* next;
         do {
             next = *nextPtr++;
-        } while (AddIntersectTs(current, next) && nextPtr != listEnd);
+        } while (AddIntersectTs(current, next, &coincidence, &allocator) && nextPtr != listEnd);
     } while (currentPtr != listEnd);
+#if DEBUG_VALIDATE
+    globalState.setPhase(SkOpGlobalState::kWalking);
+#endif
     // eat through coincident edges
-
-    int total = 0;
-    int index;
-    for (index = 0; index < contourList.count(); ++index) {
-        total += contourList[index]->segments().count();
-    }
-    if (!HandleCoincidence(&contourList, total)) {
+    if (!HandleCoincidence(&contourList, &coincidence, &allocator, &globalState)) {
         return false;
     }
     // construct closed contours
     SkPathWriter wrapper(*result);
-    bridgeOp(contourList, op, xorMask, xorOpMask, &wrapper);
+    bridgeOp(contourList, op, xorMask, xorOpMask, &wrapper, &allocator);
     {  // if some edges could not be resolved, assemble remaining fragments
         SkPath temp;
         temp.setFillType(fillType);
diff --git a/src/pathops/SkPathOpsPoint.h b/src/pathops/SkPathOpsPoint.h
index 7ddfbfb..2d07427 100644
--- a/src/pathops/SkPathOpsPoint.h
+++ b/src/pathops/SkPathOpsPoint.h
@@ -25,21 +25,25 @@
 
     friend SkDPoint operator+(const SkDPoint& a, const SkDVector& b);
 
+    // only used by testing
     void operator+=(const SkDVector& v) {
         fX += v.fX;
         fY += v.fY;
     }
 
+    // only called by nearestT, which is currently only used by testing
     void operator-=(const SkDVector& v) {
         fX -= v.fX;
         fY -= v.fY;
     }
 
+    // only used by testing
     void operator/=(const double s) {
         fX /= s;
         fY /= s;
     }
 
+    // only used by testing
     void operator*=(const double s) {
         fX *= s;
         fY *= s;
@@ -50,6 +54,7 @@
         return v;
     }
 
+    // only used by testing
     double cross(const SkDVector& a) const {
         return fX * a.fY - fY * a.fX;
     }
@@ -98,11 +103,13 @@
         fY = pt.fY;
     }
 
+    // only used by testing
     void operator+=(const SkDVector& v) {
         fX += v.fX;
         fY += v.fY;
     }
 
+    // only used by testing
     void operator-=(const SkDVector& v) {
         fX -= v.fX;
         fY -= v.fY;
@@ -122,7 +129,7 @@
         double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY);
         double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY);
         largest = SkTMax(largest, -tiniest);
-        return AlmostBequalUlps(largest, largest + dist); // is the dist within ULPS tolerance?
+        return AlmostPequalUlps(largest, largest + dist); // is the dist within ULPS tolerance?
     }
 
     bool approximatelyEqual(const SkPoint& a) const {
@@ -145,44 +152,10 @@
         float tiniest = SkTMin(SkTMin(SkTMin(a.fX, b.fX), a.fY), b.fY);
         float largest = SkTMax(SkTMax(SkTMax(a.fX, b.fX), a.fY), b.fY);
         largest = SkTMax(largest, -tiniest);
-        return AlmostBequalUlps((double) largest, largest + dist); // is dist within ULPS tolerance?
+        return AlmostPequalUlps((double) largest, largest + dist); // is dist within ULPS tolerance?
     }
 
-    static bool RoughlyEqual(const SkPoint& a, const SkPoint& b) {
-        if (approximately_equal(a.fX, b.fX) && approximately_equal(a.fY, b.fY)) {
-            return true;
-        }
-        return RoughlyEqualUlps(a.fX, b.fX) && RoughlyEqualUlps(a.fY, b.fY);
-    }
-
-    bool approximatelyPEqual(const SkDPoint& a) const {
-        if (approximately_equal(fX, a.fX) && approximately_equal(fY, a.fY)) {
-            return true;
-        }
-        if (!RoughlyEqualUlps(fX, a.fX) || !RoughlyEqualUlps(fY, a.fY)) {
-            return false;
-        }
-        double dist = distance(a);  // OPTIMIZATION: can we compare against distSq instead ?
-        double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY);
-        double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY);
-        largest = SkTMax(largest, -tiniest);
-        return AlmostPequalUlps(largest, largest + dist); // is the dist within ULPS tolerance?
-    }
-
-    bool approximatelyDEqual(const SkDPoint& a) const {
-        if (approximately_equal(fX, a.fX) && approximately_equal(fY, a.fY)) {
-            return true;
-        }
-        if (!RoughlyEqualUlps(fX, a.fX) || !RoughlyEqualUlps(fY, a.fY)) {
-            return false;
-        }
-        double dist = distance(a);  // OPTIMIZATION: can we compare against distSq instead ?
-        double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY);
-        double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY);
-        largest = SkTMax(largest, -tiniest);
-        return AlmostDequalUlps(largest, largest + dist); // is the dist within ULPS tolerance?
-    }
-
+    // only used by testing
     bool approximatelyZero() const {
         return approximately_zero(fX) && approximately_zero(fY);
     }
@@ -209,7 +182,7 @@
         return result;
     }
 
-    bool moreRoughlyEqual(const SkDPoint& a) const {
+    bool roughlyEqual(const SkDPoint& a) const {
         if (roughly_equal(fX, a.fX) && roughly_equal(fY, a.fY)) {
             return true;
         }
@@ -220,10 +193,6 @@
         return RoughlyEqualUlps(largest, largest + dist); // is the dist within ULPS tolerance?
     }
 
-    bool roughlyEqual(const SkDPoint& a) const {
-        return roughly_equal(a.fY, fY) && roughly_equal(a.fX, fX);
-    }
-
     // utilities callable by the user from the debugger when the implementation code is linked in
     void dump() const;
     static void Dump(const SkPoint& pt);
diff --git a/src/pathops/SkPathOpsPostSect.cpp b/src/pathops/SkPathOpsPostSect.cpp
old mode 100644
new mode 100755
index 15a1900..eb2d1ab
--- a/src/pathops/SkPathOpsPostSect.cpp
+++ b/src/pathops/SkPathOpsPostSect.cpp
@@ -17,8 +17,8 @@
     return segment()->contour();
 }
 
-SkOpDebugState* SkOpPtT::debugState() const {
-    return PATH_OPS_DEBUG_RELEASE(contour()->debugState(), NULL); 
+SkOpGlobalState* SkOpPtT::globalState() const {
+    return PATH_OPS_DEBUG_RELEASE(contour()->globalState(), NULL); 
 }
 
 void SkOpPtT::init(SkOpSpanBase* span, double t, const SkPoint& pt, bool duplicate) {
@@ -28,7 +28,7 @@
     fNext = this;
     fDuplicatePt = duplicate;
     fDeleted = false;
-    PATH_OPS_DEBUG_CODE(fID = ++span->debugState()->fPtTID);
+    PATH_OPS_DEBUG_CODE(fID = ++span->globalState()->fPtTID);
 }
 
 bool SkOpPtT::onEnd() const {
@@ -45,7 +45,7 @@
     do {
         SkOpPtT* next = prev->fNext;
         if (next == this) {
-            prev->removeNext();
+            prev->removeNext(this);
             fDeleted = true;
             return prev;
         }
@@ -55,14 +55,14 @@
     return NULL;
 }
 
-void SkOpPtT::removeNext() {
+void SkOpPtT::removeNext(SkOpPtT* kept) {
     SkASSERT(this->fNext);
     SkOpPtT* next = this->fNext;
     this->fNext = next->fNext;
     SkOpSpanBase* span = next->span();
     next->setDeleted();
     if (span->ptT() == next) {
-        span->upCast()->detach();
+        span->upCast()->detach(kept);
     }
 }
 
@@ -199,7 +199,7 @@
                 // omit aliases that alignment makes redundant
                 if ((!ptT->alias() || test->alias()) && (ptT->onEnd() || !test->onEnd())) {
                     SkASSERT(test->alias());
-                    prev->removeNext();
+                    prev->removeNext(ptT);
                     test = prev;
                 } else {
                     SkASSERT(ptT->alias());
@@ -239,8 +239,8 @@
     return segment()->contour();
 }
 
-SkOpDebugState* SkOpSpanBase::debugState() const {
-    return PATH_OPS_DEBUG_RELEASE(contour()->debugState(), NULL); 
+SkOpGlobalState* SkOpSpanBase::globalState() const {
+    return PATH_OPS_DEBUG_RELEASE(contour()->globalState(), NULL); 
 }
 
 void SkOpSpanBase::initBase(SkOpSegment* segment, SkOpSpan* prev, double t, const SkPoint& pt) {
@@ -252,7 +252,7 @@
     fAligned = true;
     fChased = false;
     PATH_OPS_DEBUG_CODE(fCount = 1);
-    PATH_OPS_DEBUG_CODE(fID = ++debugState()->fSpanID);
+    PATH_OPS_DEBUG_CODE(fID = ++globalState()->fSpanID);
 }
 
 // this pair of spans share a common t value or point; merge them and eliminate duplicates
@@ -261,7 +261,7 @@
     SkOpPtT* spanPtT = span->ptT();
     SkASSERT(this->t() != spanPtT->fT);
     SkASSERT(!zero_or_one(spanPtT->fT));
-    span->detach();
+    span->detach(this->ptT());
     SkOpPtT* remainder = spanPtT->next();
     ptT()->insert(spanPtT);
     while (remainder != spanPtT) {
@@ -304,7 +304,7 @@
     return false;
 }
 
-void SkOpSpan::detach() {
+void SkOpSpan::detach(SkOpPtT* kept) {
     SkASSERT(!final());
     SkOpSpan* prev = this->prev();
     SkASSERT(prev);
@@ -313,6 +313,9 @@
     prev->setNext(next);
     next->setPrev(prev);
     this->segment()->detach(this);
+    if (this->coincident()) {
+        this->globalState()->fCoincidence->fixUp(this->ptT(), kept);
+    }
     this->ptT()->setDeleted();
 }
 
diff --git a/src/pathops/SkPathOpsQuad.cpp b/src/pathops/SkPathOpsQuad.cpp
index c1d068a..4913c9f 100644
--- a/src/pathops/SkPathOpsQuad.cpp
+++ b/src/pathops/SkPathOpsQuad.cpp
@@ -8,7 +8,61 @@
 #include "SkLineParameters.h"
 #include "SkPathOpsCubic.h"
 #include "SkPathOpsQuad.h"
-#include "SkPathOpsTriangle.h"
+
+/* started with at_most_end_pts_in_common from SkDQuadIntersection.cpp */
+// Do a quick reject by rotating all points relative to a line formed by
+// a pair of one quad's points. If the 2nd quad's points
+// are on the line or on the opposite side from the 1st quad's 'odd man', the
+// curves at most intersect at the endpoints.
+/* if returning true, check contains true if quad's hull collapsed, making the cubic linear
+   if returning false, check contains true if the the quad pair have only the end point in common
+*/
+bool SkDQuad::hullIntersects(const SkDQuad& q2, bool* isLinear) const {
+    bool linear = true;
+    for (int oddMan = 0; oddMan < kPointCount; ++oddMan) {
+        const SkDPoint* endPt[2];
+        this->otherPts(oddMan, endPt);
+        double origX = endPt[0]->fX;
+        double origY = endPt[0]->fY;
+        double adj = endPt[1]->fX - origX;
+        double opp = endPt[1]->fY - origY;
+        double sign = (fPts[oddMan].fY - origY) * adj - (fPts[oddMan].fX - origX) * opp;
+        if (approximately_zero(sign)) {
+            continue;
+        }
+        linear = false;
+        bool foundOutlier = false;
+        for (int n = 0; n < kPointCount; ++n) {
+            double test = (q2[n].fY - origY) * adj - (q2[n].fX - origX) * opp;
+            if (test * sign > 0 && !precisely_zero(test)) {
+                foundOutlier = true;
+                break;
+            }
+        }
+        if (!foundOutlier) {
+            return false;
+        }
+    }
+    *isLinear = linear;
+    return true;
+}
+
+/* bit twiddling for finding the off curve index (x&~m is the pair in [0,1,2] excluding oddMan)
+oddMan    opp   x=oddMan^opp  x=x-oddMan  m=x>>2   x&~m
+    0       1         1            1         0       1
+            2         2            2         0       2
+    1       1         0           -1        -1       0
+            2         3            2         0       2
+    2       1         3            1         0       1
+            2         0           -2        -1       0
+*/
+void SkDQuad::otherPts(int oddMan, const SkDPoint* endPt[2]) const {
+    for (int opp = 1; opp < kPointCount; ++opp) {
+        int end = (oddMan ^ opp) - oddMan;  // choose a value not equal to oddMan
+        end &= ~(end >> 2);  // if the value went negative, set it to zero
+        endPt[opp - 1] = &fPts[end];
+    }
+}
 
 // from http://blog.gludion.com/2009/08/distance-to-quadratic-bezier-curve.html
 // (currently only used by testing)
@@ -43,10 +97,6 @@
     return d0 < d2 ? 0 : 1;
 }
 
-bool SkDQuad::pointInHull(const SkDPoint& pt) const {
-    return ((const SkDTriangle&) fPts).contains(pt);
-}
-
 SkDPoint SkDQuad::top(double startT, double endT) const {
     SkDQuad sub = subDivide(startT, endT);
     SkDPoint topPt = sub[0];
@@ -140,7 +190,12 @@
     // FIXME: maybe it's possible to avoid this and compare non-normalized
     lineParameters.normalize();
     double distance = lineParameters.controlPtDistance(*this);
-    return approximately_zero(distance);
+    double tiniest = SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY),
+            fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY);
+    double largest = SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY),
+            fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY);
+    largest = SkTMax(largest, -tiniest);
+    return approximately_zero_when_compared_to(distance, largest);
 }
 
 SkDCubic SkDQuad::toCubic() const {
@@ -240,13 +295,6 @@
 SkDPoint SkDQuad::subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2) const {
     SkASSERT(t1 != t2);
     SkDPoint b;
-#if 0
-    // this approach assumes that the control point computed directly is accurate enough
-    double dx = interp_quad_coords(&fPts[0].fX, (t1 + t2) / 2);
-    double dy = interp_quad_coords(&fPts[0].fY, (t1 + t2) / 2);
-    b.fX = 2 * dx - (a.fX + c.fX) / 2;
-    b.fY = 2 * dy - (a.fY + c.fY) / 2;
-#else
     SkDQuad sub = subDivide(t1, t2);
     SkDLine b0 = {{a, sub[1] + (a - sub[0])}};
     SkDLine b1 = {{c, sub[1] + (c - sub[2])}};
@@ -258,7 +306,6 @@
         SkASSERT(i.used() <= 2);
         b = SkDPoint::Mid(b0[1], b1[1]);
     }
-#endif
     if (t1 == 0 || t2 == 0) {
         align(0, &b);
     }
diff --git a/src/pathops/SkPathOpsQuad.h b/src/pathops/SkPathOpsQuad.h
index 932c5fb..81638cf 100644
--- a/src/pathops/SkPathOpsQuad.h
+++ b/src/pathops/SkPathOpsQuad.h
@@ -17,43 +17,61 @@
 };
 
 struct SkDQuad {
-    SkDPoint fPts[3];
+    static const int kPointCount = 3;
+    static const int kPointLast = kPointCount - 1;
+    static const int kMaxIntersections = 4;
+
+    SkDPoint fPts[kPointCount];
+
+    bool collapsed() const {
+        return fPts[0].approximatelyEqual(fPts[1]) && fPts[0].approximatelyEqual(fPts[2]);
+    }
+
+    bool controlsInside() const {
+        SkDVector v01 = fPts[0] - fPts[1];
+        SkDVector v02 = fPts[0] - fPts[2];
+        SkDVector v12 = fPts[1] - fPts[2];
+        return v02.dot(v01) > 0 && v02.dot(v12) > 0;
+    }
 
     SkDQuad flip() const {
         SkDQuad result = {{fPts[2], fPts[1], fPts[0]}};
         return result;
     }
 
-    void set(const SkPoint pts[3]) {
+    static bool IsCubic() { return false; }
+
+    void set(const SkPoint pts[kPointCount]) {
         fPts[0] = pts[0];
         fPts[1] = pts[1];
         fPts[2] = pts[2];
     }
 
-    const SkDPoint& operator[](int n) const { SkASSERT(n >= 0 && n < 3); return fPts[n]; }
-    SkDPoint& operator[](int n) { SkASSERT(n >= 0 && n < 3); return fPts[n]; }
+    const SkDPoint& operator[](int n) const { SkASSERT(n >= 0 && n < kPointCount); return fPts[n]; }
+    SkDPoint& operator[](int n) { SkASSERT(n >= 0 && n < kPointCount); return fPts[n]; }
 
     static int AddValidTs(double s[], int realRoots, double* t);
     void align(int endIndex, SkDPoint* dstPt) const;
     SkDQuadPair chopAt(double t) const;
     SkDVector dxdyAtT(double t) const;
     static int FindExtrema(double a, double b, double c, double tValue[1]);
+    bool hullIntersects(const SkDQuad& , bool* isLinear) const;
     bool isLinear(int startIndex, int endIndex) const;
     bool monotonicInY() const;
     double nearestT(const SkDPoint&) const;
-    bool pointInHull(const SkDPoint&) const;
+    void otherPts(int oddMan, const SkDPoint* endPt[2]) const;
     SkDPoint ptAtT(double t) const;
     static int RootsReal(double A, double B, double C, double t[2]);
     static int RootsValidT(const double A, const double B, const double C, double s[2]);
     static void SetABC(const double* quad, double* a, double* b, double* c);
     SkDQuad subDivide(double t1, double t2) const;
-    static SkDQuad SubDivide(const SkPoint a[3], double t1, double t2) {
+    static SkDQuad SubDivide(const SkPoint a[kPointCount], double t1, double t2) {
         SkDQuad quad;
         quad.set(a);
         return quad.subDivide(t1, t2);
     }
     SkDPoint subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2) const;
-    static SkDPoint SubDivide(const SkPoint pts[3], const SkDPoint& a, const SkDPoint& c,
+    static SkDPoint SubDivide(const SkPoint pts[kPointCount], const SkDPoint& a, const SkDPoint& c,
                               double t1, double t2) {
         SkDQuad quad;
         quad.set(pts);
@@ -64,7 +82,8 @@
 
     // utilities callable by the user from the debugger when the implementation code is linked in
     void dump() const;
-    void dumpComma(const char*) const;
+    void dumpID(int id) const;
+    void dumpInner() const;
 
 private:
 //  static double Tangent(const double* quadratic, double t);  // uncalled
diff --git a/src/pathops/SkPathOpsQuadSect.h b/src/pathops/SkPathOpsQuadSect.h
deleted file mode 100644
index 57f1aa0..0000000
--- a/src/pathops/SkPathOpsQuadSect.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef SkQuadSpan_DEFINE
-#define SkQuadSpan_DEFINE
-
-#include "SkChunkAlloc.h"
-#include "SkPathOpsRect.h"
-#include "SkPathOpsQuad.h"
-#include "SkTArray.h"
-
-class SkIntersections;
-
-class SkQuadCoincident {
-public:
-    bool isCoincident() const {
-        return fCoincident;
-    }
-
-    void init() {
-        fCoincident = false;
-        SkDEBUGCODE(fPerpPt.fX = fPerpPt.fY = SK_ScalarNaN);
-        SkDEBUGCODE(fPerpT = SK_ScalarNaN);
-    }
-
-    void markCoincident() {
-        if (!fCoincident) {
-            fPerpT = -1;
-        }
-        fCoincident = true;
-    }
-
-    const SkDPoint& perpPt() const {
-        return fPerpPt;
-    }
-
-    double perpT() const {
-        return fPerpT;
-    }
-
-    void setPerp(const SkDQuad& quad1, double t, const SkDPoint& qPt, const SkDQuad& quad2);
-
-private:
-    SkDPoint fPerpPt;
-    double fPerpT;  // perpendicular intersection on opposite quad
-    bool fCoincident;
-};
-
-class SkQuadSect;  // used only by debug id
-
-class SkQuadSpan {
-public:
-    void init(const SkDQuad& quad);
-    void initBounds(const SkDQuad& quad);
-
-    bool contains(double t) const {
-        return !! const_cast<SkQuadSpan*>(this)->innerFind(t);
-    }
-
-    bool contains(const SkQuadSpan* span) const;
-
-    SkQuadSpan* find(double t) {
-        SkQuadSpan* result = innerFind(t);
-        SkASSERT(result);
-        return result;
-    }
-
-    bool intersects(const SkQuadSpan* span) const;
-
-    const SkQuadSpan* next() const {
-        return fNext;
-    }
-
-    void reset() {
-        fBounded.reset();
-    }
-
-    bool split(SkQuadSpan* work) {
-        return splitAt(work, (work->fStartT + work->fEndT) * 0.5);
-    }
-
-    bool splitAt(SkQuadSpan* work, double t);
-    bool tightBoundsIntersects(const SkQuadSpan* span) const;
-
-    // implementation is for testing only
-    void dump() const;
-
-private:
-    bool hullIntersects(const SkDQuad& q2) const;
-    SkQuadSpan* innerFind(double t);
-    bool linearIntersects(const SkDQuad& q2) const;
-
-    // implementation is for testing only
-#if DEBUG_BINARY_QUAD
-    int debugID(const SkQuadSect* ) const { return fDebugID; }
-#else
-    int debugID(const SkQuadSect* ) const;
-#endif
-    void dump(const SkQuadSect* ) const;
-    void dumpID(const SkQuadSect* ) const;
-
-#if DEBUG_BINARY_QUAD
-    void validate() const;
-#endif
-
-    SkDQuad fPart;
-    SkQuadCoincident fCoinStart;
-    SkQuadCoincident fCoinEnd;
-    SkSTArray<4, SkQuadSpan*, true> fBounded;
-    SkQuadSpan* fPrev;
-    SkQuadSpan* fNext;
-    SkDRect fBounds;
-    double fStartT;
-    double fEndT;
-    double fBoundsMax;
-    bool fCollapsed;
-    bool fHasPerp;
-    mutable bool fIsLinear;
-#if DEBUG_BINARY_QUAD
-    int fDebugID;
-    bool fDebugDeleted;
-#endif
-    friend class SkQuadSect;
-};
-
-class SkQuadSect {
-public:
-    SkQuadSect(const SkDQuad& quad PATH_OPS_DEBUG_PARAMS(int id));
-    static void BinarySearch(SkQuadSect* sect1, SkQuadSect* sect2, SkIntersections* intersections);
-
-    // for testing only
-    void dumpQuads() const;
-private:
-    SkQuadSpan* addOne();
-    bool binarySearchCoin(const SkQuadSect& , double tStart, double tStep, double* t, double* oppT);
-    SkQuadSpan* boundsMax() const;
-    void coincidentCheck(SkQuadSect* sect2);
-    bool intersects(const SkQuadSpan* span, const SkQuadSect* opp, const SkQuadSpan* oppSpan) const;
-    void onCurveCheck(SkQuadSect* sect2, SkQuadSpan* first, SkQuadSpan* last);
-    void recoverCollapsed();
-    void removeSpan(SkQuadSpan* span);
-    void removeOne(const SkQuadSpan* test, SkQuadSpan* span);
-    void removeSpans(SkQuadSpan* span, SkQuadSect* opp);
-    void setPerp(const SkDQuad& opp, SkQuadSpan* first, SkQuadSpan* last);
-    const SkQuadSpan* tail() const;
-    void trim(SkQuadSpan* span, SkQuadSect* opp);
-
-    // for testing only
-    void dump() const;
-    void dumpBoth(const SkQuadSect& opp) const;
-    void dumpBoth(const SkQuadSect* opp) const;
-
-#if DEBUG_BINARY_QUAD
-    int debugID() const { return fDebugID; }
-    void validate() const;
-#else
-    int debugID() const { return 0; }
-#endif
-    const SkDQuad& fQuad;
-    SkChunkAlloc fHeap;
-    SkQuadSpan* fHead;
-    SkQuadSpan* fDeleted;
-    int fActiveCount;
-#if DEBUG_BINARY_QUAD
-    int fDebugID;
-    int fDebugCount;
-    int fDebugAllocatedCount;
-#endif
-    friend class SkQuadSpan;  // only used by debug id
-};
-
-#endif
diff --git a/src/pathops/SkPathOpsRect.cpp b/src/pathops/SkPathOpsRect.cpp
index 2ceed32..5dd3d8d 100644
--- a/src/pathops/SkPathOpsRect.cpp
+++ b/src/pathops/SkPathOpsRect.cpp
@@ -9,11 +9,6 @@
 #include "SkPathOpsQuad.h"
 #include "SkPathOpsRect.h"
 
-void SkDRect::setBounds(const SkDLine& line) {
-    set(line[0]);
-    add(line[1]);
-}
-
 void SkDRect::setBounds(const SkDQuad& quad) {
     set(quad[0]);
     add(quad[2]);
@@ -30,13 +25,6 @@
     }
 }
 
-void SkDRect::setRawBounds(const SkDQuad& quad) {
-    set(quad[0]);
-    for (int x = 1; x < 3; ++x) {
-        add(quad[x]);
-    }
-}
-
 static bool is_bounded_by_end_points(double a, double b, double c, double d) {
     return between(a, b, d) && between(a, c, d);
 }
@@ -56,10 +44,3 @@
         add(c.ptAtT(tValues[x]));
     }
 }
-
-void SkDRect::setRawBounds(const SkDCubic& cubic) {
-    set(cubic[0]);
-    for (int x = 1; x < 4; ++x) {
-        add(cubic[x]);
-    }
-}
diff --git a/src/pathops/SkPathOpsRect.h b/src/pathops/SkPathOpsRect.h
index 2c47f43..2b37a5f 100644
--- a/src/pathops/SkPathOpsRect.h
+++ b/src/pathops/SkPathOpsRect.h
@@ -13,18 +13,10 @@
     double fLeft, fTop, fRight, fBottom;
 
     void add(const SkDPoint& pt) {
-        if (fLeft > pt.fX) {
-            fLeft = pt.fX;
-        }
-        if (fTop > pt.fY) {
-            fTop = pt.fY;
-        }
-        if (fRight < pt.fX) {
-            fRight = pt.fX;
-        }
-        if (fBottom < pt.fY) {
-            fBottom = pt.fY;
-        }
+        fLeft = SkTMin(fLeft, pt.fX);
+        fTop = SkTMin(fTop, pt.fY);
+        fRight = SkTMax(fRight, pt.fX);
+        fBottom = SkTMax(fBottom, pt.fY);
     }
 
     bool contains(const SkDPoint& pt) const {
@@ -32,12 +24,15 @@
                 && approximately_between(fTop, pt.fY, fBottom);
     }
 
-    bool intersects(SkDRect* r) const {
+    bool intersects(const SkDRect& r) const {
+        if (fLeft > fRight) {
+            SkDebugf("!");
+        }
         SkASSERT(fLeft <= fRight);
         SkASSERT(fTop <= fBottom);
-        SkASSERT(r->fLeft <= r->fRight);
-        SkASSERT(r->fTop <= r->fBottom);
-        return r->fLeft <= fRight && fLeft <= r->fRight && r->fTop <= fBottom && fTop <= r->fBottom;
+        SkASSERT(r.fLeft <= r.fRight);
+        SkASSERT(r.fTop <= r.fBottom);
+        return r.fLeft <= fRight && fLeft <= r.fRight && r.fTop <= fBottom && fTop <= r.fBottom;
     }
 
     void set(const SkDPoint& pt) {
@@ -53,11 +48,8 @@
         return fBottom - fTop;
     }
 
-    void setBounds(const SkDLine&);
     void setBounds(const SkDCubic&);
     void setBounds(const SkDQuad&);
-    void setRawBounds(const SkDCubic&);
-    void setRawBounds(const SkDQuad&);
 };
 
 #endif
diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp
index 57090ac..7a234ec 100644
--- a/src/pathops/SkPathOpsSimplify.cpp
+++ b/src/pathops/SkPathOpsSimplify.cpp
@@ -5,11 +5,13 @@
  * found in the LICENSE file.
  */
 #include "SkAddIntersections.h"
+#include "SkOpCoincidence.h"
 #include "SkOpEdgeBuilder.h"
 #include "SkPathOpsCommon.h"
 #include "SkPathWriter.h"
 
-static bool bridgeWinding(SkTArray<SkOpContour*, true>& contourList, SkPathWriter* simple) {
+static bool bridgeWinding(SkTDArray<SkOpContour* >& contourList, SkPathWriter* simple,
+        SkChunkAlloc* allocator) {
     bool firstContour = true;
     bool unsortable = false;
     bool topUnsortable = false;
@@ -17,15 +19,24 @@
     SkPoint lastTopLeft;
     SkPoint topLeft = {SK_ScalarMin, SK_ScalarMin};
     do {
-        int index, endIndex;
+        SkOpSpanBase* start;
+        SkOpSpanBase* end;
         bool topDone;
         bool onlyVertical = false;
         lastTopLeft = topLeft;
-        SkOpSegment* current = FindSortableTop(contourList, SkOpAngle::kUnaryWinding, &firstContour,
-                &index, &endIndex, &topLeft, &topUnsortable, &topDone, &onlyVertical, firstPass);
+        SkOpSegment* current = FindSortableTop(contourList, firstPass, SkOpAngle::kUnaryWinding,
+                &firstContour, &start, &end, &topLeft, &topUnsortable, &topDone, &onlyVertical,
+                allocator);
         if (!current) {
             if ((!topUnsortable || firstPass) && !topDone) {
                 SkASSERT(topLeft.fX != SK_ScalarMin && topLeft.fY != SK_ScalarMin);
+                if (lastTopLeft.fX == SK_ScalarMin && lastTopLeft.fY == SK_ScalarMin) {
+                    if (firstPass) {
+                        firstPass = false;
+                    } else {
+                        break;
+                    }
+                }
                 topLeft.fX = topLeft.fY = SK_ScalarMin;
                 continue;
             }
@@ -34,62 +45,66 @@
             break;
         }
         firstPass = !topUnsortable || lastTopLeft != topLeft;
-        SkTDArray<SkOpSpan*> chase;
+        SkTDArray<SkOpSpanBase*> chase;
         do {
-            if (current->activeWinding(index, endIndex)) {
+            if (current->activeWinding(start, end)) {
                 do {
                     if (!unsortable && current->done()) {
                           break;
                     }
                     SkASSERT(unsortable || !current->done());
-                    int nextStart = index;
-                    int nextEnd = endIndex;
+                    SkOpSpanBase* nextStart = start;
+                    SkOpSpanBase* nextEnd = end;
                     SkOpSegment* next = current->findNextWinding(&chase, &nextStart, &nextEnd,
                             &unsortable);
                     if (!next) {
                         if (!unsortable && simple->hasMove()
                                 && current->verb() != SkPath::kLine_Verb
                                 && !simple->isClosed()) {
-                            current->addCurveTo(index, endIndex, simple, true);
-                            SkASSERT(simple->isClosed());
+                            current->addCurveTo(start, end, simple, true);
+                    #if DEBUG_ACTIVE_SPANS
+                            if (!simple->isClosed()) {
+                                DebugShowActiveSpans(contourList);
+                            }
+                    #endif
                         }
                         break;
                     }
         #if DEBUG_FLOW
             SkDebugf("%s current id=%d from=(%1.9g,%1.9g) to=(%1.9g,%1.9g)\n", __FUNCTION__,
-                    current->debugID(), current->xyAtT(index).fX, current->xyAtT(index).fY,
-                    current->xyAtT(endIndex).fX, current->xyAtT(endIndex).fY);
+                    current->debugID(), start->pt().fX, start->pt().fY,
+                    end->pt().fX, end->pt().fY);
         #endif
-                    current->addCurveTo(index, endIndex, simple, true);
+                    current->addCurveTo(start, end, simple, true);
                     current = next;
-                    index = nextStart;
-                    endIndex = nextEnd;
-                } while (!simple->isClosed() && (!unsortable
-                        || !current->done(SkMin32(index, endIndex))));
-                if (current->activeWinding(index, endIndex) && !simple->isClosed()) {
-//                    SkASSERT(unsortable || simple->isEmpty());
-                    int min = SkMin32(index, endIndex);
-                    if (!current->done(min)) {
-                        current->addCurveTo(index, endIndex, simple, true);
-                        current->markDoneUnary(min);
+                    start = nextStart;
+                    end = nextEnd;
+                } while (!simple->isClosed() && (!unsortable || !start->starter(end)->done()));
+                if (current->activeWinding(start, end) && !simple->isClosed()) {
+                    SkOpSpan* spanStart = start->starter(end);
+                    if (!spanStart->done()) {
+                        current->addCurveTo(start, end, simple, true);
+                        current->markDone(spanStart);
                     }
                 }
                 simple->close();
             } else {
-                SkOpSpan* last = current->markAndChaseDoneUnary(index, endIndex);
-                if (last && !last->fChased && !last->fLoop) {
-                    last->fChased = true;
+                SkOpSpanBase* last = current->markAndChaseDone(start, end);
+                if (last && !last->chased()) {
+                    last->setChased(true);
                     SkASSERT(!SkPathOpsDebug::ChaseContains(chase, last));
                     // assert that last isn't already in array
                     *chase.append() = last;
 #if DEBUG_WINDING
-                    SkDebugf("%s chase.append id=%d windSum=%d small=%d\n", __FUNCTION__,
-                            last->fOther->span(last->fOtherIndex).fOther->debugID(), last->fWindSum,
-                            last->fSmall);
+                    SkDebugf("%s chase.append id=%d", __FUNCTION__, last->segment()->debugID());
+                    if (!last->final()) {
+                         SkDebugf(" windSum=%d", last->upCast()->windSum());
+                    }
+                    SkDebugf("\n");
 #endif
                 }
             }
-            current = FindChase(&chase, &index, &endIndex);
+            current = FindChase(&chase, &start, &end);
         #if DEBUG_ACTIVE_SPANS
             DebugShowActiveSpans(contourList);
         #endif
@@ -102,9 +117,11 @@
 }
 
 // returns true if all edges were processed
-static bool bridgeXor(SkTArray<SkOpContour*, true>& contourList, SkPathWriter* simple) {
+static bool bridgeXor(SkTDArray<SkOpContour* >& contourList, SkPathWriter* simple,
+        SkChunkAlloc* allocator) {
     SkOpSegment* current;
-    int start, end;
+    SkOpSpanBase* start;
+    SkOpSpanBase* end;
     bool unsortable = false;
     bool closable = true;
     while ((current = FindUndone(contourList, &start, &end))) {
@@ -115,34 +132,38 @@
             }
     #endif
             SkASSERT(unsortable || !current->done());
-            int nextStart = start;
-            int nextEnd = end;
+            SkOpSpanBase* nextStart = start;
+            SkOpSpanBase* nextEnd = end;
             SkOpSegment* next = current->findNextXor(&nextStart, &nextEnd, &unsortable);
             if (!next) {
                 if (!unsortable && simple->hasMove()
                         && current->verb() != SkPath::kLine_Verb
                         && !simple->isClosed()) {
                     current->addCurveTo(start, end, simple, true);
-                    SkASSERT(simple->isClosed());
+            #if DEBUG_ACTIVE_SPANS
+                    if (!simple->isClosed()) {
+                        DebugShowActiveSpans(contourList);
+                    }
+            #endif
                 }
                 break;
             }
         #if DEBUG_FLOW
             SkDebugf("%s current id=%d from=(%1.9g,%1.9g) to=(%1.9g,%1.9g)\n", __FUNCTION__,
-                    current->debugID(), current->xyAtT(start).fX, current->xyAtT(start).fY,
-                    current->xyAtT(end).fX, current->xyAtT(end).fY);
+                    current->debugID(), start->pt().fX, start->pt().fY,
+                    end->pt().fX, end->pt().fY);
         #endif
             current->addCurveTo(start, end, simple, true);
             current = next;
             start = nextStart;
             end = nextEnd;
-        } while (!simple->isClosed() && (!unsortable || !current->done(SkMin32(start, end))));
+        } while (!simple->isClosed() && (!unsortable || !start->starter(end)->done()));
         if (!simple->isClosed()) {
             SkASSERT(unsortable);
-            int min = SkMin32(start, end);
-            if (!current->done(min)) {
+            SkOpSpan* spanStart = start->starter(end);
+            if (!spanStart->done()) {
                 current->addCurveTo(start, end, simple, true);
-                current->markDone(min, 1);
+                current->markDone(spanStart);
             }
             closable = false;
         }
@@ -156,52 +177,68 @@
 
 // FIXME : add this as a member of SkPath
 bool Simplify(const SkPath& path, SkPath* result) {
-#if DEBUG_SORT || DEBUG_SWAP_TOP
-    SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault;
-#endif
     // returns 1 for evenodd, -1 for winding, regardless of inverse-ness
     SkPath::FillType fillType = path.isInverseFillType() ? SkPath::kInverseEvenOdd_FillType
             : SkPath::kEvenOdd_FillType;
-
+    if (path.isConvex()) {
+        if (result != &path) {
+            *result = path;
+        }
+        result->setFillType(fillType);
+        return true;
+    }
     // turn path into list of segments
-    SkTArray<SkOpContour> contours;
-    SkOpEdgeBuilder builder(path, contours);
-    if (!builder.finish()) {
+    SkOpCoincidence coincidence;
+    SkOpContour contour;
+    SkOpGlobalState globalState(&coincidence  PATH_OPS_DEBUG_PARAMS(&contour));
+#if DEBUG_SORT || DEBUG_SWAP_TOP
+    SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault;
+#endif
+    SkChunkAlloc allocator(4096);  // FIXME: constant-ize, tune
+    SkOpEdgeBuilder builder(path, &contour, &allocator, &globalState);
+    if (!builder.finish(&allocator)) {
         return false;
     }
-    SkTArray<SkOpContour*, true> contourList;
-    MakeContourList(contours, contourList, false, false);
-    SkOpContour** currentPtr = contourList.begin();
+#if !FORCE_RELEASE
+    contour.dumpSegments((SkPathOp) -1);
+#endif
     result->reset();
     result->setFillType(fillType);
+    SkTDArray<SkOpContour* > contourList;
+    MakeContourList(&contour, contourList, false, false);
+    SkOpContour** currentPtr = contourList.begin();
     if (!currentPtr) {
         return true;
     }
-    SkOpContour** listEnd = contourList.end();
+    if ((*currentPtr)->count() == 0) {
+        SkASSERT((*currentPtr)->next() == NULL);
+        return true;
+    }
+    SkOpContour** listEnd2 = contourList.end();
     // find all intersections between segments
     do {
         SkOpContour** nextPtr = currentPtr;
         SkOpContour* current = *currentPtr++;
-        if (current->containsCubics()) {
-            AddSelfIntersectTs(current);
-        }
         SkOpContour* next;
         do {
             next = *nextPtr++;
-        } while (AddIntersectTs(current, next) && nextPtr != listEnd);
-    } while (currentPtr != listEnd);
-    if (!HandleCoincidence(&contourList, 0)) {
+        } while (AddIntersectTs(current, next, &coincidence, &allocator) && nextPtr != listEnd2);
+    } while (currentPtr != listEnd2);
+#if DEBUG_VALIDATE
+    globalState.setPhase(SkOpGlobalState::kWalking);
+#endif
+    if (!HandleCoincidence(&contourList, &coincidence, &allocator, &globalState)) {
         return false;
     }
     // construct closed contours
-    SkPathWriter simple(*result);
-    if (builder.xorMask() == kWinding_PathOpsMask ? bridgeWinding(contourList, &simple)
-                : !bridgeXor(contourList, &simple))
+    SkPathWriter wrapper(*result);
+    if (builder.xorMask() == kWinding_PathOpsMask ? bridgeWinding(contourList, &wrapper, &allocator)
+                : !bridgeXor(contourList, &wrapper, &allocator))
     {  // if some edges could not be resolved, assemble remaining fragments
         SkPath temp;
         temp.setFillType(fillType);
         SkPathWriter assembled(temp);
-        Assemble(simple, &assembled);
+        Assemble(wrapper, &assembled);
         *result = *assembled.nativePath();
         result->setFillType(fillType);
     }
diff --git a/src/pathops/SkPathOpsTCubicSect.cpp b/src/pathops/SkPathOpsTCubicSect.cpp
index 0b3ddd7..10a84a3 100644
--- a/src/pathops/SkPathOpsTCubicSect.cpp
+++ b/src/pathops/SkPathOpsTCubicSect.cpp
@@ -7,9 +7,9 @@
 
 #include "SkPathOpsTSect.h"
 
-int SkIntersections::intersectB(const SkDCubic& cubic1, const SkDCubic& cubic2) {
-    SkTSect<SkDCubic> sect1(cubic1 PATH_OPS_DEBUG_PARAMS(1));
-    SkTSect<SkDCubic> sect2(cubic2 PATH_OPS_DEBUG_PARAMS(2));
+int SkIntersections::intersect(const SkDCubic& cubic1, const SkDCubic& cubic2) {
+    SkTSect<SkDCubic> sect1(cubic1 PATH_OPS_DEBUG_T_SECT_PARAMS(1));
+    SkTSect<SkDCubic> sect2(cubic2 PATH_OPS_DEBUG_T_SECT_PARAMS(2));
     SkTSect<SkDCubic>::BinarySearch(&sect1, &sect2, this);
     return used();
 }
diff --git a/src/pathops/SkPathOpsTQuadSect.cpp b/src/pathops/SkPathOpsTQuadSect.cpp
index 46ce5cf..06b5f2f 100644
--- a/src/pathops/SkPathOpsTQuadSect.cpp
+++ b/src/pathops/SkPathOpsTQuadSect.cpp
@@ -7,9 +7,9 @@
 
 #include "SkPathOpsTSect.h"
 
-int SkIntersections::intersectB(const SkDQuad& quad1, const SkDQuad& quad2) {
-    SkTSect<SkDQuad> sect1(quad1 PATH_OPS_DEBUG_PARAMS(1));
-    SkTSect<SkDQuad> sect2(quad2 PATH_OPS_DEBUG_PARAMS(2));
+int SkIntersections::intersect(const SkDQuad& quad1, const SkDQuad& quad2) {
+    SkTSect<SkDQuad> sect1(quad1 PATH_OPS_DEBUG_T_SECT_PARAMS(1));
+    SkTSect<SkDQuad> sect2(quad2 PATH_OPS_DEBUG_T_SECT_PARAMS(2));
     SkTSect<SkDQuad>::BinarySearch(&sect1, &sect2, this);
     return used();
 }
diff --git a/src/pathops/SkPathOpsTSect.h b/src/pathops/SkPathOpsTSect.h
index 4e7d3b17..5c76da7 100644
--- a/src/pathops/SkPathOpsTSect.h
+++ b/src/pathops/SkPathOpsTSect.h
@@ -6,15 +6,25 @@
  */
 
 #include "SkChunkAlloc.h"
+#include "SkPathOpsBounds.h"
 #include "SkPathOpsRect.h"
 #include "SkPathOpsQuad.h"
 #include "SkIntersections.h"
-#include "SkTArray.h"
+#include "SkTSort.h"
 
 /* TCurve is either SkDQuadratic or SkDCubic */
 template<typename TCurve>
 class SkTCoincident {
 public:
+    SkTCoincident()
+        : fCoincident(false) {
+    }
+
+    void clear() {
+        fPerpT = -1;
+        fCoincident = false;
+    }
+
     bool isCoincident() const {
         return fCoincident;
     }
@@ -54,41 +64,73 @@
 template<typename TCurve>
 class SkTSpan {
 public:
-    void init(const TCurve& );
-    void initBounds(const TCurve& );
-
+    void addBounded(SkTSpan* );
     double closestBoundedT(const SkDPoint& pt) const;
+    bool contains(double t) const;
 
-    bool contains(double t) const {
-        return !! const_cast<SkTSpan*>(this)->innerFind(t);
-    }
-
-    bool contains(const SkTSpan* span) const;
+    const SkTSect<TCurve>* debugOpp() const;
+    const SkTSpan* debugSpan(int ) const;
+    const SkTSpan* debugT(double t) const;
+#ifdef SK_DEBUG
+    bool debugIsBefore(const SkTSpan* span) const;
+#endif
+    void dump() const;
+    void dumpBounds(int id) const;
 
     double endT() const {
         return fEndT;
     }
 
-    SkTSpan* find(double t) {
-        SkTSpan* result = innerFind(t);
+    SkTSpan* findOppSpan(const SkTSpan* opp) const;
+
+    SkTSpan* findOppT(double t) const {
+        SkTSpan* result = oppT(t);
         SkASSERT(result);
         return result;
     }
 
-    bool intersects(const SkTSpan* span, bool* check);
+    bool hasOppT(double t) const {
+        return SkToBool(oppT(t));
+    }
+
+    int hullsIntersect(SkTSpan* span, bool* start, bool* oppStart);
+    void init(const TCurve& );
+    void initBounds(const TCurve& );
+
+    bool isBounded() const {
+        return fBounded.count() > 0;
+    }
+
+    bool linearsIntersect(SkTSpan* span);
+    double linearT(const SkDPoint& ) const;
+
+    void markCoincident() {
+        fCoinStart.markCoincident();
+        fCoinEnd.markCoincident();
+    }
 
     const SkTSpan* next() const {
         return fNext;
     }
 
+    bool onlyEndPointsInCommon(const SkTSpan* opp, bool* start, bool* oppStart, bool* ptsInCommon);
+
     const TCurve& part() const {
         return fPart;
     }
 
+    bool removeAllBounded();
+    bool removeBounded(const SkTSpan* opp);
+
     void reset() {
         fBounded.reset();
     }
 
+    void resetBounds(const TCurve& curve) {
+        fIsLinear = fIsLine = false;
+        initBounds(curve);
+    }
+
     bool split(SkTSpan* work) {
         return splitAt(work, (work->fStartT + work->fEndT) * 0.5);
     }
@@ -99,29 +141,23 @@
         return fStartT;
     }
 
-    bool tightBoundsIntersects(const SkTSpan* span) const;
+private:
 
     // implementation is for testing only
-    void dump() const {
-        dump(NULL);
+    int debugID() const {
+        return PATH_OPS_DEBUG_T_SECT_RELEASE(fID, -1);
     }
 
-private:
-    SkTSpan* innerFind(double t);
-    bool linearIntersects(const TCurve& ) const;
+    void dumpID() const;
 
-    // implementation is for testing only
-#if DEBUG_T_SECT
-    int debugID(const SkTSect<TCurve>* ) const { return fDebugID; }
-#else
-    int debugID(const SkTSect<TCurve>* ) const;
-#endif
-    void dump(const SkTSect<TCurve>* ) const;
-    void dumpID(const SkTSect<TCurve>* ) const;
+    int hullCheck(const SkTSpan* opp, bool* start, bool* oppStart);
+    int linearIntersects(const TCurve& ) const;
+    SkTSpan* oppT(double t) const;
 
-#if DEBUG_T_SECT
     void validate() const;
-#endif
+    void validateBounded() const;
+    void validatePerpT(double oppT) const;
+    void validatePerpPt(double t, const SkDPoint& ) const;
 
     TCurve fPart;
     SkTCoincident<TCurve> fCoinStart;
@@ -136,23 +172,33 @@
     bool fCollapsed;
     bool fHasPerp;
     bool fIsLinear;
-#if DEBUG_T_SECT
-    int fDebugID;
-    bool fDebugDeleted;
-#endif
+    bool fIsLine;
+    bool fDeleted;
+    PATH_OPS_DEBUG_CODE(SkTSect<TCurve>* fDebugSect);
+    PATH_OPS_DEBUG_T_SECT_CODE(int fID);
     friend class SkTSect<TCurve>;
 };
 
 template<typename TCurve>
 class SkTSect {
 public:
-    SkTSect(const TCurve& c  PATH_OPS_DEBUG_PARAMS(int id));
+    SkTSect(const TCurve& c  PATH_OPS_DEBUG_T_SECT_PARAMS(int id));
     static void BinarySearch(SkTSect* sect1, SkTSect* sect2, SkIntersections* intersections);
 
     // for testing only
+    bool debugHasBounded(const SkTSpan<TCurve>* ) const;
+
+    const SkTSect* debugOpp() const {
+        return PATH_OPS_DEBUG_RELEASE(fOppSect, NULL);
+    }
+
+    const SkTSpan<TCurve>* debugSpan(int id) const;
+    const SkTSpan<TCurve>* debugT(double t) const;
     void dump() const;
-    void dumpBoth(const SkTSect& opp) const;
-    void dumpBoth(const SkTSect* opp) const;
+    void dumpBoth(SkTSect* ) const;
+    void dumpBounds(int id) const;
+    void dumpCoin() const;
+    void dumpCoinCurves() const;
     void dumpCurves() const;
 
 private:
@@ -163,36 +209,72 @@
         kOneS2Set = 8
     };
 
+    SkTSpan<TCurve>* addFollowing(SkTSpan<TCurve>* prior);
+    void addForPerp(SkTSpan<TCurve>* span, double t);
     SkTSpan<TCurve>* addOne();
-    bool binarySearchCoin(const SkTSect& , double tStart, double tStep, double* t, double* oppT);
+    
+    SkTSpan<TCurve>* addSplitAt(SkTSpan<TCurve>* span, double t) {
+        SkTSpan<TCurve>* result = this->addOne();
+        result->splitAt(span, t);
+        result->initBounds(fCurve);
+        span->initBounds(fCurve);
+        return result;
+    }
+
+    bool binarySearchCoin(SkTSect* , double tStart, double tStep, double* t, double* oppT);
     SkTSpan<TCurve>* boundsMax() const;
     void coincidentCheck(SkTSect* sect2);
-    static int EndsEqual(const SkTSect* sect1, const SkTSect* sect2, SkIntersections* );
-    bool intersects(SkTSpan<TCurve>* span, const SkTSect* opp,
-            const SkTSpan<TCurve>* oppSpan) const;
-    void onCurveCheck(SkTSect* sect2, SkTSpan<TCurve>* first, SkTSpan<TCurve>* last);
-    void recoverCollapsed();
-    void removeSpan(SkTSpan<TCurve>* span);
-    void removeOne(const SkTSpan<TCurve>* test, SkTSpan<TCurve>* span);
-    void removeSpans(SkTSpan<TCurve>* span, SkTSect* opp);
-    void setPerp(const TCurve& opp, SkTSpan<TCurve>* first, SkTSpan<TCurve>* last);
-    const SkTSpan<TCurve>* tail() const;
-    void trim(SkTSpan<TCurve>* span, SkTSect* opp);
+    bool coincidentHasT(double t);
+    void computePerpendiculars(SkTSect* sect2, SkTSpan<TCurve>* first, SkTSpan<TCurve>* last);
+    int countConsecutiveSpans(SkTSpan<TCurve>* first, SkTSpan<TCurve>** last) const;
 
-#if DEBUG_T_SECT
-    int debugID() const { return fDebugID; }
+    int debugID() const {
+        return PATH_OPS_DEBUG_T_SECT_RELEASE(fID, -1);
+    }
+
+    void deleteEmptySpans();
+    void dumpCommon(const SkTSpan<TCurve>* ) const;
+    void dumpCommonCurves(const SkTSpan<TCurve>* ) const;
+    static int EndsEqual(const SkTSect* sect1, const SkTSect* sect2, SkIntersections* );
+    SkTSpan<TCurve>* extractCoincident(SkTSect* sect2, SkTSpan<TCurve>* first,
+                                       SkTSpan<TCurve>* last);
+    SkTSpan<TCurve>* findCoincidentRun(SkTSpan<TCurve>* first, SkTSpan<TCurve>** lastPtr,
+                                       const SkTSect* sect2);
+    int intersects(SkTSpan<TCurve>* span, const SkTSect* opp,
+                   SkTSpan<TCurve>* oppSpan, int* oppResult) const;
+    int linesIntersect(const SkTSpan<TCurve>* span, const SkTSect* opp,
+                       const SkTSpan<TCurve>* oppSpan, SkIntersections* ) const;
+    void markSpanGone(SkTSpan<TCurve>* span);
+    bool matchedDirection(double t, const SkTSect* sect2, double t2) const;
+    void matchedDirCheck(double t, const SkTSect* sect2, double t2,
+                         bool* calcMatched, bool* oppMatched) const;
+    void mergeCoincidence(SkTSect* sect2);
+    SkTSpan<TCurve>* prev(SkTSpan<TCurve>* ) const;
+    void removeByPerpendicular(SkTSect* opp);
+    void recoverCollapsed();
+    void removeCoincident(SkTSpan<TCurve>* span, bool isBetween);
+    void removeAllBut(const SkTSpan<TCurve>* keep, SkTSpan<TCurve>* span, SkTSect* opp);
+    void removeSpan(SkTSpan<TCurve>* span);
+    void removeSpanRange(SkTSpan<TCurve>* first, SkTSpan<TCurve>* last);
+    void removeSpans(SkTSpan<TCurve>* span, SkTSect* opp);
+    SkTSpan<TCurve>* spanAtT(double t, SkTSpan<TCurve>** priorSpan);
+    SkTSpan<TCurve>* tail();
+    void trim(SkTSpan<TCurve>* span, SkTSect* opp);
+    void unlinkSpan(SkTSpan<TCurve>* span);
+    bool updateBounded(SkTSpan<TCurve>* first, SkTSpan<TCurve>* last, SkTSpan<TCurve>* oppFirst);
     void validate() const;
-#else
-    int debugID() const { return 0; }
-#endif
+    void validateBounded() const;
+
     const TCurve& fCurve;
     SkChunkAlloc fHeap;
     SkTSpan<TCurve>* fHead;
+    SkTSpan<TCurve>* fCoincident;
     SkTSpan<TCurve>* fDeleted;
     int fActiveCount;
+    PATH_OPS_DEBUG_CODE(SkTSect* fOppSect);
+    PATH_OPS_DEBUG_T_SECT_CODE(int fID);
+    PATH_OPS_DEBUG_T_SECT_CODE(int fDebugCount);
 #if DEBUG_T_SECT
-    int fDebugID;
-    int fDebugCount;
     int fDebugAllocatedCount;
 #endif
     friend class SkTSpan<TCurve>;  // only used by debug id
@@ -208,8 +290,8 @@
     SkIntersections i;
     int used = i.intersectRay(c2, perp);
     // only keep closest
-    if (used == 0) {
-        fPerpT = -1;
+    if (used == 0 || used == 3) {
+        this->clear();
         return;
     } 
     fPerpT = i[0][0];
@@ -223,6 +305,10 @@
             fPerpPt = i.pt(1);
         }
     }
+#if DEBUG_T_SECT
+    SkDebugf("%s cPt=(%1.9g,%1.9g) %s fPerpPt=(%1.9g,%1.9g)\n", __FUNCTION__, cPt.fX, cPt.fY,
+            cPt.approximatelyEqual(fPerpPt) ? "==" : "!=", fPerpPt.fX, fPerpPt.fY);
+#endif
     fCoincident = cPt.approximatelyEqual(fPerpPt);
 #if DEBUG_T_SECT
     if (fCoincident) {
@@ -232,29 +318,55 @@
 }
 
 template<typename TCurve>
-void SkTSpan<TCurve>::init(const TCurve& c) {
-    fPrev = fNext = NULL;
-    fIsLinear = false;
-    fStartT = 0;
-    fEndT = 1;
-    initBounds(c);
+void SkTSpan<TCurve>::addBounded(SkTSpan* span) {
+    if (this->findOppSpan(span)) {
+        return;
+    }
+    fBounded.push_back() = span;
 }
 
 template<typename TCurve>
-void SkTSpan<TCurve>::initBounds(const TCurve& c) {
-    fPart = c.subDivide(fStartT, fEndT);
-    fBounds.setBounds(fPart);
-    fCoinStart.init();
-    fCoinEnd.init();
-    fBoundsMax = SkTMax(fBounds.width(), fBounds.height());
-    fCollapsed = fPart.collapsed();
-    fHasPerp = false;
-#if DEBUG_T_SECT
-    fDebugDeleted = false;
-    if (fCollapsed) {
-        SkDebugf("");  // for convenient breakpoints
+SkTSpan<TCurve>* SkTSect<TCurve>::addFollowing(SkTSpan<TCurve>* prior) {
+    SkTSpan<TCurve>* result = this->addOne();
+    result->fStartT = prior ? prior->fEndT : 0;
+    SkTSpan<TCurve>* next = prior ? prior->fNext : fHead;
+    result->fEndT = next ? next->fStartT : 1;
+    result->fPrev = prior;
+    result->fNext = next;
+    if (prior) {
+        prior->fNext = result;
+    } else {
+        fHead = result;
     }
+    if (next) {
+        next->fPrev = result;
+    }
+    result->resetBounds(fCurve);
+    return result;
+}
+
+template<typename TCurve>
+void SkTSect<TCurve>::addForPerp(SkTSpan<TCurve>* span, double t) {
+    if (!span->hasOppT(t)) {
+        SkTSpan<TCurve>* priorSpan;
+        SkTSpan<TCurve>* opp = this->spanAtT(t, &priorSpan);
+        if (!opp) {
+            opp = this->addFollowing(priorSpan);
+#if DEBUG_PERP
+            SkDebugf("%s priorSpan=%d t=%1.9g opp=%d\n", __FUNCTION__, priorSpan->debugID(), t,
+                    opp->debugID());
 #endif
+        }
+#if DEBUG_PERP
+        opp->dump(); SkDebugf("\n");
+        SkDebugf("%s fBounded.push_back span=%d opp=%d\n", __FUNCTION__, priorSpan->debugID(),
+                opp->debugID());
+#endif
+        opp->fBounded.push_back(span);
+        span->fBounded.push_back(opp);
+    }
+    this->validate();
+    span->validatePerpT(t);
 }
 
 template<typename TCurve>
@@ -279,55 +391,143 @@
     return result;
 }
 
+#ifdef SK_DEBUG
 template<typename TCurve>
-bool SkTSpan<TCurve>::contains(const SkTSpan* span) const {
-    int count = fBounded.count();
-    for (int index = 0; index < count; ++index) {
-        const SkTSpan* test = fBounded[index];
-        if (span == test) {
+bool SkTSpan<TCurve>::debugIsBefore(const SkTSpan* span) const {
+    const SkTSpan* work = this;
+    do {
+        if (span == work) {
             return true;
         }
-    }
+    } while ((work = work->fNext));
+    return false;
+}
+#endif
+
+template<typename TCurve>
+bool SkTSpan<TCurve>::contains(double t) const {
+    const SkTSpan* work = this;
+    do {
+        if (between(work->fStartT, t, work->fEndT)) {
+            return true;
+        }
+    } while ((work = work->fNext));
     return false;
 }
 
 template<typename TCurve>
-SkTSpan<TCurve>* SkTSpan<TCurve>::innerFind(double t) {
-    SkTSpan* work = this;
-    do {
-        if (between(work->fStartT, t, work->fEndT)) {
-            return work;
+const SkTSect<TCurve>* SkTSpan<TCurve>::debugOpp() const {
+    return PATH_OPS_DEBUG_RELEASE(fDebugSect->debugOpp(), NULL);
+}
+
+template<typename TCurve>
+SkTSpan<TCurve>* SkTSpan<TCurve>::findOppSpan(const SkTSpan* opp) const {
+    int count = fBounded.count();
+    for (int index = 0; index < count; ++index) {
+        SkTSpan* test = fBounded[index];
+        if (opp == test) {
+            return test;
         }
-    } while ((work = work->fNext));
+    }
     return NULL;
 }
 
+// returns 0 if no hull intersection
+//         1 if hulls intersect
+//         2 if hulls only share a common endpoint
+//        -1 if linear and further checking is required
+template<typename TCurve>
+int SkTSpan<TCurve>::hullCheck(const SkTSpan* opp, bool* start, bool* oppStart) {
+    if (fIsLinear) {
+        return -1;
+    }
+    bool ptsInCommon;
+    if (onlyEndPointsInCommon(opp, start, oppStart, &ptsInCommon)) {
+        SkASSERT(ptsInCommon);
+        return 2;
+    }
+    bool linear;
+    if (fPart.hullIntersects(opp->fPart, &linear)) {
+        if (!linear) {  // check set true if linear
+            return 1;
+        }
+        fIsLinear = true;
+        fIsLine = fPart.controlsInside();
+        return ptsInCommon ? 2 : -1;
+    } else {  // hull is not linear; check set true if intersected at the end points
+        return ((int) ptsInCommon) << 1;  // 0 or 2
+    }
+    return 0;
+}
+
 // OPTIMIZE ? If at_most_end_pts_in_common detects that one quad is near linear,
 // use line intersection to guess a better split than 0.5
 // OPTIMIZE Once at_most_end_pts_in_common detects linear, mark span so all future splits are linear
 template<typename TCurve>
-bool SkTSpan<TCurve>::intersects(const SkTSpan* span, bool* check) {
-    if (!fBounds.intersects(span->fBounds)) {
-        *check = false;  // no need to check to see if the bounds have end points in common
-        return false;
+int SkTSpan<TCurve>::hullsIntersect(SkTSpan* opp, bool* start, bool* oppStart) {
+    if (!fBounds.intersects(opp->fBounds)) {
+        return 0;
     }
-    if (!fIsLinear && fPart.hullIntersects(span->fPart, check)) {
-        if (!*check) {
-            return true;
-        }
-        fIsLinear = true;
+    int hullSect = this->hullCheck(opp, start, oppStart);
+    if (hullSect >= 0) {
+        return hullSect;
     }
-    if (fIsLinear) {
-        *check = false;
-        return linearIntersects(span->fPart);
+    hullSect = opp->hullCheck(this, oppStart, start);
+    if (hullSect >= 0) {
+        return hullSect;
     }
-    return *check; 
+    return -1;
 }
 
 template<typename TCurve>
-bool SkTSpan<TCurve>::linearIntersects(const TCurve& q2) const {
+void SkTSpan<TCurve>::init(const TCurve& c) {
+    fPrev = fNext = NULL;
+    fStartT = 0;
+    fEndT = 1;
+    resetBounds(c);
+}
+
+template<typename TCurve>
+void SkTSpan<TCurve>::initBounds(const TCurve& c) {
+    fPart = c.subDivide(fStartT, fEndT);
+    fBounds.setBounds(fPart);
+    fCoinStart.init();
+    fCoinEnd.init();
+    fBoundsMax = SkTMax(fBounds.width(), fBounds.height());
+    fCollapsed = fPart.collapsed();
+    fHasPerp = false;
+    fDeleted = false;
+#if DEBUG_T_SECT
+    if (fCollapsed) {
+        SkDebugf("");  // for convenient breakpoints
+    }
+#endif
+}
+
+template<typename TCurve>
+bool SkTSpan<TCurve>::linearsIntersect(SkTSpan* span) {
+    int result = this->linearIntersects(span->fPart);
+    if (result <= 1) {
+        return SkToBool(result);
+    }
+    SkASSERT(span->fIsLinear);
+    result = span->linearIntersects(this->fPart);
+//    SkASSERT(result <= 1);
+    return SkToBool(result);
+}
+
+template<typename TCurve>
+double SkTSpan<TCurve>::linearT(const SkDPoint& pt) const {
+    SkDVector len = fPart[TCurve::kPointLast] - fPart[0];
+    return fabs(len.fX) > fabs(len.fY)
+            ? (pt.fX - fPart[0].fX) / len.fX
+            : (pt.fY - fPart[0].fY) / len.fY;
+}
+
+template<typename TCurve>
+int SkTSpan<TCurve>::linearIntersects(const TCurve& q2) const {
     // looks like q1 is near-linear
-    int start = 0, end = TCurve::kPointCount - 1;  // the outside points are usually the extremes
+    int start = 0, end = TCurve::kPointLast;  // the outside points are usually the extremes
     if (!fPart.controlsInside()) {
         double dist = 0;  // if there's any question, compute distance to find best outsiders
         for (int outer = 0; outer < TCurve::kPointCount - 1; ++outer) {
@@ -347,20 +547,116 @@
     double origY = fPart[start].fY;
     double adj = fPart[end].fX - origX;
     double opp = fPart[end].fY - origY;
-    double sign;
+    double maxPart = SkTMax(fabs(adj), fabs(opp));
+    double sign = 0;  // initialization to shut up warning in release build
     for (int n = 0; n < TCurve::kPointCount; ++n) {
+        double dx = q2[n].fY - origY;
+        double dy = q2[n].fX - origX;
+        double maxVal = SkTMax(maxPart, SkTMax(fabs(dx), fabs(dy)));
         double test = (q2[n].fY - origY) * adj - (q2[n].fX - origX) * opp;
-        if (precisely_zero(test)) {
-            return true;
+        if (precisely_zero_when_compared_to(test, maxVal)) {
+            return 1;
+        }
+        if (approximately_zero_when_compared_to(test, maxVal)) {
+            return 3;
         }
         if (n == 0) {
             sign = test;
             continue;
         }
         if (test * sign < 0) {
-            return true;
+            return 1;
         }
     }
+    return 0;
+}
+
+template<typename TCurve>
+bool SkTSpan<TCurve>::onlyEndPointsInCommon(const SkTSpan* opp, bool* start, bool* oppStart,
+        bool* ptsInCommon) {
+    if (opp->fPart[0] == fPart[0]) {
+        *start = *oppStart = true;
+    } else if (opp->fPart[0] == fPart[TCurve::kPointLast]) {
+        *start = false;
+        *oppStart = true;
+    } else if (opp->fPart[TCurve::kPointLast] == fPart[0]) {
+        *start = true;
+        *oppStart = false;
+    } else if (opp->fPart[TCurve::kPointLast] == fPart[TCurve::kPointLast]) {
+        *start = *oppStart = false;
+    } else {
+        *ptsInCommon = false;
+        return false;
+    }
+    *ptsInCommon = true;
+    const SkDPoint* o1Pts[TCurve::kPointCount - 1], * o2Pts[TCurve::kPointCount - 1];
+    int baseIndex = *start ? 0 : TCurve::kPointLast;
+    fPart.otherPts(baseIndex, o1Pts);
+    opp->fPart.otherPts(*oppStart ? 0 : TCurve::kPointLast, o2Pts);
+    const SkDPoint& base = fPart[baseIndex];
+    for (int o1 = 0; o1 < (int) SK_ARRAY_COUNT(o1Pts); ++o1) {
+        SkDVector v1 = *o1Pts[o1] - base;
+        for (int o2 = 0; o2 < (int) SK_ARRAY_COUNT(o2Pts); ++o2) {
+            SkDVector v2 = *o2Pts[o2] - base;
+            if (v2.dot(v1) >= 0) {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+template<typename TCurve>
+SkTSpan<TCurve>* SkTSpan<TCurve>::oppT(double t) const {
+    int count = fBounded.count();
+    for (int index = 0; index < count; ++index) {
+        SkTSpan* test = fBounded[index];
+        if (between(test->fStartT, t, test->fEndT)) {
+            return test;
+        }
+    }
+    return NULL;
+}
+
+template<typename TCurve>
+bool SkTSpan<TCurve>::removeAllBounded() {
+    bool deleteSpan = false;
+    int count = fBounded.count();
+    for (int index = 0; index < count; ++index) {
+        SkTSpan* opp = fBounded[index];
+        deleteSpan |= opp->removeBounded(this);
+    }
+    return deleteSpan;
+}
+
+template<typename TCurve>
+bool SkTSpan<TCurve>::removeBounded(const SkTSpan* opp) {
+    int count = fBounded.count();
+    if (fHasPerp) {
+        bool foundStart = false;
+        bool foundEnd = false;
+        for (int index = 0; index < count; ++index) {
+            const SkTSpan* test = fBounded[index];
+            if (opp == test) {
+                continue;
+            }
+            foundStart |= between(test->fStartT, fCoinStart.perpT(), test->fEndT);
+            foundEnd |= between(test->fStartT, fCoinEnd.perpT(), test->fEndT);
+        }
+        if (!foundStart || !foundEnd) {
+            fHasPerp = false;
+            fCoinStart.init();
+            fCoinEnd.init();
+        }
+    }
+    for (int index = 0; index < count; ++index) {
+        if (opp == fBounded[index]) {
+            fBounded.removeShuffle(index);
+            SkASSERT((count == 1) == (fBounded.count() == 0));
+            return count == 1;
+        }
+    }
+    SkASSERT(0);
     return false;
 }
 
@@ -380,6 +676,8 @@
     fPrev = work;
     fNext = work->fNext;
     fIsLinear = work->fIsLinear;
+    fIsLine = work->fIsLine;
+
     work->fNext = this;
     if (fNext) {
         fNext->fPrev = this;
@@ -393,102 +691,74 @@
 }
 
 template<typename TCurve>
-bool SkTSpan<TCurve>::tightBoundsIntersects(const SkTSpan* span) const {
-    // skew all to an axis
-    SkDVector v2_0 = fPart[TCurve::kPointLast] - fPart[0];
-    bool skewToXAxis = fabs(v2_0.fX) > fabs(v2_0.fY);
-    double ratio = skewToXAxis ? v2_0.fY / v2_0.fX : v2_0.fX / v2_0.fY;
-    TCurve r1 = fPart;
-    if (skewToXAxis) {
-        r1[1].fY -= (fPart[1].fX - r1[0].fX) * ratio;
-        if (TCurve::IsCubic()) {
-            r1[2].fY -= (fPart[2].fX - r1[0].fX) * ratio;
-            r1[3].fY = r1[0].fY;
-        } else {
-            r1[2].fY = r1[0].fY;
-        }
-    } else {
-        r1[1].fX -= (fPart[1].fY - r1[0].fY) * ratio;
-        if (TCurve::IsCubic()) {
-            r1[2].fX -= (fPart[2].fY - r1[0].fY) * ratio;
-            r1[3].fX = r1[0].fX;
-        } else {
-            r1[2].fX = r1[0].fX;
-        }
-    }
-    // compute the tight skewed bounds
-    SkDRect bounds;
-    bounds.setBounds(r1);
-    // see if opposite ends are within range of tight skewed bounds
-    TCurve r2 = span->fPart;
-    for (int i = 0; i < TCurve::kPointCount; i += 2) {
-        if (skewToXAxis) {
-            r2[i].fY -= (r2[i].fX - r1[0].fX) * ratio;
-            if (between(bounds.fTop, r2[i].fY, bounds.fBottom)) {
-                return true;
-            }
-        } else {
-            r2[i].fX -= (r2[i].fY - r1[0].fY) * ratio;
-            if (between(bounds.fLeft, r2[i].fX, bounds.fRight)) {
-                return true;
-            }
-        }
-    }
-    // see if opposite ends are on either side of tight skewed bounds
-    if ((skewToXAxis ? (r2[0].fY - r1[0].fY) * (r2[TCurve::kPointLast].fY - r1[0].fY)
-                        : (r2[0].fX - r1[0].fX) * (r2[TCurve::kPointLast].fX - r1[0].fX)) < 0) {
-        return true;
-    }
-    // compute opposite tight skewed bounds
-    if (skewToXAxis) {
-        r2[1].fY -= (r2[1].fX - r1[0].fX) * ratio;
-        if (TCurve::IsCubic()) {
-            r2[2].fY -= (r2[2].fX - r1[0].fX) * ratio;
-        }
-    } else {
-        r2[1].fX -= (r2[1].fY - r1[0].fY) * ratio;
-        if (TCurve::IsCubic()) {
-            r2[2].fX -= (r2[2].fY - r1[0].fY) * ratio;
-        }
-    }
-    SkDRect sBounds;
-    sBounds.setBounds(r2);
-    // see if tight bounds overlap
-    if (skewToXAxis) {
-        return bounds.fTop <= sBounds.fBottom && sBounds.fTop <= bounds.fBottom;  
-    } else {
-        return bounds.fLeft <= sBounds.fRight && sBounds.fLeft <= bounds.fRight;  
-    }
-}
-
-#if DEBUG_T_SECT
-template<typename TCurve>
 void SkTSpan<TCurve>::validate() const {
+#if DEBUG_T_SECT
     SkASSERT(fNext == NULL || fNext != fPrev);
     SkASSERT(fNext == NULL || this == fNext->fPrev);
-    SkASSERT(fBounds.width() || fBounds.height());
+    SkASSERT(fPrev == NULL || this == fPrev->fNext);
+    SkASSERT(fBounds.width() || fBounds.height() || fCollapsed);
     SkASSERT(fBoundsMax == SkTMax(fBounds.width(), fBounds.height()));
     SkASSERT(0 <= fStartT);
     SkASSERT(fEndT <= 1);
-    SkASSERT(fStartT < fEndT);
+    SkASSERT(fStartT <= fEndT);
     SkASSERT(fBounded.count() > 0);
-    for (int index = 0; index < fBounded.count(); ++index) {
-        const SkTSpan* overlap = fBounded[index];
-        SkASSERT(((fDebugID ^ overlap->fDebugID) & 1) == 1);
-        SkASSERT(overlap->contains(this));
+    this->validateBounded();
+    if (fHasPerp) {
+        if (fCoinStart.isCoincident()) {
+            validatePerpT(fCoinStart.perpT());
+            validatePerpPt(fCoinStart.perpT(), fCoinStart.perpPt());
+        }
+        if (fCoinEnd.isCoincident()) {
+            validatePerpT(fCoinEnd.perpT());
+            validatePerpPt(fCoinEnd.perpT(), fCoinEnd.perpPt());
+        }
     }
-}
 #endif
+}
 
 template<typename TCurve>
-SkTSect<TCurve>::SkTSect(const TCurve& c PATH_OPS_DEBUG_PARAMS(int id))
+void SkTSpan<TCurve>::validateBounded() const {
+#if DEBUG_VALIDATE
+    for (int index = 0; index < fBounded.count(); ++index) {
+        const SkTSpan* overlap = fBounded[index];
+        SkASSERT(!overlap->fDeleted);
+        SkASSERT(((this->debugID() ^ overlap->debugID()) & 1) == 1);
+        SkASSERT(overlap->findOppSpan(this));
+    }
+#endif
+}
+
+template<typename TCurve>
+void SkTSpan<TCurve>::validatePerpT(double oppT) const {
+#if DEBUG_VALIDATE
+    for (int index = 0; index < fBounded.count(); ++index) {
+        const SkTSpan* overlap = fBounded[index];
+        if (between(overlap->fStartT, oppT, overlap->fEndT)) {
+            return;
+        }
+    }
+    SkASSERT(0);
+#endif
+}
+
+template<typename TCurve>
+void SkTSpan<TCurve>::validatePerpPt(double t, const SkDPoint& pt) const {
+#if DEBUG_T_SECT
+    PATH_OPS_DEBUG_CODE(SkASSERT(fDebugSect->fOppSect->fCurve.ptAtT(t) == pt));
+#endif
+}
+
+
+template<typename TCurve>
+SkTSect<TCurve>::SkTSect(const TCurve& c PATH_OPS_DEBUG_T_SECT_PARAMS(int id))
     : fCurve(c)
     , fHeap(sizeof(SkTSpan<TCurve>) * 4)
+    , fCoincident(NULL)
     , fDeleted(NULL)
     , fActiveCount(0)
-    PATH_OPS_DEBUG_PARAMS(fDebugID(id))
-    PATH_OPS_DEBUG_PARAMS(fDebugCount(0))
-    PATH_OPS_DEBUG_PARAMS(fDebugAllocatedCount(0))
+    PATH_OPS_DEBUG_T_SECT_PARAMS(fID(id))
+    PATH_OPS_DEBUG_T_SECT_PARAMS(fDebugCount(0))
+    PATH_OPS_DEBUG_T_SECT_PARAMS(fDebugAllocatedCount(0))
 {
     fHead = addOne();
     fHead->init(c);
@@ -508,22 +778,22 @@
 #endif
     }
     ++fActiveCount; 
-#if DEBUG_T_SECT
-    result->fDebugID = fDebugCount++ * 2 + fDebugID;
-#endif
+    PATH_OPS_DEBUG_T_SECT_CODE(result->fID = fDebugCount++ * 2 + fID);
+    PATH_OPS_DEBUG_CODE(result->fDebugSect = this);
     return result;
 }
 
 template<typename TCurve>
-bool SkTSect<TCurve>::binarySearchCoin(const SkTSect& sect2, double tStart, double tStep,
+bool SkTSect<TCurve>::binarySearchCoin(SkTSect* sect2, double tStart, double tStep,
         double* resultT, double* oppT) {
     SkTSpan<TCurve> work;
     double result = work.fStartT = work.fEndT = tStart;
+    PATH_OPS_DEBUG_CODE(work.fDebugSect = this);
     SkDPoint last = fCurve.ptAtT(tStart);
     SkDPoint oppPt;
     bool flip = false;
     SkDEBUGCODE(bool down = tStep < 0);
-    const TCurve& opp = sect2.fCurve;
+    const TCurve& opp = sect2->fCurve;
     do {
         tStep *= 0.5;
         work.fStartT += tStep;
@@ -541,8 +811,11 @@
         last = work.fPart[0];
         work.fCoinStart.setPerp(fCurve, work.fStartT, last, opp);
         if (work.fCoinStart.isCoincident()) {
+#if DEBUG_T_SECT
+            work.validatePerpPt(work.fCoinStart.perpT(), work.fCoinStart.perpPt());
+#endif
             double oppTTest = work.fCoinStart.perpT();
-            if (sect2.fHead->contains(oppTTest)) {
+            if (sect2->fHead->contains(oppTTest)) {
                 *oppT = oppTTest;
                 oppPt = work.fCoinStart.perpPt();
                 SkASSERT(down ? result > work.fStartT : result < work.fStartT);
@@ -574,194 +847,472 @@
 SkTSpan<TCurve>* SkTSect<TCurve>::boundsMax() const {
     SkTSpan<TCurve>* test = fHead;
     SkTSpan<TCurve>* largest = fHead;
-    bool largestCoin = largest->fCoinStart.isCoincident() && largest->fCoinEnd.isCoincident();
+    bool lCollapsed = largest->fCollapsed;
     while ((test = test->fNext)) {
-        bool testCoin = test->fCoinStart.isCoincident() || test->fCoinEnd.isCoincident();
-        if ((largestCoin && !testCoin) || (largestCoin == testCoin
-                && (largest->fBoundsMax < test->fBoundsMax
-                || (largest->fCollapsed && !test->fCollapsed)))) {
+        bool tCollapsed = test->fCollapsed;
+        if ((lCollapsed && !tCollapsed) || (lCollapsed == tCollapsed &&
+                largest->fBoundsMax < test->fBoundsMax)) {
             largest = test;
-            largestCoin = testCoin;
         }
     }
-    return largestCoin ? NULL : largest;
+    return largest;
 }
 
 template<typename TCurve>
 void SkTSect<TCurve>::coincidentCheck(SkTSect* sect2) {
     SkTSpan<TCurve>* first = fHead;
-    SkTSpan<TCurve>* next;
+    SkTSpan<TCurve>* last, * next;
     do {
-        int consecutive = 1;
-        SkTSpan<TCurve>* last = first;
-        do {
-            next = last->fNext;
-            if (!next) {
-                break;
-            }
-            if (next->fStartT > last->fEndT) {
-                break;
-            }
-            ++consecutive;
-            last = next;
-        } while (true);
+        int consecutive = this->countConsecutiveSpans(first, &last);
+        next = last->fNext;
         if (consecutive < COINCIDENT_SPAN_COUNT) {
             continue;
         }
-        setPerp(sect2->fCurve, first, last);
+        this->validate();
+        sect2->validate();
+        this->computePerpendiculars(sect2, first, last);
+        this->validate();
+        sect2->validate();
         // check to see if a range of points are on the curve
-        onCurveCheck(sect2, first, last);
-        SkTSpan<TCurve>* removalCandidate = NULL;
-        if (!first->fCoinStart.isCoincident()) {
-            SkTSpan<TCurve>* firstCoin = first->fNext;
-            removalCandidate = first;
-            first = firstCoin;
-        }
-        if (!first->fCoinStart.isCoincident()) {
-            continue;
-        }
-        if (removalCandidate) {
-            removeSpans(removalCandidate, sect2);
-        }
-        if (!last->fCoinStart.isCoincident()) {
-            continue;
-        }
-        if (!last->fCoinEnd.isCoincident()) {
-            if (--consecutive < COINCIDENT_SPAN_COUNT) {
-                continue;
-            }
-            last = last->fPrev;
-            SkASSERT(last->fCoinStart.isCoincident());
-            SkASSERT(last->fCoinEnd.isCoincident());
-        }
-        SkASSERT(between(0, first->fCoinStart.perpT(), 1) || first->fCoinStart.perpT() == -1);
-        if (first->fCoinStart.perpT() < 0) {
-            first->fCoinStart.setPerp(fCurve, first->fStartT, first->fPart[0], sect2->fCurve);
-        }
-        SkASSERT(between(0, last->fCoinEnd.perpT(), 1) || last->fCoinEnd.perpT() == -1);
-        if (last->fCoinEnd.perpT() < 0) {
-            last->fCoinEnd.setPerp(fCurve, last->fEndT, last->fPart[TCurve::kPointLast],
-                    sect2->fCurve);
-        }
-        SkTSpan<TCurve>* removeMe = first->fNext;
-        while (removeMe != last) {
-            SkTSpan<TCurve>* removeNext = removeMe->fNext;
-            removeSpans(removeMe, sect2);
-            removeMe = removeNext;
-        }
+        SkTSpan<TCurve>* coinStart = first;
+        do {
+            coinStart = this->extractCoincident(sect2, coinStart, last);
+        } while (coinStart && !last->fDeleted);
     } while ((first = next));
 }
 
 template<typename TCurve>
-bool SkTSect<TCurve>::intersects(SkTSpan<TCurve>* span, const SkTSect* opp,
-        const SkTSpan<TCurve>* oppSpan) const {
-    bool check;  // we ignore whether the end points are in common or not
-    if (!span->intersects(oppSpan, &check)) {
-        return false;
+bool SkTSect<TCurve>::coincidentHasT(double t) {
+    SkTSpan<TCurve>* test = fCoincident;
+    while (test) {
+        if (between(test->fStartT, t, test->fEndT)) {
+            return true;
+        }
+        test = test->fNext;
     }
-    if (fActiveCount < COINCIDENT_SPAN_COUNT || opp->fActiveCount < COINCIDENT_SPAN_COUNT) {
-        return true;
-    }
-    return span->tightBoundsIntersects(oppSpan);
+    return false;
 }
 
 template<typename TCurve>
-void SkTSect<TCurve>::onCurveCheck(SkTSect* sect2, SkTSpan<TCurve>* first, SkTSpan<TCurve>* last) {
-    SkTSpan<TCurve>* work = first;
-    first = NULL;
+void SkTSect<TCurve>::computePerpendiculars(SkTSect* sect2, SkTSpan<TCurve>* first,
+        SkTSpan<TCurve>* last) {
+    const TCurve& opp = sect2->fCurve;
+        SkTSpan<TCurve>* work = first;
+    SkTSpan<TCurve>* prior = NULL;
     do {
-        if (work->fCoinStart.isCoincident()) {
-            if (!first) {
-                first = work;
+        if (!work->fHasPerp && !work->fCollapsed) {
+            if (prior) {
+                work->fCoinStart = prior->fCoinEnd;
+            } else {
+                work->fCoinStart.setPerp(fCurve, work->fStartT, work->fPart[0], opp);
             }
-        } else if (first) {
-            break;
+            if (work->fCoinStart.isCoincident()) {
+                double perpT = work->fCoinStart.perpT();
+                if (sect2->coincidentHasT(perpT)) {
+                    work->fCoinStart.clear();
+                } else {
+                    sect2->addForPerp(work, perpT);
+                }
+            }
+            work->fCoinEnd.setPerp(fCurve, work->fEndT, work->fPart[TCurve::kPointLast], opp);
+            if (work->fCoinEnd.isCoincident()) {
+                double perpT = work->fCoinEnd.perpT();
+                if (sect2->coincidentHasT(perpT)) {
+                    work->fCoinEnd.clear();
+                } else {
+                    sect2->addForPerp(work, perpT);
+                }
+            }
+            work->fHasPerp = true;
         }
         if (work == last) {
             break;
         }
+        prior = work;
         work = work->fNext;
         SkASSERT(work);
     } while (true);
+}
+
+template<typename TCurve>
+int SkTSect<TCurve>::countConsecutiveSpans(SkTSpan<TCurve>* first,
+        SkTSpan<TCurve>** lastPtr) const {
+    int consecutive = 1;
+    SkTSpan<TCurve>* last = first;
+    do {
+        SkTSpan<TCurve>* next = last->fNext;
+        if (!next) {
+            break;
+        }
+        if (next->fStartT > last->fEndT) {
+            break;
+        }
+        ++consecutive;
+        last = next;
+    } while (true);
+    *lastPtr = last;
+    return consecutive;
+}
+
+template<typename TCurve>
+bool SkTSect<TCurve>::debugHasBounded(const SkTSpan<TCurve>* span) const {
+    const SkTSpan<TCurve>* test = fHead;
+    if (!test) {
+        return false;
+    }
+    do {
+        if (test->findOppSpan(span)) {
+            return true;
+        }
+    } while ((test = test->next()));
+    return false;
+}
+
+template<typename TCurve>
+void SkTSect<TCurve>::deleteEmptySpans() {
+    SkTSpan<TCurve>* test;
+    SkTSpan<TCurve>* next = fHead;
+    while ((test = next)) {
+        next = test->fNext;
+        if (test->fBounded.count() == 0) {
+            this->removeSpan(test);
+        }
+    }
+}
+
+template<typename TCurve>
+SkTSpan<TCurve>* SkTSect<TCurve>::extractCoincident(SkTSect* sect2, SkTSpan<TCurve>* first,
+        SkTSpan<TCurve>* last) {
+    first = findCoincidentRun(first, &last, sect2);
     if (!first) {
-        return;
+        return NULL;
     }
     // march outwards to find limit of coincidence from here to previous and next spans
     double startT = first->fStartT;
-    double oppT;
+    double oppStartT;
+    double oppEndT SK_INIT_TO_AVOID_WARNING;
     SkTSpan<TCurve>* prev = first->fPrev;
-    if (prev) {
-        double coinStart;
-        if (binarySearchCoin(*sect2, startT, prev->fStartT - startT, &coinStart, &oppT)) {
-            if (coinStart < startT) {
-                SkASSERT(prev->fStartT < coinStart && coinStart < prev->fEndT);
-                SkTSpan<TCurve>* oppStart = sect2->fHead->find(oppT);
-                if (oppStart->fStartT < oppT && oppT < oppStart->fEndT) {
-                    // split prev at coinStart if needed
-                    SkTSpan<TCurve>* half2 = addOne();
-                    half2->splitAt(prev, coinStart);
-                    half2->initBounds(fCurve);
-                    prev->initBounds(fCurve);
-                    prev->fCoinEnd.markCoincident();
-                    half2->fCoinStart.markCoincident();
-                    half2->fCoinEnd.markCoincident();
-                    // find span containing opposite t, and split that too
-                    SkTSpan<TCurve>* oppHalf = sect2->addOne();
-                    oppHalf->splitAt(oppStart, oppT);
-                    oppHalf->initBounds(sect2->fCurve);
-                    oppStart->initBounds(sect2->fCurve);
+    SkASSERT(first->fCoinStart.isCoincident());
+    SkTSpan<TCurve>* oppFirst = first->findOppT(first->fCoinStart.perpT());
+    SkASSERT(last->fCoinEnd.isCoincident());
+    bool oppMatched = first->fCoinStart.perpT() < first->fCoinEnd.perpT();
+    double coinStart;
+    SkDEBUGCODE(double coinEnd);
+    if (prev && prev->fEndT == startT
+            && this->binarySearchCoin(sect2, startT, prev->fStartT - startT, &coinStart,
+                                      &oppStartT)
+            && prev->fStartT < coinStart && coinStart < startT) {
+        oppFirst = prev->findOppT(oppStartT);  // find opp start before splitting prev
+        SkASSERT(oppFirst);
+        first = this->addSplitAt(prev, coinStart);
+        first->markCoincident();
+        prev->fCoinEnd.markCoincident();
+        if (oppFirst->fStartT < oppStartT && oppStartT < oppFirst->fEndT) {
+            SkTSpan<TCurve>* oppHalf = sect2->addSplitAt(oppFirst, oppStartT);
+            if (oppMatched) {
+                oppFirst->fCoinEnd.markCoincident();
+                oppHalf->markCoincident();
+                oppFirst = oppHalf;
+            } else {
+                oppFirst->markCoincident();
+                oppHalf->fCoinStart.markCoincident();
+            }
+        }
+    } else {
+        SkDEBUGCODE(coinStart = first->fStartT);
+        SkDEBUGCODE(oppStartT = oppMatched ? oppFirst->fStartT : oppFirst->fEndT);
+    }
+    SkTSpan<TCurve>* oppLast;
+    SkASSERT(last->fCoinEnd.isCoincident());
+    oppLast = last->findOppT(last->fCoinEnd.perpT());
+    SkDEBUGCODE(coinEnd = last->fEndT);
+    SkDEBUGCODE(oppEndT = oppMatched ? oppLast->fEndT : oppLast->fStartT);
+    if (!oppMatched) {
+        SkTSwap(oppFirst, oppLast);
+        SkTSwap(oppStartT, oppEndT);
+    }
+    SkASSERT(oppStartT < oppEndT);
+    SkASSERT(coinStart == first->fStartT);
+    SkASSERT(coinEnd == last->fEndT);
+    SkASSERT(oppStartT == oppFirst->fStartT);
+    SkASSERT(oppEndT == oppLast->fEndT);
+    // reduce coincident runs to single entries
+    this->validate();
+    sect2->validate();
+    bool deleteThisSpan = this->updateBounded(first, last, oppFirst);
+    bool deleteSect2Span = sect2->updateBounded(oppFirst, oppLast, first);
+    this->removeSpanRange(first, last);
+    sect2->removeSpanRange(oppFirst, oppLast);
+    first->fEndT = last->fEndT;
+    first->resetBounds(this->fCurve);
+    first->fCoinStart.setPerp(fCurve, first->fStartT, first->fPart[0], sect2->fCurve);
+    first->fCoinEnd.setPerp(fCurve, first->fEndT, first->fPart[TCurve::kPointLast], sect2->fCurve);
+    oppStartT = first->fCoinStart.perpT();
+    oppEndT = first->fCoinEnd.perpT();
+    if (between(0, oppStartT, 1) && between(0, oppEndT, 1)) {
+        if (!oppMatched) {
+            SkTSwap(oppStartT, oppEndT);
+        }
+        oppFirst->fStartT = oppStartT;
+        oppFirst->fEndT = oppEndT;
+        oppFirst->resetBounds(sect2->fCurve);
+    }
+    this->validateBounded();
+    sect2->validateBounded();
+    last = first->fNext;
+    this->removeCoincident(first, false);
+    sect2->removeCoincident(oppFirst, true);
+    if (deleteThisSpan) {
+        this->deleteEmptySpans();
+    }
+    if (deleteSect2Span) {
+        sect2->deleteEmptySpans();
+    }
+    this->validate();
+    sect2->validate();
+    return last && !last->fDeleted ? last : NULL;
+}
+
+template<typename TCurve>
+SkTSpan<TCurve>* SkTSect<TCurve>::findCoincidentRun(SkTSpan<TCurve>* first,
+        SkTSpan<TCurve>** lastPtr, const SkTSect* sect2) {
+    SkTSpan<TCurve>* work = first;
+    SkTSpan<TCurve>* lastCandidate = NULL;
+    first = NULL;
+    // find the first fully coincident span
+    do {
+        if (work->fCoinStart.isCoincident()) {
+            work->validatePerpT(work->fCoinStart.perpT());
+            work->validatePerpPt(work->fCoinStart.perpT(), work->fCoinStart.perpPt());
+            SkASSERT(work->hasOppT(work->fCoinStart.perpT()));
+            if (!work->fCoinEnd.isCoincident()) {
+                break;
+            }
+            lastCandidate = work;
+            if (!first) {
+                first = work;
+            }
+        } else {
+            lastCandidate = NULL;
+            SkASSERT(!first);
+        }
+        if (work == *lastPtr) {
+            return first;
+        }
+        work = work->fNext;
+        SkASSERT(work);
+    } while (true);
+    if (lastCandidate) {
+        *lastPtr = lastCandidate;
+    }
+    return first;
+}
+
+template<typename TCurve>
+int SkTSect<TCurve>::intersects(SkTSpan<TCurve>* span, const SkTSect* opp,
+        SkTSpan<TCurve>* oppSpan, int* oppResult) const {
+    bool spanStart, oppStart;
+    int hullResult = span->hullsIntersect(oppSpan, &spanStart, &oppStart);
+    if (hullResult >= 0) {
+        if (hullResult == 2) {  // hulls have one point in common
+            if (span->fBounded.count() <= 1) {
+                SkASSERT(span->fBounded.count() == 0 || span->fBounded[0] == oppSpan);
+                if (spanStart) {
+                    span->fEndT = span->fStartT;
                 } else {
-                    SkASSERT(oppStart->fStartT == oppT || oppT == oppStart->fEndT);
-                    first->fStartT = coinStart;
-                    prev->fEndT = coinStart;
-                    first->initBounds(fCurve);
-                    prev->initBounds(fCurve);
-                    first->fCoinStart.markCoincident();
-                    first->fCoinEnd.markCoincident();
+                    span->fStartT = span->fEndT;
+                }
+            } else {
+                hullResult = 1;
+            }
+            if (oppSpan->fBounded.count() <= 1) {
+                SkASSERT(span->fBounded.count() == 0 || oppSpan->fBounded[0] == span);
+                if (oppStart) {
+                    oppSpan->fEndT = oppSpan->fStartT;
+                } else {
+                    oppSpan->fStartT = oppSpan->fEndT;
+                }
+                *oppResult = 2;
+            } else {
+                *oppResult = 1;
+            }
+        } else {
+            *oppResult = 1;
+        }
+        return hullResult;
+    }
+    if (span->fIsLine && oppSpan->fIsLine) {
+        SkIntersections i;
+        int sects = this->linesIntersect(span, opp, oppSpan, &i);
+        if (!sects) {
+            return -1;
+        }
+        span->fStartT = span->fEndT = i[0][0];
+        oppSpan->fStartT = oppSpan->fEndT = i[1][0];
+        return *oppResult = 2;
+    }
+    if (span->fIsLinear || oppSpan->fIsLinear) {
+        return *oppResult = (int) span->linearsIntersect(oppSpan);
+    }
+    return *oppResult = 1;
+}
+
+// while the intersection points are sufficiently far apart:
+// construct the tangent lines from the intersections
+// find the point where the tangent line intersects the opposite curve
+template<typename TCurve>
+int SkTSect<TCurve>::linesIntersect(const SkTSpan<TCurve>* span, const SkTSect* opp,
+            const SkTSpan<TCurve>* oppSpan, SkIntersections* i) const {
+    SkIntersections thisRayI, oppRayI;
+    SkDLine thisLine = {{ span->fPart[0], span->fPart[TCurve::kPointLast] }};
+    SkDLine oppLine = {{ oppSpan->fPart[0], oppSpan->fPart[TCurve::kPointLast] }};
+    int loopCount = 0;
+    double bestDistSq = DBL_MAX;
+    do {
+        if (!thisRayI.intersectRay(opp->fCurve, thisLine)) {
+            return 0;
+        }
+        if (!oppRayI.intersectRay(this->fCurve, oppLine)) {
+            return 0;
+        }
+        // pick the closest pair of points
+        double closest = DBL_MAX;
+        int closeIndex SK_INIT_TO_AVOID_WARNING;
+        int oppCloseIndex SK_INIT_TO_AVOID_WARNING;
+        for (int index = 0; index < oppRayI.used(); ++index) {
+            if (!roughly_between(span->fStartT, oppRayI[0][index], span->fEndT)) {
+                continue;
+            }
+            for (int oIndex = 0; oIndex < thisRayI.used(); ++oIndex) {
+                if (!roughly_between(oppSpan->fStartT, thisRayI[0][oIndex], oppSpan->fEndT)) {
+                    continue;
+                }
+                double distSq = thisRayI.pt(index).distanceSquared(oppRayI.pt(oIndex));
+                if (closest > distSq) {
+                    closest = distSq;
+                    closeIndex = index;
+                    oppCloseIndex = oIndex;
                 }
             }
         }
-    }
-    if (!work->fCoinEnd.isCoincident()) {
-        if (work->fEndT == 1) {
-            SkDebugf("!");
+        if (closest == DBL_MAX) {
+            return 0;
         }
-//        SkASSERT(work->fEndT < 1);
-        startT = work->fStartT;
-        double coinEnd;
-        if (binarySearchCoin(*sect2, startT, work->fEndT - startT, &coinEnd, &oppT)) {
-            if (coinEnd > startT) {
-                SkTSpan<TCurve>* oppStart = sect2->fHead->find(oppT);
-                if (oppStart->fStartT < oppT && oppT < oppStart->fEndT) {
-                    SkASSERT(coinEnd < work->fEndT);
-                    // split prev at coinEnd if needed
-                    SkTSpan<TCurve>* half2 = addOne();
-                    half2->splitAt(work, coinEnd);
-                    half2->initBounds(fCurve);
-                    work->initBounds(fCurve);
-                    work->fCoinStart.markCoincident();
-                    work->fCoinEnd.markCoincident();
-                    half2->fCoinStart.markCoincident();
-                    SkTSpan<TCurve>* oppHalf = sect2->addOne();
-                    oppHalf->splitAt(oppStart, oppT);
-                    oppHalf->initBounds(sect2->fCurve);
-                    oppStart->initBounds(sect2->fCurve);
-                } else {
-                    SkASSERT(oppStart->fStartT == oppT || oppT == oppStart->fEndT);
-                    SkTSpan<TCurve>* next = work->fNext;
-                    bool hasNext = next && work->fEndT == next->fStartT;
-                    work->fEndT = coinEnd;
-                    work->initBounds(fCurve);
-                    work->fCoinStart.markCoincident();
-                    work->fCoinEnd.markCoincident();
-                    if (hasNext) { 
-                        next->fStartT = coinEnd;
-                        next->initBounds(fCurve);
-                    }
-                }
+        const SkDPoint& oppIPt = thisRayI.pt(oppCloseIndex);
+        const SkDPoint& iPt = oppRayI.pt(closeIndex);
+        if (between(span->fStartT, oppRayI[0][closeIndex], span->fEndT)
+                && between(oppSpan->fStartT, thisRayI[0][oppCloseIndex], oppSpan->fEndT)
+                && oppIPt.approximatelyEqual(iPt)) {
+            i->merge(oppRayI, closeIndex, thisRayI, oppCloseIndex);
+            return i->used();
+        }
+        double distSq = oppIPt.distanceSquared(iPt);
+        if (bestDistSq < distSq || ++loopCount > 5) {
+            break;
+        }
+        bestDistSq = distSq;
+        thisLine[0] = fCurve.ptAtT(oppRayI[0][closeIndex]);
+        thisLine[1] = thisLine[0] + fCurve.dxdyAtT(oppRayI[0][closeIndex]);
+        oppLine[0] = opp->fCurve.ptAtT(thisRayI[0][oppCloseIndex]);
+        oppLine[1] = oppLine[0] + opp->fCurve.dxdyAtT(thisRayI[0][oppCloseIndex]);
+    } while (true);
+    return false;
+}
+
+
+template<typename TCurve>
+void SkTSect<TCurve>::markSpanGone(SkTSpan<TCurve>* span) {
+    --fActiveCount;
+    span->fNext = fDeleted;
+    fDeleted = span;
+    SkASSERT(!span->fDeleted);
+    span->fDeleted = true;
+}
+
+template<typename TCurve>
+bool SkTSect<TCurve>::matchedDirection(double t, const SkTSect* sect2, double t2) const {
+    SkDVector dxdy = this->fCurve.dxdyAtT(t);
+    SkDVector dxdy2 = sect2->fCurve.dxdyAtT(t2);
+    return dxdy.dot(dxdy2) >= 0;
+}
+
+template<typename TCurve>
+void SkTSect<TCurve>::matchedDirCheck(double t, const SkTSect* sect2, double t2,
+        bool* calcMatched, bool* oppMatched) const {
+    if (*calcMatched) {
+        SkASSERT(*oppMatched == this->matchedDirection(t, sect2, t2)); 
+    } else {
+        *oppMatched = this->matchedDirection(t, sect2, t2);
+        *calcMatched = true;
+    }
+}
+
+template<typename TCurve>
+void SkTSect<TCurve>::mergeCoincidence(SkTSect* sect2) {
+    double smallLimit = 0;
+    do {
+        // find the smallest unprocessed span
+        SkTSpan<TCurve>* smaller = NULL;
+        SkTSpan<TCurve>* test = fCoincident;
+        do {
+            if (test->fStartT < smallLimit) {
+                continue;
+            }
+            if (smaller && smaller->fEndT < test->fStartT) {
+                continue;
+            }
+            smaller = test;
+        } while ((test = test->fNext));
+        if (!smaller) {
+            return;
+        }
+        smallLimit = smaller->fEndT;
+        // find next larger span
+        SkTSpan<TCurve>* prior = NULL;
+        SkTSpan<TCurve>* larger = NULL;
+        SkTSpan<TCurve>* largerPrior = NULL;
+        test = fCoincident;
+        do {
+            if (test->fStartT < smaller->fEndT) {
+                continue;
+            }
+            SkASSERT(test->fStartT != smaller->fEndT);
+            if (larger && larger->fStartT < test->fStartT) {
+                continue;
+            }
+            largerPrior = prior;
+            larger = test;
+        } while ((prior = test), (test = test->fNext));
+        if (!larger) {
+            continue;
+        }
+        // check middle t value to see if it is coincident as well
+        double midT = (smaller->fEndT + larger->fStartT) / 2;
+        SkDPoint midPt = fCurve.ptAtT(midT);
+        SkTCoincident<TCurve> coin;
+        coin.setPerp(fCurve, midT, midPt, sect2->fCurve);
+        if (coin.isCoincident()) {
+            smaller->fEndT = larger->fEndT;
+            smaller->fCoinEnd = larger->fCoinEnd;
+            if (largerPrior) {
+                largerPrior->fNext = larger->fNext;
+            } else {
+                fCoincident = larger->fNext;
             }
         }
+    } while (true);
+}
+
+template<typename TCurve>
+SkTSpan<TCurve>* SkTSect<TCurve>::prev(SkTSpan<TCurve>* span) const {
+    SkTSpan<TCurve>* result = NULL;
+    SkTSpan<TCurve>* test = fHead;
+    while (span != test) {
+        result = test;
+        test = test->fNext;
+        SkASSERT(test);
     }
+    return result; 
 }
 
 template<typename TCurve>
@@ -782,80 +1333,118 @@
 }
 
 template<typename TCurve>
-void SkTSect<TCurve>::removeSpan(SkTSpan<TCurve>* span) {
-    SkTSpan<TCurve>* prev = span->fPrev;
-    SkTSpan<TCurve>* next = span->fNext;
-    if (prev) {
-        prev->fNext = next;
-        if (next) {
-            next->fPrev = prev;
+void SkTSect<TCurve>::removeAllBut(const SkTSpan<TCurve>* keep, SkTSpan<TCurve>* span,
+        SkTSect* opp) {
+    int count = span->fBounded.count();
+    for (int index = 0; index < count; ++index) {
+        SkTSpan<TCurve>* bounded = span->fBounded[0];
+        if (bounded == keep) {
+            continue;
         }
-    } else {
-        fHead = next;
-        if (next) {
-            next->fPrev = NULL;
+        if (bounded->fDeleted) {  // may have been deleted when opp did 'remove all but'
+            continue;
+        }
+        SkAssertResult(SkDEBUGCODE(!) span->removeBounded(bounded));
+        if (bounded->removeBounded(span)) {
+            opp->removeSpan(bounded);
         }
     }
-    --fActiveCount;
-    span->fNext = fDeleted;
-    fDeleted = span;
-#if DEBUG_T_SECT
-    SkASSERT(!span->fDebugDeleted);
-    span->fDebugDeleted = true;
-#endif
+    SkASSERT(!span->fDeleted);
+    SkASSERT(span->findOppSpan(keep));
+    SkASSERT(keep->findOppSpan(span));
 }
 
 template<typename TCurve>
-void SkTSect<TCurve>::removeOne(const SkTSpan<TCurve>* test, SkTSpan<TCurve>* span) {
-    int last = span->fBounded.count() - 1;
-    for (int index = 0; index <= last; ++index) {
-        if (span->fBounded[index] == test) {
-            span->fBounded.removeShuffle(index);
-            if (!last) {
-                removeSpan(span);
-            }
-            return;
+void SkTSect<TCurve>::removeByPerpendicular(SkTSect<TCurve>* opp) {
+    SkTSpan<TCurve>* test = fHead;
+    SkTSpan<TCurve>* next;
+    do {
+        next = test->fNext;
+        if (test->fCoinStart.perpT() < 0 || test->fCoinEnd.perpT() < 0) {
+            continue;
         }
+        SkDVector startV = test->fCoinStart.perpPt() - test->fPart[0];
+        SkDVector endV = test->fCoinEnd.perpPt() - test->fPart[TCurve::kPointLast];
+#if DEBUG_T_SECT
+        SkDebugf("%s startV=(%1.9g,%1.9g) endV=(%1.9g,%1.9g) dot=%1.9g\n", __FUNCTION__,
+                startV.fX, startV.fY, endV.fX, endV.fY, startV.dot(endV));
+#endif
+        if (startV.dot(endV) <= 0) {
+            continue;
+        }
+        this->removeSpans(test, opp);
+    } while ((test = next));
+}
+
+template<typename TCurve>
+void SkTSect<TCurve>::removeCoincident(SkTSpan<TCurve>* span, bool isBetween) {
+    this->unlinkSpan(span);
+    if (isBetween || between(0, span->fCoinStart.perpT(), 1)) {
+        --fActiveCount;
+        span->fNext = fCoincident;
+        fCoincident = span;
+    } else {
+        this->markSpanGone(span);
     }
 }
 
 template<typename TCurve>
+void SkTSect<TCurve>::removeSpan(SkTSpan<TCurve>* span) {
+    this->unlinkSpan(span);
+    this->markSpanGone(span);
+}
+
+template<typename TCurve>
+void SkTSect<TCurve>::removeSpanRange(SkTSpan<TCurve>* first, SkTSpan<TCurve>* last) {
+    if (first == last) {
+        return;
+    }
+    SkTSpan<TCurve>* span = first;
+    SkASSERT(span);
+    SkTSpan<TCurve>* final = last->fNext;
+    SkTSpan<TCurve>* next = span->fNext;
+    while ((span = next) && span != final) {
+        next = span->fNext;
+        this->markSpanGone(span);
+    }
+    if (final) {
+        final->fPrev = first;
+    }
+    first->fNext = final;
+}
+
+template<typename TCurve>
 void SkTSect<TCurve>::removeSpans(SkTSpan<TCurve>* span, SkTSect<TCurve>* opp) {
     int count = span->fBounded.count();
     for (int index = 0; index < count; ++index) {
         SkTSpan<TCurve>* bounded = span->fBounded[0];
-        removeOne(bounded, span);  // shuffles last into position 0
-        opp->removeOne(span, bounded);
+        if (span->removeBounded(bounded)) {  // shuffles last into position 0
+            this->removeSpan(span);
+        }
+        if (bounded->removeBounded(span)) {
+            opp->removeSpan(bounded);
+        }
+        SkASSERT(!span->fDeleted || !opp->debugHasBounded(span));
+
     }
 }
 
 template<typename TCurve>
-void SkTSect<TCurve>::setPerp(const TCurve& opp, SkTSpan<TCurve>* first, SkTSpan<TCurve>* last) {
-    SkTSpan<TCurve>* work = first;
-    if (!work->fHasPerp) {
-        work->fCoinStart.setPerp(fCurve, work->fStartT, work->fPart[0], opp);
+SkTSpan<TCurve>* SkTSect<TCurve>::spanAtT(double t, SkTSpan<TCurve>** priorSpan) {
+    SkTSpan<TCurve>* test = fHead;
+    SkTSpan<TCurve>* prev = NULL;
+    while (test && test->fEndT < t) {
+        prev = test;
+        test = test->fNext;
     }
-    do {
-        if (!work->fHasPerp) {
-            work->fCoinEnd.setPerp(fCurve, work->fEndT, work->fPart[TCurve::kPointLast], opp);
-            work->fHasPerp = true;
-        }
-        if (work == last) {
-            break;
-        }
-        SkTSpan<TCurve>* last = work;
-        work = work->fNext;
-        SkASSERT(work);
-        if (!work->fHasPerp) {
-            work->fCoinStart = last->fCoinEnd;
-        }
-    } while (true);
+    *priorSpan = prev;
+    return test && test->fStartT <= t ? test : NULL;
 }
 
 template<typename TCurve>
-const SkTSpan<TCurve>* SkTSect<TCurve>::tail() const {
-    const SkTSpan<TCurve>* result = fHead;
-    const SkTSpan<TCurve>* next = fHead;
+SkTSpan<TCurve>* SkTSect<TCurve>::tail() {
+    SkTSpan<TCurve>* result = fHead;
+    SkTSpan<TCurve>* next = fHead;
     while ((next = next->fNext)) {
         if (next->fEndT > result->fEndT) {
             result = next;
@@ -869,32 +1458,75 @@
 template<typename TCurve>
 void SkTSect<TCurve>::trim(SkTSpan<TCurve>* span, SkTSect* opp) {
     span->initBounds(fCurve);
-    int count = span->fBounded.count();
-    for (int index = 0; index < count; ) {
+    for (int index = 0; index < span->fBounded.count(); ) {
         SkTSpan<TCurve>* test = span->fBounded[index];
-        bool sects = intersects(span, opp, test);
-        if (sects) {
+        int oppSects, sects = this->intersects(span, opp, test, &oppSects);
+        if (sects >= 1) {
+            if (sects == 2) {
+                span->initBounds(fCurve);
+                this->removeAllBut(test, span, opp);
+            }
+            if (oppSects == 2) {
+                test->initBounds(opp->fCurve);
+                opp->removeAllBut(span, test, this);
+            }
             ++index;
         } else {
-            removeOne(test, span);
-            opp->removeOne(span, test);
-            --count;
+            if (span->removeBounded(test)) {
+                this->removeSpan(span);
+            }
+            if (test->removeBounded(span)) {
+                opp->removeSpan(test);
+            }
         }
     }
 }
 
-#if DEBUG_T_SECT
+template<typename TCurve>
+void SkTSect<TCurve>::unlinkSpan(SkTSpan<TCurve>* span) {
+    SkTSpan<TCurve>* prev = span->fPrev;
+    SkTSpan<TCurve>* next = span->fNext;
+    if (prev) {
+        prev->fNext = next;
+        if (next) {
+            next->fPrev = prev;
+        }
+    } else {
+        fHead = next;
+        if (next) {
+            next->fPrev = NULL;
+        }
+    }
+}
+
+template<typename TCurve>
+bool SkTSect<TCurve>::updateBounded(SkTSpan<TCurve>* first, SkTSpan<TCurve>* last,
+        SkTSpan<TCurve>* oppFirst) {
+    SkTSpan<TCurve>* test = first;
+    const SkTSpan<TCurve>* final = last->next();
+    bool deleteSpan = false;
+    do {
+        deleteSpan |= test->removeAllBounded();
+    } while ((test = test->fNext) != final);
+    first->fBounded.resize_back(1);
+    first->fBounded[0] = oppFirst;
+    // cannot call validate until remove span range is called
+    return deleteSpan;
+}
+
+
 template<typename TCurve>
 void SkTSect<TCurve>::validate() const {
+#if DEBUG_T_SECT
     int count = 0;
     if (fHead) {
         const SkTSpan<TCurve>* span = fHead;
         SkASSERT(!span->fPrev);
-        double last = 0;
+        SkDEBUGCODE(double last = 0);
         do {
             span->validate();
             SkASSERT(span->fStartT >= last);
-            last = span->fEndT;
+            SkDEBUGCODE(last = span->fEndT);
             ++count;
         } while ((span = span->fNext) != NULL);
     }
@@ -906,54 +1538,81 @@
         ++deletedCount;
         deleted = deleted->fNext;
     }
+    const SkTSpan<TCurve>* coincident = fCoincident;
+    while (coincident) {
+        ++deletedCount;
+        coincident = coincident->fNext;
+    }
     SkASSERT(fActiveCount + deletedCount == fDebugAllocatedCount);
-}
 #endif
+}
+
+template<typename TCurve>
+void SkTSect<TCurve>::validateBounded() const {
+#if DEBUG_T_SECT
+    if (!fHead) {
+        return;
+    }
+    const SkTSpan<TCurve>* span = fHead;
+    do {
+        span->validateBounded();
+    } while ((span = span->fNext) != NULL);
+#endif
+}
 
 template<typename TCurve>
 int SkTSect<TCurve>::EndsEqual(const SkTSect* sect1, const SkTSect* sect2,
         SkIntersections* intersections) {
     int zeroOneSet = 0;
-    // check for zero
-    if (sect1->fCurve[0].approximatelyEqual(sect2->fCurve[0])) {
+    if (sect1->fCurve[0] == sect2->fCurve[0]) {
         zeroOneSet |= kZeroS1Set | kZeroS2Set;
-        if (sect1->fCurve[0] != sect2->fCurve[0]) {
-            intersections->insertNear(0, 0, sect1->fCurve[0], sect2->fCurve[0]);
-        } else {
-            intersections->insert(0, 0, sect1->fCurve[0]);
-        }
-    } 
-    if (sect1->fCurve[0].approximatelyEqual(sect2->fCurve[TCurve::kPointLast])) {
+        intersections->insert(0, 0, sect1->fCurve[0]);
+    }
+    if (sect1->fCurve[0] == sect2->fCurve[TCurve::kPointLast]) {
         zeroOneSet |= kZeroS1Set | kOneS2Set;
-        if (sect1->fCurve[0] != sect2->fCurve[TCurve::kPointLast]) {
-            intersections->insertNear(0, 1, sect1->fCurve[0], sect2->fCurve[TCurve::kPointLast]);
-        } else {
-            intersections->insert(0, 1, sect1->fCurve[0]);
-        }
-    } 
-    // check for one
-    if (sect1->fCurve[TCurve::kPointLast].approximatelyEqual(sect2->fCurve[0])) {
+        intersections->insert(0, 1, sect1->fCurve[0]);
+    }
+    if (sect1->fCurve[TCurve::kPointLast] == sect2->fCurve[0]) {
         zeroOneSet |= kOneS1Set | kZeroS2Set;
-        if (sect1->fCurve[TCurve::kPointLast] != sect2->fCurve[0]) {
-            intersections->insertNear(1, 0, sect1->fCurve[TCurve::kPointLast], sect2->fCurve[0]);
-        } else {
-            intersections->insert(1, 0, sect1->fCurve[TCurve::kPointLast]);
-        }
-    } 
-    if (sect1->fCurve[TCurve::kPointLast].approximatelyEqual(sect2->fCurve[TCurve::kPointLast])) {
+        intersections->insert(1, 0, sect1->fCurve[TCurve::kPointLast]);
+    }
+    if (sect1->fCurve[TCurve::kPointLast] == sect2->fCurve[TCurve::kPointLast]) {
         zeroOneSet |= kOneS1Set | kOneS2Set;
-        if (sect1->fCurve[TCurve::kPointLast] != sect2->fCurve[TCurve::kPointLast]) {
-            intersections->insertNear(1, 1, sect1->fCurve[TCurve::kPointLast],
-                    sect2->fCurve[TCurve::kPointLast]);
-        } else {
             intersections->insert(1, 1, sect1->fCurve[TCurve::kPointLast]);
-        }
+    }
+    // check for zero
+    if (!(zeroOneSet & (kZeroS1Set | kZeroS2Set))
+            && sect1->fCurve[0].approximatelyEqual(sect2->fCurve[0])) {
+        zeroOneSet |= kZeroS1Set | kZeroS2Set;
+        intersections->insertNear(0, 0, sect1->fCurve[0], sect2->fCurve[0]);
+    }
+    if (!(zeroOneSet & (kZeroS1Set | kOneS2Set))
+            && sect1->fCurve[0].approximatelyEqual(sect2->fCurve[TCurve::kPointLast])) {
+        zeroOneSet |= kZeroS1Set | kOneS2Set;
+        intersections->insertNear(0, 1, sect1->fCurve[0], sect2->fCurve[TCurve::kPointLast]);
+    }
+    // check for one
+    if (!(zeroOneSet & (kOneS1Set | kZeroS2Set))
+            && sect1->fCurve[TCurve::kPointLast].approximatelyEqual(sect2->fCurve[0])) {
+        zeroOneSet |= kOneS1Set | kZeroS2Set;
+        intersections->insertNear(1, 0, sect1->fCurve[TCurve::kPointLast], sect2->fCurve[0]);
+    }
+    if (!(zeroOneSet & (kOneS1Set | kOneS2Set))
+            && sect1->fCurve[TCurve::kPointLast].approximatelyEqual(sect2->fCurve[
+            TCurve::kPointLast])) {
+        zeroOneSet |= kOneS1Set | kOneS2Set;
+        intersections->insertNear(1, 1, sect1->fCurve[TCurve::kPointLast],
+                sect2->fCurve[TCurve::kPointLast]);
     }
     return zeroOneSet;
 }
 
 template<typename TCurve>
 struct SkClosestRecord {
+    bool operator<(const SkClosestRecord& rh) const {
+        return fClosest < rh.fClosest;
+    }
+
     void addIntersection(SkIntersections* intersections) const {
         double r1t = fC1Index ? fC1Span->endT() : fC1Span->startT();
         double r2t = fC2Index ? fC2Span->endT() : fC2Span->startT();
@@ -1033,14 +1692,14 @@
         fClosest.push_back().reset();
     }
 
-    void find(const SkTSpan<TCurve>* span1, const SkTSpan<TCurve>* span2) {
+    bool find(const SkTSpan<TCurve>* span1, const SkTSpan<TCurve>* span2) {
         SkClosestRecord<TCurve>* record = &fClosest[fUsed];
         record->findEnd(span1, span2, 0, 0);
         record->findEnd(span1, span2, 0, TCurve::kPointLast);
         record->findEnd(span1, span2, TCurve::kPointLast, 0);
         record->findEnd(span1, span2, TCurve::kPointLast, TCurve::kPointLast);
         if (record->fClosest == FLT_MAX) {
-            return;
+            return false;
         }
         for (int index = 0; index < fUsed; ++index) {
             SkClosestRecord<TCurve>* test = &fClosest[index];
@@ -1050,37 +1709,46 @@
                 }
                 test->update(*record);
                 record->reset();
-                return;
+                return false;
             }
         }
         ++fUsed;
         fClosest.push_back().reset();
+        return true;
     }
 
     void finish(SkIntersections* intersections) const {
+        SkSTArray<TCurve::kMaxIntersections * 2, const SkClosestRecord<TCurve>*, true> closestPtrs;
         for (int index = 0; index < fUsed; ++index) {
-            const SkClosestRecord<TCurve>& test = fClosest[index];
-            test.addIntersection(intersections);
+            closestPtrs.push_back(&fClosest[index]);
+        }
+        SkTQSort<const SkClosestRecord<TCurve> >(closestPtrs.begin(), closestPtrs.end() - 1);
+        for (int index = 0; index < fUsed; ++index) {
+            const SkClosestRecord<TCurve>* test = closestPtrs[index];
+            test->addIntersection(intersections);
         }
     }
 
-    // this is oversized by one so that an extra record can merge into final one
-    SkSTArray<TCurve::kMaxIntersections + 1, SkClosestRecord<TCurve>, true> fClosest;
+    // this is oversized so that an extra records can merge into final one
+    SkSTArray<TCurve::kMaxIntersections * 2, SkClosestRecord<TCurve>, true> fClosest;
     int fUsed;
 };
 
 // returns true if the rect is too small to consider
 template<typename TCurve>
 void SkTSect<TCurve>::BinarySearch(SkTSect* sect1, SkTSect* sect2, SkIntersections* intersections) {
+    PATH_OPS_DEBUG_CODE(sect1->fOppSect = sect2);
+    PATH_OPS_DEBUG_CODE(sect2->fOppSect = sect1);
     intersections->reset();
-    intersections->setMax(TCurve::kMaxIntersections);
+    intersections->setMax(TCurve::kMaxIntersections * 2);  // give extra for slop
     SkTSpan<TCurve>* span1 = sect1->fHead;
     SkTSpan<TCurve>* span2 = sect2->fHead;
-    bool check;
-    if (!span1->intersects(span2, &check)) {
+    int oppSect, sect = sect1->intersects(span1, sect2, span2, &oppSect);
+//    SkASSERT(between(0, sect, 2));
+    if (!sect) {
         return;
     }
-    if (check) {
+    if (sect == 2 && oppSect == 2) {
         (void) EndsEqual(sect1, sect2, intersections);
         return;
     }
@@ -1096,12 +1764,12 @@
         bool split1 = !largest2 || (largest1 && (largest1->fBoundsMax > largest2->fBoundsMax
             || (!largest1->fCollapsed && largest2->fCollapsed)));
         // split it
-        SkTSect* splitSect = split1 ? sect1 : sect2;
         SkTSpan<TCurve>* half1 = split1 ? largest1 : largest2;
         SkASSERT(half1);
         if (half1->fCollapsed) {
             break;
         }
+        SkTSect* splitSect = split1 ? sect1 : sect2;
         // trim parts that don't intersect the opposite
         SkTSpan<TCurve>* half2 = splitSect->addOne();
         SkTSect* unsplitSect = split1 ? sect2 : sect1;
@@ -1110,50 +1778,52 @@
         }
         splitSect->trim(half1, unsplitSect);
         splitSect->trim(half2, unsplitSect);
+        sect1->validate();
+        sect2->validate();
         // if there are 9 or more continuous spans on both sects, suspect coincidence
         if (sect1->fActiveCount >= COINCIDENT_SPAN_COUNT
                 && sect2->fActiveCount >= COINCIDENT_SPAN_COUNT) {
             sect1->coincidentCheck(sect2);
+            sect1->validate();
+            sect2->validate();
         }
-#if DEBUG_T_SECT
-        sect1->validate();
-        sect2->validate();
-#endif
-#if DEBUG_T_SECT_DUMP > 1
-        sect1->dumpBoth(*sect2);
+        if (sect1->fActiveCount >= COINCIDENT_SPAN_COUNT
+                && sect2->fActiveCount >= COINCIDENT_SPAN_COUNT) {
+            sect1->computePerpendiculars(sect2, sect1->fHead, sect1->tail());
+            sect2->computePerpendiculars(sect1, sect2->fHead, sect2->tail());
+            sect1->removeByPerpendicular(sect2);
+            sect1->validate();
+            sect2->validate();
+        }
+#if DEBUG_T_SECT_DUMP
+        sect1->dumpBoth(sect2);
 #endif
         if (!sect1->fHead || !sect2->fHead) {
-            return;
+            break;
         }
     } while (true);
-    if (sect1->fActiveCount >= 2 && sect2->fActiveCount >= 2) {
-        // check for coincidence
-        SkTSpan<TCurve>* first = sect1->fHead;
+    SkTSpan<TCurve>* coincident = sect1->fCoincident;
+    if (coincident) {
+        // if there is more than one coincident span, check loosely to see if they should be joined
+        if (coincident->fNext) {
+            sect1->mergeCoincidence(sect2);
+            coincident = sect1->fCoincident;
+        }
+        SkASSERT(sect2->fCoincident);  // courtesy check : coincidence only looks at sect 1
         do {
-            if (!first->fCoinStart.isCoincident()) {
-                continue;
-            }
-            int spanCount = 1;
-            SkTSpan<TCurve>* last = first;
-            while (last->fCoinEnd.isCoincident()) {
-                SkTSpan<TCurve>* next = last->fNext;
-                if (!next || !next->fCoinEnd.isCoincident()) {
-                    break;
-                }
-                last = next;
-                ++spanCount;
-            }
-            if (spanCount < 2) {
-                first = last;
-                continue;
-            }
-            int index = intersections->insertCoincident(first->fStartT, first->fCoinStart.perpT(),
-                    first->fPart[0]);
-            if (intersections->insertCoincident(last->fEndT, last->fCoinEnd.perpT(),
-                    last->fPart[TCurve::kPointLast]) < 0) {
+            SkASSERT(coincident->fCoinStart.isCoincident());
+            SkASSERT(coincident->fCoinEnd.isCoincident());
+            int index = intersections->insertCoincident(coincident->fStartT,
+                    coincident->fCoinStart.perpT(), coincident->fPart[0]);
+            if ((intersections->insertCoincident(coincident->fEndT,
+                    coincident->fCoinEnd.perpT(),
+                    coincident->fPart[TCurve::kPointLast]) < 0) && index >= 0) {
                 intersections->clearCoincidence(index);
             }
-        } while ((first = first->fNext));
+        } while ((coincident = coincident->fNext));
+    }
+    if (!sect1->fHead || !sect2->fHead) {
+        return;
     }
     int zeroOneSet = EndsEqual(sect1, sect2, intersections);
     sect1->recoverCollapsed();
@@ -1163,33 +1833,41 @@
     const SkTSpan<TCurve>* head1 = result1;
     if (!(zeroOneSet & kZeroS1Set) && approximately_less_than_zero(head1->fStartT)) {
         const SkDPoint& start1 = sect1->fCurve[0];
-        double t = head1->closestBoundedT(start1);
-        if (sect2->fCurve.ptAtT(t).approximatelyEqual(start1)) {
-            intersections->insert(0, t, start1);
+        if (head1->isBounded()) {
+            double t = head1->closestBoundedT(start1);
+            if (sect2->fCurve.ptAtT(t).approximatelyEqual(start1)) {
+                intersections->insert(0, t, start1);
+            }
         }
     }
     const SkTSpan<TCurve>* head2 = sect2->fHead;
     if (!(zeroOneSet & kZeroS2Set) && approximately_less_than_zero(head2->fStartT)) {
         const SkDPoint& start2 = sect2->fCurve[0];
-        double t = head2->closestBoundedT(start2);
-        if (sect1->fCurve.ptAtT(t).approximatelyEqual(start2)) {
-            intersections->insert(t, 0, start2);
+        if (head2->isBounded()) {
+            double t = head2->closestBoundedT(start2);
+            if (sect1->fCurve.ptAtT(t).approximatelyEqual(start2)) {
+                intersections->insert(t, 0, start2);
+            }
         }
     }
     const SkTSpan<TCurve>* tail1 = sect1->tail();
     if (!(zeroOneSet & kOneS1Set) && approximately_greater_than_one(tail1->fEndT)) {
         const SkDPoint& end1 = sect1->fCurve[TCurve::kPointLast];
-        double t = tail1->closestBoundedT(end1);
-        if (sect2->fCurve.ptAtT(t).approximatelyEqual(end1)) {
-            intersections->insert(1, t, end1);
+        if (tail1->isBounded()) {
+            double t = tail1->closestBoundedT(end1);
+            if (sect2->fCurve.ptAtT(t).approximatelyEqual(end1)) {
+                intersections->insert(1, t, end1);
+            }
         }
     }
     const SkTSpan<TCurve>* tail2 = sect2->tail();
     if (!(zeroOneSet & kOneS2Set) && approximately_greater_than_one(tail2->fEndT)) {
         const SkDPoint& end2 = sect2->fCurve[TCurve::kPointLast];
-        double t = tail2->closestBoundedT(end2);
-        if (sect1->fCurve.ptAtT(t).approximatelyEqual(end2)) {
-            intersections->insert(t, 1, end2);
+        if (tail2->isBounded()) {
+            double t = tail2->closestBoundedT(end2);
+            if (sect1->fCurve.ptAtT(t).approximatelyEqual(end2)) {
+                intersections->insert(t, 1, end2);
+            }
         }
     }
     SkClosestSect<TCurve> closest;
@@ -1201,11 +1879,39 @@
             break;
         }
         SkTSpan<TCurve>* result2 = sect2->fHead;
+        bool found = false;
         while (result2) {
-            closest.find(result1, result2);
+            found |= closest.find(result1, result2);
             result2 = result2->fNext;
         }
-        
     } while ((result1 = result1->fNext));
     closest.finish(intersections);
+    // if there is more than one intersection and it isn't already coincident, check
+    int last = intersections->used() - 1;
+    for (int index = 0; index < last; ) {
+        if (intersections->isCoincident(index) && intersections->isCoincident(index + 1)) {
+            ++index;
+            continue;
+        }
+        double midT = ((*intersections)[0][index] + (*intersections)[0][index + 1]) / 2;
+        SkDPoint midPt = sect1->fCurve.ptAtT(midT);
+        // intersect perpendicular with opposite curve
+        SkTCoincident<TCurve> perp;
+        perp.setPerp(sect1->fCurve, midT, midPt, sect2->fCurve);
+        if (!perp.isCoincident()) {
+            ++index;
+            continue;
+        }
+        if (intersections->isCoincident(index)) {
+            intersections->removeOne(index);
+            --last;
+        } else if (intersections->isCoincident(index + 1)) {
+            intersections->removeOne(index + 1);
+            --last;
+        } else {
+            intersections->setCoincident(index++);
+        }
+        intersections->setCoincident(index);
+    }
+    SkASSERT(intersections->used() <= TCurve::kMaxIntersections);
 }
diff --git a/src/pathops/SkPathOpsTightBounds.cpp b/src/pathops/SkPathOpsTightBounds.cpp
index 0f63f39..d03efeb 100644
--- a/src/pathops/SkPathOpsTightBounds.cpp
+++ b/src/pathops/SkPathOpsTightBounds.cpp
@@ -8,14 +8,16 @@
 #include "SkPathOpsCommon.h"
 
 bool TightBounds(const SkPath& path, SkRect* result) {
+    SkOpContour contour;
+    SkOpGlobalState globalState( NULL  PATH_OPS_DEBUG_PARAMS(&contour));
     // turn path into list of segments
-    SkTArray<SkOpContour> contours;
-    SkOpEdgeBuilder builder(path, contours);
-    if (!builder.finish()) {
+    SkChunkAlloc allocator(4096);  // FIXME: constant-ize, tune
+    SkOpEdgeBuilder builder(path, &contour, &allocator, &globalState);
+    if (!builder.finish(&allocator)) {
         return false;
     }
-    SkTArray<SkOpContour*, true> contourList;
-    MakeContourList(contours, contourList, false, false);
+    SkTDArray<SkOpContour* > contourList;
+    MakeContourList(&contour, contourList, false, false);
     SkOpContour** currentPtr = contourList.begin();
     result->setEmpty();
     if (!currentPtr) {
diff --git a/src/pathops/SkPathOpsTriangle.cpp b/src/pathops/SkPathOpsTriangle.cpp
deleted file mode 100644
index 77845e0..0000000
--- a/src/pathops/SkPathOpsTriangle.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkPathOpsTriangle.h"
-
-// http://www.blackpawn.com/texts/pointinpoly/default.html
-// return true if pt is inside triangle; false if outside or on the line
-bool SkDTriangle::contains(const SkDPoint& pt) const {
-// Compute vectors
-    SkDVector v0 = fPts[2] - fPts[0];
-    SkDVector v1 = fPts[1] - fPts[0];
-    SkDVector v2 = pt - fPts[0];
-
-// Compute dot products
-    double dot00 = v0.dot(v0);
-    double dot01 = v0.dot(v1);
-    double dot02 = v0.dot(v2);
-    double dot11 = v1.dot(v1);
-    double dot12 = v1.dot(v2);
-
-// original code doesn't handle degenerate input; isn't symmetric with inclusion of corner pts;
-// introduces error with divide; doesn't short circuit on early answer
-#if 0
-// Compute barycentric coordinates
-    double invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
-    double u = (dot11 * dot02 - dot01 * dot12) * invDenom;
-    double v = (dot00 * dot12 - dot01 * dot02) * invDenom;
-
-// Check if point is in triangle
-    return (u >= 0) && (v >= 0) && (u + v <= 1);
-#else
-    double w = dot00 * dot11 - dot01 * dot01;
-    if (w == 0) {
-        return false;
-    }
-    double wSign = w < 0 ? -1 : 1;
-    double u = (dot11 * dot02 - dot01 * dot12) * wSign;
-    if (u <= 0) {
-        return false;
-    }
-    double v = (dot00 * dot12 - dot01 * dot02) * wSign;
-    if (v <= 0) {
-        return false;
-    }
-    return u + v < w * wSign;
-#endif
-}
diff --git a/src/pathops/SkPathOpsTriangle.h b/src/pathops/SkPathOpsTriangle.h
deleted file mode 100644
index 8cc8c6d..0000000
--- a/src/pathops/SkPathOpsTriangle.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkPathOpsTriangle_DEFINED
-#define SkPathOpsTriangle_DEFINED
-
-#include "SkPathOpsPoint.h"
-
-struct SkDTriangle {
-    SkDPoint fPts[3];
-
-    bool contains(const SkDPoint& pt) const;
-
-};
-
-#endif
diff --git a/src/pathops/SkPathOpsTypes.h b/src/pathops/SkPathOpsTypes.h
index 01fec0d..0248e71 100644
--- a/src/pathops/SkPathOpsTypes.h
+++ b/src/pathops/SkPathOpsTypes.h
@@ -22,6 +22,111 @@
     kEvenOdd_PathOpsMask = 1
 };
 
+class SkOpCoincidence;
+class SkOpContour;
+
+class SkOpGlobalState {
+public:
+    SkOpGlobalState(SkOpCoincidence* coincidence  PATH_OPS_DEBUG_PARAMS(SkOpContour* head))
+        : fCoincidence(coincidence)
+        , fWindingFailed(false)
+        , fAngleCoincidence(false)
+#if DEBUG_VALIDATE
+        , fPhase(kIntersecting)
+#endif
+        PATH_OPS_DEBUG_PARAMS(fHead(head))
+        PATH_OPS_DEBUG_PARAMS(fAngleID(0))
+        PATH_OPS_DEBUG_PARAMS(fContourID(0))
+        PATH_OPS_DEBUG_PARAMS(fPtTID(0))
+        PATH_OPS_DEBUG_PARAMS(fSegmentID(0))
+        PATH_OPS_DEBUG_PARAMS(fSpanID(0)) {
+    }
+
+#if DEBUG_VALIDATE
+    enum Phase {
+        kIntersecting,
+        kWalking
+    };
+#endif
+
+    bool angleCoincidence() {
+        return fAngleCoincidence;
+    }
+
+    SkOpCoincidence* coincidence() {
+        return fCoincidence;
+    }
+
+#ifdef SK_DEBUG
+    const struct SkOpAngle* debugAngle(int id) const;
+    SkOpContour* debugContour(int id);
+    const class SkOpPtT* debugPtT(int id) const;
+    const class SkOpSegment* debugSegment(int id) const;
+    const class SkOpSpanBase* debugSpan(int id) const;
+
+    int nextAngleID() {
+        return ++fAngleID;
+    }
+
+    int nextContourID() {
+        return ++fContourID;
+    }
+    int nextPtTID() {
+        return ++fPtTID;
+    }
+
+    int nextSegmentID() {
+        return ++fSegmentID;
+    }
+
+    int nextSpanID() {
+        return ++fSpanID;
+    }
+#endif
+
+#if DEBUG_VALIDATE
+    Phase phase() const {
+        return fPhase;
+    }
+#endif
+
+    void setAngleCoincidence() {
+        fAngleCoincidence = true;
+    }
+    
+#if DEBUG_VALIDATE
+    void setPhase(Phase phase) {
+        SkASSERT(fPhase != phase);
+        fPhase = phase;
+    }
+#endif
+
+    // called in very rare cases where angles are sorted incorrectly -- signfies op will fail
+    void setWindingFailed() {
+        fWindingFailed = true;
+    }
+
+    bool windingFailed() const {
+        return fWindingFailed;
+    }
+
+private:
+    SkOpCoincidence* fCoincidence;
+    bool fWindingFailed;
+    bool fAngleCoincidence;
+#if DEBUG_VALIDATE
+    Phase fPhase;
+#endif
+#ifdef SK_DEBUG
+    SkOpContour* fHead;
+    int fAngleID;
+    int fContourID;
+    int fPtTID;
+    int fSegmentID;
+    int fSpanID;
+#endif
+};
+
 // Use Almost Equal when comparing coordinates. Use epsilon to compare T values.
 bool AlmostEqualUlps(float a, float b);
 inline bool AlmostEqualUlps(double a, double b) {
@@ -92,6 +197,7 @@
 const double ROUGH_EPSILON = FLT_EPSILON * 64;
 const double MORE_ROUGH_EPSILON = FLT_EPSILON * 256;
 const double WAY_ROUGH_EPSILON = FLT_EPSILON * 2048;
+const double BUMP_EPSILON = FLT_EPSILON * 4096;
 
 inline bool zero_or_one(double x) {
     return x == 0 || x == 1;
@@ -141,12 +247,6 @@
     return fabs(x) < ROUGH_EPSILON;
 }
 
-#if 0  // unused for now
-inline bool way_roughly_zero(double x) {
-    return fabs(x) < WAY_ROUGH_EPSILON;
-}
-#endif
-
 inline bool approximately_zero_inverse(double x) {
     return fabs(x) > FLT_EPSILON_INVERSE;
 }
@@ -156,6 +256,10 @@
     return x == 0 || fabs(x) < fabs(y * FLT_EPSILON);
 }
 
+inline bool precisely_zero_when_compared_to(double x, double y) {
+    return x == 0 || fabs(x) < fabs(y * DBL_EPSILON);
+}
+
 // Use this for comparing Ts in the range of 0 to 1. For general numbers (larger and smaller) use
 // AlmostEqualUlps instead.
 inline bool approximately_equal(double x, double y) {
@@ -304,7 +408,8 @@
 
 // returns true if (a <= b <= c) || (a >= b >= c)
 inline bool between(double a, double b, double c) {
-    SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0));
+    SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0)
+            || (precisely_zero(a) && precisely_zero(b) && precisely_zero(c)));
     return (a - b) * (c - b) <= 0;
 }
 
@@ -312,6 +417,15 @@
     return fabs(x - y) < ROUGH_EPSILON;
 }
 
+inline bool roughly_negative(double x) {
+    return x < ROUGH_EPSILON;
+}
+
+inline bool roughly_between(double a, double b, double c) {
+    return a <= c ? roughly_negative(a - b) && roughly_negative(b - c)
+            : roughly_negative(b - a) && roughly_negative(c - b);
+}
+
 inline bool more_roughly_equal(double x, double y) {
     return fabs(x - y) < MORE_ROUGH_EPSILON;
 }
@@ -324,7 +438,6 @@
 struct SkDVector;
 struct SkDLine;
 struct SkDQuad;
-struct SkDTriangle;
 struct SkDCubic;
 struct SkDRect;
 
diff --git a/src/pathops/SkQuarticRoot.cpp b/src/pathops/SkQuarticRoot.cpp
deleted file mode 100644
index f9a7bf5..0000000
--- a/src/pathops/SkQuarticRoot.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-// from http://tog.acm.org/resources/GraphicsGems/gems/Roots3And4.c
-/*
- *  Roots3And4.c
- *
- *  Utility functions to find cubic and quartic roots,
- *  coefficients are passed like this:
- *
- *      c[0] + c[1]*x + c[2]*x^2 + c[3]*x^3 + c[4]*x^4 = 0
- *
- *  The functions return the number of non-complex roots and
- *  put the values into the s array.
- *
- *  Author:         Jochen Schwarze (schwarze@isa.de)
- *
- *  Jan 26, 1990    Version for Graphics Gems
- *  Oct 11, 1990    Fixed sign problem for negative q's in SolveQuartic
- *                  (reported by Mark Podlipec),
- *                  Old-style function definitions,
- *                  IsZero() as a macro
- *  Nov 23, 1990    Some systems do not declare acos() and cbrt() in
- *                  <math.h>, though the functions exist in the library.
- *                  If large coefficients are used, EQN_EPS should be
- *                  reduced considerably (e.g. to 1E-30), results will be
- *                  correct but multiple roots might be reported more
- *                  than once.
- */
-
-#include "SkPathOpsCubic.h"
-#include "SkPathOpsQuad.h"
-#include "SkQuarticRoot.h"
-
-int SkReducedQuarticRoots(const double t4, const double t3, const double t2, const double t1,
-        const double t0, const bool oneHint, double roots[4]) {
-#ifdef SK_DEBUG
-    // create a string mathematica understands
-    // GDB set print repe 15 # if repeated digits is a bother
-    //     set print elements 400 # if line doesn't fit
-    char str[1024];
-    sk_bzero(str, sizeof(str));
-    SK_SNPRINTF(str, sizeof(str),
-            "Solve[%1.19g x^4 + %1.19g x^3 + %1.19g x^2 + %1.19g x + %1.19g == 0, x]",
-            t4, t3, t2, t1, t0);
-    SkPathOpsDebug::MathematicaIze(str, sizeof(str));
-#if ONE_OFF_DEBUG && ONE_OFF_DEBUG_MATHEMATICA
-    SkDebugf("%s\n", str);
-#endif
-#endif
-    if (approximately_zero_when_compared_to(t4, t0)  // 0 is one root
-            && approximately_zero_when_compared_to(t4, t1)
-            && approximately_zero_when_compared_to(t4, t2)) {
-        if (approximately_zero_when_compared_to(t3, t0)
-            && approximately_zero_when_compared_to(t3, t1)
-            && approximately_zero_when_compared_to(t3, t2)) {
-            return SkDQuad::RootsReal(t2, t1, t0, roots);
-        }
-        if (approximately_zero_when_compared_to(t4, t3)) {
-            return SkDCubic::RootsReal(t3, t2, t1, t0, roots);
-        }
-    }
-    if ((approximately_zero_when_compared_to(t0, t1) || approximately_zero(t1))  // 0 is one root
-      //      && approximately_zero_when_compared_to(t0, t2)
-            && approximately_zero_when_compared_to(t0, t3)
-            && approximately_zero_when_compared_to(t0, t4)) {
-        int num = SkDCubic::RootsReal(t4, t3, t2, t1, roots);
-        for (int i = 0; i < num; ++i) {
-            if (approximately_zero(roots[i])) {
-                return num;
-            }
-        }
-        roots[num++] = 0;
-        return num;
-    }
-    if (oneHint) {
-        SkASSERT(approximately_zero_double(t4 + t3 + t2 + t1 + t0) ||
-                approximately_zero_when_compared_to(t4 + t3 + t2 + t1 + t0,  // 1 is one root
-                SkTMax(fabs(t4), SkTMax(fabs(t3), SkTMax(fabs(t2), SkTMax(fabs(t1), fabs(t0)))))));
-        // note that -C == A + B + D + E
-        int num = SkDCubic::RootsReal(t4, t4 + t3, -(t1 + t0), -t0, roots);
-        for (int i = 0; i < num; ++i) {
-            if (approximately_equal(roots[i], 1)) {
-                return num;
-            }
-        }
-        roots[num++] = 1;
-        return num;
-    }
-    return -1;
-}
-
-int SkQuarticRootsReal(int firstCubicRoot, const double A, const double B, const double C,
-        const double D, const double E, double s[4]) {
-    double  u, v;
-    /* normal form: x^4 + Ax^3 + Bx^2 + Cx + D = 0 */
-    const double invA = 1 / A;
-    const double a = B * invA;
-    const double b = C * invA;
-    const double c = D * invA;
-    const double d = E * invA;
-    /*  substitute x = y - a/4 to eliminate cubic term:
-    x^4 + px^2 + qx + r = 0 */
-    const double a2 = a * a;
-    const double p = -3 * a2 / 8 + b;
-    const double q = a2 * a / 8 - a * b / 2 + c;
-    const double r = -3 * a2 * a2 / 256 + a2 * b / 16 - a * c / 4 + d;
-    int num;
-    double largest = SkTMax(fabs(p), fabs(q));
-    if (approximately_zero_when_compared_to(r, largest)) {
-    /* no absolute term: y(y^3 + py + q) = 0 */
-        num = SkDCubic::RootsReal(1, 0, p, q, s);
-        s[num++] = 0;
-    } else {
-        /* solve the resolvent cubic ... */
-        double cubicRoots[3];
-        int roots = SkDCubic::RootsReal(1, -p / 2, -r, r * p / 2 - q * q / 8, cubicRoots);
-        int index;
-        /* ... and take one real solution ... */
-        double z;
-        num = 0;
-        int num2 = 0;
-        for (index = firstCubicRoot; index < roots; ++index) {
-            z = cubicRoots[index];
-            /* ... to build two quadric equations */
-            u = z * z - r;
-            v = 2 * z - p;
-            if (approximately_zero_squared(u)) {
-                u = 0;
-            } else if (u > 0) {
-                u = sqrt(u);
-            } else {
-                continue;
-            }
-            if (approximately_zero_squared(v)) {
-                v = 0;
-            } else if (v > 0) {
-                v = sqrt(v);
-            } else {
-                continue;
-            }
-            num = SkDQuad::RootsReal(1, q < 0 ? -v : v, z - u, s);
-            num2 = SkDQuad::RootsReal(1, q < 0 ? v : -v, z + u, s + num);
-            if (!((num | num2) & 1)) {
-                break;  // prefer solutions without single quad roots
-            }
-        }
-        num += num2;
-        if (!num) {
-            return 0;  // no valid cubic root
-        }
-    }
-    /* resubstitute */
-    const double sub = a / 4;
-    for (int i = 0; i < num; ++i) {
-        s[i] -= sub;
-    }
-    // eliminate duplicates
-    for (int i = 0; i < num - 1; ++i) {
-        for (int j = i + 1; j < num; ) {
-            if (AlmostDequalUlps(s[i], s[j])) {
-                if (j < --num) {
-                    s[j] = s[num];
-                }
-            } else {
-                ++j;
-            }
-        }
-    }
-    return num;
-}
diff --git a/src/pathops/SkQuarticRoot.h b/src/pathops/SkQuarticRoot.h
deleted file mode 100644
index 6ce0867..0000000
--- a/src/pathops/SkQuarticRoot.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef SkDQuarticRoot_DEFINED
-#define SkDQuarticRoot_DEFINED
-
-int SkReducedQuarticRoots(const double t4, const double t3, const double t2, const double t1,
-        const double t0, const bool oneHint, double s[4]);
-
-int SkQuarticRootsReal(int firstCubicRoot, const double A, const double B, const double C,
-        const double D, const double E, double s[4]);
-
-#endif
diff --git a/src/pathops/SkReduceOrder.cpp b/src/pathops/SkReduceOrder.cpp
index 6f06447..c19cd3d 100644
--- a/src/pathops/SkReduceOrder.cpp
+++ b/src/pathops/SkReduceOrder.cpp
@@ -272,6 +272,11 @@
 }
 
 SkPath::Verb SkReduceOrder::Cubic(const SkPoint a[4], SkPoint* reducePts) {
+    if (SkDPoint::ApproximatelyEqual(a[0], a[1]) && SkDPoint::ApproximatelyEqual(a[0], a[2])
+            && SkDPoint::ApproximatelyEqual(a[0], a[3])) {
+        reducePts[0] = a[0];
+        return SkPath::kMove_Verb;
+    }
     SkDCubic cubic;
     cubic.set(a);
     SkReduceOrder reducer;
diff --git a/src/pathops/SkReduceOrder.h b/src/pathops/SkReduceOrder.h
index 4ff9a1d..397b58d 100644
--- a/src/pathops/SkReduceOrder.h
+++ b/src/pathops/SkReduceOrder.h
@@ -7,11 +7,9 @@
 #ifndef SkReduceOrder_DEFINED
 #define SkReduceOrder_DEFINED
 
-#include "SkPath.h"
 #include "SkPathOpsCubic.h"
 #include "SkPathOpsLine.h"
 #include "SkPathOpsQuad.h"
-#include "SkTArray.h"
 
 union SkReduceOrder {
     enum Quadratics {
