private XSDElementDeclaration getElementDeclaration(final Name descriptorName) {

    QName qname = Types.toQName(descriptorName);
    XSDElementDeclaration elemDecl = null;
    for (SchemaIndex schemaIndex : schemas) {
      elemDecl = schemaIndex.getElementDeclaration(qname);
      if (elemDecl != null) {
        break;
      }
    }
    if (elemDecl == null) {
      String msg = "No top level element found in schemas: " + qname;
      LOGGER.log(Level.WARNING, msg);
      throw new NoSuchElementException(msg);
    }
    return elemDecl;
  }
  /**
   * If the type of elemDecl is annonymous creates a new type with the same name than the atrribute
   * and returns it. If it is not anonymous, looks it up on the registry and in case the type does
   * not exists in the registry uses a proxy.
   *
   * @param elemDecl
   * @return
   */
  private AttributeType getTypeOf(XSDElementDeclaration elemDecl, CoordinateReferenceSystem crs) {
    XSDTypeDefinition typeDefinition;

    // TODO REVISIT, I'm not sure this is the way to find out if the
    // element's type is defined in line (an thus no need to register it
    // as a global type)
    if (elemDecl.isElementDeclarationReference()) {
      elemDecl = elemDecl.getResolvedElementDeclaration();
    }
    boolean hasToBeRegistered = false;
    typeDefinition = elemDecl.getAnonymousTypeDefinition();
    if (typeDefinition == null) {
      // anonymous types already has type definition inline in the element
      // so the handling is different
      hasToBeRegistered = true;
      typeDefinition = elemDecl.getTypeDefinition();
    }

    if (typeDefinition == null) {
      // last resort.. look in the lazy schemas
      QName qname =
          Types.toQName(Types.typeName(elemDecl.getTargetNamespace(), elemDecl.getName()));
      for (SchemaIndex schemaIndex : schemas) {
        elemDecl = schemaIndex.getElementDeclaration(qname);
        if (elemDecl != null) {
          break;
        }
      }
      if (elemDecl != null) {
        if (elemDecl.isElementDeclarationReference()) {
          elemDecl = elemDecl.getResolvedElementDeclaration();
        }
        typeDefinition = elemDecl.getAnonymousTypeDefinition();
        if (typeDefinition == null) {
          typeDefinition = elemDecl.getTypeDefinition();
        }
      }
    }

    if (typeDefinition == null) {
      String msg =
          "The element declaration "
              + elemDecl.getTargetNamespace()
              + "#"
              + elemDecl.getName()
              + " has a null type definition, can't continue, fix it on the schema";
      LOGGER.warning(msg);
      throw new NoSuchElementException(msg);
    }

    AttributeType type;
    if (hasToBeRegistered) {
      String targetNamespace = typeDefinition.getTargetNamespace();
      String name = typeDefinition.getName();
      Name typeName = Types.typeName(targetNamespace, name);
      type = getAttributeType(typeName, typeDefinition, crs);
      if (type == null) {
        type = createType(typeName, typeDefinition, crs, false);
      }
    } else {
      String name = elemDecl.getName();
      String targetNamespace = elemDecl.getTargetNamespace();
      Name overrideName = Types.typeName(targetNamespace, name);
      type = createType(overrideName, typeDefinition, crs, true);
    }

    return type;
  }