/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.olingo.server.core.serializer.xml;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.apache.olingo.commons.api.edm.EdmAction;
import org.apache.olingo.commons.api.edm.EdmActionImport;
import org.apache.olingo.commons.api.edm.EdmAnnotatable;
import org.apache.olingo.commons.api.edm.EdmAnnotation;
import org.apache.olingo.commons.api.edm.EdmAnnotations;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmEnumType;
import org.apache.olingo.commons.api.edm.EdmFunction;
import org.apache.olingo.commons.api.edm.EdmFunctionImport;
import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
import org.apache.olingo.commons.api.edm.EdmMember;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmNavigationPropertyBinding;
import org.apache.olingo.commons.api.edm.EdmOperation;
import org.apache.olingo.commons.api.edm.EdmParameter;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmReferentialConstraint;
import org.apache.olingo.commons.api.edm.EdmReturnType;
import org.apache.olingo.commons.api.edm.EdmSchema;
import org.apache.olingo.commons.api.edm.EdmSingleton;
import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.edm.EdmTerm;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.EdmTypeDefinition;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.TargetType;
import org.apache.olingo.commons.api.edm.annotation.EdmApply;
import org.apache.olingo.commons.api.edm.annotation.EdmCast;
import org.apache.olingo.commons.api.edm.annotation.EdmConstantExpression;
import org.apache.olingo.commons.api.edm.annotation.EdmDynamicExpression;
import org.apache.olingo.commons.api.edm.annotation.EdmExpression;
import org.apache.olingo.commons.api.edm.annotation.EdmIf;
import org.apache.olingo.commons.api.edm.annotation.EdmIsOf;
import org.apache.olingo.commons.api.edm.annotation.EdmLabeledElement;
import org.apache.olingo.commons.api.edm.annotation.EdmLabeledElementReference;
import org.apache.olingo.commons.api.edm.annotation.EdmLogicalOrComparisonExpression;
import org.apache.olingo.commons.api.edm.annotation.EdmNavigationPropertyPath;
import org.apache.olingo.commons.api.edm.annotation.EdmNot;
import org.apache.olingo.commons.api.edm.annotation.EdmPath;
import org.apache.olingo.commons.api.edm.annotation.EdmPropertyPath;
import org.apache.olingo.commons.api.edm.annotation.EdmPropertyValue;
import org.apache.olingo.commons.api.edm.annotation.EdmRecord;
import org.apache.olingo.commons.api.edm.annotation.EdmUrlRef;
import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
import org.apache.olingo.commons.api.edmx.EdmxReference;
import org.apache.olingo.commons.api.edmx.EdmxReferenceInclude;
import org.apache.olingo.commons.api.edmx.EdmxReferenceIncludeAnnotation;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.SerializerException;

public class MetadataDocumentXmlSerializer {

  private static final String TRUE = "true";
  private static final String XML_EXTENDS = "Extends";
  private static final String XML_TARGET = "Target";
  private static final String XML_PATH = "Path";
  private static final String XML_NAVIGATION_PROPERTY_BINDING = "NavigationPropertyBinding";
  private static final String XML_VALUE = "Value";
  private static final String XML_MEMBER = "Member";
  private static final String XML_UNDERLYING_TYPE = "UnderlyingType";
  private static final String XML_IS_FLAGS = "IsFlags";
  private static final String XML_ENUM_TYPE = "EnumType";
  private static final String XML_PROPERTY_REF = "PropertyRef";
  private static final String XML_KEY = "Key";
  private static final String XML_SCALE = "Scale";
  private static final String XML_SRID = "SRID";
  private static final String XML_PRECISION = "Precision";
  private static final String XML_MAX_LENGTH = "MaxLength";
  private static final String XML_DEFAULT_VALUE = "DefaultValue";
  private static final String XML_UNICODE = "Unicode";
  private static final String XML_PROPERTY = "Property";
  private static final String XML_PARTNER = "Partner";
  private static final String XML_NULLABLE = "Nullable";
  private static final String XML_NAVIGATION_PROPERTY = "NavigationProperty";
  private static final String XML_HAS_STREAM = "HasStream";
  private static final String XML_BASE_TYPE = "BaseType";
  private static final String XML_COMPLEX_TYPE = "ComplexType";
  private static final String XML_RETURN_TYPE = "ReturnType";
  private static final String XML_TYPE = "Type";
  private static final String XML_PARAMETER = "Parameter";
  private static final String XML_IS_COMPOSABLE = "IsComposable";
  private static final String XML_IS_BOUND = "IsBound";
  private static final String XML_ENTITY_TYPE = "EntityType";
  private static final String XML_SINGLETON_TYPE = XML_TYPE;
  private static final String XML_SINGLETON = "Singleton";
  private static final String XML_ACTION = "Action";
  private static final String XML_ACTION_IMPORT = "ActionImport";
  private static final String XML_INCLUDE_IN_SERVICE_DOCUMENT = "IncludeInServiceDocument";
  private static final String XML_ENTITY_SET = "EntitySet";
  private static final String XML_FUNCTION = "Function";
  private static final String XML_FUNCTION_IMPORT = "FunctionImport";
  private static final String XML_NAME = "Name";
  private static final String XML_ENTITY_CONTAINER = "EntityContainer";
  private static final String XML_ALIAS = "Alias";
  private static final String XML_NAMESPACE = "Namespace";
  private static final String XML_TYPE_DEFINITION = "TypeDefinition";
  private static final String XML_ANNOTATION = "Annotation";
  private static final String REFERENCE = "Reference";
  private static final String INCLUDE = "Include";
  private static final String INCLUDE_ANNOTATIONS = "IncludeAnnotations";
  private static final String XML_TERM_NAMESPACE = "TermNamespace";
  private static final String XML_TARGET_NAMESPACE = "TargetNamespace";
  private static final String XML_QUALIFIER = "Qualifier";
  private static final String URI = "Uri";
  private static final String SCHEMA = "Schema";
  private static final String DATA_SERVICES = "DataServices";
  private static final String ABSTRACT = "Abstract";

