/**
   * Create the objects described in an XML element containing layer and/or layer-list descriptions.
   * Nested layer lists and included layers are created recursively.
   *
   * @param domElement an XML element describing the layers and/or layer lists.
   * @param params any properties to apply when creating the included layers.
   * @return a <code>Layer</code>, <code>LayerList</code> or array of <code>LayerList</code>s, as
   *     described by the specified description.
   * @throws Exception if an exception occurs during creation. Exceptions occurring during creation
   *     of internal layers or layer lists are not re-thrown but are logged. The layer or layer list
   *     associated with the exception is not contained in the returned object.
   */
  @Override
  protected Object doCreateFromElement(Element domElement, AVList params) throws Exception {
    Element[] elements = WWXML.getElements(domElement, "//LayerList", null);
    if (elements != null && elements.length > 0) return createLayerLists(elements, params);

    elements = WWXML.getElements(domElement, "./Layer", null);
    if (elements != null && elements.length > 1) return createLayerList(elements, params);

    if (elements != null && elements.length == 1)
      return this.createFromLayerDocument(elements[0], params);

    String localName = WWXML.getUnqualifiedName(domElement);
    if (localName != null && localName.equals("Layer"))
      return this.createFromLayerDocument(domElement, params);

    return null;
  }
  /**
   * Returns true if a specified DOM document should be accepted as an ElevationModel configuration
   * document, and false otherwise.
   *
   * @param domElement the DOM document in question.
   * @return true if the document is an ElevationModel configuration document; false otherwise.
   * @throws IllegalArgumentException if document is null.
   */
  public static boolean isElevationModelDocument(Element domElement) {
    if (domElement == null) {
      String message = Logging.getMessage("nullValue.DocumentIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    XPath xpath = WWXML.makeXPath();
    Element[] elements = WWXML.getElements(domElement, "//ElevationModel", xpath);

    return elements != null && elements.length > 0;
  }
  /**
   * Create a collection of layer lists and their included layers described by an array of XML
   * layer-list description elements.
   *
   * <p>Any exceptions occurring during creation of the layer lists or their included layers are
   * logged and not re-thrown. The layers associated with the exceptions are not included in the
   * returned layer list.
   *
   * @param elements the XML elements describing the layer lists to create.
   * @param params any parameters to apply when creating the included layers.
   * @return an array containing the specified layer lists.
   */
  protected LayerList[] createLayerLists(Element[] elements, AVList params) {
    ArrayList<LayerList> layerLists = new ArrayList<LayerList>();

    for (Element element : elements) {
      try {
        String href = WWXML.getText(element, "@href");
        if (href != null && href.length() > 0) {
          Object o = this.createFromConfigSource(href, params);
          if (o == null) continue;

          if (o instanceof Layer) {
            LayerList ll = new LayerList();
            ll.add((Layer) o);
            o = ll;
          }

          if (o instanceof LayerList) {
            LayerList list = (LayerList) o;
            if (list != null && list.size() > 0) layerLists.add(list);
          } else if (o instanceof LayerList[]) {
            LayerList[] lists = (LayerList[]) o;
            if (lists != null && lists.length > 0) layerLists.addAll(Arrays.asList(lists));
          } else {
            String msg =
                Logging.getMessage("LayerFactory.UnexpectedTypeForLayer", o.getClass().getName());
            Logging.logger().log(java.util.logging.Level.WARNING, msg);
          }

          continue;
        }

        String title = WWXML.getText(element, "@title");
        Element[] children = WWXML.getElements(element, "./Layer", null);
        if (children != null && children.length > 0) {
          LayerList list = this.createLayerList(children, params);
          if (list != null && list.size() > 0) {
            layerLists.add(list);
            if (title != null && title.length() > 0) list.setValue(AVKey.DISPLAY_NAME, title);
          }
        }
      } catch (Exception e) {
        Logging.logger().log(java.util.logging.Level.WARNING, e.getMessage(), e);
        // keep going to create other layers
      }
    }

    return layerLists.toArray(new LayerList[layerLists.size()]);
  }