/** Specified in Node */
 protected Node copy(Node caller) {
   Iterator it = edges.iterator();
   Edge next, e1, e2;
   InnerNode thiscopy = new InnerNode();
   Node tmp;
   while (it.hasNext()) { // Invoke recursively
     next = (Edge) it.next();
     if (next.to != caller) {
       tmp = next.to.copy(this);
       e1 = thiscopy.addNeighbour(tmp);
       e2 = tmp.addNeighbour(thiscopy);
       e1.backedge = e2;
       e2.backedge = e1;
     }
   }
   return thiscopy;
 }
  /** Specified in Node */
  protected Node makeBinary(Collection newedges, Edge[] edgemapping, Node caller) {
    // O(n) each edge is visited 1 time in the first part
    // In the second part an upper bound of the total number
    // of runs through the while-loop is O(n) (number of edges).
    Iterator it = edges.iterator();
    Edge e1, e2, newedge1, newedge2, next;
    InnerNode thiscopy = new InnerNode();
    Node tmp;

    // first part (recursion)
    while (it.hasNext()) { // Invoke recursively    //Like the copy-method
      next = (Edge) it.next();
      if (next.to != caller) {
        tmp = next.to.makeBinary(newedges, edgemapping, this);
        e1 = thiscopy.addNeighbour(tmp);
        e2 = tmp.addNeighbour(thiscopy);
        e1.backedge = e2;
        e2.backedge = e1;
        edgemapping[next.getId()] = e1;
        edgemapping[next.getBackEdge().getId()] = e2;
      }
    }

    // second part (fixing degree with a while-loop)
    while ((thiscopy.edges.size() > 2 && caller != null)
        || thiscopy.edges.size() > 3) { // not binary
      // System.out.println(thiscopy+" has "+thiscopy.edges.size()+" edges");
      it = thiscopy.edges.iterator();
      e1 =
          (Edge)
              it.next(); // 1               //Save two outgoing edges (e1 and e2) for binarification
      if (e1.to == caller) e1 = (Edge) it.next(); // 1 or 2
      it.remove(); // Remove this edge from the edge list, see why below **
      e2 = (Edge) it.next(); // 2 or 3
      if (e2.to == caller)
        e2 =
            (Edge)
                it
                    .next(); // 3  //since edges.size() >=4 I can get three elements out without
                             // problems
      it.remove(); // Remove this edge from the edge list, see why below **

      // e1 and e2 are two outgoing edges that does not lead back to the caller

      InnerNode newnode = new InnerNode(); // Make a new node to attach e1 and e2 to

      newedge1 = thiscopy.addNeighbour(newnode); // attach this node to the new node
      newedge2 = newnode.addNeighbour(thiscopy); // and vice versa
      newedge1.backedge = newedge2;
      newedge2.backedge = newedge1;
      newedges.add(newedge1); // Since these edges are new edges, add them to the collection
      newedges.add(newedge2);

      // Now instead of using removeNeighbour and that stuff, we use a 'hack'. We change the
      // endpoint of the
      // edges between 'e1' and 'thiscopy' to 'e1' and 'newnode', and 'e2' and 'thiscopy' to 'e2'
      // and 'newnode' respectively.
      // This way any new edge already added to the newedges-collection is still valid.

      e1.from = newnode; // change the endpoints
      e2.from = newnode;
      e1.getBackEdge().to = newnode; //
      e2.getBackEdge().to = newnode;

      // now we need to remove e1 and e2 from this nodes edgelist and add them to newnode's edge
      // list, but we
      // already did half of that above **
      newnode.edges.add(e1);
      newnode.edges.add(e2); // the other half well done.

      // For each run of this while-loop one neighbour is added and two are removed, hence it must
      // terminate.
    }

    return thiscopy;
  }