  private static final String XML_ANNOTATIONS = "Annotations";
  private static final String OPEN_TYPE = "OpenType";

  private static final String EDMX = "Edmx";
  private static final String PREFIX_EDMX = "edmx";
  private static final String NS_EDMX = "http://docs.oasis-open.org/odata/ns/edmx";

  private static final String NS_EDM = "http://docs.oasis-open.org/odata/ns/edm";
  private static final String XML_ENTITY_SET_PATH = "EntitySetPath";
  private static final String XML_CONTAINS_TARGET = "ContainsTarget";
  private static final String XML_TERM_ATT = "Term";
  private static final String XML_QUALIFIER_ATT = "Qualifier";
  private static final String XML_PROPERTY_VALUE = "PropertyValue";
  private static final String XML_BASE_TERM = "BaseTerm";
  private static final String XML_APPLIES_TO = "AppliesTo";

  private final ServiceMetadata serviceMetadata;
  private final Map<String, String> namespaceToAlias = new HashMap<>();

  public MetadataDocumentXmlSerializer(final ServiceMetadata serviceMetadata) throws SerializerException {
    if (serviceMetadata == null || serviceMetadata.getEdm() == null) {
      throw new SerializerException("Service Metadata and EDM must not be null for a service.",
          SerializerException.MessageKeys.NULL_METADATA_OR_EDM);
    }
    this.serviceMetadata = serviceMetadata;
  }

  public void writeMetadataDocument(final XMLStreamWriter writer) throws XMLStreamException {
    writer.writeStartDocument(ODataSerializer.DEFAULT_CHARSET, "1.0");
    writer.setPrefix(PREFIX_EDMX, NS_EDMX);
    writer.setDefaultNamespace(NS_EDMX);
    writer.writeStartElement(PREFIX_EDMX, EDMX, NS_EDMX);
    writer.writeAttribute("Version", "4.0");
    writer.writeNamespace(PREFIX_EDMX, NS_EDMX);

    appendReference(writer);
    appendDataServices(writer);

    writer.writeEndDocument();
  }

  private void appendDataServices(final XMLStreamWriter writer) throws XMLStreamException {
    writer.setDefaultNamespace(NS_EDM);
    writer.writeStartElement(NS_EDMX, DATA_SERVICES);
    for (EdmSchema schema : serviceMetadata.getEdm().getSchemas()) {
      appendSchema(writer, schema);
    }
    writer.writeEndElement();
  }

  private void appendSchema(final XMLStreamWriter writer, final EdmSchema schema) throws XMLStreamException {
    writer.writeStartElement(NS_EDM, SCHEMA);
    writer.writeDefaultNamespace(NS_EDM);
    writer.writeAttribute(XML_NAMESPACE, schema.getNamespace());
    if (schema.getAlias() != null) {
      writer.writeAttribute(XML_ALIAS, schema.getAlias());
      namespaceToAlias.put(schema.getNamespace(), schema.getAlias());
    }

    // EnumTypes
    appendEnumTypes(writer, schema.getEnumTypes());

    // TypeDefinitions
    appendTypeDefinitions(writer, schema.getTypeDefinitions());

    // EntityTypes
    appendEntityTypes(writer, schema.getEntityTypes());

    // ComplexTypes
    appendComplexTypes(writer, schema.getComplexTypes());

    // Actions
    appendActions(writer, schema.getActions());

    // Functions
    appendFunctions(writer, schema.getFunctions());

    appendTerms(writer, schema.getTerms());

    // EntityContainer
    appendEntityContainer(writer, schema.getEntityContainer());

    // AnnotationGroups
    appendAnnotationGroups(writer, schema.getAnnotationGroups());

    appendAnnotations(writer, schema);

    writer.writeEndElement();
  }

