Produces a string identifying this half-edge by the point index values of
its tail and head vertices.

@return identifying string
183821
public String getVertexString() {
        if (tail() != null) {
            return "" + tail().index + "-" + head().index;
        } else {
            return "?-" + head().index;
        }
    }
728628
private String toStringIterative() {
		final String PADDING = "                                 ";
		final StringBuilder sb = new StringBuilder();
		int elements_debug_local_recounter = 0;
		Node<K, V> node = null;
		int nodeid = rootIdx;
		int depth = 0;
		stackSlots.clear();
		stackSlots.push(rootIdx); // init seed, root node
		boolean lastIsInternal = !Node.isLeaf(rootIdx);
		while (!stackSlots.isEmpty()) {
			nodeid = stackSlots.pop();
			node = getNode(nodeid);
			if (!node.isLeaf()) {
				for (int i = node.allocated; i >= 0; i--) {
					stackSlots.push(((InternalNode<K, V>) node).childs[i]);
				}
			} else {
				elements_debug_local_recounter += node.allocated;
			}
			// For Indentation
			if (lastIsInternal || !node.isLeaf()) { // Last or Curret are Internal
				depth += (lastIsInternal ? +1 : -1);
			}
			lastIsInternal = !node.isLeaf();
			sb.append(PADDING.substring(0, Math.min(PADDING.length(), Math.max(depth - 1, 0))));
			//
			sb.append(node.toString()).append("\n");
		}

		// Count elements
		sb.append("height=").append(getHeight()).append(" root=").append(rootIdx).append(" low=")
				.append(lowIdx).append(" high=").append(highIdx).append(" elements=").append(elements)
				.append(" recounter=").append(elements_debug_local_recounter);

		return sb.toString();
	}
1203836
public String dot() {
        StringBuilder builder = new StringBuilder();
        builder.append("digraph RegressionTree {\n node [shape=box, style=\"filled, rounded\", color=\"black\", fontname=helvetica];\n edge [fontname=helvetica];\n");

        int n = 0; // number of nodes processed
        Queue<DotNode> queue = new LinkedList<>();
        queue.add(new DotNode(-1, 0, root));

        while (!queue.isEmpty()) {
            // Dequeue a vertex from queue and print it
            DotNode dnode = queue.poll();
            int id = dnode.id;
            int parent = dnode.parent;
            Node node = dnode.node;

            // leaf node
            if (node.trueChild == null && node.falseChild == null) {
                builder.append(String.format(" %d [label=<%.4f>, fillcolor=\"#00000000\", shape=ellipse];\n", id, node.output));
            } else {
                Attribute attr = attributes[node.splitFeature];
                if (attr.getType() == Attribute.Type.NOMINAL) {
                    builder.append(String.format(" %d [label=<%s = %s<br/>nscore = %.4f>, fillcolor=\"#00000000\"];\n", id, attr.getName(), attr.toString(node.splitValue), node.splitScore));
                } else if (attr.getType() == Attribute.Type.NUMERIC) {
                    builder.append(String.format(" %d [label=<%s &le; %.4f<br/>score = %.4f>, fillcolor=\"#00000000\"];\n", id, attr.getName(), node.splitValue, node.splitScore));
                } else {
                    throw new IllegalStateException("Unsupported attribute type: " + attr.getType());
                }
            }

            // add edge
            if (parent >= 0) {
                builder.append(' ').append(parent).append(" -> ").append(id);
                // only draw edge label at top
                if (parent == 0) {
                    if (id == 1) {
                        builder.append(" [labeldistance=2.5, labelangle=45, headlabel=\"True\"]");
                    } else {
                        builder.append(" [labeldistance=2.5, labelangle=-45, headlabel=\"False\"]");
                    }
                }
                builder.append(";\n");
            }

            if (node.trueChild != null) {
                queue.add(new DotNode(id, ++n, node.trueChild));
            }

            if (node.falseChild != null) {
                queue.add(new DotNode(id, ++n, node.falseChild));
            }
        }

        builder.append("}");
        return builder.toString();
    }
1193610
public String toDinString() {
        Optional<String> laenderkennzahl = getLaenderkennzahl();
        return laenderkennzahl.map(s -> s + " " + getVorwahl().substring(1) + " " + getRufnummer()).orElseGet(
                () -> getVorwahl() + " " + getRufnummer());
    }
