You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2015/10/22 10:40:19 UTC

[36/48] olingo-odata4 git commit: [OLINGO-786] Annotation metadata serialization and tests

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d00e3881/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java
index 87cb4b4..356b90e 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java
@@ -26,11 +26,11 @@ import java.util.Map;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 
-import org.apache.olingo.commons.api.data.Valuable;
 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;
@@ -40,6 +40,7 @@ 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;
@@ -53,8 +54,23 @@ import org.apache.olingo.commons.api.edm.EdmStructuredType;
 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.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.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.edmx.EdmxReference;
@@ -119,6 +135,8 @@ public class MetadataDocumentXmlSerializer {
   private static final String DATA_SERVICES = "DataServices";
   private static final String ABSTRACT = "Abstract";
 
+  private static final String XML_ANNOTATIONS = "Annotations";
+
   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";
@@ -128,6 +146,7 @@ public class MetadataDocumentXmlSerializer {
   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 final ServiceMetadata serviceMetadata;
   private final Map<String, String> namespaceToAlias = new HashMap<String, String>();
@@ -140,8 +159,6 @@ public class MetadataDocumentXmlSerializer {
     this.serviceMetadata = serviceMetadata;
   }
 
-  // TODO: Annotations in metadata document
-
   public void writeMetadataDocument(final XMLStreamWriter writer) throws XMLStreamException {
     writer.writeStartDocument(ODataSerializer.DEFAULT_CHARSET, "1.0");
     writer.setPrefix(PREFIX_EDMX, NS_EDMX);
@@ -195,13 +212,227 @@ public class MetadataDocumentXmlSerializer {
     // EntityContainer
     appendEntityContainer(writer, schema.getEntityContainer());
 
+    // AnnotationGroups
+    appendAnnotationGroups(writer, schema.getAnnotationGroups());
+
+    appendAnnotations(writer, schema);
+
+    writer.writeEndElement();
+  }
+
+  private void appendAnnotationGroups(XMLStreamWriter writer, List<EdmAnnotations> annotationGroups)
+      throws XMLStreamException {
+    for (EdmAnnotations annotationGroup : annotationGroups) {
+      appendAnnotationGroup(writer, annotationGroup);
+    }
+  }
+
+  private void appendAnnotationGroup(XMLStreamWriter writer, 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(XMLStreamWriter writer, 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, annotation.getTerm().getFullQualifiedName()
+              .getFullQualifiedNameAsString());
+        }
+        if (annotation.getQualifier() != null) {
+          writer.writeAttribute(XML_QUALIFIER_ATT, annotation.getQualifier());
+        }
+        appendExpression(writer, annotation.getExpression());
+        appendAnnotations(writer, annotation);
+        writer.writeEndElement();
+      }
+    }
+  }
+
+  private void appendExpression(XMLStreamWriter writer, 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(XMLStreamWriter writer, 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, asCast.getType().getFullQualifiedName().getFullQualifiedNameAsString());
+
+      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, asIsOf.getType().getFullQualifiedName().getFullQualifiedNameAsString());
+
+      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();
+      writer.writeAttribute(XML_TYPE, asRecord.getType().getFullQualifiedName().getFullQualifiedNameAsString());
+      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(XMLStreamWriter writer, EdmNot exp) throws XMLStreamException {
+    appendExpression(writer, exp.getLeftExpression());
+    appendAnnotations(writer, exp);
+  }
+
+  private void appendLogicalOrComparisonExpression(XMLStreamWriter writer, EdmLogicalOrComparisonExpression exp)
+      throws XMLStreamException {
+    appendExpression(writer, exp.getLeftExpression());
+    appendExpression(writer, exp.getRightExpression());
+    appendAnnotations(writer, exp);
+  }
+
+  private void appendConstantExpression(XMLStreamWriter writer, 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.writeEmptyElement(XML_TYPE_DEFINITION);
+      writer.writeStartElement(XML_TYPE_DEFINITION);
       writer.writeAttribute(XML_NAME, definition.getName());
       writer.writeAttribute(XML_UNDERLYING_TYPE, getFullQualifiedName(definition.getUnderlyingType(), false));
 
@@ -217,6 +448,9 @@ public class MetadataDocumentXmlSerializer {
       if (definition.getScale() != null) {
         writer.writeAttribute(XML_SCALE, "" + definition.getScale());
       }
+
+      appendAnnotations(writer, definition);
+      writer.writeEndElement();
     }
   }
 