  private void appendTerms(final XMLStreamWriter writer, final List<EdmTerm> terms) throws XMLStreamException {
    for (EdmTerm term : terms) {
      writer.writeStartElement(XML_TERM_ATT);

      writer.writeAttribute(XML_NAME, term.getName());

      writer.writeAttribute(XML_TYPE, getAliasedFullQualifiedName(term.getType(), false));

      if (term.getBaseTerm() != null) {
        writer.writeAttribute(XML_BASE_TERM, getAliasedFullQualifiedName(term.getBaseTerm().getFullQualifiedName(),
            false));
      }

      if (term.getAppliesTo() != null && !term.getAppliesTo().isEmpty()) {
        String appliesToString = "";
        boolean first = true;
        for (TargetType target : term.getAppliesTo()) {
          if (first) {
            first = false;
            appliesToString = target.toString();
          } else {
            appliesToString = appliesToString + " " + target.toString();
          }
        }
        writer.writeAttribute(XML_APPLIES_TO, appliesToString);
      }

      // Facets
      if (!term.isNullable()) {
        writer.writeAttribute(XML_NULLABLE, "" + term.isNullable());
      }

      if (term.getDefaultValue() != null) {
        writer.writeAttribute(XML_DEFAULT_VALUE, term.getDefaultValue());
      }

      if (term.getMaxLength() != null) {
        writer.writeAttribute(XML_MAX_LENGTH, "" + term.getMaxLength());
      }

      if (term.getPrecision() != null) {
        writer.writeAttribute(XML_PRECISION, "" + term.getPrecision());
      }

      if (term.getScale() != null) {
        writer.writeAttribute(XML_SCALE, "" + term.getScale());
      }

      appendAnnotations(writer, term);
      writer.writeEndElement();
    }
  }

  private void appendAnnotationGroups(final XMLStreamWriter writer, final List<EdmAnnotations> annotationGroups)
      throws XMLStreamException {
    for (EdmAnnotations annotationGroup : annotationGroups) {
      appendAnnotationGroup(writer, annotationGroup);
    }
  }

  private void appendAnnotationGroup(final XMLStreamWriter writer, final EdmAnnotations annotationGroup)
      throws XMLStreamException {
    writer.writeStartElement(XML_ANNOTATIONS);
    writer.writeAttribute(XML_TARGET, annotationGroup.getTargetPath());
    if (annotationGroup.getQualifier() != null) {
      writer.writeAttribute(XML_QUALIFIER_ATT, annotationGroup.getQualifier());
    }
    appendAnnotations(writer, annotationGroup);
    writer.writeEndElement();
  }

  private void appendAnnotations(final XMLStreamWriter writer, final EdmAnnotatable annotatable)
      throws XMLStreamException {
    List<EdmAnnotation> annotations = annotatable.getAnnotations();
    if (annotations != null && !annotations.isEmpty()) {
      for (EdmAnnotation annotation : annotations) {
        writer.writeStartElement(XML_ANNOTATION);
        if (annotation.getTerm() != null) {
          writer.writeAttribute(XML_TERM_ATT, getAliasedFullQualifiedName(annotation.getTerm().getFullQualifiedName(),
              false));
        }
        if (annotation.getQualifier() != null) {
          writer.writeAttribute(XML_QUALIFIER_ATT, annotation.getQualifier());
        }
        appendExpression(writer, annotation.getExpression());
        appendAnnotations(writer, annotation);
        writer.writeEndElement();
      }
    }
  }

  private void appendExpression(final XMLStreamWriter writer,
      final EdmExpression expression) throws XMLStreamException {
    if (expression == null) {
      return;
    }
    if (expression.isConstant()) {
      appendConstantExpression(writer, expression.asConstant());
    } else if (expression.isDynamic()) {
      appendDynamicExpression(writer, expression.asDynamic());
    } else {
      throw new IllegalArgumentException("Unkown expressiontype in metadata");
    }
  }