1072787
public String getInfo() {
		
		String ret = "";
		double[] teDTs = this.getTrajectory().getDTs();
		double[] teCTs = this.getCTs();

		DecimalFormat df = new DecimalFormat("#0.00");
		df.setRoundingMode(RoundingMode.HALF_DOWN);
		ret += this + "\n  Ground envelopes:";
		for (TrajectoryEnvelope te : this.getGroundEnvelopes()) {
			ret += "\n    " + te;
		}
		ret += "\n\nSeq\tDT\tCT\n------------------------------------------\n";
		for (int i = 0; i < teDTs.length; i++) {
			ret += i + "\t" + df.format(teDTs[i]) + " \t" + df.format(teCTs[i]);
			if (i < teDTs.length-1) ret += "\n";
		}
		return ret;
	}
945469
public AtlasEdge getEdgeForLabel(AtlasVertex vertex, String edgeLabel) {
        return getEdgeForLabel(vertex, edgeLabel, AtlasEdgeDirection.OUT);
    }
1117777
public String lineProtocol() {
    StringBuilder sb = new StringBuilder();

    for (Point point : this.points) {
      sb.append(point.lineProtocol(this.precision)).append("\n");
    }
    return sb.toString();
  }
646345
public String str()
  {
    int node = item(0);
    return (node != DTM.NULL) ? getStringFromNode(node).toString() : "";   
  }
967045
public Integer[] getBestPath()
    {
        assert (vertexCount > 2);

        Stack<Integer> stack = new Stack<Integer>();
        int curNode = vertexCount - 1, curIndex = 0;
        QueueElement element;

        element = fromArray[curNode - 1][curIndex].GetFirst();

        stack.push(curNode);
        stack.push(element.from);
        curNode = element.from;

        while (curNode != 0)
        {
            element = fromArray[element.from - 1][element.index].GetFirst();
            stack.push(element.from);
            curNode = element.from;
        }

        return (Integer[]) stack.toArray();
    }
226109
public String getAsSimpleString() {
        String rewardString = "";
        for (Map.Entry<Integer, Float> entry : this.map.entrySet()) {
            Integer dimension = entry.getKey();
            Float reward_value = entry.getValue();
            if (!rewardString.isEmpty())
                rewardString += ",";
            rewardString += dimension + ":" + reward_value;
        }
        return rewardString;
    }
8741
public String graph() {// throws Exception {
        StringBuffer text = new StringBuffer();

        text.append("digraph CobwebTree {\n");
        m_cobwebTree.graphTree(text);
        text.append("}\n");
        return text.toString();
    }
