public Renderable removeComponent(Renderable renderable) {
   Renderable target = getTarget(renderable);
   stoichiometries.remove(target);
   if (componentsInHiearchy != null) componentsInHiearchy.remove(renderable);
   if (oldIdToBounds != null) oldIdToBounds.remove(renderable.getID());
   return super.removeComponent(renderable);
 }
 private void recoverOldBounds() {
   // Make sure it is recoverable. If not, just do a simple
   // layout
   if (!isOldBoundsRecoverable()) {
     // Copy any known bounds
     if (oldIdToBounds != null) {
       for (Renderable r : componentsInHiearchy) {
         Rectangle bounds = oldIdToBounds.get(r.getID());
         if (bounds == null) continue;
         if (r.bounds != null) {
           r.bounds.width = bounds.width;
           r.bounds.height = bounds.height;
         } else r.bounds = new Rectangle(bounds);
       }
     }
     // Just do an auto layout. Should start from the smalled complexes
     for (Renderable r : componentsInHiearchy) {
       if (r instanceof RenderableComplex) ((RenderableComplex) r).layout();
     }
     layout();
     return;
   }
   Rectangle oldBounds = oldIdToBounds.get(getID());
   int dx = bounds.x - oldBounds.x;
   int dy = bounds.y - oldBounds.y;
   bounds.width = oldBounds.width;
   bounds.height = oldBounds.height;
   invalidateTextBounds();
   for (Renderable r : componentsInHiearchy) {
     oldBounds = oldIdToBounds.get(r.getID());
     oldBounds.translate(dx, dy);
     Rectangle newBounds = r.getBounds();
     if (newBounds == null) {
       newBounds = new Rectangle(oldBounds);
       r.setBounds(newBounds);
     } else {
       newBounds.x = oldBounds.x;
       newBounds.y = oldBounds.y;
       newBounds.width = oldBounds.width;
       newBounds.height = oldBounds.height;
     }
     ((Node) r).invalidateTextBounds();
   }
 }
 private void saveOldBounds() {
   if (oldIdToBounds == null) oldIdToBounds = new HashMap<Integer, Rectangle>();
   else oldIdToBounds.clear();
   // Save the bounds for this RenderableComplex. This bounds
   // will be used as the reference for future recovering
   oldIdToBounds.put(getID(), new Rectangle(bounds));
   for (Renderable r : componentsInHiearchy) {
     Rectangle rBounds = r.getBounds();
     if (rBounds != null) { // Just in case
       oldIdToBounds.put(r.getID(), new Rectangle(rBounds));
     }
   }
 }
 private boolean isOldBoundsRecoverable() {
   if (oldIdToBounds == null || oldIdToBounds.size() == 0) return false;
   // Make sure all nodes have been registered
   if (componentsInHiearchy == null || componentsInHiearchy.size() == 0) return false;
   for (Renderable r : componentsInHiearchy) {
     if (!oldIdToBounds.containsKey(r.getID())) return false;
   }
   // Check if a complex component has the same size as its container.
   // This may occur when a hidecomponent complex forms a complex with
   // another Node.
   for (Renderable r : componentsInHiearchy) {
     if (!(r instanceof RenderableComplex)) continue;
     RenderableComplex complex = (RenderableComplex) r;
     Rectangle complexBounds = oldIdToBounds.get(complex.getID());
     List<Renderable> list = RenderUtility.getComponentsInHierarchy(complex);
     for (Renderable tmp : list) {
       Rectangle tmpBounds = oldIdToBounds.get(tmp.getID());
       if (tmpBounds.width == complexBounds.width && tmpBounds.height == complexBounds.height)
         return false;
     }
   }
   return true;
 }