  private void appendDynamicExpression(final XMLStreamWriter writer, final EdmDynamicExpression dynExp)
      throws XMLStreamException {
    writer.writeStartElement(dynExp.getExpressionName());
    switch (dynExp.getExpressionType()) {
    // Logical
    case And:
      appendLogicalOrComparisonExpression(writer, dynExp.asAnd());
      break;
    case Or:
      appendLogicalOrComparisonExpression(writer, dynExp.asOr());
      break;
    case Not:
      appendNotExpression(writer, dynExp.asNot());
      break;
    // Comparison
    case Eq:
      appendLogicalOrComparisonExpression(writer, dynExp.asEq());
      break;
    case Ne:
      appendLogicalOrComparisonExpression(writer, dynExp.asNe());
      break;
    case Gt:
      appendLogicalOrComparisonExpression(writer, dynExp.asGt());
      break;
    case Ge:
      appendLogicalOrComparisonExpression(writer, dynExp.asGe());
      break;
    case Lt:
      appendLogicalOrComparisonExpression(writer, dynExp.asLt());
      break;
    case Le:
      appendLogicalOrComparisonExpression(writer, dynExp.asLe());
      break;
    case AnnotationPath:
      writer.writeCharacters(dynExp.asAnnotationPath().getValue());
      break;
    case Apply:
      EdmApply asApply = dynExp.asApply();
      writer.writeAttribute(XML_FUNCTION, asApply.getFunction());
      for (EdmExpression parameter : asApply.getParameters()) {
        appendExpression(writer, parameter);
      }
      appendAnnotations(writer, asApply);
      break;
    case Cast:
      EdmCast asCast = dynExp.asCast();
      writer.writeAttribute(XML_TYPE, getAliasedFullQualifiedName(asCast.getType(), false));

      if (asCast.getMaxLength() != null) {
        writer.writeAttribute(XML_MAX_LENGTH, "" + asCast.getMaxLength());
      }

      if (asCast.getPrecision() != null) {
        writer.writeAttribute(XML_PRECISION, "" + asCast.getPrecision());
      }

      if (asCast.getScale() != null) {
        writer.writeAttribute(XML_SCALE, "" + asCast.getScale());
      }
      appendExpression(writer, asCast.getValue());
      appendAnnotations(writer, asCast);
      break;
    case Collection:
      for (EdmExpression item : dynExp.asCollection().getItems()) {
        appendExpression(writer, item);
      }
      break;
    case If:
      EdmIf asIf = dynExp.asIf();
      appendExpression(writer, asIf.getGuard());
      appendExpression(writer, asIf.getThen());
      appendExpression(writer, asIf.getElse());
      appendAnnotations(writer, asIf);
      break;
    case IsOf:
      EdmIsOf asIsOf = dynExp.asIsOf();
      writer.writeAttribute(XML_TYPE, getAliasedFullQualifiedName(asIsOf.getType(), false));

      if (asIsOf.getMaxLength() != null) {
        writer.writeAttribute(XML_MAX_LENGTH, "" + asIsOf.getMaxLength());
      }

      if (asIsOf.getPrecision() != null) {
        writer.writeAttribute(XML_PRECISION, "" + asIsOf.getPrecision());
      }

      if (asIsOf.getScale() != null) {
        writer.writeAttribute(XML_SCALE, "" + asIsOf.getScale());
      }
      appendExpression(writer, asIsOf.getValue());
      appendAnnotations(writer, asIsOf);
      break;
    case LabeledElement:
      EdmLabeledElement asLabeledElement = dynExp.asLabeledElement();
      writer.writeAttribute(XML_NAME, asLabeledElement.getName());
      appendExpression(writer, asLabeledElement.getValue());
      appendAnnotations(writer, asLabeledElement);
      break;
    case LabeledElementReference:
      EdmLabeledElementReference asLabeledElementReference = dynExp.asLabeledElementReference();
      writer.writeCharacters(asLabeledElementReference.getValue());
      break;
    case Null:
      appendAnnotations(writer, dynExp.asNull());
      break;
    case NavigationPropertyPath:
      EdmNavigationPropertyPath asNavigationPropertyPath = dynExp.asNavigationPropertyPath();
      writer.writeCharacters(asNavigationPropertyPath.getValue());
      break;
    case Path:
      EdmPath asPath = dynExp.asPath();
      writer.writeCharacters(asPath.getValue());
      break;
    case PropertyPath:
      EdmPropertyPath asPropertyPath = dynExp.asPropertyPath();
      writer.writeCharacters(asPropertyPath.getValue());
      break;
    case Record:
      EdmRecord asRecord = dynExp.asRecord();
      EdmStructuredType type = asRecord.getType();
      if (type != null) {
        writer.writeAttribute(XML_TYPE, getAliasedFullQualifiedName(type, false));
      }
      for (EdmPropertyValue propValue : asRecord.getPropertyValues()) {
        writer.writeStartElement(XML_PROPERTY_VALUE);
        writer.writeAttribute(XML_PROPERTY, propValue.getProperty());
        appendExpression(writer, propValue.getValue());
        appendAnnotations(writer, propValue);
        writer.writeEndElement();
      }
      appendAnnotations(writer, asRecord);
      break;
    case UrlRef:
      EdmUrlRef asUrlRef = dynExp.asUrlRef();
      appendExpression(writer, asUrlRef.getValue());
      appendAnnotations(writer, asUrlRef);
      break;
    default:
      throw new IllegalArgumentException("Unkown ExpressionType for dynamic expression: " + dynExp.getExpressionType());
    }

    writer.writeEndElement();
  }

  private void appendNotExpression(final XMLStreamWriter writer, final EdmNot exp) throws XMLStreamException {
    appendExpression(writer, exp.getLeftExpression());
    appendAnnotations(writer, exp);
  }

  private void appendLogicalOrComparisonExpression(final XMLStreamWriter writer,
      final EdmLogicalOrComparisonExpression exp)
      throws XMLStreamException {
    appendExpression(writer, exp.getLeftExpression());
    appendExpression(writer, exp.getRightExpression());
    appendAnnotations(writer, exp);
  }

  private void appendConstantExpression(final XMLStreamWriter writer, final EdmConstantExpression constExp)
      throws XMLStreamException {
    writer.writeStartElement(constExp.getExpressionName());
    writer.writeCharacters(constExp.getValueAsString());
    writer.writeEndElement();
  }

  private void appendTypeDefinitions(final XMLStreamWriter writer, final List<EdmTypeDefinition> typeDefinitions)
      throws XMLStreamException {
    for (EdmTypeDefinition definition : typeDefinitions) {
      writer.writeStartElement(XML_TYPE_DEFINITION);
      writer.writeAttribute(XML_NAME, definition.getName());
      writer.writeAttribute(XML_UNDERLYING_TYPE, getFullQualifiedName(definition.getUnderlyingType(), false));

      // Facets
      if (definition.getMaxLength() != null) {
        writer.writeAttribute(XML_MAX_LENGTH, "" + definition.getMaxLength());
      }

      if (definition.getPrecision() != null) {
        writer.writeAttribute(XML_PRECISION, "" + definition.getPrecision());
      }

      if (definition.getScale() != null) {
        writer.writeAttribute(XML_SCALE, "" + definition.getScale());
      }

      appendAnnotations(writer, definition);
      writer.writeEndElement();
    }
  }

