void removeBreakpoint(Breakpoint breakpoint) {
   String templateName = breakpoint.getTemplateName();
   synchronized (templateDebugInfos) {
     TemplateDebugInfo tdi = findTemplateDebugInfo(templateName);
     if (tdi != null) {
       List breakpoints = tdi.breakpoints;
       int pos = Collections.binarySearch(breakpoints, breakpoint);
       if (pos >= 0) {
         breakpoints.remove(pos);
         for (Iterator iter = tdi.templates.iterator(); iter.hasNext(); ) {
           TemplateReference ref = (TemplateReference) iter.next();
           Template t = ref.getTemplate();
           if (t == null) {
             iter.remove();
           } else {
             removeDebugBreak(t, breakpoint);
           }
         }
       }
       if (tdi.isEmpty()) {
         templateDebugInfos.remove(templateName);
       }
     }
   }
 }
 private static void insertDebugBreak(Template t, Breakpoint breakpoint) {
   TemplateElement te = findTemplateElement(t.getRootTreeNode(), breakpoint.getLine());
   if (te == null) {
     return;
   }
   TemplateElement parent = (TemplateElement) te.getParent();
   DebugBreak db = new DebugBreak(te);
   // TODO: Ensure there always is a parent by making sure
   // that the root element in the template is always a MixedContent
   // Also make sure it doesn't conflict with anyone's code.
   parent.setChildAt(parent.getIndex(te), db);
 }
 private void removeDebugBreak(Template t, Breakpoint breakpoint) {
   TemplateElement te = findTemplateElement(t.getRootTreeNode(), breakpoint.getLine());
   if (te == null) {
     return;
   }
   DebugBreak db = null;
   while (te != null) {
     if (te instanceof DebugBreak) {
       db = (DebugBreak) te;
       break;
     }
     te = (TemplateElement) te.getParent();
   }
   if (db == null) {
     return;
   }
   TemplateElement parent = (TemplateElement) db.getParent();
   parent.setChildAt(parent.getIndex(db), (TemplateElement) db.getChildAt(0));
 }
 void addBreakpoint(Breakpoint breakpoint) {
   String templateName = breakpoint.getTemplateName();
   synchronized (templateDebugInfos) {
     TemplateDebugInfo tdi = createTemplateDebugInfo(templateName);
     List breakpoints = tdi.breakpoints;
     int pos = Collections.binarySearch(breakpoints, breakpoint);
     if (pos < 0) {
       // Add to the list of breakpoints
       breakpoints.add(-pos - 1, breakpoint);
       // Inject the breakpoint into all templates with this name
       for (Iterator iter = tdi.templates.iterator(); iter.hasNext(); ) {
         TemplateReference ref = (TemplateReference) iter.next();
         Template t = ref.getTemplate();
         if (t == null) {
           iter.remove();
         } else {
           insertDebugBreak(t, breakpoint);
         }
       }
     }
   }
 }