@@ -256,6 +490,9 @@ public class MetadataDocumentXmlSerializer {
       // Singletons
       appendSingletons(writer, container.getSingletons());
 
+      // Annotations
+      appendAnnotations(writer, container);
+
       writer.writeEndElement();
     }
   }
@@ -283,6 +520,7 @@ public class MetadataDocumentXmlSerializer {
       if (functionImport.isIncludeInServiceDocument()) {
         writer.writeAttribute(XML_INCLUDE_IN_SERVICE_DOCUMENT, "" + functionImport.isIncludeInServiceDocument());
       }
+      appendAnnotations(writer, functionImport);
       writer.writeEndElement();
     }
   }
@@ -294,6 +532,7 @@ public class MetadataDocumentXmlSerializer {
       writer.writeAttribute(XML_NAME, actionImport.getName());
       writer.writeAttribute(XML_ACTION, getAliasedFullQualifiedName(actionImport.getUnboundAction(), false));
       writer.writeEndElement();
+      appendAnnotations(writer, actionImport);
     }
   }
 
@@ -305,6 +544,7 @@ public class MetadataDocumentXmlSerializer {
       writer.writeAttribute(XML_ENTITY_TYPE, getAliasedFullQualifiedName(singleton.getEntityType(), false));
 
       appendNavigationPropertyBindings(writer, singleton);
+      appendAnnotations(writer, singleton);
       writer.writeEndElement();
     }
 
@@ -357,6 +597,8 @@ public class MetadataDocumentXmlSerializer {
 
       appendOperationReturnType(writer, function);
 
+      appendAnnotations(writer, function);
+
       writer.writeEndElement();
     }
   }
@@ -382,7 +624,7 @@ public class MetadataDocumentXmlSerializer {
       throws XMLStreamException {
     for (String parameterName : operation.getParameterNames()) {
       EdmParameter parameter = operation.getParameter(parameterName);
-      writer.writeEmptyElement(XML_PARAMETER);
+      writer.writeStartElement(XML_PARAMETER);
       writer.writeAttribute(XML_NAME, parameterName);
       String typeFqnString;
       if (EdmTypeKind.PRIMITIVE.equals(parameter.getType().getKind())) {
@@ -393,6 +635,9 @@ public class MetadataDocumentXmlSerializer {
       writer.writeAttribute(XML_TYPE, typeFqnString);
 
       appendParameterFacets(writer, parameter);
+
+      appendAnnotations(writer, parameter);
+      writer.writeEndElement();
     }
   }
 
@@ -409,6 +654,8 @@ public class MetadataDocumentXmlSerializer {
 
       appendOperationReturnType(writer, action);
 
+      appendAnnotations(writer, action);
+
       writer.writeEndElement();
     }
   }
@@ -463,6 +710,8 @@ public class MetadataDocumentXmlSerializer {
 
       appendNavigationProperties(writer, complexType);
 
+      appendAnnotations(writer, complexType);
+
       writer.writeEndElement();
     }
   }
@@ -497,30 +746,6 @@ public class MetadataDocumentXmlSerializer {
     }
   }
 