  private void appendEntityContainer(final XMLStreamWriter writer, final EdmEntityContainer container)
      throws XMLStreamException {
    if (container != null) {
      writer.writeStartElement(XML_ENTITY_CONTAINER);

      writer.writeAttribute(XML_NAME, container.getName());
      FullQualifiedName parentContainerName = container.getParentContainerName();
      if (parentContainerName != null) {
        String parentContainerNameString;
        if (namespaceToAlias.get(parentContainerName.getNamespace()) != null) {
          parentContainerNameString =
              namespaceToAlias.get(parentContainerName.getNamespace()) + "." + parentContainerName.getName();
        } else {
          parentContainerNameString = parentContainerName.getFullQualifiedNameAsString();
        }
        writer.writeAttribute(XML_EXTENDS, parentContainerNameString);
      }

      // EntitySets
      appendEntitySets(writer, container.getEntitySets());

      // ActionImports
      appendActionImports(writer, container.getActionImports());

      // FunctionImports
      String containerNamespace;
      if (namespaceToAlias.get(container.getNamespace()) != null) {
        containerNamespace = namespaceToAlias.get(container.getNamespace());
      } else {
        containerNamespace = container.getNamespace();
      }
      appendFunctionImports(writer, container.getFunctionImports(), containerNamespace);

      // Singletons
      appendSingletons(writer, container.getSingletons());

      // Annotations
      appendAnnotations(writer, container);

      writer.writeEndElement();
    }
  }

  private void appendFunctionImports(final XMLStreamWriter writer, final List<EdmFunctionImport> functionImports,
      final String containerNamespace) throws XMLStreamException {
    for (EdmFunctionImport functionImport : functionImports) {
      writer.writeStartElement(XML_FUNCTION_IMPORT);
      writer.writeAttribute(XML_NAME, functionImport.getName());

      String functionFQNString;
      FullQualifiedName functionFqn = functionImport.getFunctionFqn();
      if (namespaceToAlias.get(functionFqn.getNamespace()) != null) {
        functionFQNString = namespaceToAlias.get(functionFqn.getNamespace()) + "." + functionFqn.getName();
      } else {
        functionFQNString = functionFqn.getFullQualifiedNameAsString();
      }
      writer.writeAttribute(XML_FUNCTION, functionFQNString);

      EdmEntitySet returnedEntitySet = functionImport.getReturnedEntitySet();
      if (returnedEntitySet != null) {
        String returnedEntitySetNamespace = returnedEntitySet.getEntityContainer().getNamespace();
        if ((null != returnedEntitySetNamespace && returnedEntitySetNamespace.equals(containerNamespace)) || (
            namespaceToAlias.get(returnedEntitySetNamespace) != null && 
            namespaceToAlias.get(returnedEntitySetNamespace).equals(containerNamespace))) {
          writer.writeAttribute(XML_ENTITY_SET, returnedEntitySet.getName());
        } else {
          writer.writeAttribute(XML_ENTITY_SET, containerNamespace + "." + returnedEntitySet.getName());
        }
      }
      // Default is false and we do not write the default
      if (functionImport.isIncludeInServiceDocument()) {
        writer.writeAttribute(XML_INCLUDE_IN_SERVICE_DOCUMENT, "" + functionImport.isIncludeInServiceDocument());
      }
      appendAnnotations(writer, functionImport);
      writer.writeEndElement();
    }
  }

  private void appendActionImports(final XMLStreamWriter writer, final List<EdmActionImport> actionImports)
      throws XMLStreamException {
    for (EdmActionImport actionImport : actionImports) {
      writer.writeStartElement(XML_ACTION_IMPORT);
      writer.writeAttribute(XML_NAME, actionImport.getName());
      writer.writeAttribute(XML_ACTION, getAliasedFullQualifiedName(actionImport.getUnboundAction(), false));
      appendAnnotations(writer, actionImport);
      writer.writeEndElement();
    }
  }

  private void appendSingletons(final XMLStreamWriter writer, final List<EdmSingleton> singletons)
      throws XMLStreamException {
    for (EdmSingleton singleton : singletons) {
      writer.writeStartElement(XML_SINGLETON);
      writer.writeAttribute(XML_NAME, singleton.getName());
      writer.writeAttribute(XML_SINGLETON_TYPE, getAliasedFullQualifiedName(singleton.getEntityType(), false));

      appendNavigationPropertyBindings(writer, singleton);
      appendAnnotations(writer, singleton);
      writer.writeEndElement();
    }

  }

  private void appendNavigationPropertyBindings(final XMLStreamWriter writer, final EdmBindingTarget bindingTarget)
      throws XMLStreamException {
    if (bindingTarget.getNavigationPropertyBindings() != null) {
      for (EdmNavigationPropertyBinding binding : bindingTarget.getNavigationPropertyBindings()) {
        writer.writeEmptyElement(XML_NAVIGATION_PROPERTY_BINDING);
        writer.writeAttribute(XML_PATH, binding.getPath());
        writer.writeAttribute(XML_TARGET, binding.getTarget());
      }
    }
  }

