protected EdmAnnotation<?> getAnnotationElements(XMLEvent2 event, XMLEventReader2 reader) {
   StartElement2 annotationStartElement = event.asStartElement();
   QName2 q = annotationStartElement.getName();
   String value = null;
   EdmAnnotationElement<?> element = null;
   List<EdmAnnotation<?>> list = new ArrayList<EdmAnnotation<?>>();
   if (!NON_USER_NAMESPACES.contains(q.getNamespaceUri())) {
     // a user extension
     while (reader.hasNext()) {
       event = reader.nextEvent();
       if (event.isStartElement()) {
         EdmAnnotation<?> childElement = getAnnotationElements(event, reader);
         if (childElement != null) {
           list.add(childElement);
         }
       } else if (event.isCharacters()) {
         value = event.asCharacters().getData().trim();
       } else if (event.isEndElement()) {
         if (value != null) {
           element =
               EdmAnnotation.element(
                   q.getNamespaceUri(), q.getPrefix(), q.getLocalPart(), String.class, value);
         } else {
           element =
               EdmAnnotation.element(
                   q.getNamespaceUri(), q.getPrefix(), q.getLocalPart(), String.class, "");
         }
         element.setAnnotationElements(list);
         element.setAnnotations(getAnnotations(annotationStartElement));
         return element;
       }
     }
   }
   return null;
 }
  private EdmAssociation.Builder parseEdmAssociation(
      XMLEventReader2 reader,
      String schemaNamespace,
      String schemaAlias,
      StartElement2 associationElement) {
    String name = associationElement.getAttributeByName("Name").getValue();

    List<EdmAssociationEnd.Builder> ends = new ArrayList<EdmAssociationEnd.Builder>();
    List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();
    EdmReferentialConstraint.Builder referentialConstraint = null;

    while (reader.hasNext()) {
      XMLEvent2 event = reader.nextEvent();
      if (event.isStartElement()) {
        if (isElement(
            event,
            EDM2006_END,
            EDM2007_END,
            EDM2008_1_END,
            EDM2008_9_END,
            EDM2009_8_END,
            EDM2009_11_END)) {
          EdmAssociationEnd.Builder edmAssociationEnd = parseEdmAssociationEnd(reader, event);
          ends.add(edmAssociationEnd);
        } else if (isElement(
            event,
            EDM2006_REFCONSTRAINT,
            EDM2007_REFCONSTRAINT,
            EDM2008_1_REFCONSTRAINT,
            EDM2008_9_REFCONSTRAINT,
            EDM2009_8_REFCONSTRAINT,
            EDM2009_11_REFCONSTRAINT)) {
          StartElement2 constraintElement = event.asStartElement();
          referentialConstraint = parseEdmConstraintElement(reader, constraintElement);
        } else {
          EdmAnnotation<?> anElement = getAnnotationElements(event, reader);
          if (anElement != null) {
            annotElements.add(anElement);
          }
        }
      }

      if (isEndElement(event, associationElement.getName())) {
        return EdmAssociation.newBuilder()
            .setNamespace(schemaNamespace)
            .setAlias(schemaAlias)
            .setName(name)
            .setEnds(ends.get(0), ends.get(1))
            .setRefConstraint(referentialConstraint == null ? null : referentialConstraint)
            .setAnnotations(getAnnotations(associationElement))
            .setAnnotationElements(annotElements);
      }
    }
    throw new UnsupportedOperationException();
  }
  private EdmFunctionImport.Builder parseEdmFunctionImport(
      XMLEventReader2 reader, String schemaNamespace, StartElement2 functionImportElement) {
    String name = functionImportElement.getAttributeByName("Name").getValue();
    String entitySet = getAttributeValueIfExists(functionImportElement, "EntitySet");
    Attribute2 returnTypeAttr = functionImportElement.getAttributeByName("ReturnType");
    String returnType = returnTypeAttr != null ? returnTypeAttr.getValue() : null;

    List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();

    // strict parsing
    boolean isCollection = returnType != null && returnType.matches("^Collection\\(.*\\)$");
    if (isCollection) {
      returnType = returnType.substring(11, returnType.length() - 1);
    }
    String httpMethod =
        getAttributeValueIfExists(functionImportElement, new QName2(NS_METADATA, "HttpMethod"));

    List<EdmFunctionParameter.Builder> parameters = new ArrayList<EdmFunctionParameter.Builder>();

    while (reader.hasNext()) {
      XMLEvent2 event = reader.nextEvent();
      if (event.isStartElement()) {
        if (isElement(
            event,
            EDM2006_PARAMETER,
            EDM2007_PARAMETER,
            EDM2008_1_PARAMETER,
            EDM2008_9_PARAMETER,
            EDM2009_8_PARAMETER,
            EDM2009_11_PARAMETER)) {
          StartElement2 paramStartElement = event.asStartElement();
          EdmFunctionParameter.Builder functionParameter =
              parseEdmFunctionParameter(reader, paramStartElement);
          parameters.add(functionParameter);
        } else {
          EdmAnnotation<?> anElement = getAnnotationElements(event, reader);
          if (anElement != null) {
            annotElements.add(anElement);
          }
        }
      }
      if (isEndElement(event, functionImportElement.getName())) {
        return EdmFunctionImport.newBuilder()
            .setName(name)
            .setEntitySetName(entitySet)
            .setReturnTypeName(returnType)
            .setIsCollection(isCollection)
            .setHttpMethod(httpMethod)
            .addParameters(parameters)
            .setAnnotations(getAnnotations(functionImportElement))
            .setAnnotationElements(annotElements);
      }
    }
    throw new UnsupportedOperationException();
  }
 private EdmReferentialConstraint.Builder parseEdmConstraintElement(
     XMLEventReader2 tmpReader, StartElement2 constraintElement) {
   List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();
   List<String> principalPropertyRef = new ArrayList<String>();
   List<String> dependentPropertyRef = new ArrayList<String>();
   String principalRole = null;
   String dependentRole = null;
   while (tmpReader.hasNext()) {
     XMLEvent2 event = tmpReader.nextEvent();
     if (event.isStartElement()) {
       if (isElement(
           event,
           EDM2006_PRINCIPAL,
           EDM2007_PRINCIPAL,
           EDM2008_1_PRINCIPAL,
           EDM2008_9_PRINCIPAL,
           EDM2009_8_PRINCIPAL,
           EDM2009_11_PRINCIPAL)) {
         StartElement2 principalElement = event.asStartElement();
         principalPropertyRef = parsePropertyRef(tmpReader, principalElement);
         principalRole = principalElement.getAttributeByName("Role").getValue();
       } else if (isElement(
           event,
           EDM2006_DEPENDENT,
           EDM2007_DEPENDENT,
           EDM2008_1_DEPENDENT,
           EDM2008_9_DEPENDENT,
           EDM2009_8_DEPENDENT,
           EDM2009_11_DEPENDENT)) {
         StartElement2 dependentElement = event.asStartElement();
         dependentPropertyRef = parsePropertyRef(tmpReader, dependentElement);
         dependentRole = dependentElement.getAttributeByName("Role").getValue();
       } else {
         EdmAnnotation<?> anElement = getAnnotationElements(event, tmpReader);
         if (anElement != null) {
           annotElements.add(anElement);
         }
       }
     }
     if (isEndElement(event, constraintElement.getName())) {
       return EdmReferentialConstraint.newBuilder()
           .setPrincipalRole(principalRole)
           .setDependentRole(dependentRole)
           .addDependentReferences(dependentPropertyRef)
           .addPrincipalReferences(principalPropertyRef)
           .setAnnotationElements(annotElements)
           .setAnnotations(getAnnotations(constraintElement));
     }
   }
   throw new UnsupportedOperationException();
 }
  private EdmComplexType.Builder parseEdmComplexType(
      XMLEventReader2 reader, String schemaNamespace, StartElement2 complexTypeElement) {
    String name = complexTypeElement.getAttributeByName("Name").getValue();
    String isAbstractS = getAttributeValueIfExists(complexTypeElement, "Abstract");
    String baseType = getAttributeValueIfExists(complexTypeElement, "BaseType");
    List<EdmProperty.Builder> edmProperties = new ArrayList<EdmProperty.Builder>();
    List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();

    while (reader.hasNext()) {
      XMLEvent2 event = reader.nextEvent();
      if (event.isStartElement()) {
        if (isElement(
            event,
            EDM2006_PROPERTY,
            EDM2007_PROPERTY,
            EDM2008_1_PROPERTY,
            EDM2008_9_PROPERTY,
            EDM2009_8_PROPERTY,
            EDM2009_11_PROPERTY)) {
          edmProperties.add(parseEdmProperty(reader, event));
        } else {
          EdmAnnotation<?> anElement = getAnnotationElements(event, reader);
          if (anElement != null) {
            annotElements.add(anElement);
          }
        }
      }

      if (isEndElement(event, complexTypeElement.getName())) {
        EdmComplexType.Builder complexType =
            EdmComplexType.newBuilder()
                .setNamespace(schemaNamespace)
                .setName(name)
                .setBaseType(baseType)
                .addProperties(edmProperties)
                .setAnnotations(getAnnotations(complexTypeElement))
                .setAnnotationElements(annotElements);
        if (isAbstractS != null) complexType.setIsAbstract("true".equals(isAbstractS));
        return complexType;
      }
    }

    throw new UnsupportedOperationException();
  }
  private EdmAssociationSet.Builder parseEdmAssociationSet(
      XMLEventReader2 reader, String schemaNamespace, StartElement2 associationSetElement) {
    String name = associationSetElement.getAttributeByName("Name").getValue();
    String associationName = associationSetElement.getAttributeByName("Association").getValue();

    List<EdmAssociationSetEnd.Builder> ends = new ArrayList<EdmAssociationSetEnd.Builder>();
    List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();

    while (reader.hasNext()) {
      XMLEvent2 event = reader.nextEvent();
      if (event.isStartElement()) {
        if (isElement(
            event,
            EDM2006_END,
            EDM2007_END,
            EDM2008_1_END,
            EDM2008_9_END,
            EDM2009_8_END,
            EDM2009_11_END)) {
          StartElement2 endStartElement = event.asStartElement();
          EdmAssociationSetEnd.Builder assocSetEnd =
              parseEdmAssociationSetEnd(reader, endStartElement);
          ends.add(assocSetEnd);
        } else {
          EdmAnnotation<?> anElement = getAnnotationElements(event, reader);
          if (anElement != null) {
            annotElements.add(anElement);
          }
        }
      }
      if (isEndElement(event, associationSetElement.getName())) {
        return EdmAssociationSet.newBuilder()
            .setName(name)
            .setAssociationName(associationName)
            .setEnds(ends.get(0), ends.get(1))
            .setAnnotations(getAnnotations(associationSetElement))
            .setAnnotationElements(annotElements);
      }
    }
    throw new UnsupportedOperationException();
  }
  private EdmNavigationProperty.Builder parseEdmNavigationProperty(
      XMLEventReader2 reader, XMLEvent2 event) {
    List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();

    StartElement2 navPropStartElement = event.asStartElement();
    String associationName = navPropStartElement.getAttributeByName("Name").getValue();
    String relationshipName = navPropStartElement.getAttributeByName("Relationship").getValue();
    String fromRoleName = navPropStartElement.getAttributeByName("FromRole").getValue();
    String toRoleName = navPropStartElement.getAttributeByName("ToRole").getValue();
    while (reader.hasNext()) {
      event = reader.nextEvent();
      if (event.isStartElement()) {
        EdmAnnotation<?> anElement = getAnnotationElements(event, reader);
        if (anElement != null) {
          annotElements.add(anElement);
        }
      }
      if (isEndElement(event, navPropStartElement.getName())) {
        return EdmNavigationProperty.newBuilder(associationName)
            .setRelationshipName(relationshipName)
            .setFromToName(fromRoleName, toRoleName)
            .setAnnotations(getAnnotations(navPropStartElement))
            .setAnnotationElements(annotElements);
      }
    }
    throw new UnsupportedOperationException();
  }
 private EdmAssociationSetEnd.Builder parseEdmAssociationSetEnd(
     XMLEventReader2 reader, StartElement2 endStartElement) {
   List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();
   String role = endStartElement.getAttributeByName("Role").getValue();
   String entitySetName = endStartElement.getAttributeByName("EntitySet").getValue();
   while (reader.hasNext()) {
     XMLEvent2 event = reader.nextEvent();
     if (event.isStartElement()) {
       EdmAnnotation<?> anElement = getAnnotationElements(event, reader);
       if (anElement != null) {
         annotElements.add(anElement);
       }
     }
     if (isEndElement(event, endStartElement.getName())) {
       return EdmAssociationSetEnd.newBuilder()
           .setRoleName(role)
           .setEntitySetName(entitySetName)
           .setAnnotations(getAnnotations(endStartElement))
           .setAnnotationElements(annotElements);
     }
   }
   throw new UnsupportedOperationException();
 }
 private EdmEntitySet.Builder parseEdmEntitySet(
     XMLEventReader2 reader, String schemaNamespace, StartElement2 entitySetStartElement) {
   List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();
   String name = entitySetStartElement.getAttributeByName("Name").getValue();
   String entityTypeName = getAttributeValueIfExists(entitySetStartElement, "EntityType");
   while (reader.hasNext()) {
     XMLEvent2 event = reader.nextEvent();
     if (event.isStartElement()) {
       EdmAnnotation<?> anElement = getAnnotationElements(event, reader);
       if (anElement != null) {
         annotElements.add(anElement);
       }
     }
     if (isEndElement(event, entitySetStartElement.getName())) {
       return EdmEntitySet.newBuilder()
           .setName(name)
           .setEntityTypeName(entityTypeName)
           .setAnnotations(getAnnotations(entitySetStartElement))
           .setAnnotationElements(annotElements);
     }
   }
   throw new UnsupportedOperationException();
 }
 private EdmFunctionParameter.Builder parseEdmFunctionParameter(
     XMLEventReader2 reader, StartElement2 paramStartElement) {
   List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();
   Attribute2 modeAttribute = paramStartElement.getAttributeByName("Mode");
   String nullableS = getAttributeValueIfExists(paramStartElement, "Nullable");
   String maxLength = getAttributeValueIfExists(paramStartElement, "MaxLength");
   String precision = getAttributeValueIfExists(paramStartElement, "Precision");
   String scale = getAttributeValueIfExists(paramStartElement, "Scale");
   while (reader.hasNext()) {
     XMLEvent2 event = reader.nextEvent();
     if (event.isStartElement()) {
       EdmAnnotation<?> anElement = getAnnotationElements(event, reader);
       if (anElement != null) {
         annotElements.add(anElement);
       }
     }
     if (isEndElement(event, paramStartElement.getName())) {
       return EdmFunctionParameter.newBuilder()
           .setName(paramStartElement.getAttributeByName("Name").getValue())
           .setType(
               EdmType.newDeferredBuilder(
                   paramStartElement.getAttributeByName("Type").getValue(), dataServices))
           .setMode(modeAttribute != null ? Mode.valueOf(modeAttribute.getValue()) : null)
           .setNullable(nullableS == null ? null : "true".equalsIgnoreCase(nullableS))
           .setMaxLength(
               maxLength == null
                   ? null
                   : maxLength.equals("Max") ? Integer.MAX_VALUE : Integer.parseInt(maxLength))
           .setPrecision(precision == null ? null : Integer.parseInt(precision))
           .setScale(scale == null ? null : Integer.parseInt(scale))
           .setAnnotations(getAnnotations(paramStartElement))
           .setAnnotationElements(annotElements);
     }
   }
   throw new UnsupportedOperationException();
 }
  public static Iterable<OProperty<?>> parseProperties(
      XMLEventReader2 reader, StartElement2 propertiesElement) {
    List<OProperty<?>> rt = new ArrayList<OProperty<?>>();

    while (reader.hasNext()) {
      XMLEvent2 event = reader.nextEvent();

      if (event.isEndElement()
          && event.asEndElement().getName().equals(propertiesElement.getName())) {
        return rt;
      }

      if (event.isStartElement()
          && event.asStartElement().getName().getNamespaceURI().equals(NS_DATASERVICES)) {

        String name = event.asStartElement().getName().getLocalPart();
        Attribute2 typeAttribute = event.asStartElement().getAttributeByName(M_TYPE);
        Attribute2 nullAttribute = event.asStartElement().getAttributeByName(M_NULL);
        boolean isNull = nullAttribute != null && "true".equals(nullAttribute.getValue());

        OProperty<?> op = null;

        String type = null;
        boolean isComplexType = false;
        if (typeAttribute != null) {
          type = typeAttribute.getValue();
          EdmType et = EdmType.get(type);
          isComplexType = !et.isSimple();
        }

        if (isComplexType) {
          op =
              OProperties.complex(
                  name,
                  type,
                  isNull
                      ? null
                      : Enumerable.create(parseProperties(reader, event.asStartElement()))
                          .toList());
        } else {
          op = OProperties.parse(name, type, isNull ? null : reader.getElementText());
        }
        rt.add(op);
      }
    }

    throw new RuntimeException();
  }
  protected List<PrefixedNamespace> getExtensionNamespaces(StartElement2 startElement) {

    try {
      Enumerable<Namespace2> nse = startElement.getNamespaces();
      List<PrefixedNamespace> nsl = new ArrayList<PrefixedNamespace>();
      for (Namespace2 ns : nse) {
        if (this.isExtensionNamespace(ns.getNamespaceURI())) {
          nsl.add(new PrefixedNamespace(ns.getNamespaceURI(), ns.getPrefix()));
        }
      }
      return nsl;
    } catch (Exception ex) {
      // not all of the xml parsing implementations implement getNamespaces() yet.
      return null;
    }
  }
  private static String innerText(XMLEventReader2 reader, StartElement2 element) {
    StringWriter sw = new StringWriter();
    XMLEventWriter2 writer =
        XMLFactoryProvider2.getInstance().newXMLOutputFactory2().createXMLEventWriter(sw);
    while (reader.hasNext()) {

      XMLEvent2 event = reader.nextEvent();
      if (event.isEndElement() && event.asEndElement().getName().equals(element.getName())) {

        return sw.toString();
      } else {
        writer.add(event);
      }
    }
    throw new RuntimeException();
  }
 protected List<EdmAnnotation<?>> getAnnotations(StartElement2 element) {
   // extract Annotation attributes
   try {
     Enumerable<Attribute2> atts = element.getAttributes();
     List<EdmAnnotation<?>> annots = new ArrayList<EdmAnnotation<?>>();
     for (Attribute2 att : atts) {
       QName2 q = att.getName();
       if (isExtensionNamespace(q.getNamespaceUri())) {
         // a user extension
         annots.add(
             EdmAnnotation.attribute(
                 q.getNamespaceUri(), q.getPrefix(), q.getLocalPart(), att.getValue()));
       }
     }
     return annots;
   } catch (Exception ex) {
     // not all of the xml parsing implementations implement getAttributes() yet.
     return null;
   }
 }
  private AtomLink parseAtomLink(XMLEventReader2 reader, StartElement2 linkElement) {
    AtomLink rt = new AtomLink();
    rt.relation = getAttributeValueIfExists(linkElement, "rel");
    rt.type = getAttributeValueIfExists(linkElement, "type");
    rt.title = getAttributeValueIfExists(linkElement, "title");
    rt.href = getAttributeValueIfExists(linkElement, "href");

    while (reader.hasNext()) {
      XMLEvent2 event = reader.nextEvent();

      if (event.isEndElement() && event.asEndElement().getName().equals(linkElement.getName())) {
        break;
      } else if (isStartElement(event, ATOM_FEED)) {
        rt.inlineFeed = parseFeed(reader);
      } else if (isStartElement(event, ATOM_ENTRY)) {
        rt.inlineEntry = parseEntry(reader, event.asStartElement());
      }
    }
    return rt;
  }
  private List<String> parsePropertyRef(XMLEventReader2 tmpReader, StartElement2 startElement) {
    List<String> references = new ArrayList<String>();

    while (tmpReader.hasNext()) {
      XMLEvent2 event = tmpReader.nextEvent();
      if (isStartElement(
          event,
          EDM2006_PROPERTYREF,
          EDM2007_PROPERTYREF,
          EDM2008_1_PROPERTYREF,
          EDM2008_9_PROPERTYREF,
          EDM2009_8_PROPERTYREF,
          EDM2009_11_PROPERTYREF)) {
        references.add(event.asStartElement().getAttributeByName("Name").getValue());
      }
      if (isEndElement(event, startElement.getName())) {
        return references;
      }
    }
    throw new UnsupportedOperationException();
  }
  private EdmAssociationEnd.Builder parseEdmAssociationEnd(
      XMLEventReader2 tmpReader, XMLEvent2 event) {
    List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();
    StartElement2 endStartElement = event.asStartElement();
    String onDeleteAction = null;
    while (tmpReader.hasNext()) {
      XMLEvent2 event2 = tmpReader.nextEvent();
      if (event2.isStartElement()) {
        if (isElement(
            event2,
            EDM2006_ONDELETE,
            EDM2007_ONDELETE,
            EDM2008_1_ONDELETE,
            EDM2008_9_ONDELETE,
            EDM2009_8_ONDELETE,
            EDM2009_11_ONDELETE)) {
          StartElement2 onDeleteStartElement = event2.asStartElement();
          onDeleteAction = onDeleteStartElement.getAttributeByName("Action").getValue();

        } else {
          EdmAnnotation<?> anElement = getAnnotationElements(event2, tmpReader);
          if (anElement != null) {
            annotElements.add(anElement);
          }
        }
      }
      if (isEndElement(event2, endStartElement.getName())) {
        return EdmAssociationEnd.newBuilder()
            .setRole(endStartElement.getAttributeByName("Role").getValue())
            .setTypeName(endStartElement.getAttributeByName("Type").getValue())
            .setMultiplicity(
                EdmMultiplicity.fromSymbolString(
                    endStartElement.getAttributeByName("Multiplicity").getValue()))
            .setOnDeleteAction(
                onDeleteAction == null ? null : EdmOnDeleteAction.fromSymbolString(onDeleteAction))
            .setAnnotations(getAnnotations(endStartElement))
            .setAnnotationElements(annotElements);
      }
    }
    throw new UnsupportedOperationException();
  }
  private AtomEntry parseEntry(XMLEventReader2 reader, StartElement2 entryElement) {

    String id = null;
    String categoryTerm = null;
    String categoryScheme = null;
    String title = null;
    String summary = null;
    String updated = null;
    String contentType = null;
    List<AtomLink> atomLinks = new ArrayList<AtomLink>();

    String etag = getAttributeValueIfExists(entryElement, M_ETAG);

    AtomEntry rt = null;

    while (reader.hasNext()) {
      XMLEvent2 event = reader.nextEvent();

      if (event.isEndElement() && event.asEndElement().getName().equals(entryElement.getName())) {
        rt.id = id; // http://localhost:8810/Oneoff01.svc/Comment(1)
        rt.title = title;
        rt.summary = summary;
        rt.updated = updated;
        rt.categoryScheme =
            categoryScheme; // http://schemas.microsoft.com/ado/2007/08/dataservices/scheme
        rt.categoryTerm = categoryTerm; // NorthwindModel.Customer
        rt.contentType = contentType;
        rt.atomLinks = atomLinks;

        if (rt instanceof DataServicesAtomEntry) {
          DataServicesAtomEntry dsae = (DataServicesAtomEntry) rt;
          String entitySetName = this.entitySetName;
          if (rt.id != null && rt.id.endsWith(")")) entitySetName = parseEntitySetName(rt.id);
          EdmEntitySet ees = metadata.findEdmEntitySet(entitySetName);
          if (ees == null) {
            // panic! could not determine the entity-set, is it a function?
            EdmFunctionImport efi = metadata.findEdmFunctionImport(entitySetName);
            if (efi != null) ees = efi.entitySet;
          }
          if (ees == null)
            throw new RuntimeException("Could not derive the entity-set for entry: " + rt.id);
          dsae.setOEntity(entityFromAtomEntry(metadata, ees, dsae, fcMapping));
        }
        return rt;
      }

      if (isStartElement(event, ATOM_ID)) {
        id = reader.getElementText();
      } else if (isStartElement(event, ATOM_TITLE)) {
        title = reader.getElementText();
      } else if (isStartElement(event, ATOM_SUMMARY)) {
        summary = reader.getElementText();
      } else if (isStartElement(event, ATOM_UPDATED)) {
        updated = reader.getElementText();
      } else if (isStartElement(event, ATOM_CATEGORY)) {
        categoryTerm = getAttributeValueIfExists(event.asStartElement(), "term");
        categoryScheme = getAttributeValueIfExists(event.asStartElement(), "scheme");

      } else if (isStartElement(event, ATOM_LINK)) {
        AtomLink link = parseAtomLink(reader, event.asStartElement());
        atomLinks.add(link);
      } else if (isStartElement(event, M_PROPERTIES)) {
        rt = parseDSAtomEntry(etag, reader, event);
      } else if (isStartElement(event, ATOM_CONTENT)) {
        contentType = getAttributeValueIfExists(event.asStartElement(), "type");

        if (contentType.equals(MediaType.APPLICATION_XML)) {

          StartElement2 contentElement = event.asStartElement();
          StartElement2 valueElement = null;
          while (reader.hasNext()) {

            XMLEvent2 event2 = reader.nextEvent();

            if (valueElement == null && event2.isStartElement()) {
              valueElement = event2.asStartElement();

              if (isStartElement(event2, M_PROPERTIES)) {
                rt = parseDSAtomEntry(etag, reader, event2);
              } else {
                BasicAtomEntry bae = new BasicAtomEntry();
                bae.content = innerText(reader, event2.asStartElement());
                rt = bae;
              }
            }
            if (event2.isEndElement()
                && event2.asEndElement().getName().equals(contentElement.getName())) {

              break;
            }
          }

        } else {
          BasicAtomEntry bae = new BasicAtomEntry();
          bae.content = innerText(reader, event.asStartElement());
          rt = bae;
        }
      }
    }

    throw new RuntimeException();
  }
  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();
  }
  private EdmEntityContainer.Builder parseEdmEntityContainer(
      XMLEventReader2 reader, String schemaNamespace, StartElement2 entityContainerElement) {
    String name = entityContainerElement.getAttributeByName("Name").getValue();
    boolean isDefault =
        "true"
            .equals(
                getAttributeValueIfExists(
                    entityContainerElement, new QName2(NS_METADATA, "IsDefaultEntityContainer")));
    String lazyLoadingEnabledValue =
        getAttributeValueIfExists(
            entityContainerElement, new QName2(NS_EDMANNOTATION, "LazyLoadingEnabled"));
    Boolean lazyLoadingEnabled =
        lazyLoadingEnabledValue == null ? null : lazyLoadingEnabledValue.equals("true");
    String extendz = getAttributeValueIfExists(entityContainerElement, new QName2("Extends"));

    List<EdmEntitySet.Builder> edmEntitySets = new ArrayList<EdmEntitySet.Builder>();
    List<EdmAssociationSet.Builder> edmAssociationSets = new ArrayList<EdmAssociationSet.Builder>();
    List<EdmFunctionImport.Builder> edmFunctionImports = new ArrayList<EdmFunctionImport.Builder>();
    List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();

    while (reader.hasNext()) {
      XMLEvent2 event = reader.nextEvent();
      if (event.isStartElement()) {
        if (isElement(
            event,
            EDM2006_ENTITYSET,
            EDM2007_ENTITYSET,
            EDM2008_1_ENTITYSET,
            EDM2008_9_ENTITYSET,
            EDM2009_8_ENTITYSET,
            EDM2009_11_ENTITYSET)) {
          EdmEntitySet.Builder entitySet =
              parseEdmEntitySet(reader, schemaNamespace, event.asStartElement());
          edmEntitySets.add(entitySet);
        } else if (isElement(
            event,
            EDM2006_ASSOCIATIONSET,
            EDM2007_ASSOCIATIONSET,
            EDM2008_1_ASSOCIATIONSET,
            EDM2008_9_ASSOCIATIONSET,
            EDM2009_8_ASSOCIATIONSET,
            EDM2009_11_ASSOCIATIONSET)) {
          edmAssociationSets.add(
              parseEdmAssociationSet(reader, schemaNamespace, event.asStartElement()));
        } else if (isElement(
            event,
            EDM2006_FUNCTIONIMPORT,
            EDM2007_FUNCTIONIMPORT,
            EDM2008_1_FUNCTIONIMPORT,
            EDM2008_9_FUNCTIONIMPORT,
            EDM2009_8_FUNCTIONIMPORT,
            EDM2009_11_FUNCTIONIMPORT)) {
          edmFunctionImports.add(
              parseEdmFunctionImport(reader, schemaNamespace, event.asStartElement()));
        } else {
          EdmAnnotation<?> anElement = getAnnotationElements(event, reader);
          if (anElement != null) {
            annotElements.add(anElement);
          }
        }
      }
      if (isEndElement(event, entityContainerElement.getName())) {
        return EdmEntityContainer.newBuilder()
            .setName(name)
            .setIsDefault(isDefault)
            .setLazyLoadingEnabled(lazyLoadingEnabled)
            .setExtendz(extendz)
            .addEntitySets(edmEntitySets)
            .addAssociationSets(edmAssociationSets)
            .addFunctionImports(edmFunctionImports)
            .setAnnotations(getAnnotations(entityContainerElement))
            .setAnnotationElements(annotElements);
      }
    }
    throw new UnsupportedOperationException();
  }
  private EdmEntityType.Builder parseEdmEntityType(
      XMLEventReader2 reader,
      String schemaNamespace,
      String schemaAlias,
      StartElement2 entityTypeElement) {
    String name = entityTypeElement.getAttributeByName("Name").getValue();
    String hasStreamValue =
        getAttributeValueIfExists(entityTypeElement, new QName2(NS_METADATA, "HasStream"));
    Boolean hasStream = hasStreamValue == null ? null : hasStreamValue.equals("true");
    String baseType = getAttributeValueIfExists(entityTypeElement, "BaseType");
    String isAbstractS = getAttributeValueIfExists(entityTypeElement, "Abstract");
    String openTypeValue = getAttributeValueIfExists(entityTypeElement, "OpenType");
    Boolean openType = openTypeValue == null ? null : openTypeValue.equals("true");

    List<String> keys = new ArrayList<String>();
    List<EdmProperty.Builder> edmProperties = new ArrayList<EdmProperty.Builder>();
    List<EdmNavigationProperty.Builder> edmNavigationProperties =
        new ArrayList<EdmNavigationProperty.Builder>();
    List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();

    while (reader.hasNext()) {
      XMLEvent2 event = reader.nextEvent();
      if (event.isStartElement()) {
        if (isElement(
            event,
            EDM2006_PROPERTYREF,
            EDM2007_PROPERTYREF,
            EDM2008_1_PROPERTYREF,
            EDM2008_9_PROPERTYREF,
            EDM2009_8_PROPERTYREF,
            EDM2009_11_PROPERTYREF)) {
          keys.add(event.asStartElement().getAttributeByName("Name").getValue());
        } else if (isElement(
            event,
            EDM2006_PROPERTY,
            EDM2007_PROPERTY,
            EDM2008_1_PROPERTY,
            EDM2008_9_PROPERTY,
            EDM2009_8_PROPERTY,
            EDM2009_11_PROPERTY)) {
          edmProperties.add(parseEdmProperty(reader, event));
        } else if (isElement(
            event,
            EDM2006_NAVIGATIONPROPERTY,
            EDM2007_NAVIGATIONPROPERTY,
            EDM2008_1_NAVIGATIONPROPERTY,
            EDM2008_9_NAVIGATIONPROPERTY,
            EDM2009_8_NAVIGATIONPROPERTY,
            EDM2009_11_NAVIGATIONPROPERTY)) {
          edmNavigationProperties.add(parseEdmNavigationProperty(reader, event));

        } else {
          EdmAnnotation<?> anElement = getAnnotationElements(event, reader);
          if (anElement != null) {
            annotElements.add(anElement);
          }
        }
      }

      if (isEndElement(event, entityTypeElement.getName())) {
        return EdmEntityType.newBuilder()
            .setNamespace(schemaNamespace)
            .setAlias(schemaAlias)
            .setName(name)
            .setHasStream(hasStream)
            .setOpenType(openType)
            .addKeys(keys)
            .addProperties(edmProperties)
            .addNavigationProperties(edmNavigationProperties)
            .setBaseType(baseType)
            .setIsAbstract(isAbstractS == null ? null : "true".equals(isAbstractS))
            .setAnnotations(getAnnotations(entityTypeElement))
            .setAnnotationElements(annotElements);
      }
    }

    throw new UnsupportedOperationException();
  }
  private EdmProperty.Builder parseEdmProperty(XMLEventReader2 reader, XMLEvent2 event) {
    List<EdmAnnotation<?>> annotElements = new ArrayList<EdmAnnotation<?>>();
    StartElement2 startElement = event.asStartElement();
    String propertyName = getAttributeValueIfExists(startElement, "Name");
    String propertyType = getAttributeValueIfExists(startElement, "Type");
    String propertyNullable = getAttributeValueIfExists(startElement, "Nullable");
    String maxLength = getAttributeValueIfExists(startElement, "MaxLength");
    String unicode = getAttributeValueIfExists(startElement, "Unicode");
    String fixedLength = getAttributeValueIfExists(startElement, "FixedLength");
    String collation = getAttributeValueIfExists(startElement, "Collation");
    String collectionKindS = getAttributeValueIfExists(startElement, "CollectionKind");
    CollectionKind ckind = CollectionKind.NONE;
    if (collectionKindS != null) {
      ckind = Enum.valueOf(CollectionKind.class, collectionKindS);
    }
    String defaultValue = getAttributeValueIfExists(startElement, "DefaultValue");
    String precision = getAttributeValueIfExists(startElement, "Precision");
    String scale = getAttributeValueIfExists(startElement, "Scale");

    String storeGeneratedPattern =
        getAttributeValueIfExists(
            startElement, new QName2(NS_EDMANNOTATION, "StoreGeneratedPattern"));
    String concurrencyMode = getAttributeValueIfExists(startElement, "ConcurrencyMode");

    String mimeType = getAttributeValueIfExists(startElement, M_MIMETYPE);
    String fcTargetPath = getAttributeValueIfExists(startElement, M_FC_TARGETPATH);
    String fcContentKind = getAttributeValueIfExists(startElement, M_FC_CONTENTKIND);
    String fcKeepInContent = getAttributeValueIfExists(startElement, M_FC_KEEPINCONTENT);
    String fcEpmContentKind = getAttributeValueIfExists(startElement, M_FC_EPMCONTENTKIND);
    String fcEpmKeepInContent = getAttributeValueIfExists(startElement, M_FC_EPMKEEPINCONTENT);
    String fcNsPrefix = getAttributeValueIfExists(startElement, M_FC_NSPREFIX);
    String fcNsUri = getAttributeValueIfExists(startElement, M_FC_NSURI);

    while (reader.hasNext()) {
      XMLEvent2 event2 = reader.nextEvent();

      if (event2.isStartElement()) {
        EdmAnnotation<?> anElement = getAnnotationElements(event2, reader);
        if (anElement != null) {
          annotElements.add(anElement);
        }
      }

      if (isEndElement(event2, startElement.getName())) {
        return EdmProperty.newBuilder(propertyName)
            .setType(EdmType.newDeferredBuilder(propertyType, dataServices))
            .setNullable("true".equalsIgnoreCase(propertyNullable))
            .setMaxLength(
                maxLength == null
                    ? null
                    : maxLength.equals("Max") ? Integer.MAX_VALUE : Integer.parseInt(maxLength))
            .setUnicode(unicode == null ? null : "true".equalsIgnoreCase(unicode))
            .setFixedLength(fixedLength == null ? null : "true".equalsIgnoreCase(fixedLength))
            .setCollation(collation)
            .setConcurrencyMode(concurrencyMode)
            .setStoreGeneratedPattern(storeGeneratedPattern)
            .setMimeType(mimeType)
            .setFcTargetPath(fcTargetPath)
            .setFcContentKind(fcContentKind)
            .setFcKeepInContent(fcKeepInContent)
            .setFcEpmContentKind(fcEpmContentKind)
            .setFcEpmKeepInContent(fcEpmKeepInContent)
            .setFcNsPrefix(fcNsPrefix)
            .setFcNsUri(fcNsUri)
            .setCollectionKind(ckind)
            .setDefaultValue(defaultValue)
            .setPrecision(precision == null ? null : Integer.parseInt(precision))
            .setScale(scale == null ? null : Integer.parseInt(scale))
            .setAnnotations(getAnnotations(startElement))
            .setAnnotationElements(annotElements.isEmpty() ? null : annotElements);
      }
    }
    throw new UnsupportedOperationException();
  }