long getReturnTime(GraphObject to) {
   for (GraphLink lnk : out_links) {
     if (lnk.getType() == LinkType.RETURN) {
       GraphObject go = lnk.getToObject();
       if (go == to) return lnk.getTime();
       else {
         long rt = go.getReturnTime(to);
         if (rt != 0) return Math.min(lnk.getTime(), rt);
       }
     }
   }
   return 0;
 }
  private void drawLinks(Graphics2D g, GraphObject go) {
    double x0 = graph_locations.get(go);

    for (GraphLink gl : go.getLinks()) {
      GraphObject got = gl.getToObject();
      double x1 = graph_locations.get(got);
      double y0 = getTimeY(gl.getTime());
      double x3, x4;
      if (x0 < x1) {
        x3 = x0 + active_width / 2;
        x4 = x1 - active_width / 2;
      } else {
        x3 = x0 - active_width / 2;
        x4 = x1 + active_width / 2;
      }
      Stroke sk = type_strokes.get(gl.getType());
      Color c = getThreadBlockColor(gl.getThread());
      g.setColor(c);
      g.setStroke(sk);
      Line2D ln = new Line2D.Double(x3, y0, x4, y0);
      g.draw(ln);
      drawArrow(g, x3, y0, x4, y0);
    }
  }