gt:         Collection<Subset> subsets = new ArrayList<Subset>();
context: package edu.mit.blocks.workspace;
  
  import java.awt.BorderLayout;
  import java.awt.Color;
  import java.awt.Container;
  import java.awt.Dimension;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.awt.event.ComponentEvent;
  import java.awt.event.ComponentListener;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.HashSet;
  import java.util.List;
  
  import javax.swing.JComponent;
  import javax.swing.JPanel;
  
  import edu.mit.blocks.codeblocks.Block;
  import edu.mit.blocks.codeblocks.BlockStub;
  import edu.mit.blocks.codeblockutil.CBorderlessButton;
  import edu.mit.blocks.codeblockutil.CLabel;
  import edu.mit.blocks.codeblockutil.Canvas;
  import edu.mit.blocks.codeblockutil.Navigator;
  import edu.mit.blocks.renderable.FactoryRenderableBlock;
  import edu.mit.blocks.renderable.RenderableBlock;
  
  /**
   * ***********************OVERVIEW**************************
   * The FactoryManager manages all block factories in the workspace.
   * It has three main functions:  to control and display all factories
   * in one simple UI design, to manage the additions of new drawers,
   * and to add blocks to throse drawers appropriately.
   * 
   * The FactoryManager manages two factories: the static factory
   * and dynamic factory.  Each factory has a set of drawers.  NO TWO
   * DRAWERS WITHIN ANY FACTORY MAY SHARE the same name.
   * 
   * ********************FACTORY STRUCTURE***********************
   * 
   * Let's take a look into the stucture of a factory.  Factory is
   * a pallete that sits on the far left side of the workspace.
   * It has a bunch of drawers that slides up and down.  Each
   * drawer contains a bunch of related blocks that can be dragged
   * out.
   * 
   * The FactoryManager has two types of drawers: static and dynamic.
   * To add, remove, rename, drawers of either type, users should
   * invoke the name that specifies a particular drawer. Users
   * may also add blocks to the drawers or retrieve the set of blocks
   * that each drawer holds.
   * 
   * *************IMPLEMENTATION DETAIL******************
   * 
   * How the FactoryManager implements this UI is implementation
   * dependant.  Right now, it uses the Navigator-Explorer-Canvas deisgn.
   * Clients of the FactoryManager should know nothing about the
   * internal GUIs used to control the interface.  Internally,
   * a Canvas (rahter than an instance of Drawer) is created for every
   * "drawer" that the user wishes to add.  But this is an implementation
   * detail that the user should not be bothered with.  All the user should
   * know is that a "drawer" specified by some String object was created.
   * The handling of the drawers themselves are dealt with internally.
   * In a previous design of the factories, developers had to create
   * instance of Drawers and pass them along to the the factories.
   * In the NEW design, we remove that burden from the developer and allow the
   * developer to access drawers by calling its name only.  This may
   * limit extensibility but keeps the system more robust.
   * 
   * *********************A WORD ON DRAWER**********************
   * Please note that the word "drawer" as it is used by the
   * FactoryManager refers to the object that holds blocks.
   * A factory holds a bunch of drawers, which in turn holds
   * a bunch of blocks.
   * 
   * Please do not mix this definition with the CSwing Drawer class.
   * A CSwing Drawer is a low-level component that is used
   * in a CSwing Exlorer.  Here, when the documentation refers
   * to drawers, it is NOT refering to the CSwing Drawer.  Rather,
   * when we say "drawer", we are referign to that object that holds blocks.
   * 
   * *****************NAMING OF DRAWERS*************************
   * Each factory may have only ONE drawer with a particular name.
   * Two different factories may NOT share a name.   If we have
   * a static drawer named "FOO", we may not have another drawer named
   * "FOO" in the dynamic drawers.
   * 
   * @author An Ho
   *
   */
  public class FactoryManager implements WorkspaceWidget, ComponentListener, WorkspaceListener {
  
      /** The string identifier of static drawers */
      private static final String STATIC_NAME = "Factory";
      /** The string identifier of dynamic drawers */
      private static final String DYNAMIC_NAME = "My Blocks";
      /** The string identifier of subset drawers */
      private static final String SUBSETS_NAME = "Subsets";
      /** The high-level UI that manages the controlling of internal CWsing components */
      private Navigator navigator;
      /** The high-level UI widget that manages swicthing between different factories */
      private JComponent factorySwicther;
      /** the set os static drawers */
      private List<FactoryCanvas> staticCanvases;
      /** The set of dynaic drawers */
      private List<FactoryCanvas> dynamicCanvases;
      /** The set of subset drawers */
      private List<FactoryCanvas> subsetCanvases;
      /** The workspace in use */
      private final Workspace workspace;
  
      /**
       * Constucts new Factorymanager
       */
      public FactoryManager(Workspace workspace) {
          this.workspace = workspace;
          this.navigator = new Navigator(workspace);
          this.navigator.getJComponent().setPreferredSize(new Dimension(160, 600));
          this.navigator.addExlorer(STATIC_NAME);
          this.navigator.addExlorer(DYNAMIC_NAME);
          this.navigator.addExlorer(SUBSETS_NAME);
          this.factorySwicther = new JPanel(new BorderLayout());
          this.factorySwicther.add(navigator.getSwitcher());
          this.factorySwicther.setOpaque(false);
          this.navigator.getJComponent().addComponentListener(this);
          this.staticCanvases = new ArrayList<FactoryCanvas>();
          this.dynamicCanvases = new ArrayList<FactoryCanvas>();
          this.subsetCanvases = new ArrayList<FactoryCanvas>();
      }
  
      /**
       * Resets FactoryManager
       */
      public void reset() {
          this.staticCanvases = new ArrayList<FactoryCanvas>();
          this.dynamicCanvases = new ArrayList<FactoryCanvas>();
          this.subsetCanvases = new ArrayList<FactoryCanvas>();
          this.navigator.setCanvas(this.staticCanvases, STATIC_NAME);
          this.navigator.setCanvas(this.dynamicCanvases, DYNAMIC_NAME);
          this.navigator.setCanvas(this.subsetCanvases, SUBSETS_NAME);
      }
  
      /**
       * Sets up the subsets by clearing all subsets and installing
       * the new collection of subsets.  If "usingSys" is true,
       * the the factory and myblocks drawers will be accessible.
       * If "usingSubs" is true, then the subset drawers will
       * be accessible.
       * @param subsets - collection of subsets
       * @param usingSys - true for factory and myblocks
       * @param usingSubs - true for subsets
       */
      public void setupSubsets(Collection<Subset> subsets, boolean usingSys, boolean usingSubs) {
          if (usingSubs) {
              this.subsetCanvases.clear();
              for (Subset subset : subsets) {
                  FactoryCanvas canvas = new FactoryCanvas(subset.getName(), subset.getColor());
                  for (RenderableBlock frb : subset.getBlocks()) {
                      canvas.addBlock(frb);
                      workspace.notifyListeners(new WorkspaceEvent(workspace, this, frb.getBlockID(), WorkspaceEvent.BLOCK_ADDED));
                  }
                  canvas.layoutBlocks();
                  this.subsetCanvases.add(canvas);
              }
              this.navigator.setCanvas(this.subsetCanvases, SUBSETS_NAME);
              if (usingSys) {
                  this.factorySwicther.removeAll();
                  this.factorySwicther.add(this.navigator.getSwitcher());
              } else {
                  this.factorySwicther.removeAll();
                  this.factorySwicther.add(new CLabel(SUBSETS_NAME));
              }
              this.viewSubsetsDrawers();
          } else if (usingSys) {
              this.factorySwicther.removeAll();
              final CBorderlessButton factoryButton = new CBorderlessButton(STATIC_NAME);
              final CBorderlessButton myblocksButton = new CBorderlessButton(DYNAMIC_NAME);
              ActionListener listener = new ActionListener() {
  
                  public void actionPerformed(ActionEvent e) {
                      if (factoryButton.equals(e.getSource())) {
                          FactoryManager.this.viewStaticDrawers();
                      } else if (myblocksButton.equals(e.getSource())) {
                          FactoryManager.this.viewDynamicDrawers();
                      }
                  }
              };
              factoryButton.addActionListener(listener);
              myblocksButton.addActionListener(listener);
              this.factorySwicther.add(factoryButton, BorderLayout.WEST);
              this.factorySwicther.add(myblocksButton, BorderLayout.EAST);
              this.viewStaticDrawers();
          }
          this.factorySwicther.revalidate();
          this.factorySwicther.repaint();
      }
  
      /**
       * prints an error message in red without ending the run process.
       * For debuggin purposes
       * @param m
       */
      private void printError(String m) {
          System.err.println(m);
      }
  
      /////////////////////
      //Reforming methods//
      /////////////////////
      public void componentResized(ComponentEvent e) {
          this.relayoutFactory();
          //this.relayoutBlocks();
      }
  
      public void componentHidden(ComponentEvent e) {
      }
  
      public void componentMoved(ComponentEvent e) {
      }
  
      public void componentShown(ComponentEvent e) {
      }
  
      /**
       * Relayout all factories
       */
      private void relayoutFactory() {
          this.navigator.reformView();
      }
  
      /**
       * Relayout all the drawers
       */
      public void relayoutBlocks() {
          for (FactoryCanvas canvas : this.staticCanvases) {
              canvas.layoutBlocks();
          }
          for (FactoryCanvas canvas : this.dynamicCanvases) {
              canvas.layoutBlocks();
          }
      }
  
      public Navigator getNavigator() {
          return this.navigator;
      }
  
      //////////////////
      //Drawer Methods//
      //////////////////
      /**
       * @return the set of searchable contianers in all factories
       */
      public Collection<SearchableContainer> getSearchableContainers() {
          Collection<SearchableContainer> containers = new HashSet<SearchableContainer>();
          for (SearchableContainer con : this.staticCanvases) {
              containers.add(con);
          }
          for (SearchableContainer con : this.dynamicCanvases) {
              containers.add(con);
          }
          return containers;
      }
  
      /**
       * Returns a collection of the subsets within this
       * @return a collection of the subsets within this
       */
      public Collection<Subset> getSubsets() {
  