private ComponentSet addComponents(
      Map<String, Connectable> connectables, int rows, int cols, Elements componentElements) {
    ComponentSet set;
    set = new ComponentSet(cols, rows);
    for (int i = 0; i < componentElements.size(); i++) {
      Element componentElement = componentElements.get(i);
      String type = componentElement.getAttributeValue("type");
      String name = componentElement.getAttributeValue("name");

      Connectable connectable = factory.make(type, name);
      if (connectable != null) {
        connectables.put(name, connectable);
        if (connectable instanceof Component) {
          Component component = (Component) connectable;
          component.setxLoc(Integer.parseInt(componentElement.getAttributeValue("col")));
          component.setyLoc(Integer.parseInt(componentElement.getAttributeValue("row")));
          component.setInverted(Boolean.parseBoolean(componentElement.getAttributeValue("inv")));
          set.addComponent(component);
        } else if (connectable instanceof Endpoint) {
          set.addEndpoint((Endpoint) connectable);
        }
      }
    }
    return set;
  }
  protected ComponentSet loadSet(File componentsDef, File connectionsDef) {
    ComponentSet set = null;

    // for collecting all connectables
    Map<String, Connectable> connectables = new HashMap<String, Connectable>();

    try {
      // open the components.xml file
      Builder builder = new Builder();
      Document doc = builder.build(componentsDef);
      Element componentsRoot = doc.getRootElement();

      int rows = Integer.parseInt(componentsRoot.getAttributeValue("rows"));
      int cols = Integer.parseInt(componentsRoot.getAttributeValue("cols"));
      boolean autoLocate = Boolean.parseBoolean(componentsRoot.getAttributeValue("autoLocate"));

      // add connectables (components need to be located in the set,
      // endpoints are not so they are just added to the connectables map
      Elements componentElements = componentsRoot.getChildElements();
      if (autoLocate) {
        set = addComponentsWithAutoLocate(connectables, rows, cols, componentElements);
      } else {
        set = addComponents(connectables, rows, cols, componentElements);
      }

      doc = builder.build(connectionsDef);
      Element connectionsRoot = doc.getRootElement();

      // add connections
      Elements connections = connectionsRoot.getChildElements();
      for (int i = 0; i < connections.size(); i++) {
        Element c = connections.get(i);
        String from = c.getAttributeValue("from");
        String to = c.getAttributeValue("to");
        String fromPinLabel = c.getAttributeValue("fromPin");
        String toPinLabel = c.getAttributeValue("toPin");

        Connectable fromComp = connectables.get(from);
        Connectable toComp = connectables.get(to);

        Collection<Pin> fromPins = fromComp.getPins(fromPinLabel);
        Collection<Pin> toPins = toComp.getPins(toPinLabel);

        Connection con = new Connection(fromComp, fromPins, toComp, toPins);
        set.addConnection(con);
      }

    } catch (ParsingException ex) {
      System.err.println("malformed XML file : " + ex.getMessage());
    } catch (IOException ex) {
      System.err.println("io error : " + ex.getMessage());
    }
    return set;
  }
  public void writeToFile(File file, ComponentSet set) {

    // add Components
    Element componentRoot = new Element("components");
    componentRoot.addAttribute(new Attribute("autoLocate", "false"));
    componentRoot.addAttribute(new Attribute("rows", Integer.toString(set.getSizeY())));
    componentRoot.addAttribute(new Attribute("cols", Integer.toString(set.getSizeX())));

    Map<Location, Component> componentPositions = set.getComponentPositions();
    for (Location loc : componentPositions.keySet()) {
      Component c = componentPositions.get(loc);

      Element componentElement = new Element("component");
      componentElement.addAttribute(new Attribute("type", c.getId()));
      componentElement.addAttribute(new Attribute("name", c.getName()));
      componentElement.addAttribute(new Attribute("row", Integer.toString(loc.getY())));
      componentElement.addAttribute(new Attribute("col", Integer.toString(loc.getX())));
      componentElement.addAttribute(new Attribute("inv", Boolean.toString(c.isInverted())));

      componentRoot.appendChild(componentElement);
    }

    // add Endpoints
    Set<Endpoint> endpointSet = set.getEndpoints();
    for (Endpoint e : endpointSet) {

      Element endpointElement = new Element("endpoint");
      endpointElement.addAttribute(new Attribute("type", e.getId()));
      endpointElement.addAttribute(new Attribute("name", e.getName()));

      componentRoot.appendChild(endpointElement);
    }

    Document doc = new Document(componentRoot);

    try {
      OutputStream os = new FileOutputStream(file);
      Serializer serializer = new Serializer(os, "ISO-8859-1");
      serializer.setIndent(4);
      serializer.setMaxLength(120);
      serializer.write(doc);
    } catch (IOException e) {
      System.err.println("io error : " + e.getMessage());
    }
  }
  private ComponentSet addComponentsWithAutoLocate(
      Map<String, Connectable> connectables, int rows, int cols, Elements componentElements) {
    ComponentSet set;
    set = new AutoAddComponentSet(cols, rows);
    for (int i = 0; i < componentElements.size(); i++) {
      Element componentElement = componentElements.get(i);
      String type = componentElement.getAttributeValue("type");
      String name = componentElement.getAttributeValue("name");

      Connectable connectable = factory.make(type, name);
      if (connectable != null) {
        connectables.put(name, connectable);
        if (connectable instanceof Component) {
          ((AutoAddComponentSet) set).addComponent((Component) connectable);
        } else if (connectable instanceof Endpoint) {
          set.addEndpoint((Endpoint) connectable);
        }
      }
    }
    return set;
  }