private static void buildEntityTypes(
      MetadataStore metadataStore, List<EdmSchema.Builder> edmSchemas) {
    for (Schema schema : metadataStore.getSchemaList()) {

      List<EdmEntitySet.Builder> entitySets = new ArrayList<EdmEntitySet.Builder>();
      List<EdmEntityType.Builder> entityTypes = new ArrayList<EdmEntityType.Builder>();

      for (Table table : schema.getTables().values()) {

        KeyRecord primaryKey = table.getPrimaryKey();
        List<KeyRecord> uniques = table.getUniqueKeys();
        if (primaryKey == null && uniques.isEmpty()) {
          LogManager.logDetail(
              LogConstants.CTX_ODATA,
              ODataPlugin.Util.gs(ODataPlugin.Event.TEIID16002, table.getFullName()));
          continue;
        }

        EdmEntityType.Builder entityType =
            EdmEntityType.newBuilder().setName(table.getName()).setNamespace(schema.getName());

        // adding key
        if (primaryKey != null) {
          for (Column c : primaryKey.getColumns()) {
            entityType.addKeys(c.getName());
          }
        } else {
          for (Column c : uniques.get(0).getColumns()) {
            entityType.addKeys(c.getName());
          }
        }

        // adding properties
        for (Column c : table.getColumns()) {
          EdmProperty.Builder property =
              EdmProperty.newBuilder(c.getName())
                  .setType(ODataTypeManager.odataType(c.getDatatype().getRuntimeTypeName()))
                  .setNullable(c.getNullType() == NullType.Nullable);
          if (c.getDatatype()
              .getRuntimeTypeName()
              .equals(DataTypeManager.DefaultDataTypes.STRING)) {
            property.setFixedLength(c.isFixedLength()).setMaxLength(c.getLength()).setUnicode(true);
          }
          entityType.addProperties(property);
        }

        // entity set one for one entity type
        EdmEntitySet.Builder entitySet =
            EdmEntitySet.newBuilder().setName(table.getName()).setEntityType(entityType);

        entityType.setNamespace(schema.getName());
        entitySets.add(entitySet);

        // add enitity types for entity schema
        entityTypes.add(entityType);
      }

      // entity container is holder entity sets, association sets, function imports
      EdmEntityContainer.Builder entityContainer =
          EdmEntityContainer.newBuilder()
              .setName(schema.getName())
              .setIsDefault(false)
              .addEntitySets(entitySets);

      // build entity schema
      EdmSchema.Builder modelSchema =
          EdmSchema.newBuilder()
              .setNamespace(schema.getName())
              .addEntityTypes(entityTypes)
              .addEntityContainers(entityContainer);

      edmSchemas.add(modelSchema);
    }
  }
  private EdmSchema.Builder parseEdmSchema(XMLEventReader2 reader, StartElement2 schemaElement) {

    String schemaNamespace = schemaElement.getAttributeByName(new QName2("Namespace")).getValue();
    String schemaAlias = getAttributeValueIfExists(schemaElement, new QName2("Alias"));
    final List<EdmEntityType.Builder> edmEntityTypes = new ArrayList<EdmEntityType.Builder>();
    List<EdmComplexType.Builder> edmComplexTypes = new ArrayList<EdmComplexType.Builder>();
    List<EdmAssociation.Builder> edmAssociations = new ArrayList<EdmAssociation.Builder>();
    List<EdmEntityContainer.Builder> edmEntityContainers =
        new ArrayList<EdmEntityContainer.Builder>();
    List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();

    while (reader.hasNext()) {
      XMLEvent2 event = reader.nextEvent();
      if (event.isStartElement()) {
        if (isElement(
            event,
            EDM2006_ENTITYTYPE,
            EDM2007_ENTITYTYPE,
            EDM2008_1_ENTITYTYPE,
            EDM2008_9_ENTITYTYPE,
            EDM2009_8_ENTITYTYPE,
            EDM2009_11_ENTITYTYPE)) {
          EdmEntityType.Builder edmEntityType =
              parseEdmEntityType(reader, schemaNamespace, schemaAlias, event.asStartElement());
          edmEntityTypes.add(edmEntityType);
        } else if (isElement(
            event,
            EDM2006_ASSOCIATION,
            EDM2007_ASSOCIATION,
            EDM2008_1_ASSOCIATION,
            EDM2008_9_ASSOCIATION,
            EDM2009_8_ASSOCIATION,
            EDM2009_11_ASSOCIATION)) {
          EdmAssociation.Builder edmAssociation =
              parseEdmAssociation(reader, schemaNamespace, schemaAlias, event.asStartElement());
          edmAssociations.add(edmAssociation);
        } else if (isElement(
            event,
            EDM2006_COMPLEXTYPE,
            EDM2007_COMPLEXTYPE,
            EDM2008_1_COMPLEXTYPE,
            EDM2008_9_COMPLEXTYPE,
            EDM2009_8_COMPLEXTYPE,
            EDM2009_11_COMPLEXTYPE)) {
          EdmComplexType.Builder edmComplexType =
              parseEdmComplexType(reader, schemaNamespace, event.asStartElement());
          edmComplexTypes.add(edmComplexType);
        } else if (isElement(
            event,
            EDM2006_ENTITYCONTAINER,
            EDM2007_ENTITYCONTAINER,
            EDM2008_1_ENTITYCONTAINER,
            EDM2008_9_ENTITYCONTAINER,
            EDM2009_8_ENTITYCONTAINER,
            EDM2009_11_ENTITYCONTAINER)) {
          EdmEntityContainer.Builder edmEntityContainer =
              parseEdmEntityContainer(reader, schemaNamespace, event.asStartElement());
          edmEntityContainers.add(edmEntityContainer);
        } else {
          EdmAnnotation<?> anElement = getAnnotationElements(event, reader);
          if (anElement != null) {
            annotElements.add(anElement);
          }
        }
      }

      if (isEndElement(event, schemaElement.getName())) {
        return EdmSchema.newBuilder()
            .setNamespace(schemaNamespace)
            .setAlias(schemaAlias)
            .addEntityTypes(edmEntityTypes)
            .addComplexTypes(edmComplexTypes)
            .addAssociations(edmAssociations)
            .addEntityContainers(edmEntityContainers)
            .setAnnotations(getAnnotations(schemaElement))
            .setAnnotationElements(annotElements);
      }
    }

    throw new UnsupportedOperationException();
  }