private void outputEntry(TraceEntry te) {
    ThreadData td = te.getThread();
    if (td == null) return;

    // System.err.println("TRACE: " + te);

    BdynCallback cb = bdyn_factory.getCallback(te.getEntryLocation());
    if (cb == null) return;

    if (cb.getCallbackType() == CallbackType.CONSTRUCTOR) {
      OutputTask ot = td.getCurrentTransaction();
      if (ot == null) return;
      if (ot.isMainTask() && !BdynFactory.getOptions().useMainTask()) return;
      int i0 = te.getObject1();
      if (i0 != 0) {
        // System.err.println("ASSOC TASK " + i0 + " " + te.getObject2() + " " +
        // ot.getTaskRoot().getDisplayName());
        OutputTask ot1 = object_tasks.get(i0);
        if (ot1 == null) object_tasks.put(i0, ot);
        else if (ot1 != dummy_task && ot1 != ot) object_tasks.put(i0, dummy_task);
      }
      return;
    }

    td.beginTask(te);
    end_time = Math.max(end_time, te.getTime());
  }
 @Override
 public int compareTo(OutputEntry e) {
   long dl = start_time - e.start_time;
   if (dl < 0) return -1;
   if (dl > 0) return 1;
   dl = finish_time - e.finish_time;
   if (dl < 0) return -1;
   if (dl > 0) return 1;
   int idl = entry_thread.getOutputId() - e.entry_thread.getOutputId();
   if (idl < 0) return -1;
   if (idl > 0) return 1;
   return 0;
 }
 @Override
 public String toString() {
   StringBuffer buf = new StringBuffer();
   buf.append(entry_loc);
   if (is_exit) buf.append("^");
   buf.append(" ");
   buf.append(entry_time);
   buf.append(" ");
   buf.append(entry_thread.getOutputId());
   buf.append(" ");
   buf.append(entry_o1);
   buf.append(" ");
   buf.append(entry_o2);
   return buf.toString();
 }
 @Override
 public int compareTo(ThreadData td) {
   return getThreadName().compareTo(td.getThreadName());
 }