  private void appendEntitySets(final XMLStreamWriter writer, final List<EdmEntitySet> entitySets)
      throws XMLStreamException {
    for (EdmEntitySet entitySet : entitySets) {
      writer.writeStartElement(XML_ENTITY_SET);
      writer.writeAttribute(XML_NAME, entitySet.getName());
      writer.writeAttribute(XML_ENTITY_TYPE, getAliasedFullQualifiedName(entitySet.getEntityType(), false));
      if (!entitySet.isIncludeInServiceDocument()) {
        writer.writeAttribute(XML_INCLUDE_IN_SERVICE_DOCUMENT, "" + entitySet.isIncludeInServiceDocument());
      }

      appendNavigationPropertyBindings(writer, entitySet);
      appendAnnotations(writer, entitySet);
      writer.writeEndElement();
    }
  }

  private void appendFunctions(final XMLStreamWriter writer, final List<EdmFunction> functions)
      throws XMLStreamException {
    for (EdmFunction function : functions) {
      writer.writeStartElement(XML_FUNCTION);
      writer.writeAttribute(XML_NAME, function.getName());
      if (function.getEntitySetPath() != null) {
        writer.writeAttribute(XML_ENTITY_SET_PATH, function.getEntitySetPath());
      }
      if (function.isBound()) {
        writer.writeAttribute(XML_IS_BOUND, "" + function.isBound());
      }

      if (function.isComposable()) {
        writer.writeAttribute(XML_IS_COMPOSABLE, "" + function.isComposable());
      }

      appendOperationParameters(writer, function);

      appendOperationReturnType(writer, function);

      appendAnnotations(writer, function);

      writer.writeEndElement();
    }
  }

  private void appendOperationReturnType(final XMLStreamWriter writer, final EdmOperation operation)
      throws XMLStreamException {
    EdmReturnType returnType = operation.getReturnType();
    if (returnType != null) {
      writer.writeEmptyElement(XML_RETURN_TYPE);
      String returnTypeFqnString;
      if (EdmTypeKind.PRIMITIVE.equals(returnType.getType().getKind())) {
        returnTypeFqnString = getFullQualifiedName(returnType.getType(), returnType.isCollection());
      } else {
        returnTypeFqnString = getAliasedFullQualifiedName(returnType.getType(), returnType.isCollection());
      }
      writer.writeAttribute(XML_TYPE, returnTypeFqnString);

      appendReturnTypeFacets(writer, returnType);
    }
  }

  private void appendOperationParameters(final XMLStreamWriter writer, final EdmOperation operation)
      throws XMLStreamException {
    for (String parameterName : operation.getParameterNames()) {
      EdmParameter parameter = operation.getParameter(parameterName);
      writer.writeStartElement(XML_PARAMETER);
      writer.writeAttribute(XML_NAME, parameterName);
      String typeFqnString;
      if (EdmTypeKind.PRIMITIVE.equals(parameter.getType().getKind())) {
        typeFqnString = getFullQualifiedName(parameter.getType(), parameter.isCollection());
      } else {
        typeFqnString = getAliasedFullQualifiedName(parameter.getType(), parameter.isCollection());
      }
      writer.writeAttribute(XML_TYPE, typeFqnString);

      appendParameterFacets(writer, parameter);

      appendAnnotations(writer, parameter);
      writer.writeEndElement();
    }
  }

  private void appendActions(final XMLStreamWriter writer, final List<EdmAction> actions) throws XMLStreamException {
    for (EdmAction action : actions) {
      writer.writeStartElement(XML_ACTION);
      writer.writeAttribute(XML_NAME, action.getName());
      if (action.getEntitySetPath() != null) {
        writer.writeAttribute(XML_ENTITY_SET_PATH, action.getEntitySetPath());
      }
      writer.writeAttribute(XML_IS_BOUND, "" + action.isBound());

      appendOperationParameters(writer, action);

      appendOperationReturnType(writer, action);

      appendAnnotations(writer, action);

      writer.writeEndElement();
    }
  }

  private void appendReturnTypeFacets(final XMLStreamWriter writer, final EdmReturnType returnType)
      throws XMLStreamException {
    if (!returnType.isNullable()) {
      writer.writeAttribute(XML_NULLABLE, "" + returnType.isNullable());
    }
    if (returnType.getMaxLength() != null) {
      writer.writeAttribute(XML_MAX_LENGTH, "" + returnType.getMaxLength());
    }
    if (returnType.getPrecision() != null) {
      writer.writeAttribute(XML_PRECISION, "" + returnType.getPrecision());
    }
    if (returnType.getScale() != null) {
      writer.writeAttribute(XML_SCALE, "" + returnType.getScale());
    }
  }

  private void appendParameterFacets(final XMLStreamWriter writer, final EdmParameter parameter)
      throws XMLStreamException {
    if (!parameter.isNullable()) {
      writer.writeAttribute(XML_NULLABLE, "" + parameter.isNullable());
    }
    if (parameter.getMaxLength() != null) {
      writer.writeAttribute(XML_MAX_LENGTH, "" + parameter.getMaxLength());
    }
    if (parameter.getPrecision() != null) {
      writer.writeAttribute(XML_PRECISION, "" + parameter.getPrecision());
    }
    if (parameter.getScale() != null) {
      writer.writeAttribute(XML_SCALE, "" + parameter.getScale());
    }
  }