-  private void appendAnnotations(XMLStreamWriter writer, EdmAnnotatable annotatable) throws XMLStreamException {
-    List<EdmAnnotation> annotations = annotatable.getAnnotations();
-    for (EdmAnnotation annotation : annotations) {
-      writer.writeStartElement(XML_ANNOTATION);
-      String term = getAliasedFullQualifiedName(annotation.getTerm().getFullQualifiedName(), false);
-      writer.writeAttribute(XML_TERM_ATT, term);
-      String qualifier = annotation.getQualifier();
-      if (qualifier != null) {
-        writer.writeAttribute(XML_QUALIFIER_ATT, qualifier);
-      }
-      EdmExpression expression = annotation.getExpression();
-      if (expression != null) {
-        if (expression.isConstant()) {
-          EdmConstantExpression constExpression = expression.asConstant();
-          Valuable value = constExpression.getValue();
-          writer.writeAttribute(value.getType(), constExpression.getValueAsString());
-        } else {
-          // TODO: mibo_150930: Handle dynamic expressions
-        }
-      }
-      writer.writeEndElement();
-    }
-  }
-
   private void appendNavigationProperties(final XMLStreamWriter writer, final EdmStructuredType type)
       throws XMLStreamException {
     List<String> navigationPropertyNames = new ArrayList<String>(type.getNavigationPropertyNames());
@@ -549,12 +774,16 @@ public class MetadataDocumentXmlSerializer {
 
       if (navigationProperty.getReferentialConstraints() != null) {
         for (EdmReferentialConstraint constraint : navigationProperty.getReferentialConstraints()) {
-          writer.writeEmptyElement("ReferentialConstraint");
+          writer.writeStartElement("ReferentialConstraint");
           writer.writeAttribute(XML_PROPERTY, constraint.getPropertyName());
           writer.writeAttribute("ReferencedProperty", constraint.getReferencedPropertyName());
+          appendAnnotations(writer, constraint);
+          writer.writeEndElement();
         }
       }
 
+      appendAnnotations(writer, navigationProperty);
+
       writer.writeEndElement();
     }
   }
