private int checkEdgeCrossings(S2Loop b, S2EdgeUtil.WedgeRelation relation) {
    DataEdgeIterator it = getEdgeIterator(b.numVertices);
    int result = 1;
    // since 'this' usually has many more vertices than 'b', use the index on
    // 'this' and loop over 'b'
    for (int j = 0; j < b.numVertices(); ++j) {
      S2EdgeUtil.EdgeCrosser crosser =
        new S2EdgeUtil.EdgeCrosser(b.vertex(j), b.vertex(j + 1), vertex(0));
      int previousIndex = -2;
      for (it.getCandidates(b.vertex(j), b.vertex(j + 1)); it.hasNext(); it.next()) {
        int i = it.index();
        if (previousIndex != i - 1) {
          crosser.restartAt(vertex(i));
        }
        previousIndex = i;
        int crossing = crosser.robustCrossing(vertex(i + 1));
        if (crossing < 0) {
          continue;
        }
        if (crossing > 0) {
          return -1; // There is a proper edge crossing.
        }
        if (vertex(i + 1).equals(b.vertex(j + 1))) {
          result = Math.min(result, relation.test(
              vertex(i), vertex(i + 1), vertex(i + 2), b.vertex(j), b.vertex(j + 2)));
          if (result < 0) {
            return result;
          }
        }
      }
    }
    return result;
  }