  private void appendComplexTypes(final XMLStreamWriter writer, final List<EdmComplexType> complexTypes)
      throws XMLStreamException {
    for (EdmComplexType complexType : complexTypes) {
      writer.writeStartElement(XML_COMPLEX_TYPE);
      writer.writeAttribute(XML_NAME, complexType.getName());

      if (complexType.getBaseType() != null) {
        writer.writeAttribute(XML_BASE_TYPE, getAliasedFullQualifiedName(complexType.getBaseType(), false));
      }

      if (complexType.isAbstract()) {
        writer.writeAttribute(ABSTRACT, TRUE);
      }
      
      if (complexType.isOpenType()) {
          writer.writeAttribute(OPEN_TYPE, TRUE);
      }
      
      appendProperties(writer, complexType);

      appendNavigationProperties(writer, complexType);

      appendAnnotations(writer, complexType);

      writer.writeEndElement();
    }
  }

  private void appendEntityTypes(final XMLStreamWriter writer, final List<EdmEntityType> entityTypes)
      throws XMLStreamException {
    for (EdmEntityType entityType : entityTypes) {
      writer.writeStartElement(XML_ENTITY_TYPE);
      writer.writeAttribute(XML_NAME, entityType.getName());

      if (entityType.hasStream()) {
        writer.writeAttribute(XML_HAS_STREAM, "" + entityType.hasStream());
      }

      if (entityType.getBaseType() != null) {
        writer.writeAttribute(XML_BASE_TYPE, getAliasedFullQualifiedName(entityType.getBaseType(), false));
      }

      if (entityType.isAbstract()) {
        writer.writeAttribute(ABSTRACT, TRUE);
      }

      if (entityType.isOpenType()) {
          writer.writeAttribute(OPEN_TYPE, TRUE);
      }      
      
      appendKey(writer, entityType);

      appendProperties(writer, entityType);

      appendNavigationProperties(writer, entityType);

      appendAnnotations(writer, entityType);

      writer.writeEndElement();
    }
  }

  private void appendNavigationProperties(final XMLStreamWriter writer, final EdmStructuredType type)
      throws XMLStreamException {
    List<String> navigationPropertyNames = new ArrayList<>(type.getNavigationPropertyNames());
    if (type.getBaseType() != null) {
      navigationPropertyNames.removeAll(type.getBaseType().getNavigationPropertyNames());
    }
    for (String navigationPropertyName : navigationPropertyNames) {
      EdmNavigationProperty navigationProperty = type.getNavigationProperty(navigationPropertyName);

      writer.writeStartElement(XML_NAVIGATION_PROPERTY);
      writer.writeAttribute(XML_NAME, navigationPropertyName);
      writer.writeAttribute(XML_TYPE, getAliasedFullQualifiedName(navigationProperty.getType(), navigationProperty
          .isCollection()));
      if (!navigationProperty.isNullable()) {
        writer.writeAttribute(XML_NULLABLE, "" + navigationProperty.isNullable());
      }

      if (navigationProperty.getPartner() != null) {
        EdmNavigationProperty partner = navigationProperty.getPartner();
        writer.writeAttribute(XML_PARTNER, partner.getName());
      }

      if (navigationProperty.containsTarget()) {
        writer.writeAttribute(XML_CONTAINS_TARGET, "" + navigationProperty.containsTarget());
      }

      if (navigationProperty.getReferentialConstraints() != null) {
        for (EdmReferentialConstraint constraint : navigationProperty.getReferentialConstraints()) {
          writer.writeStartElement("ReferentialConstraint");
          writer.writeAttribute(XML_PROPERTY, constraint.getPropertyName());
          writer.writeAttribute("ReferencedProperty", constraint.getReferencedPropertyName());
          appendAnnotations(writer, constraint);
          writer.writeEndElement();
        }
      }

      appendAnnotations(writer, navigationProperty);

      writer.writeEndElement();
    }
  }

  private void appendProperties(final XMLStreamWriter writer, final EdmStructuredType type) throws XMLStreamException {
    List<String> propertyNames = new ArrayList<>(type.getPropertyNames());
    if (type.getBaseType() != null) {
      propertyNames.removeAll(type.getBaseType().getPropertyNames());
    }
    for (String propertyName : propertyNames) {
      EdmProperty property = type.getStructuralProperty(propertyName);
      writer.writeStartElement(XML_PROPERTY);
      writer.writeAttribute(XML_NAME, propertyName);
      String fqnString;
      if (property.isPrimitive()) {
        fqnString = getFullQualifiedName(property.getType(), property.isCollection());
      } else {
        fqnString = getAliasedFullQualifiedName(property.getType(), property.isCollection());
      }
      writer.writeAttribute(XML_TYPE, fqnString);

      // Facets
      if (!property.isNullable()) {
        writer.writeAttribute(XML_NULLABLE, "" + property.isNullable());
      }

      if (!property.isUnicode()) {
        writer.writeAttribute(XML_UNICODE, "" + property.isUnicode());
      }

      if (property.getDefaultValue() != null) {
        writer.writeAttribute(XML_DEFAULT_VALUE, property.getDefaultValue());
      }

      if (property.getMaxLength() != null) {
        writer.writeAttribute(XML_MAX_LENGTH, "" + property.getMaxLength());
      }

      if (property.getPrecision() != null) {
        writer.writeAttribute(XML_PRECISION, "" + property.getPrecision());
      }

      if (property.getScale() != null) {
        writer.writeAttribute(XML_SCALE, "" + property.getScale());
      }
      
      if (property.getSrid() != null) {
          writer.writeAttribute(XML_SRID, "" + property.getSrid());
      }

      appendAnnotations(writer, property);
      writer.writeEndElement();
    }
  }