1103356
private Point2D[] getLinkPoints(TwoNotesLink slurDef) {
		if (slurDef.getEnd()==null){
			return new Point2D[] {};
		}
		JNoteElementAbstract elmtStart, elmtEnd;
		elmtStart = (JNoteElementAbstract) getRenditionObjectFor(slurDef.getStart());
		elmtEnd = (JNoteElementAbstract) getRenditionObjectFor(slurDef.getEnd());
		if (elmtStart == null || elmtStart == null) {
			System.err.println("getLinkPoints error: elmtStart or elmtEnd are null");
			return new Point2D[] {};
		}
		
		if ((elmtStart.getStaffLine() != null) && (elmtEnd.getStaffLine() != null)) {
			if (!elmtStart.getStaffLine().equals(elmtEnd.getStaffLine())) {
				System.err.println("Warning - abc4j limitation : Slurs / ties cannot be drawn accross several lines for now.");
				return new Point2D[] {};
			}
		}
		final short UNDER_IN = 0; //the only existing in old abc4j
		final short UNDER_OUT = 1; //down and out of stems
		final short ABOVE_IN = 2; //up and can go across the stems
		final short ABOVE_OUT = 3; //up and out of stems (e.g. for tuplet)
		Point2D[][] p = new Point2D[4][3];

		//it's a tie, anchors are different and curve is flater
		if (slurDef instanceof TieDefinition) {
			Point2D[] above = new Point2D[3];
			Point2D[] under = new Point2D[3];
			Point2D[] ret;
			above[START] = elmtStart.getTieStartAboveAnchor();
			above[END] = elmtEnd.getTieEndAboveAnchor();
			under[START] = elmtStart.getTieStartUnderAnchor();
			under[END] = elmtEnd.getTieEndUnderAnchor();
		
			short position = elmtStart.getJSlurDefinition().getPosition();
			if (position==JSlurOrTie.POSITION_AUTO
				&& (elmtStart instanceof JChordNote)) {
				if (elmtStart.isStemUp()) {
					//in a chord stem up, all ties are under
					//the highest note tie is above
					position = ((JChordNote) elmtStart).isHighest()
						?JSlurOrTie.POSITION_ABOVE
						:JSlurOrTie.POSITION_UNDER;
				} else {
					//in a chord stem down, all ties are above
					//the lowest note tie is under
					position = ((JChordNote) elmtStart).isLowest()
						?JSlurOrTie.POSITION_UNDER
						:JSlurOrTie.POSITION_ABOVE;
				}
			}
			int factor;
			if ((position==JSlurOrTie.POSITION_ABOVE)
				|| (position==JSlurOrTie.POSITION_AUTO
						&& (!elmtStart.isStemUp() || !elmtEnd.isStemUp()))) {
				//tie above
				ret = above;
				factor = -1;
			} else {// if ((position==JSlurOrTie.POSITION_UNDER)
					//|| (position==JSlurOrTie.POSITION_AUTO
					//		&& elmtStart.isStemUp() && elmtEnd.isStemUp())) {
				//tie under
				ret = under;
				factor = 1;
			}
			ret[CONTROL] = new Point2D.Double(
					ret[START].getX() + (ret[END].getX()-ret[START].getX())/2,
					ret[START].getY() + factor*getMetrics().getSlurAnchorYOffset()
				);
			return ret;
		}
		
		p[UNDER_IN][START] = elmtStart.getSlurUnderAnchor();
		p[UNDER_OUT][START] = elmtStart.getSlurUnderAnchorOutOfStem();
		p[ABOVE_IN][START] = elmtStart.getSlurAboveAnchor();
		p[ABOVE_OUT][START] = elmtStart.getSlurAboveAnchorOutOfStem();
		p[UNDER_IN][END] = elmtEnd.getSlurUnderAnchor();
		p[UNDER_OUT][END] = elmtEnd.getSlurUnderAnchorOutOfStem();
		p[ABOVE_IN][END] = elmtEnd.getSlurAboveAnchor();
		p[ABOVE_OUT][END] = elmtEnd.getSlurAboveAnchorOutOfStem();

		//
		//determinate peaks (lowest/highest) note and note glyph
		// FIXME: ties should enclose note decorations
		//
		NoteAbstract[] peakNote = new NoteAbstract[4];
		JNoteElementAbstract[] peakNoteGlyph = new JNoteElementAbstract[4];

		NoteAbstract startNote =// (NoteAbstract) m_music.getElementByReference(slurDef.getStart());
			(NoteAbstract) elmtStart.getMusicElement();
		NoteAbstract endNote =// (NoteAbstract) m_music.getElementByReference(slurDef.getEnd());
			(NoteAbstract) elmtEnd.getMusicElement();
		String voiceNo = startNote.getReference().getVoice();
		//under in
		peakNote[UNDER_IN] = m_music.getVoice(voiceNo).getLowestNoteBewteen(startNote, endNote);
		peakNoteGlyph[UNDER_IN] = (JNoteElementAbstract) getRenditionObjectFor(peakNote[UNDER_IN]);
		
		//under out of stems
		peakNoteGlyph[UNDER_OUT] = getLowestNoteGlyphBetween(startNote, endNote, true);
		//enhance: if lowest glyph strictly between start/end is at same Y than start or end
		if (peakNoteGlyph[UNDER_OUT] == null) { //no notes between start and end
			peakNoteGlyph[UNDER_OUT] = p[UNDER_OUT][START].getY()>p[UNDER_OUT][END].getY()
				?elmtStart:elmtEnd; //Low
		} else {
			Point2D lowAnchor = peakNoteGlyph[UNDER_OUT].getSlurUnderAnchorOutOfStem();
			if (lowAnchor.getY() < p[UNDER_OUT][START].getY())
				peakNoteGlyph[UNDER_OUT] = elmtStart;//Low;
			if (lowAnchor.getY() < p[UNDER_OUT][END].getY())
				peakNoteGlyph[UNDER_OUT] = elmtEnd;//Low;
		}
		peakNote[UNDER_OUT] = (NoteAbstract) peakNoteGlyph[UNDER_OUT].getMusicElement();

		//above in
		peakNote[ABOVE_IN] = m_music.getVoice(voiceNo).getHighestNoteBewteen(startNote, endNote);
		peakNoteGlyph[ABOVE_IN] = (JNoteElementAbstract)getRenditionObjectFor(peakNote[ABOVE_IN]);

		//above out of stems (e.g. tuplet)
		peakNoteGlyph[ABOVE_OUT] = getHighestNoteGlyphBetween(startNote, endNote, true);
		//enhance: if lowest glyph strictly between start/end is at same Y than start or end
		if (peakNoteGlyph[ABOVE_OUT] == null) { //no notes between start and end
			peakNoteGlyph[ABOVE_OUT] = p[ABOVE_OUT][START].getY()<p[ABOVE_OUT][END].getY()
				?elmtStart:elmtEnd;//High
		} else {
			Point2D highAnchor = peakNoteGlyph[ABOVE_OUT].getSlurAboveAnchorOutOfStem();
			if (highAnchor.getY() > p[ABOVE_OUT][START].getY())
				peakNoteGlyph[ABOVE_OUT] = elmtStart;//High
			if (highAnchor.getY() > p[ABOVE_OUT][END].getY())
				peakNoteGlyph[ABOVE_OUT] = elmtEnd;//High
		}
		peakNote[ABOVE_OUT] = (NoteAbstract) peakNoteGlyph[ABOVE_OUT].getMusicElement();

		//
		//if peak=start then control=start
		//if peak=end then control=end
		//else control=peak
		//
		for (short i = 0; i < 4; i++) {
			int factor = (i<=UNDER_OUT)?(1):(-1);
			if (peakNote[i].getReference().equals(slurDef.getStart())) {
				p[i][CONTROL] = new Point2D.Double(
					p[i][START].getX() + (p[i][END].getX()-p[i][START].getX())/2,
					p[i][START].getY() + factor*getMetrics().getSlurAnchorYOffset()
				);
			}
			else if (peakNote[i].getReference().equals(slurDef.getEnd())) {
				p[i][CONTROL] = new Point2D.Double(
					p[i][START].getX() + (p[i][END].getX()-p[i][START].getX())/2,
					p[i][END].getY() + factor*getMetrics().getSlurAnchorYOffset()
				);
			}
			else { //control=peak
				switch(i) {
				case UNDER_IN: p[i][CONTROL]=peakNoteGlyph[UNDER_IN].getSlurUnderAnchor();break;
				case UNDER_OUT: p[i][CONTROL]=peakNoteGlyph[UNDER_OUT].getSlurUnderAnchorOutOfStem();break;
				case ABOVE_IN: p[i][CONTROL]=peakNoteGlyph[ABOVE_IN].getSlurAboveAnchor();break;
				case ABOVE_OUT: p[i][CONTROL]=peakNoteGlyph[ABOVE_OUT].getSlurAboveAnchorOutOfStem();break;
				}
			}

			//we don't like straight slurs, if Ystart=Ycontrol=Yend, Ycontrol+=slurOffset
			double Ycontrol = p[i][CONTROL].getY(),
					Ystart = p[i][START].getY(),
					Yend = p[i][END].getY();
			if ((Ycontrol == Ystart) || (Ycontrol == Yend)) {
				double Xoffset = 0;
				if (Ycontrol != Ystart) Xoffset = -getMetrics().getNoteWidth()/2;
				else if (Ycontrol != Yend) Xoffset = getMetrics().getNoteWidth()/2;
				p[i][CONTROL] = new Point2D.Double(
					p[i][CONTROL].getX() + Xoffset,
					p[i][CONTROL].getY() + factor*getMetrics().getSlurAnchorYOffset()*2);
			}
		}

		//
		//Now the funny part, determinate which curve is the best
		//
		//Point2D[] ret = null;
		Vector curves = new Vector(); //Combinaison to compare
		JSlurOrTie jSlurDef = getJSlurOrTie(slurDef);
		if (!jSlurDef.isOutOfStems()) { //we can add all curves
			Vector underCurves = new Vector(), aboveCurves = new Vector();
			if (!jSlurDef.isAbove()) { //down or auto
				curves.add(p[UNDER_IN]);
				underCurves.add(new Point2D[] {p[UNDER_IN][START],p[UNDER_IN][CONTROL],p[UNDER_OUT][END]});
				underCurves.add(new Point2D[] {p[UNDER_IN][START],p[UNDER_OUT][CONTROL],p[UNDER_IN][END]});
				underCurves.add(new Point2D[] {p[UNDER_IN][START],p[UNDER_OUT][CONTROL],p[UNDER_OUT][END]});
				underCurves.add(new Point2D[] {p[UNDER_OUT][START],p[UNDER_IN][CONTROL],p[UNDER_IN][END]});
				underCurves.add(new Point2D[] {p[UNDER_OUT][START],p[UNDER_IN][CONTROL],p[UNDER_OUT][END]});
				underCurves.add(new Point2D[] {p[UNDER_OUT][START],p[UNDER_OUT][CONTROL],p[UNDER_IN][END]});
			}
			if (!jSlurDef.isUnder()) { //up or auto
				curves.add(p[ABOVE_IN]);
				aboveCurves.add(new Point2D[] {p[ABOVE_IN][START],p[ABOVE_IN][CONTROL],p[ABOVE_OUT][END]});
				aboveCurves.add(new Point2D[] {p[ABOVE_IN][START],p[ABOVE_OUT][CONTROL],p[ABOVE_IN][END]});
				aboveCurves.add(new Point2D[] {p[ABOVE_IN][START],p[ABOVE_OUT][CONTROL],p[ABOVE_OUT][END]});
				aboveCurves.add(new Point2D[] {p[ABOVE_OUT][START],p[ABOVE_IN][CONTROL],p[ABOVE_IN][END]});
				aboveCurves.add(new Point2D[] {p[ABOVE_OUT][START],p[ABOVE_IN][CONTROL],p[ABOVE_OUT][END]});
				aboveCurves.add(new Point2D[] {p[ABOVE_OUT][START],p[ABOVE_OUT][CONTROL],p[ABOVE_IN][END]});
			}
			//verify above and under curves must be above / under
            for (Object aboveCurve : aboveCurves) {
                Point2D[] p2d = (Point2D[]) aboveCurve;
                if ((p2d[CONTROL].getY() < p2d[START].getY())
                        && (p2d[CONTROL].getY() < p2d[END].getY()))
                    curves.add(p2d);
            }
            for (Object underCurve : underCurves) {
                Point2D[] p2d = (Point2D[]) underCurve;
                if ((p2d[CONTROL].getY() > p2d[START].getY())
                        && (p2d[CONTROL].getY() > p2d[END].getY()))
                    curves.add(p2d);
            }
		}
		//Out of stems
		if (!jSlurDef.isAbove()) //under or auto
			curves.add(p[UNDER_OUT]);
		if (!jSlurDef.isUnder()) //above or auto
			curves.add(p[ABOVE_OUT]);


		//
		//Correct controlPoint (center it) if the curve gets ugly
		//(something like a little nose lefter/righter than min/maxX
		//and compute a mark to determinate best curve
		//
		//vector for newly generated curves
		Vector additionnalCurves = new Vector();
		Point2D[] bestCurve = null;
		float bestMark = -99;
		//int cpt = 0; int bestCurveIdx = -1;
		for (Iterator itCurves = curves.iterator(); itCurves.hasNext();) {
			Point2D[] p2d = (Point2D[]) itCurves.next();
			//System.out.print((cpt++) + " : ");

			try {
				SlurInfos slurInfos = new SlurInfos(p2d,
					getNoteGlyphesBetween(startNote, endNote),
					getMetrics());

				//Check results
				//If some intersections, try to draw a new curve
				//by moving the control point
				if (slurInfos.intersect > 0) {
					Point2D newPtControl;
					double yOffset = getMetrics().getNoteHeight();
					double xOffset = getMetrics().getNoteWidth();
					int yFactor = slurInfos.isAbove?-1:1;
					double distanceControlEnd = p2d[END].getX()-p2d[CONTROL].getX();
					double distanceControlStart = p2d[CONTROL].getX()-p2d[START].getX();
					int xFactor = 0;
					if (distanceControlEnd < distanceControlStart)
						xFactor = -1;
					else if (distanceControlEnd > distanceControlStart)
						xFactor = 1;
					for (float xO = 0f; xO <= 1; xO += .25f) {
						for (float yO = .5f; yO <= 2f; yO += .25f) {
							//move X note width, Y*factor note height
							newPtControl = new Point2D.Double(
									p2d[CONTROL].getX()+xO*xFactor*xOffset,
									p2d[CONTROL].getY()+yO*yFactor*yOffset);
							additionnalCurves.add(new Point2D[] {p2d[START],newPtControl,p2d[END]});
						}
					}
//					//move Y=1 note height
//					newPtControl = new Point2D.Double(p2d[CONTROL].getX(),
//							p2d[CONTROL].getY()+factor*yOffset);
//					additionnalCurves.add(new Point2D[] {p2d[START],newPtControl,p2d[END]});
//					//move Y=1.5 note height
//					newPtControl = new Point2D.Double(p2d[CONTROL].getX(),
//							p2d[CONTROL].getY()+1.5*factor*yOffset);
//					additionnalCurves.add(new Point2D[] {p2d[START],newPtControl,p2d[END]});
//					//move Y=2 note height
//					newPtControl = new Point2D.Double(p2d[CONTROL].getX(),
//							p2d[CONTROL].getY()+2*factor*yOffset);
//					additionnalCurves.add(new Point2D[] {p2d[START],newPtControl,p2d[END]});
				}

				//TODO if flatness is high, away start/end position from original
				//(distance allowed = nb notes*m_metrics.getNoteHeight)

				if (slurInfos.mark>bestMark || (bestCurve==null)) {
					bestMark = slurInfos.mark;
					bestCurve = p2d;
					//bestCurveIdx = cpt-1;
				}
			} catch (MalFormedCurveException mfce) {
				//not good curve, remove it
				if (curves.size() > 1) {
					itCurves.remove();
                } else {
					break;
				}
			}
		}

		//Checks additional curves
        for (Object additionnalCurve : additionnalCurves) {
            Point2D[] p2d = (Point2D[]) additionnalCurve;
            //System.out.print((cpt++) + " : ");
            try {
                SlurInfos slurInfos = new SlurInfos(p2d,
                        getNoteGlyphesBetween(startNote, endNote),
                        getMetrics());
                if (slurInfos.mark > bestMark || (bestCurve == null)) {
                    bestMark = slurInfos.mark;
                    bestCurve = p2d;
                    //bestComboIdx = cpt-1;
                }
                curves.add(p2d);
            } catch (MalFormedCurveException mfce) {
                //nothing to do
            }
        }

		//System.out.println("curves.size()="+curves.size());
		//System.out.println("best curve n� "+bestCurveIdx+", mark="+bestMark);
		return bestCurve!=null
				? bestCurve
				: (curves.size()==0 ? new Point2D[] {} : (Point2D[]) curves.get(0));
	}
