/** ***************************************************************************** */
  void handleUpdate(Element ep) {
    String reason = IvyXml.getAttrString(ep, "REASON");

    List<BumpBreakImpl> rem = new ArrayList<BumpBreakImpl>();
    List<BumpBreakImpl> add = new ArrayList<BumpBreakImpl>();
    List<BumpBreakImpl> upd = new ArrayList<BumpBreakImpl>();

    synchronized (current_breakpoints) {
      for (Element be : IvyXml.children(ep, "BREAKPOINT")) {
        String id = IvyXml.getAttrString(be, "ID");
        if (reason.equals("REMOVE")) {
          BumpBreakImpl bbi = current_breakpoints.remove(id);
          if (bbi != null) rem.add(bbi);
        } else {
          BumpBreakImpl bbi = current_breakpoints.get(id);
          if (bbi != null) {
            if (bbi.update(be)) upd.add(bbi);
          } else {
            bbi = new BumpBreakImpl(be);
            current_breakpoints.put(id, bbi);
            add.add(bbi);
          }
        }
      }
    }

    for (Map.Entry<BumpBreakpointHandler, File> ent : break_handlers.entrySet()) {
      BumpBreakpointHandler hdlr = ent.getKey();
      File f = ent.getValue();
      for (BumpBreakImpl bbi : rem) {
        if (fileMatch(f, bbi)) hdlr.handleBreakpointRemoved(bbi);
      }
      for (BumpBreakImpl bbi : add) {
        if (fileMatch(f, bbi)) hdlr.handleBreakpointAdded(bbi);
      }
      for (BumpBreakImpl bbi : upd) {
        if (fileMatch(f, bbi)) hdlr.handleBreakpointChanged(bbi);
      }
    }
  }
 /** ***************************************************************************** */
 private boolean fileMatch(File forfile, BumpBreakImpl bp) {
   if (forfile == null) return true;
   return forfile.equals(bp.getFile());
 }