  private void appendKey(final XMLStreamWriter writer, final EdmEntityType entityType) throws XMLStreamException {
    List<EdmKeyPropertyRef> keyPropertyRefs = entityType.getKeyPropertyRefs();
    if (keyPropertyRefs != null && !keyPropertyRefs.isEmpty()) {
      // Resolve Base Type key as it is shown in derived type
      EdmEntityType baseType = entityType.getBaseType();
      if (baseType != null && baseType.getKeyPropertyRefs() != null && !(baseType.getKeyPropertyRefs().isEmpty())) {
        return;
      }

      writer.writeStartElement(XML_KEY);
      for (EdmKeyPropertyRef keyRef : keyPropertyRefs) {
        writer.writeEmptyElement(XML_PROPERTY_REF);

        writer.writeAttribute(XML_NAME, keyRef.getName());

        if (keyRef.getAlias() != null) {
          writer.writeAttribute(XML_ALIAS, keyRef.getAlias());
        }
      }
      writer.writeEndElement();
    }
  }

  private void appendEnumTypes(final XMLStreamWriter writer, final List<EdmEnumType> enumTypes)
      throws XMLStreamException {
    for (EdmEnumType enumType : enumTypes) {
      writer.writeStartElement(XML_ENUM_TYPE);
      writer.writeAttribute(XML_NAME, enumType.getName());
      writer.writeAttribute(XML_IS_FLAGS, Boolean.toString(enumType.isFlags()));
      writer.writeAttribute(XML_UNDERLYING_TYPE, getFullQualifiedName(enumType.getUnderlyingType(), false));

      for (String memberName : enumType.getMemberNames()) {
        writer.writeStartElement(XML_MEMBER);
        writer.writeAttribute(XML_NAME, memberName);

        EdmMember member = enumType.getMember(memberName);
        if (member.getValue() != null) {
          writer.writeAttribute(XML_VALUE, member.getValue());
        }

        appendAnnotations(writer, member);
        writer.writeEndElement();
      }

      writer.writeEndElement();
    }
  }

  private String getFullQualifiedName(final EdmType type, final boolean isCollection) {
    final String name = type.getFullQualifiedName().getFullQualifiedNameAsString();
    return isCollection ? "Collection(" + name + ")" : name;
  }

  private String getAliasedFullQualifiedName(final EdmType type, final boolean isCollection) {
    FullQualifiedName fqn = type.getFullQualifiedName();
    return getAliasedFullQualifiedName(fqn, isCollection);
  }

  private String getAliasedFullQualifiedName(final FullQualifiedName fqn, final boolean isCollection) {
    final String name;
    if (namespaceToAlias.get(fqn.getNamespace()) != null) {
      name = namespaceToAlias.get(fqn.getNamespace()) + "." + fqn.getName();
    } else {
      name = fqn.getFullQualifiedNameAsString();
    }

    return isCollection ? "Collection(" + name + ")" : name;
  }

  /**
   * Appends references, e.g., to the OData Core Vocabulary, as defined in the OData specification
   * and mentioned in its Common Schema Definition Language (CSDL) document.
   */
  private void appendReference(final XMLStreamWriter writer) throws XMLStreamException {
    for (final EdmxReference reference : serviceMetadata.getReferences()) {
      writer.writeStartElement(PREFIX_EDMX, REFERENCE, NS_EDMX);
      writer.writeAttribute(URI, reference.getUri().toASCIIString());

      List<EdmxReferenceInclude> includes = reference.getIncludes();
      for (EdmxReferenceInclude include : includes) {
        writer.writeStartElement(PREFIX_EDMX, INCLUDE, NS_EDMX);
        writer.writeAttribute(XML_NAMESPACE, include.getNamespace());
        if (include.getAlias() != null) {
          namespaceToAlias.put(include.getNamespace(), include.getAlias());
          // Reference Aliases are ignored for now since they are not V2 compatible
          writer.writeAttribute(XML_ALIAS, include.getAlias());
        }
        writer.writeEndElement();
      }

      List<EdmxReferenceIncludeAnnotation> includeAnnotations = reference.getIncludeAnnotations();
      for (EdmxReferenceIncludeAnnotation includeAnnotation : includeAnnotations) {
        writer.writeStartElement(PREFIX_EDMX, INCLUDE_ANNOTATIONS, NS_EDMX);
        writer.writeAttribute(XML_TERM_NAMESPACE, includeAnnotation.getTermNamespace());
        if (includeAnnotation.getQualifier() != null) {
          writer.writeAttribute(XML_QUALIFIER, includeAnnotation.getQualifier());
        }
        if (includeAnnotation.getTargetNamespace() != null) {
          writer.writeAttribute(XML_TARGET_NAMESPACE, includeAnnotation.getTargetNamespace());
        }
        writer.writeEndElement();
      }

      writer.writeEndElement();
    }
  }
}