793487
public HalfEdge findEdge(Vertex vt, Vertex vh) {
        HalfEdge he = he0;
        do {
            if (he.head() == vh && he.tail() == vt) {
                return he;
            }
            he = he.next;
        } while (he != he0);
        return null;
    }
1251537
public String toWKT() {
        StringBuffer sb = new StringBuffer();
        sb.append("POLYGON (");

        boolean isFirstLoop = true;
        for (List<XYZPoint> loop : m_loops) {
            if (!isFirstLoop) {
                sb.append(", ");
            }

            sb.append("(");
            int startIdx = (isFirstLoop ? 1 : loop.size()-1);
            int endIdx = (isFirstLoop ? loop.size() : 0);
            int increment = (isFirstLoop ? 1 : -1);
            sb.append(loop.get(0).toGeographyPointValue().formatLngLat()).append(", ");
            for (int idx = startIdx; idx != endIdx; idx += increment) {
                XYZPoint xyz = loop.get(idx);
                sb.append(xyz.toGeographyPointValue().formatLngLat());
                sb.append(", ");
            }

            // Repeat the start vertex to close the loop as WKT requires.
            sb.append(loop.get(0).toGeographyPointValue().formatLngLat());
            sb.append(")");
            isFirstLoop = false;
        }

        sb.append(")");
        return sb.toString();
    }
985995
def format_edges_section(self):
        
        buf = io.StringIO()
        buf.write('edges\n')
        buf.write('(\n')
        for e in self.edges.values():
            buf.write('  ' + e.format(self.vertices) + '\n')
        buf.write(');')
        return buf.getvalue()
382600
public int getThisTaskIndex() {
    List<Integer> allTasks = getComponentTasks(getThisComponentId());
    int retVal = 0;
    for (Integer tsk : allTasks) {
      if (tsk < myTaskId) {
        retVal++;
      }
    }
    return retVal;
  }
726936
public static String deidentifyEdge(String str, int start, int end) {
		return deidentifyLeft(deidentifyRight(str, end), start);
	}