@@ -566,7 +795,7 @@ public class MetadataDocumentXmlSerializer {
     }
     for (String propertyName : propertyNames) {
       EdmProperty property = type.getStructuralProperty(propertyName);
-      writer.writeEmptyElement(XML_PROPERTY);
+      writer.writeStartElement(XML_PROPERTY);
       writer.writeAttribute(XML_NAME, propertyName);
       String fqnString;
       if (property.isPrimitive()) {
@@ -600,6 +829,9 @@ public class MetadataDocumentXmlSerializer {
       if (property.getScale() != null) {
         writer.writeAttribute(XML_SCALE, "" + property.getScale());
       }
+
+      appendAnnotations(writer, property);
+      writer.writeEndElement();
     }
   }
 
@@ -637,7 +869,9 @@ public class MetadataDocumentXmlSerializer {
       for (String memberName : enumType.getMemberNames()) {
         writer.writeEmptyElement(XML_MEMBER);
         writer.writeAttribute(XML_NAME, memberName);
-        writer.writeAttribute(XML_VALUE, enumType.getMember(memberName).getValue());
+        EdmMember member = enumType.getMember(memberName);
+        writer.writeAttribute(XML_VALUE, member.getValue());
+        appendAnnotations(writer, member);
       }
 
       writer.writeEndElement();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d00e3881/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializerTest.java
index ea39b17..7af3780 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializerTest.java
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
 import java.util.ArrayList;
@@ -32,16 +33,16 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.olingo.commons.api.ex.ODataException;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmComplexType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.EdmSchema;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
-import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
 import org.apache.olingo.commons.api.edm.provider.CsdlAction;
 import org.apache.olingo.commons.api.edm.provider.CsdlActionImport;
 import org.apache.olingo.commons.api.edm.provider.CsdlAliasInfo;
+import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation;
+import org.apache.olingo.commons.api.edm.provider.CsdlAnnotations;
 import org.apache.olingo.commons.api.edm.provider.CsdlComplexType;
 import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
 import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
@@ -58,6 +59,31 @@ import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef;
 import org.apache.olingo.commons.api.edm.provider.CsdlReturnType;
 import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
 import org.apache.olingo.commons.api.edm.provider.CsdlSingleton;
+import org.apache.olingo.commons.api.edm.provider.CsdlTerm;
+import org.apache.olingo.commons.api.edm.provider.CsdlTypeDefinition;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlAnnotationPath;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlApply;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlCast;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlCollection;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlConstantExpression;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlIf;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlIsOf;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlPath;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlPropertyValue;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlConstantExpression.ConstantExpressionType;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlExpression;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlLabeledElement;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlLabeledElementReference;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlLogicalOrComparisonExpression;
+//CHECKSTYLE:OFF
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlLogicalOrComparisonExpression.LogicalOrComparisonExpressionType;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlNavigationPropertyPath;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlNull;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlPropertyPath;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlRecord;
+import org.apache.olingo.commons.api.edm.provider.annotation.CsdlUrlRef;
+//CHECKSTYLE:ON
+import org.apache.olingo.commons.api.ex.ODataException;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.core.edm.EdmComplexTypeImpl;
 import org.apache.olingo.server.api.OData;
@@ -74,7 +100,7 @@ import org.junit.Test;
 public class MetadataDocumentXmlSerializerTest {
 
   private static ODataSerializer serializer;
-  
+
   @BeforeClass
   public static void init() throws SerializerException {
     serializer = OData.newInstance().createSerializer(ContentType.APPLICATION_XML);
@@ -113,7 +139,6 @@ public class MetadataDocumentXmlSerializerTest {
         IOUtils.toString(metadata));
   }
 
-
   /** Writes simplest (empty) Schema. */
   @Test
   public void writeMetadataWithSimpleSchema() throws Exception {
@@ -127,11 +152,11 @@ public class MetadataDocumentXmlSerializerTest {
     InputStream metadata = serializer.metadataDocument(serviceMetadata).getContent();
     assertNotNull(metadata);
     assertEquals("<?xml version='1.0' encoding='UTF-8'?>" +
-            "<edmx:Edmx Version=\"4.0\" xmlns:edmx=\"http://docs.oasis-open.org/odata/ns/edmx\">" +
-            "<edmx:DataServices>" +
-            "<Schema xmlns=\"http://docs.oasis-open.org/odata/ns/edm\" Namespace=\"MyNamespace\"/>" +
-            "</edmx:DataServices>" +
-            "</edmx:Edmx>",
+        "<edmx:Edmx Version=\"4.0\" xmlns:edmx=\"http://docs.oasis-open.org/odata/ns/edmx\">" +
+        "<edmx:DataServices>" +
+        "<Schema xmlns=\"http://docs.oasis-open.org/odata/ns/edm\" Namespace=\"MyNamespace\"/>" +
+        "</edmx:DataServices>" +
+        "</edmx:Edmx>",
         IOUtils.toString(metadata));
   }
 
@@ -235,11 +260,7 @@ public class MetadataDocumentXmlSerializerTest {
 
   @Test
   public void aliasTest() throws Exception {
-    CsdlEdmProvider provider = new LocalProvider();
-    ServiceMetadata serviceMetadata = new ServiceMetadataImpl(provider, Collections.<EdmxReference> emptyList(), null);
-    InputStream metadataStream = serializer.metadataDocument(serviceMetadata).getContent();
-    String metadata = IOUtils.toString(metadataStream);
-    assertNotNull(metadata);
+    String metadata = localMetadata();
 
     assertTrue(metadata.contains("<EnumType Name=\"ENString\" IsFlags=\"true\" UnderlyingType=\"Edm.Int16\">"));
     assertTrue(metadata.contains("<EntityType Name=\"ETAbstractBase\" BaseType=\"Alias.ETAbstract\">"));
@@ -253,6 +274,81 @@ public class MetadataDocumentXmlSerializerTest {
   }
 
   @Test
+  public void annotationsTest() throws Exception {
+    String metadata = localMetadata();
+    // All constant expressions
+    assertTrue(metadata.contains("<Annotations Target=\"Alias.ETAbstract\" Qualifier=\"Tablett\">"));
+    assertTrue(metadata.contains("</Annotations>"));
+    assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><Binary>qrvM3e7_</Binary></Annotation>"));
+    assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><Bool>true</Bool></Annotation>"));
+    assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><Date>2012-02-29</Date></Annotation>"));
+    assertTrue(metadata
+        .contains("<Annotation Term=\"ns.term\"><DateTimeOffset>2012-02-29T01:02:03Z</DateTimeOffset></Annotation>"));
+    assertTrue(metadata
+        .contains("<Annotation Term=\"ns.term\"><Decimal>-12345678901234567234567890</Decimal></Annotation>"));
+    assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><Duration>PT10S</Duration></Annotation>"));
+    assertTrue(metadata
+        .contains("<Annotation Term=\"ns.term\"><EnumMember>Enum/enumMember</EnumMember></Annotation>"));
+    assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><Float>1.42</Float></Annotation>"));
+    assertTrue(metadata
+        .contains("<Annotation Term=\"ns.term\"><Guid>aabbccdd-aabb-ccdd-eeff-aabbccddeeff</Guid></Annotation>"));
+    assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><Int>42</Int></Annotation>"));
+    assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><String>ABCD</String></Annotation>"));
+    assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><TimeOfDay>00:00:00.999</TimeOfDay></Annotation>"));
+
+    // All dynamic expressions
+    // Logical expressions
+    assertTrue(metadata.contains("<And><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></And>"));
+    assertTrue(metadata.contains("<Or><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Or>"));
+    assertTrue(metadata.contains("<Not><Bool>true</Bool><Annotation Term=\"ns.term\"/></Not>"));
+
+    // Comparison expressions
+    assertTrue(metadata.contains("<Eq><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Eq>"));
+    assertTrue(metadata.contains("<Ne><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Ne>"));
+    assertTrue(metadata.contains("<Gt><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Gt>"));
+    assertTrue(metadata.contains("<Ge><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Ge>"));
+    assertTrue(metadata.contains("<Lt><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Lt>"));
+    assertTrue(metadata.contains("<Le><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Le>"));
+
+    // Other
+    assertTrue(metadata.contains("<AnnotationPath>AnnoPathValue</AnnotationPath>"));
+    assertTrue(metadata
+        .contains("<Apply Function=\"odata.concat\"><Bool>true</Bool><Annotation Term=\"ns.term\"/></Apply>"));
+    assertTrue(metadata
+        .contains("<Cast Type=\"Edm.String\" MaxLength=\"1\" Precision=\"2\" Scale=\"3\">"
+            + "<String>value</String><Annotation Term=\"ns.term\"/></Cast>"));
+    assertTrue(metadata.contains("<Collection><Bool>true</Bool>"
+        + "<Bool>false</Bool><String>String</String></Collection>"));
+    assertTrue(metadata
+        .contains("<If><Bool>true</Bool><String>Then</String>"
+            + "<String>Else</String><Annotation Term=\"ns.term\"/></If>"));
+    assertTrue(metadata
+        .contains("<IsOf Type=\"Edm.String\" MaxLength=\"1\" Precision=\"2\" Scale=\"3\">"
+            + "<String>value</String><Annotation Term=\"ns.term\"/></IsOf>"));
+    assertTrue(metadata
+        .contains("<LabeledElement Name=\"NameAtt\">"
+            + "<String>value</String><Annotation Term=\"ns.term\"/></LabeledElement>"));
+    assertTrue(metadata.contains("<LabeledElementReference>LabeledElementReferenceValue</LabeledElementReference>"));
+    assertTrue(metadata.contains("<NavigationPropertyPath>NavigationPropertyPathValue</NavigationPropertyPath>"));
+    assertTrue(metadata.contains("<Path>PathValue</Path>"));
+    assertTrue(metadata.contains("<PropertyPath>PropertyPathValue</PropertyPath>"));
+    assertTrue(metadata
+        .contains("<Record Type=\"namespace.ETAbstract\"><PropertyValue Property=\"PropName\"><String>value</String>"
+            + "<Annotation Term=\"ns.term\"/></PropertyValue><Annotation Term=\"ns.term\"/></Record>"));
+    assertTrue(metadata.contains("<UrlRef><String>URLRefValue</String><Annotation Term=\"ns.term\"/></UrlRef>"));
+
+  }
+
+  private String localMetadata() throws SerializerException, IOException {
+    CsdlEdmProvider provider = new LocalProvider();
+    ServiceMetadata serviceMetadata = new ServiceMetadataImpl(provider, Collections.<EdmxReference> emptyList(), null);
+    InputStream metadataStream = serializer.metadataDocument(serviceMetadata).getContent();
+    String metadata = IOUtils.toString(metadataStream);
+    assertNotNull(metadata);
+    return metadata;
+  }
+
+  @Test
   public void writeAbstractComplexType() throws Exception {
     EdmSchema schema = mock(EdmSchema.class);
     when(schema.getNamespace()).thenReturn("MyNamespace");
@@ -286,7 +382,7 @@ public class MetadataDocumentXmlSerializerTest {
         + "</ComplexType>"));
   }
 
-  static class LocalProvider extends CsdlAbstractEdmProvider {
+  static class LocalProvider implements CsdlEdmProvider {
     private final static String nameSpace = "namespace";
 
     private final FullQualifiedName nameETAbstract = new FullQualifiedName(nameSpace, "ETAbstract");
@@ -318,12 +414,15 @@ public class MetadataDocumentXmlSerializerTest {
 
     @Override
     public CsdlEnumType getEnumType(final FullQualifiedName enumTypeName) throws ODataException {
-      return new CsdlEnumType()
-          .setName("ENString")
-          .setFlags(true)
-          .setUnderlyingType(EdmPrimitiveTypeKind.Int16.getFullQualifiedName())
-          .setMembers(Arrays.asList(
-              new CsdlEnumMember().setName("String1").setValue("1")));
+      if ("ENString".equals(enumTypeName.getName())) {
+        return new CsdlEnumType()
+            .setName("ENString")
+            .setFlags(true)
+            .setUnderlyingType(EdmPrimitiveTypeKind.Int16.getFullQualifiedName())
+            .setMembers(Arrays.asList(
+                new CsdlEnumMember().setName("String1").setValue("1")));
+      }
+      return null;
     }
 
     @Override
@@ -488,6 +587,11 @@ public class MetadataDocumentXmlSerializerTest {
       // EntityContainer
       schema.setEntityContainer(getEntityContainer());
 
+      // Annotationgroups
+      List<CsdlAnnotations> annotationGroups = new ArrayList<CsdlAnnotations>();
+      annotationGroups.add(getAnnotationsGroup(new FullQualifiedName("Alias.ETAbstract"), "Tablett"));
+      schema.setAnnotationsGroup(annotationGroups);
+
       return schemas;
     }
 
@@ -499,7 +603,7 @@ public class MetadataDocumentXmlSerializerTest {
       }
       return null;
     }
-    
+
     @Override
     public CsdlEntityContainer getEntityContainer() throws ODataException {
       CsdlEntityContainer container = new CsdlEntityContainer();
@@ -527,5 +631,188 @@ public class MetadataDocumentXmlSerializerTest {
 
       return container;
     }
+
+    @Override
+    public CsdlTypeDefinition getTypeDefinition(FullQualifiedName typeDefinitionName) throws ODataException {
+      return null;
+    }
+
+    @Override
+    public CsdlTerm getTerm(FullQualifiedName termName) throws ODataException {
+      if (new FullQualifiedName("ns.term").equals(termName)) {
+        return new CsdlTerm().setType("Edm.String").setName("term");
+      }
+      return null;
+    }
+
+    @Override
+    public CsdlAnnotations getAnnotationsGroup(FullQualifiedName targetName, String qualifier) throws ODataException {
+      if (new FullQualifiedName("Alias.ETAbstract").equals(targetName) && "Tablett".equals(qualifier)) {
+        CsdlAnnotations annoGroup = new CsdlAnnotations();
+        annoGroup.setTarget("Alias.ETAbstract");
+        annoGroup.setQualifier("Tablett");
+
+        List<CsdlAnnotation> innerAnnotations = new ArrayList<CsdlAnnotation>();
+        innerAnnotations.add(new CsdlAnnotation().setTerm("ns.term"));
+
+        List<CsdlAnnotation> annotationsList = new ArrayList<CsdlAnnotation>();
+        annoGroup.setAnnotations(annotationsList);
+        // Constant Annotations
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlConstantExpression(ConstantExpressionType.Binary).setValue("qrvM3e7_")));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlConstantExpression(ConstantExpressionType.Bool, "true")));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlConstantExpression(ConstantExpressionType.Date, "2012-02-29")));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlConstantExpression(ConstantExpressionType.DateTimeOffset, "2012-02-29T01:02:03Z")));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlConstantExpression(ConstantExpressionType.Decimal, "-12345678901234567234567890")));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlConstantExpression(ConstantExpressionType.Duration, "PT10S")));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlConstantExpression(ConstantExpressionType.EnumMember, "Enum/enumMember")));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlConstantExpression(ConstantExpressionType.Float, "1.42")));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(
+                new CsdlConstantExpression(ConstantExpressionType.Guid, "aabbccdd-aabb-ccdd-eeff-aabbccddeeff")));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlConstantExpression(ConstantExpressionType.Int, "42")));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlConstantExpression(ConstantExpressionType.String, "ABCD")));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlConstantExpression(ConstantExpressionType.TimeOfDay, "00:00:00.999")));
+
+        // logical expressions
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.And)
+                .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true"))
+                .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false"))
+                .setAnnotations(innerAnnotations)));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Or)
+                .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true"))
+                .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false"))
+                .setAnnotations(innerAnnotations)));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Not)
+                .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true"))
+                .setAnnotations(innerAnnotations)));
+
+        // comparison
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Eq)
+                .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true"))
+                .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false"))
+                .setAnnotations(innerAnnotations)));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Ne)
+                .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true"))
+                .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false"))
+                .setAnnotations(innerAnnotations)));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Gt)
+                .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true"))
+                .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false"))
+                .setAnnotations(innerAnnotations)));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Ge)
+                .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true"))
+                .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false"))
+                .setAnnotations(innerAnnotations)));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Lt)
+                .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true"))
+                .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false"))
+                .setAnnotations(innerAnnotations)));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Le)
+                .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true"))
+                .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false"))
+                .setAnnotations(innerAnnotations)));
+
+        // Other
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlAnnotationPath().setValue("AnnoPathValue")));
+
+        List<CsdlExpression> parameters = new ArrayList<CsdlExpression>();
+        parameters.add(new CsdlConstantExpression(ConstantExpressionType.Bool, "true"));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlApply().setFunction("odata.concat")
+                .setParameters(parameters)
+                .setAnnotations(innerAnnotations)));
+
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlCast()
+                .setValue(new CsdlConstantExpression(ConstantExpressionType.String, "value"))
+                .setMaxLength(1)
+                .setPrecision(2)
+                .setScale(3)
+                .setType("Edm.String")
+                .setAnnotations(innerAnnotations)));
+
+        List<CsdlExpression> items = new ArrayList<CsdlExpression>();
+        items.add(new CsdlConstantExpression(ConstantExpressionType.Bool, "true"));
+        items.add(new CsdlConstantExpression(ConstantExpressionType.Bool, "false"));
+        items.add(new CsdlConstantExpression(ConstantExpressionType.String, "String"));
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlCollection().setItems(items)));
+
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlIf()
+                .setGuard(new CsdlConstantExpression(ConstantExpressionType.Bool, "true"))
+                .setThen(new CsdlConstantExpression(ConstantExpressionType.String, "Then"))
+                .setElse(new CsdlConstantExpression(ConstantExpressionType.String, "Else"))
+                .setAnnotations(innerAnnotations)));
+
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlIsOf()
+                .setMaxLength(1)
+                .setPrecision(2)
+                .setScale(3)
+                .setType("Edm.String")
+                .setValue(new CsdlConstantExpression(ConstantExpressionType.String, "value"))
+                .setAnnotations(innerAnnotations)));
+
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlLabeledElement()
+                .setName("NameAtt")
+                .setValue(new CsdlConstantExpression(ConstantExpressionType.String, "value"))
+                .setAnnotations(innerAnnotations)));
+
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlLabeledElementReference().setValue("LabeledElementReferenceValue")));
+
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlNull().setAnnotations(innerAnnotations)));
+
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlNavigationPropertyPath().setValue("NavigationPropertyPathValue")));
+
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlPath().setValue("PathValue")));
+
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlPropertyPath().setValue("PropertyPathValue")));
+
+        CsdlPropertyValue prop = new CsdlPropertyValue()
+            .setProperty("PropName")
+            .setValue(new CsdlConstantExpression(ConstantExpressionType.String, "value"))
+            .setAnnotations(innerAnnotations);
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlRecord().setType("Alias.ETAbstract")
+                .setPropertyValues(Arrays.asList(prop))
+                .setAnnotations(innerAnnotations)));
+
+        annotationsList.add(new CsdlAnnotation().setTerm("ns.term")
+            .setExpression(new CsdlUrlRef()
+                .setValue(new CsdlConstantExpression(ConstantExpressionType.String, "URLRefValue"))
+                .setAnnotations(innerAnnotations)));
+
+        return annoGroup;
+      }
+      return null;
+    }
   }
 }