/**
   * Internal method for loading a model from the given xml document
   *
   * @param xmlDoc
   * @param rootPath
   * @return
   */
  private SparkModel load(Document xmlDoc, File rootPath) throws Exception {
    SparkModel model = null;
    ClassLoader classLoader = null;

    ArrayList<Node> nodes;
    Node root = xmlDoc.getFirstChild();
    Node node;

    if (root == null) throw new Exception("No root node in the xml document");

    root = XmlDocUtils.getChildByTagName(root, "model");

    if (root == null) throw new Exception("No model node in the xml document");

    /* Load class path */
    classLoader = setupClassPath(rootPath);

    /* Load main model class */
    nodes = XmlDocUtils.getChildrenByTagName(root, "setup");
    if (nodes.size() != 1) throw new Exception("The model class must be uniquely specified");

    node = nodes.get(0);

    String setupName = node.getTextContent().trim();
    if (classLoader != null) {
      model = (SparkModel) classLoader.loadClass(setupName).newInstance();
    } else {
      model = (SparkModel) Class.forName(setupName).newInstance();
    }

    startConstruction(model);

    /* Load basic parameters */
    loadBasicModelParameters(root);

    /* Load agents */
    loadAgents(root, classLoader);

    /* Load variables */
    loadVariables(model, root);

    /* Load methods */
    loadMethods(model, root);

    return model;
  }