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 void removeBreakpoints(TemplateDebugInfo tdi) {
   tdi.breakpoints.clear();
   for (Iterator iter = tdi.templates.iterator(); iter.hasNext(); ) {
     TemplateReference ref = (TemplateReference) iter.next();
     Template t = ref.getTemplate();
     if (t == null) {
       iter.remove();
     } else {
       removeDebugBreaks(t.getRootTreeNode());
     }
   }
 }
 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);
         }
       }
     }
   }
 }