private S2Loop assembleLoop(S2Point v0,S2Point v1,List<S2Edge> unusedEdges){
  List<S2Point> path=Lists.newArrayList();
  Map<S2Point,Integer> index=Maps.newHashMap();
  path.add(v0);
  path.add(v1);
  index.put(v1,1);
  while (path.size() >= 2) {
    v0=path.get(path.size() - 2);
    v1=path.get(path.size() - 1);
    S2Point v2=null;
    boolean v2Found=false;
    Multiset<S2Point> vset=edges.get(v1);
    if (vset != null) {
      for (      S2Point v : vset) {
        if (v.equals(v0)) {
          continue;
        }
        if (!v2Found || S2.orderedCCW(v0,v2,v,v1)) {
          v2=v;
        }
        v2Found=true;
      }
    }
    if (!v2Found) {
      unusedEdges.add(new S2Edge(v0,v1));
      eraseEdge(v0,v1);
      index.remove(v1);
      path.remove(path.size() - 1);
    }
 else     if (index.get(v2) == null) {
      index.put(v2,path.size());
      path.add(v2);
    }
 else {
      path=path.subList(index.get(v2),path.size());
      if (options.getValidate() && !S2Loop.isValid(path)) {
        rejectLoop(path,path.size(),unusedEdges);
        eraseLoop(path,path.size());
        return null;
      }
      return new S2Loop(path);
    }
  }
  return null;
}

private S2Loop assembleLoop ( S2Point v0 , S2Point v1 , List < S2Edge > unusedEdges ) { List < S2Point > path = Lists . newArrayList ( ) ; Map < S2Point , Integer > index = Maps . newHashMap ( ) ; path . add ( v0 ) ; path . add ( v1 ) ; index . put ( v1 , 1 ) ; while ( path . size ( ) >= 2 ) { v0 = path . get ( path . size ( ) - 2 ) ; v1 = path . get ( path . size ( ) - 1 ) ; S2Point v2 = null ; boolean v2Found = false ; Multiset < S2Point > vset = edges . get ( v1 ) ; if ( vset != null ) { for ( S2Point v : vset ) { if ( v . equals ( v0 ) ) { continue ; } if ( ! v2Found || S2 . orderedCCW ( v0 , v2 , v , v1 ) ) { v2 = v ; } v2Found = true ; } } if ( ! v2Found ) { unusedEdges . add ( new S2Edge ( v0 , v1 ) ) ; eraseEdge ( v0 , v1 ) ; index . remove ( v1 ) ; path . remove ( path . size ( ) - 1 ) ; } else if ( index . get ( v2 ) == null ) { index . put ( v2 , path . size ( ) ) ; path . add ( v2 ) ; } else { path = path . subList ( index . get ( v2 ) , path . size ( ) ) ; if ( options . getValidate ( ) && ! S2Loop . isValid ( path ) ) { rejectLoop ( path , path . size ( ) , unusedEdges ) ; eraseLoop ( path , path . size ( ) ) ; return null ; } return new S2Loop ( path ) ; } } return null ; }
we start at the given edge and assemble a loop taking left turns whenever possible . we stop the loop as soon as we encounter any vertex that we have seen before * except * for the first vertex ( v0 ) . this ensures that only ccw loops are constructed when possible .
