You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2013/12/05 10:15:35 UTC

[01/12] Removed not to merge PoC parts

Updated Branches:
  refs/heads/PocEdmAnnotationsExtension a73d1975c -> 12ea18aed


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonWriter.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonWriter.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonWriter.java
deleted file mode 100644
index a277b41..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonWriter.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/**
- * *****************************************************************************
- * 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.odata2.core.annotation.processor.json;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-public class JsonWriter {
-
-  private final Writer writer;
-  private boolean firstProperty = true;
-
-  public JsonWriter(Writer writer) {
-    this.writer = writer;
-  }
-
-  public void startCallback(String functionName) {
-    try {
-      writer.write(encode(functionName) + "(");
-    } catch (IOException e) {
-      throw new ODataRuntimeException(e.getMessage(), e);
-    }
-  }
-
-  public void endCallback() {
-    try {
-      writer.write(");");
-    } catch (IOException e) {
-      throw new ODataRuntimeException(e.getMessage(), e);
-    }
-  }
-
-  public void startObject() {
-    try {
-      firstProperty = true;
-      writer.write("{\n");
-    } catch (IOException e) {
-      throw new ODataRuntimeException(e.getMessage(), e);
-    }
-  }
-
-  public void endObject() {
-    try {
-      firstProperty = false;
-      writer.write("\n}");
-    } catch (IOException e) {
-      throw new ODataRuntimeException(e.getMessage(), e);
-    }
-  }
-
-  public void writeName(String name) {
-    try {
-      writer.write("\"" + encode(name) + "\" : ");
-    } catch (IOException e) {
-      throw new ODataRuntimeException(e.getMessage(), e);
-    }
-  }
-
-  public void startArray() {
-    try {
-      writer.write("[\n");
-    } catch (IOException e) {
-      throw new ODataRuntimeException(e.getMessage(), e);
-    }
-  }
-
-  public void endArray() {
-    try {
-      writer.write("\n]");
-    } catch (IOException e) {
-      throw new ODataRuntimeException(e.getMessage(), e);
-    }
-  }
-
-  public void writeSeparator() {
-    try {
-      writer.write(", ");
-    } catch (IOException e) {
-      throw new ODataRuntimeException(e.getMessage(), e);
-    }
-  }
-
-  public void writeRawString(String value) {
-    try {
-      writer.write("\"" + value + "\"");
-    } catch (IOException e) {
-      throw new ODataRuntimeException(e.getMessage(), e);
-    }
-  }
-
-  public void writeString(String value) {
-    try {
-      writer.write("\"" + encode(value) + "\"");
-    } catch (IOException e) {
-      throw new ODataRuntimeException(e.getMessage(), e);
-    }
-  }
-
-  public void writeNull() {
-    try {
-      writer.write("null");
-    } catch (IOException e) {
-      throw new ODataRuntimeException(e.getMessage(), e);
-    }
-  }
-
-  public void writeStringProperty(String name, String value) {
-    if (value == null) {
-      writeProperty(name, value, false);
-    } else {
-      writeProperty(name, encode(value), false);
-    }
-  }
-
-  public void writeRawStringProperty(String name, String value) {
-    writeProperty(name, value, false);
-  }
-
-  public void writeRawProperty(String name, String value) {
-    writeProperty(name, value, true);
-  }
-
-  private void writeProperty(String name, String value, boolean raw) {
-    if (firstProperty) {
-      firstProperty = false;
-    } else {
-      writeSeparator();
-    }
-
-    // write content
-    this.writeName(name);
-    if (value == null) {
-      writeNull();
-    } else {
-      try {
-        if (raw) {
-          writeRaw(value);
-        } else {
-          writeString(value);
-        }
-      } catch (Exception e) {
-        writeString("exception for property with name '" + name
-                + "' with message '" + e.getMessage()
-                + "' and toString '" + value.toString() + "'.");
-      }
-    }
-
-  }
-
-  private void writeRaw(String value) {
-    try {
-      writer.write(value);
-    } catch (IOException e) {
-      throw new ODataRuntimeException(e.getMessage(), e);
-    }
-  }
-
-  private String encode(String unencoded) {
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < unencoded.length(); i++) {
-      char c = unencoded.charAt(i);
-      if (c == '\\') {
-        sb.append("\\\\");
-      } else if (c == '"') {
-        sb.append("\\\"");
-      } else if (c == '\n') {
-        sb.append("\\n");
-      } else if (c == '\r') {
-        sb.append("\\r");
-      } else if (c == '\f') {
-        sb.append("\\f");
-      } else if (c == '\b') {
-        sb.append("\\b");
-      } else if (c == '\t') {
-        sb.append("\\t");
-      } else {
-        sb.append(c);
-      }
-    }
-    return sb.toString();
-  }
-
-  public void start() {
-    writeRaw("{\n\"d\":");
-  }
-
-  public void finish() {
-    writeRaw("\n}");
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
new file mode 100644
index 0000000..0c81fb1
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
@@ -0,0 +1,726 @@
+/**
+ * *****************************************************************************
+ * 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.odata2.core.annotation.util;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+/**
+ *
+ */
+public class AnnotationHelper {
+
+  public static final String DEFAULT_CONTAINER_NAME = "DefaultContainer";
+
+  /**
+   * Compare keys of both instances.
+   * 
+   * @param firstInstance
+   * @param secondInstance
+   * @return 
+   */
+  public boolean keyMatch(Object firstInstance, Object secondInstance) {
+    if (firstInstance == null || secondInstance == null) {
+      return false;
+    } else if (firstInstance.getClass() != secondInstance.getClass()) {
+      return false;
+    }
+
+    Map<String, Object> firstKeyFields = getValueForAnnotatedFields(firstInstance, EdmKey.class);
+    Map<String, Object> secondKeyFields = getValueForAnnotatedFields(secondInstance, EdmKey.class);
+
+    return keyValuesMatch(firstKeyFields, secondKeyFields);
+  }
+
+  /**
+   * Compare keys of instance with key values in map.
+   * 
+   * @param instance
+   * @param keyName2Value
+   * @return 
+   */
+  public boolean keyMatch(Object instance, Map<String, Object> keyName2Value) {
+    Map<String, Object> instanceKeyFields = getValueForAnnotatedFields(instance, EdmKey.class);
+    return keyValuesMatch(instanceKeyFields, keyName2Value);
+  }
+
+  private boolean keyValuesMatch(Map<String, Object> firstKeyValues, Map<String, Object> secondKeyValues) {
+    if (firstKeyValues.size() != secondKeyValues.size()) {
+      return false;
+    } else {
+      Set<Map.Entry<String, Object>> entries = firstKeyValues.entrySet();
+      for (Map.Entry<String, Object> entry : entries) {
+        Object firstKey = entry.getValue();
+        Object secondKey = secondKeyValues.get(entry.getKey());
+        if (!isEqual(firstKey, secondKey)) {
+          return false;
+        }
+      }
+      return true;
+    }
+  }
+  
+  private boolean isEqual(Object firstKey, Object secondKey) {
+    if (firstKey == null) {
+      if (secondKey == null) {
+        return true;
+      } else {
+        return secondKey.equals(firstKey);
+      }
+    } else {
+      return firstKey.equals(secondKey);
+    }
+  }
+
+  public String extractEntitTypeName(EdmNavigationProperty enp, Class<?> fallbackClass) {
+    Class<?> entityTypeClass = enp.toType();
+    return extractEntityTypeName(entityTypeClass == Object.class ? fallbackClass : entityTypeClass);
+  }
+
+  public String extractEntitTypeName(EdmNavigationProperty enp, Field field) {
+    Class<?> entityTypeClass = enp.toType();
+    if (entityTypeClass == Object.class) {
+      Class<?> toClass = field.getType();
+      return extractEntityTypeName((toClass.isArray() || Collection.class.isAssignableFrom(toClass) ?
+          (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0] : toClass));
+    } else {
+      return extractEntityTypeName(entityTypeClass);
+    }
+  }
+
+  /**
+   * Returns <code>NULL</code> if given class is not annotated. If annotated the set entity type name is returned and if
+   * no name is set the default name is generated from the simple class name.
+   *
+   * @param annotatedClass
+   * @return
+   */
+  public String extractEntityTypeName(Class<?> annotatedClass) {
+    return extractTypeName(annotatedClass, EdmEntityType.class);
+  }
+
+  public FullQualifiedName extractEntityTypeFqn(EdmEntityType type, Class<?> annotatedClass) {
+    if(type.namespace().isEmpty()) {
+      return new FullQualifiedName(generateNamespace(annotatedClass), extractEntityTypeName(annotatedClass));
+    }
+    return new FullQualifiedName(type.namespace(), extractEntityTypeName(annotatedClass));
+  }
+  
+  public FullQualifiedName extractEntityTypeFqn(Class<?> annotatedClass) {
+    EdmEntityType type = annotatedClass.getAnnotation(EdmEntityType.class);
+    if(type == null) {
+      return null;
+    }
+    return extractEntityTypeFqn(type, annotatedClass);
+  }
+
+  public FullQualifiedName extractComplexTypeFqn(Class<?> annotatedClass) {
+    EdmComplexType type = annotatedClass.getAnnotation(EdmComplexType.class);
+    if(type == null) {
+      return null;
+    }
+    return extractComplexTypeFqn(type, annotatedClass);
+  }
+
+  public FullQualifiedName extractComplexTypeFqn(EdmComplexType type, Class<?> annotatedClass) {
+    if(type.namespace().isEmpty()) {
+      return new FullQualifiedName(generateNamespace(annotatedClass), extractComplexTypeName(annotatedClass));
+    }
+    return new FullQualifiedName(type.namespace(), extractComplexTypeName(annotatedClass));
+  }
+
+  public String extractComplexTypeName(Class<?> annotatedClass) {
+    return extractTypeName(annotatedClass, EdmComplexType.class);
+  }
+  
+  public String generateNamespace(Class<?> annotatedClass) {
+    String packageName = annotatedClass.getPackage().getName();
+    return packageName;
+  }
+
+  /**
+   *
+   *
+   * @param <T> must be EdmEntityType or EdmComplexType annotation
+   * @param annotatedClass
+   * @param typeAnnotation
+   * @return null if annotatedClass is not annotated or name set via annotation or generated via
+   * {@link #getCanonicalName(java.lang.Class)}
+   */
+  private <T extends Annotation> String extractTypeName(Class<?> annotatedClass, Class<T> typeAnnotation) {
+    if (annotatedClass == Object.class) {
+      return null;
+    }
+    T type = annotatedClass.getAnnotation(typeAnnotation);
+    if (type == null) {
+      return null;
+    }
+
+    String name;
+    if (typeAnnotation == EdmEntityType.class) {
+      name = ((EdmEntityType) type).name();
+    } else if (typeAnnotation == EdmComplexType.class) {
+      name = ((EdmComplexType) type).name();
+    } else {
+      return null;
+    }
+
+    if (name.isEmpty()) {
+      return getCanonicalName(annotatedClass);
+    }
+    return name;
+  }
+
+  /**
+   * Get the set property name from an EdmProperty or EdmNavigationProperty annotation.
+   *
+   * @param field
+   * @return
+   */
+  public String getPropertyNameFromAnnotation(Field field) {
+    EdmProperty property = field.getAnnotation(EdmProperty.class);
+    if (property == null) {
+      EdmNavigationProperty navProperty = field.getAnnotation(EdmNavigationProperty.class);
+      if (navProperty == null) {
+        throw new EdmAnnotationException("Given field '" + field
+            + "' has no EdmProperty or EdmNavigationProperty annotation.");
+      }
+      return navProperty.name();
+    }
+    return property.name();
+  }
+
+  public String getPropertyName(Field field) {
+    String propertyName = getPropertyNameFromAnnotation(field);
+    if (propertyName.isEmpty()) {
+      propertyName = getCanonicalName(field);
+    }
+    return propertyName;
+  }
+
+  public String extractFromRoleName(EdmNavigationProperty enp, Field field) {
+    return getCanonicalRole(field.getDeclaringClass());
+  }
+
+  public String extractToRoleName(EdmNavigationProperty enp, Field field) {
+    String role = enp.toRole();
+    if (role.isEmpty()) {
+      role = getCanonicalRole(
+          field.getType().isArray() || Collection.class.isAssignableFrom(field.getType()) ?
+              (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0] : field.getType());
+    }
+    return role;
+  }
+
+  public String getCanonicalRole(Class<?> fallbackClass) {
+    String toRole = extractEntityTypeName(fallbackClass);
+    return "r_" + toRole;
+  }
+
+  public String extractRelationshipName(EdmNavigationProperty enp, Field field) {
+    String relationshipName = enp.association();
+    if (relationshipName.isEmpty()) {
+      final String fromRole = extractFromRoleName(enp, field);
+      final String toRole = extractToRoleName(enp, field);
+      if (fromRole.compareTo(toRole) > 0) {
+        relationshipName = toRole + "-" + fromRole;
+      } else {
+        relationshipName = fromRole + "-" + toRole;
+      }
+    }
+    return relationshipName;
+  }
+
+  public EdmMultiplicity getMultiplicity(EdmNavigationProperty enp, Field field) {
+    EdmMultiplicity multiplicity = mapMultiplicity(enp.toMultiplicity());
+    final boolean isCollectionType = field.getType().isArray() || Collection.class.isAssignableFrom(field.getType());
+
+    if (multiplicity == EdmMultiplicity.ONE && isCollectionType) {
+      return EdmMultiplicity.MANY;
+    }
+    return multiplicity;
+  }
+
+
+  /**
+   * Set key fields based on values in map.
+   * If an key field is not available or <code>NULL</code> in the map 
+   * it will be not set as <code>NULL</code> at the instance object.
+   * 
+   * @param instance
+   * @param keys
+   * @return
+   */
+  public <T> T setKeyFields(T instance, Map<String, Object> keys) {
+    List<Field> fields = getAnnotatedFields(instance, EdmKey.class);
+
+    for (Field field : fields) {
+      String propertyName = getPropertyName(field);
+      Object keyValue = keys.get(propertyName);
+      setValueForProperty(instance, propertyName, keyValue);
+    }
+
+    return instance;
+  }
+
+  public static final class ODataAnnotationException extends ODataException {
+    private static final long serialVersionUID = 1L;
+
+    public ODataAnnotationException(String message) {
+      super(message);
+    }
+  }
+
+  
+  public class AnnotatedNavInfo {
+    private final Field fromField;
+    private final Field toField;
+    private final EdmNavigationProperty fromNavigation;
+    private final EdmNavigationProperty toNavigation;
+
+    public AnnotatedNavInfo(Field fromField, Field toField, EdmNavigationProperty fromNavigation,
+        EdmNavigationProperty toNavigation) {
+      this.fromField = fromField;
+      this.toField = toField;
+      this.fromNavigation = fromNavigation;
+      this.toNavigation = toNavigation;
+    }
+
+    public Field getFromField() {
+      return fromField;
+    }
+
+    public Field getToField() {
+      return toField;
+    }
+
+    public EdmMultiplicity getFromMultiplicity() {
+      return getMultiplicity(toNavigation, toField);
+    }
+
+    public EdmMultiplicity getToMultiplicity() {
+      return getMultiplicity(fromNavigation, fromField);
+    }
+    
+    public boolean isBiDirectional() {
+      return toNavigation != null;
+    }
+  }
+
+  public AnnotatedNavInfo getCommonNavigationInfo(Class<?> sourceClass, Class<?> targetClass) {
+    List<Field> sourceFields = getAnnotatedFields(sourceClass, EdmNavigationProperty.class);
+    List<Field> targetFields = getAnnotatedFields(targetClass, EdmNavigationProperty.class);
+
+    // first try via association name to get full navigation information
+    for (Field sourceField : sourceFields) {
+      final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
+      final String sourceAssociation = extractRelationshipName(sourceNav, sourceField);
+      for (Field targetField : targetFields) {
+        final EdmNavigationProperty targetNav = targetField.getAnnotation(EdmNavigationProperty.class);
+        final String targetAssociation = extractRelationshipName(targetNav, targetField);
+        if (sourceAssociation.equals(targetAssociation)) {
+          return new AnnotatedNavInfo(sourceField, targetField, sourceNav, targetNav);
+        }
+      }
+    }
+    
+    // if nothing was found assume none bi-directinal navigation
+    String targetEntityTypeName = extractEntityTypeName(targetClass);
+    for (Field sourceField : sourceFields) {
+      final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
+      final String navTargetEntityName = extractEntitTypeName(sourceNav, sourceField);
+      
+      if (navTargetEntityName.equals(targetEntityTypeName)) {
+        return new AnnotatedNavInfo(sourceField, null, sourceNav, null);
+      }
+    }
+    
+    return null;
+  }
+
+  public Class<?> getFieldTypeForProperty(Object instance, String propertyName) throws ODataAnnotationException {
+    if (instance == null) {
+      return null;
+    }
+
+    Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
+    if (field == null) {
+      throw new ODataAnnotationException("No field for property '" + propertyName
+          + "' found at class '" + instance.getClass() + "'.");
+    }
+    return field.getType();
+  }
+
+  public Object getValueForProperty(Object instance, String propertyName) throws ODataAnnotationException {
+    if (instance == null) {
+      return null;
+    }
+
+    Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
+    if (field == null) {
+      throw new ODataAnnotationException("No field for property '" + propertyName
+          + "' found at class '" + instance.getClass() + "'.");
+    }
+    return getFieldValue(instance, field);
+  }
+
+  public void setValueForProperty(Object instance, String propertyName, Object propertyValue) {
+    if (instance != null) {
+      Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
+      if (field != null) {
+        setFieldValue(instance, field, propertyValue);
+      }
+    }
+  }
+
+  private Field getFieldForPropertyName(Object instance, String propertyName,
+      Class<?> resultClass, boolean inherited) {
+    if (instance == null) {
+      return null;
+    }
+
+    Field[] fields = resultClass.getDeclaredFields();
+    for (Field field : fields) {
+      EdmProperty property = field.getAnnotation(EdmProperty.class);
+      if (property != null) {
+        if (property.name().isEmpty() && getCanonicalName(field).equals(propertyName)) {
+          return field;
+        } else if (property.name().equals(propertyName)) {
+          return field;
+        }
+      }
+    }
+
+    Class<?> superClass = resultClass.getSuperclass();
+    if (inherited && superClass != Object.class) {
+      return getFieldForPropertyName(instance, propertyName, superClass, true);
+    }
+
+    return null;
+  }
+
+  public Object getValueForField(Object instance, String fieldName, Class<? extends Annotation> annotation) {
+    if (instance == null) {
+      return null;
+    }
+    return getValueForField(instance, fieldName, instance.getClass(), annotation, true);
+  }
+
+  public Object getValueForField(Object instance, Class<? extends Annotation> annotation) {
+    if (instance == null) {
+      return null;
+    }
+    return getValueForField(instance, instance.getClass(), annotation, true);
+  }
+
+  private Object getValueForField(Object instance, Class<?> resultClass,
+      Class<? extends Annotation> annotation, boolean inherited) {
+    return getValueForField(instance, null, resultClass, annotation, inherited);
+  }
+
+  public Map<String, Object> getValueForAnnotatedFields(Object instance,
+      Class<? extends Annotation> annotation) {
+    return getValueForAnnotatedFields(instance, instance.getClass(), annotation, true);
+  }
+
+  private Map<String, Object> getValueForAnnotatedFields(Object instance, Class<?> resultClass,
+      Class<? extends Annotation> annotation, boolean inherited) {
+    if (instance == null) {
+      return null;
+    }
+
+    Field[] fields = resultClass.getDeclaredFields();
+    Map<String, Object> fieldName2Value = new HashMap<String, Object>();
+
+    for (Field field : fields) {
+      if (field.getAnnotation(annotation) != null) {
+        Object value = getFieldValue(instance, field);
+        final EdmProperty property = field.getAnnotation(EdmProperty.class);
+        final String name = property == null || property.name().isEmpty() ? field.getName() : property.name();
+        fieldName2Value.put(name, value);
+      }
+    }
+
+    Class<?> superClass = resultClass.getSuperclass();
+    if (inherited && superClass != Object.class) {
+      Map<String, Object> tmp = getValueForAnnotatedFields(instance, superClass, annotation, true);
+      fieldName2Value.putAll(tmp);
+    }
+
+    return fieldName2Value;
+  }
+
+  public void setValueForAnnotatedField(Object instance, Class<? extends Annotation> annotation, Object value) 
+      throws ODataAnnotationException {
+    List<Field> fields = getAnnotatedFields(instance, annotation);
+
+    if(fields.isEmpty()) {
+      throw new ODataAnnotationException("No field found for annotation '" + annotation
+          + "' on instance '" + instance + "'.");
+    } else if(fields.size() > 1) {
+      throw new ODataAnnotationException("More then one field found for annotation '" + annotation
+          + "' on instance '" + instance + "'.");
+    }
+
+    setFieldValue(instance, fields.get(0), value);
+  }
+
+  public void setValuesToAnnotatedFields(Object instance,
+      Class<? extends Annotation> annotation, Map<String, Object> fieldName2Value) {
+    List<Field> fields = getAnnotatedFields(instance, annotation);
+
+    // XXX: refactore
+    for (Field field : fields) {
+      final String canonicalName = getCanonicalName(field);
+      if (fieldName2Value.containsKey(canonicalName)) {
+        Object value = fieldName2Value.get(canonicalName);
+        setFieldValue(instance, field, value);
+      }
+    }
+  }
+
+  public List<Field> getAnnotatedFields(Object instance, Class<? extends Annotation> annotation) {
+    if (instance == null) {
+      return null;
+    }
+    return getAnnotatedFields(instance.getClass(), annotation, true);
+  }
+
+  public List<Field> getAnnotatedFields(Class<?> fieldClass, Class<? extends Annotation> annotation) {
+    return getAnnotatedFields(fieldClass, annotation, true);
+  }
+
+  /**
+   *
+   * @param instance
+   * @param resultClass
+   * @param annotation
+   * @param inherited
+   * @return
+   */
+  private List<Field> getAnnotatedFields(Class<?> resultClass,
+      Class<? extends Annotation> annotation, boolean inherited) {
+    if (resultClass == null) {
+      return null;
+    }
+
+    Field[] fields = resultClass.getDeclaredFields();
+    List<Field> annotatedFields = new ArrayList<Field>();
+
+    for (Field field : fields) {
+      if (field.getAnnotation(annotation) != null) {
+        annotatedFields.add(field);
+      }
+    }
+
+    Class<?> superClass = resultClass.getSuperclass();
+    if (inherited && superClass != Object.class) {
+      List<Field> tmp = getAnnotatedFields(superClass, annotation, true);
+      annotatedFields.addAll(tmp);
+    }
+
+    return annotatedFields;
+  }
+
+  private Object getValueForField(Object instance, String fieldName, Class<?> resultClass,
+      Class<? extends Annotation> annotation, boolean inherited) {
+    if (instance == null) {
+      return null;
+    }
+
+    Field[] fields = resultClass.getDeclaredFields();
+    for (Field field : fields) {
+      if (field.getAnnotation(annotation) != null
+          && (fieldName == null || field.getName().equals(fieldName))) {
+        return getFieldValue(instance, field);
+      }
+    }
+
+    Class<?> superClass = resultClass.getSuperclass();
+    if (inherited && superClass != Object.class) {
+      return getValueForField(instance, fieldName, superClass, annotation, true);
+    }
+
+    return null;
+  }
+
+  private Object getFieldValue(Object instance, Field field) {
+    try {
+      boolean access = field.isAccessible();
+      field.setAccessible(true);
+      Object value = field.get(instance);
+      field.setAccessible(access);
+      return value;
+    } catch (IllegalArgumentException ex) { // should never happen
+      throw new ODataRuntimeException(ex);
+    } catch (IllegalAccessException ex) { // should never happen
+      throw new ODataRuntimeException(ex);
+    }
+  }
+
+  private void setFieldValue(Object instance, Field field, Object value) {
+    try {
+      Object usedValue = value;
+      if (value != null
+          && field.getType() != value.getClass()
+          && value.getClass() == String.class) {
+        usedValue = convert(field, (String) value);
+      }
+      boolean access = field.isAccessible();
+      field.setAccessible(true);
+      field.set(instance, usedValue);
+      field.setAccessible(access);
+    } catch (IllegalArgumentException ex) { // should never happen
+      throw new ODataRuntimeException(ex);
+    } catch (IllegalAccessException ex) { // should never happen
+      throw new ODataRuntimeException(ex);
+    }
+  }
+
+  public Object convert(Field field, String propertyValue) {
+    Class<?> fieldClass = field.getType();
+    try {
+      EdmProperty property = field.getAnnotation(EdmProperty.class);
+      EdmSimpleTypeKind type = mapTypeKind(property.type());
+      return type.getEdmSimpleTypeInstance().valueOfString(propertyValue,
+          EdmLiteralKind.DEFAULT, null, fieldClass);
+    } catch (EdmSimpleTypeException ex) {
+      throw new ODataRuntimeException("Conversion failed for string property with error: "
+          + ex.getMessage(), ex);
+    }
+  }
+
+  public boolean isEdmAnnotated(Object object) {
+    if (object == null) {
+      return false;
+    }
+    return isEdmAnnotated(object.getClass());
+  }
+
+  public boolean isEdmTypeAnnotated(Class<?> clazz) {
+    boolean isComplexEntity = clazz.getAnnotation(EdmComplexType.class) != null;
+    boolean isEntity = clazz.getAnnotation(EdmEntityType.class) != null;
+    return isComplexEntity || isEntity;
+  }
+
+  public boolean isEdmAnnotated(Class<?> clazz) {
+    if (clazz == null) {
+      return false;
+    } else {
+      final boolean isEntity = null != clazz.getAnnotation(EdmEntityType.class);
+      final boolean isEntitySet = null != clazz.getAnnotation(EdmEntitySet.class);
+      final boolean isComplexEntity = null != clazz.getAnnotation(EdmComplexType.class);
+      return isEntity || isComplexEntity || isEntitySet;
+    }
+  }
+
+  public String getCanonicalName(Field field) {
+    return firstCharToUpperCase(field.getName());
+  }
+
+  public String getCanonicalName(Class<?> clazz) {
+    return firstCharToUpperCase(clazz.getSimpleName());
+  }
+
+  private String firstCharToUpperCase(String content) {
+    if (content == null || content.isEmpty()) {
+      return content;
+    }
+    return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1);
+  }
+
+  public EdmSimpleTypeKind mapTypeKind(org.apache.olingo.odata2.api.annotation.edm.EdmType type) {
+    switch (type) {
+      case BINARY: return EdmSimpleTypeKind.Binary;
+      case BOOLEAN: return EdmSimpleTypeKind.Boolean;
+      case BYTE: return EdmSimpleTypeKind.Byte;
+      case COMPLEX: return EdmSimpleTypeKind.Null;
+      case DATE_TIME: return EdmSimpleTypeKind.DateTime;
+      case DATE_TIME_OFFSET: return EdmSimpleTypeKind.DateTimeOffset;
+      case DECIMAL: return EdmSimpleTypeKind.Decimal;
+      case DOUBLE: return EdmSimpleTypeKind.Double;
+      case GUID: return EdmSimpleTypeKind.Guid;
+      case INT16: return EdmSimpleTypeKind.Int16;
+      case INT32: return EdmSimpleTypeKind.Int32;
+      case INT64: return EdmSimpleTypeKind.Int64;
+      case NULL: return EdmSimpleTypeKind.Null;
+      case SBYTE: return EdmSimpleTypeKind.SByte;
+      case SINGLE: return EdmSimpleTypeKind.Single;
+      case STRING: return EdmSimpleTypeKind.String;
+      case TIME: return EdmSimpleTypeKind.Time;
+      default: throw new ODataRuntimeException("Unknown type '" + type
+        + "' for mapping to EdmSimpleTypeKind.");
+    }
+  }
+
+  public EdmMultiplicity mapMultiplicity(Multiplicity multiplicity) {
+    switch (multiplicity) {
+    case ZERO_OR_ONE: return EdmMultiplicity.ZERO_TO_ONE;
+    case ONE: return EdmMultiplicity.ONE;
+    case MANY: return EdmMultiplicity.MANY;
+    default: throw new ODataRuntimeException("Unknown type '" + multiplicity + "' for mapping to EdmMultiplicity.");
+    }
+  }
+  
+  /**
+   * 
+   */
+  private static class EdmAnnotationException extends RuntimeException {
+
+    private static final long serialVersionUID = 42L;
+
+    public EdmAnnotationException(String message) {
+      super(message);
+    }
+  }
+
+  public String getCanonicalNamespace(Class<?> aClass) {
+    return generateNamespace(aClass);
+  }
+
+  public String extractContainerName(Class<?> aClass) {
+    EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
+    if(entitySet != null) {
+      String containerName = entitySet.container();
+      if(!containerName.isEmpty()) {
+        return containerName;
+      }
+    }
+    return DEFAULT_CONTAINER_NAME;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
new file mode 100644
index 0000000..5e9fcdb
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.util;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ */
+public class ClassHelper {
+  
+  private static final File[] EMPTY_FILE_ARRAY = new File[0];
+  
+  private static final FilenameFilter CLASSFILE_FILTER = new FilenameFilter() {
+    @Override
+    public boolean accept(File dir, String name) {
+      return name.endsWith(CLASSFILE_ENDING);
+    }
+    public static final String CLASSFILE_ENDING = ".class";
+  };
+  
+  private static final FileFilter FOLDER_FILTER = new FileFilter() {
+    @Override
+    public boolean accept(File pathname) {
+      return pathname.isDirectory();
+    }
+  };
+  
+  public static final List<Class<?>> loadClasses(String packageToScan, ClassValidator cv) {
+    return loadClasses(packageToScan, CLASSFILE_FILTER, cv);
+  }
+
+  
+  public static final List<Class<?>> loadClasses(String packageToScan, FilenameFilter ff, ClassValidator cv) {
+    final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+    String folderToScan = packageToScan.replace(".", "/");
+    URL url = classLoader.getResource(folderToScan);
+    if(url == null) {
+      throw new IllegalArgumentException("No folder to scan found for package '" + packageToScan + "'.");
+    }
+    File folder = new File(url.getFile());
+    File[] classFiles = folder.listFiles(ff);
+    if(classFiles == null) {
+      classFiles = EMPTY_FILE_ARRAY;
+    }
+
+    List<Class<?>> annotatedClasses = new ArrayList<Class<?>>(classFiles.length);
+    for (File file : classFiles) {
+      String name = file.getName();
+      String fqn = packageToScan + "." + name.substring(0, name.length() - 6);
+      try {
+        Class<?> c = classLoader.loadClass(fqn);
+        if (cv.isClassValid(c)) {
+          annotatedClasses.add(c);
+        }
+      } catch (ClassNotFoundException ex) {
+        throw new IllegalArgumentException("Exception during class loading of class '" + fqn + 
+                "' with message '" + ex.getMessage() + "'.");
+      }
+    }
+    
+    // recursive search
+    File[] subfolders = listSubFolder(folder);
+    for (File file : subfolders) {
+      List<Class<?>> subFolderClazzes = loadClasses(packageToScan + "." + file.getName(), ff, cv);
+      annotatedClasses.addAll(subFolderClazzes);
+    }
+    //
+    
+    return annotatedClasses;
+  }
+
+  private static File[] listSubFolder(File folder) {
+    File[] subfolders = folder.listFiles(FOLDER_FILTER);
+    if(subfolders == null) {
+      return EMPTY_FILE_ARRAY;
+    }
+    return subfolders;
+  }
+  
+  public interface ClassValidator {
+    boolean isClassValid(Class<?> c);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/resources/log4j.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/resources/log4j.xml b/odata2-edm-annotation/edm-annotation-core/src/main/resources/log4j.xml
deleted file mode 100644
index 90a4706..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/resources/log4j.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
-  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.
--->
-<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
-
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
-    <appender name="console" class="org.apache.log4j.ConsoleAppender">
-        <param name="Target" value="System.out" />
-        <layout class="org.apache.log4j.PatternLayout">
-            <param name="ConversionPattern" value="%-5p %c{1} - %m%n" />
-        </layout>
-    </appender>
-
-    <logger name="org.apache.olingo.odata2.ref" additivity="false">
-        <level value="trace" />
-        <appender-ref ref="console" />
-    </logger>
-    
-    <root>
-        <priority value="error" />
-        <appender-ref ref="console" />
-    </root>
-</log4j:configuration>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
index b132a0b..04dbefc 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
@@ -24,10 +24,10 @@ import org.apache.olingo.odata2.api.edm.FullQualifiedName;
 import org.apache.olingo.odata2.api.edm.provider.EntitySet;
 import org.apache.olingo.odata2.api.exception.ODataException;
 import org.apache.olingo.odata2.core.annotation.edm.AnnotationEdmProvider;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
 import org.apache.olingo.odata2.core.annotation.model.Building;
 import org.apache.olingo.odata2.core.annotation.model.ModelSharedConstants;
 import org.apache.olingo.odata2.core.annotation.model.Photo;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
 import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumerTest.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumerTest.java
deleted file mode 100644
index 3d7b89d..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumerTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2013 The Apache Software Foundation.
- *
- * Licensed 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.odata2.core.annotation.processor.json;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.Map;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- *
- */
-public class JsonConsumerTest {
-
-  public static final String SIMPLE_TEAM = "{\"d\":{"
-          + "\"__metadata\":{\"id\":\"https://localhost/Test.svc/Teams('1')\","
-          + "\"uri\":\"https://localhost/Test.svc/Teams('1')\","
-          + "\"type\":\"Test.Team\""
-          + "},"
-          + "\"Id\":\"1\","
-          + "\"Name\":\"Team 1\","
-          + "\"isScrumTeam\":false}}";
-
-  public static final String SIMPLER_TEAM = "{"
-          + "\"d\":{"
-          + "\"Id\":\"1\",\"Name\":\"Team 1\",\"isScrumTeam\":false"
-          + "}}";
-
-  @Test
-  public void simplerRead() throws Exception {
-    InputStream content = encapsulate(SIMPLER_TEAM);
-    JsonConsumer jc = new JsonConsumer(content);
-    Map<String, String> name2Values = jc.read();
-
-//    System.out.println("" + name2Values);
-    Assert.assertEquals(3, name2Values.size());
-
-    Assert.assertEquals("1", name2Values.get("Id"));
-    Assert.assertEquals("Team 1", name2Values.get("Name"));
-    Assert.assertEquals("false", name2Values.get("isScrumTeam"));
-  }
-
-  @Test
-  public void simpleRead() throws Exception {
-    InputStream content = encapsulate(SIMPLE_TEAM);
-    JsonConsumer jc = new JsonConsumer(content);
-    Map<String, String> name2Values = jc.read();
-
-//    System.out.println("" + name2Values);
-    Assert.assertEquals(6, name2Values.size());
-
-    Assert.assertEquals("1", name2Values.get("Id"));
-    Assert.assertEquals("Team 1", name2Values.get("Name"));
-    Assert.assertEquals("false", name2Values.get("isScrumTeam"));
-    
-    Assert.assertEquals("https://localhost/Test.svc/Teams('1')", name2Values.get("md_id"));
-    Assert.assertEquals("https://localhost/Test.svc/Teams('1')", name2Values.get("md_uri"));
-    Assert.assertEquals("Test.Team", name2Values.get("md_type"));
-  }
-
-  public static InputStream encapsulate(final String content) {
-    try {
-      return new ByteArrayInputStream(content.getBytes("UTF-8"));
-    } catch (UnsupportedEncodingException e) {
-      // we know that UTF-8 is supported
-      throw new RuntimeException("UTF-8 MUST be supported.", e);
-    }
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-webref/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/pom.xml b/odata2-edm-annotation/edm-annotation-webref/pom.xml
index 9f4e99f..18ff957 100644
--- a/odata2-edm-annotation/edm-annotation-webref/pom.xml
+++ b/odata2-edm-annotation/edm-annotation-webref/pom.xml
@@ -21,6 +21,10 @@ the License. -->
     <relativePath>..</relativePath>
   </parent>
 
+  <properties>
+      <version.slf4j>1.7.1</version.slf4j>
+  </properties>
+
   <build>
     <finalName>${project.artifactId}</finalName>
     <resources>
@@ -88,17 +92,11 @@ the License. -->
       <artifactId>olingo-odata2-edm-annotation-core-incubating</artifactId>
       <version>${project.version}</version>
     </dependency>
-    <dependency>
-      <groupId>org.apache.olingo</groupId>
-      <artifactId>olingo-odata2-ref-incubating</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    
     
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-log4j12</artifactId>
-      <version>1.7.1</version>
+      <version>${version.slf4j}</version>
     </dependency>
   </dependencies>
 


[04/12] Renamed project

Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
deleted file mode 100644
index 73d1218..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.model;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.WritableRaster;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import javax.imageio.ImageIO;
-
-/**
- *
- */
-public class ResourceHelper {
-
-  public enum Format {BMP, JPEG, PNG, GIF};
-  
-  public static byte[] generateImage() {
-    return generateImage(Format.PNG);
-  }
-  
-  public static byte[] generateImage(Format format) {
-    try {
-      int width = 320;
-      int height = 320;
-      BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
-      WritableRaster raster = image.getRaster();
-      
-      int mod = format.ordinal() + 2;
-      for (int h = 0; h < height; h++) {
-        for (int w = 0; w < width; w++) {
-          if (((h / 32) + (w / 32)) % mod == 0) {
-            raster.setSample(w, h, 0, 0);
-          } else {
-            raster.setSample(w, h, 0, 1);
-          }
-        }
-      }
-      
-      ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
-      ImageIO.write(image, format.name(), out);
-      return out.toByteArray();
-    } catch (IOException ex) {
-      return new byte[0];
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
deleted file mode 100644
index 7c9e486..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2013 The Apache Software Foundation.
- *
- * Licensed 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.odata2.core.annotation.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-
-/**
- *
- */
-@EdmEntityType(name = "Room", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Rooms")
-public class Room extends RefBase {
-
-  @EdmProperty
-  private Integer seats;
-  @EdmProperty
-  private Integer version;
-  @EdmNavigationProperty(name = "nr_Building", association = "BuildingRooms")
-  private Building building;
-  @EdmNavigationProperty(name = "nr_Employees")
-  private List<Employee> employees = new ArrayList<Employee>();
-
-  public Room(final int id, final String name) {
-    super(id, name);
-  }
-
-  public void setSeats(final int seats) {
-    this.seats = seats;
-  }
-
-  public int getSeats() {
-    return seats;
-  }
-
-  public void setVersion(final int version) {
-    this.version = version;
-  }
-
-  public int getVersion() {
-    return version;
-  }
-
-  public void setBuilding(final Building building) {
-    this.building = building;
-  }
-
-  public Building getBuilding() {
-    return building;
-  }
-
-  public List<Employee> getEmployees() {
-    return employees;
-  }
-
-  @Override
-  public int hashCode() {
-    return id;
-  }
-
-  @Override
-  public boolean equals(final Object obj) {
-    return this == obj
-        || obj != null && getClass() == obj.getClass() && id == ((Room) obj).id;
-  }
-
-  @Override
-  public String toString() {
-    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Seats\":" + seats + ",\"Version\":" + version + "}";
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
deleted file mode 100644
index e9b296f..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
-*  
-*/
-@EdmEntityType(name = "Team", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Teams")
-public class Team extends RefBase {
-  @EdmProperty(type = EdmType.BOOLEAN)
-  private Boolean isScrumTeam;
-  @EdmNavigationProperty(name = "nt_Employees", association = "TeamEmployees", toMultiplicity = Multiplicity.MANY)
-  private List<Employee> employees = new ArrayList<Employee>();
-
-  public Team() {
-    super(-1, null);
-  }
-
-  public Team(final int id, final String name) {
-    super(id, name);
-  }
-
-  public Boolean isScrumTeam() {
-    return isScrumTeam;
-  }
-
-  public void setScrumTeam(final Boolean isScrumTeam) {
-    this.isScrumTeam = isScrumTeam;
-  }
-
-  public void addEmployee(Employee e) {
-    this.employees.add(e);
-  }
-
-  public List<Employee> getEmployees() {
-    return employees;
-  }
-
-  @Override
-  public int hashCode() {
-    return id;
-  }
-
-  @Override
-  public boolean equals(final Object obj) {
-    return this == obj
-        || obj != null && getClass() == obj.getClass() && id == ((Team) obj).id;
-  }
-
-  @Override
-  public String toString() {
-    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"IsScrumTeam\":" + isScrumTeam + "}";
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/pom.xml b/odata2-edm-annotation/edm-annotation-webref/pom.xml
deleted file mode 100644
index 18ff957..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/pom.xml
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>olingo-odata2-edm-annotation-webref-incubating</artifactId>
-  <packaging>war</packaging>
-  <name>${project.artifactId}</name>
-
-  <parent>
-    <groupId>org.apache.olingo</groupId>
-    <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
-    <version>1.1.0-SNAPSHOT</version>
-    <relativePath>..</relativePath>
-  </parent>
-
-  <properties>
-      <version.slf4j>1.7.1</version.slf4j>
-  </properties>
-
-  <build>
-    <finalName>${project.artifactId}</finalName>
-    <resources>
-      <resource>
-        <directory>src/main/version</directory>
-        <filtering>true</filtering>
-        <targetPath>../${project.build.finalName}/gen</targetPath>
-      </resource>
-      <resource>
-        <directory>src/main/resources</directory>
-        <filtering>true</filtering>
-      </resource>
-      <resource>
-        <directory>target/maven-shared-archive-resources</directory>
-      </resource>
-    </resources>
-
-    <plugins>
-      <plugin>
-        <groupId>com.sap.research</groupId>
-        <artifactId>nwcloud-maven-plugin</artifactId>
-        <version>1.0.0.RELEASE</version>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-    </plugins>
-
-  </build>
-
-  <dependencies>
-    <dependency>
-      <!-- required because of auto detection of web facet 2.5 -->
-      <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
-      <version>2.5</version>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cxf</groupId>
-      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
-      <version>${cxf.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.olingo</groupId>
-      <artifactId>olingo-odata2-api-incubating</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.olingo</groupId>
-      <artifactId>olingo-odata2-core-incubating</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.olingo</groupId>
-      <artifactId>olingo-odata2-edm-annotation-api-incubating</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.olingo</groupId>
-      <artifactId>olingo-odata2-edm-annotation-core-incubating</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
-      <version>${version.slf4j}</version>
-    </dependency>
-  </dependencies>
-
-  <profiles>
-    <profile>
-      <id>dev</id>
-
-      <build>
-        <defaultGoal>cargo:run</defaultGoal>
-
-        <plugins>
-          <plugin>
-            <groupId>org.codehaus.cargo</groupId>
-            <artifactId>cargo-maven2-plugin</artifactId>
-            <version>1.4.2</version>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
-</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
deleted file mode 100644
index 668ac86..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*******************************************************************************
- * 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.odata2.ref.annotation.model;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *  
- */
-@EdmEntityType(name = "Building", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Buildings")
-public class Building {
-  @EdmKey
-  @EdmProperty(type = EdmType.INT32)
-  private int id;
-  @EdmProperty
-  private String name;
-  @EdmProperty(name = "Image", type = EdmType.BINARY)
-  private byte[] image;
-  @EdmNavigationProperty(name = "nb_Rooms", toType = Room.class,
-      association = "BuildingRooms", toMultiplicity = Multiplicity.MANY)
-  private List<Room> rooms = new ArrayList<Room>();
-
-  public String getId() {
-    return Integer.toString(id);
-  }
-
-  public void setName(final String name) {
-    this.name = name;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public void setImage(final byte[] byteArray) {
-    image = byteArray;
-  }
-
-  public byte[] getImage() {
-    if (image == null) {
-      return null;
-    } else {
-      return image.clone();
-    }
-  }
-
-  public void addRoom(Room room) {
-    rooms.add(room);
-  }
-
-  public List<Room> getRooms() {
-    return rooms;
-  }
-
-  @Override
-  public int hashCode() {
-    return id;
-  }
-
-  @Override
-  public boolean equals(final Object obj) {
-    return this == obj
-        || obj != null && getClass() == obj.getClass() && id == ((Building) obj).id;
-  }
-
-  @Override
-  public String toString() {
-    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Image\":\"" + Arrays.toString(image) + "\"}";
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
deleted file mode 100644
index a4d5a56..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
- * 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.odata2.ref.annotation.model;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-
-/**
- *  
- */
-@EdmComplexType(name="c_City", namespace = ModelSharedConstants.NAMESPACE_1)
-public class City {
-
-  @EdmProperty
-  private String postalCode;
-  @EdmProperty
-  private String cityName;
-
-  public City(final String postalCode, final String name) {
-    this.postalCode = postalCode;
-    cityName = name;
-  }
-
-  public void setPostalCode(final String postalCode) {
-    this.postalCode = postalCode;
-  }
-
-  public String getPostalCode() {
-    return postalCode;
-  }
-
-  public void setCityName(final String cityName) {
-    this.cityName = cityName;
-  }
-
-  public String getCityName() {
-    return cityName;
-  }
-
-  @Override
-  public String toString() {
-    return String.format("%s, %s", cityName, postalCode);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
deleted file mode 100644
index 2204ee8..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*******************************************************************************
- * 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.odata2.ref.annotation.model;
-
-import java.text.DateFormat;
-import java.util.Calendar;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmFacets;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *  
- */
-@EdmEntityType(name = "Employee", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Employees")
-public class Employee {
-  @EdmKey
-  @EdmProperty(name = "EmployeeId", type = EdmType.STRING)
-  private String employeeId;
-  @EdmProperty(name = "EmployeeName")
-  private String employeeName;
-  @EdmProperty
-  private int age;
-  @EdmNavigationProperty(name = "ne_Manager", association = "ManagerEmployees")
-  private Manager manager;
-  @EdmNavigationProperty(name = "ne_Team", association = "TeamEmployees")
-  private Team team;
-  @EdmNavigationProperty(name = "ne_Room")
-  private Room room;
-  @EdmMediaResourceMimeType
-  private String imageType;
-  @EdmMediaResourceContent
-  private byte[] image;
-  @EdmProperty(name = "ImageUrl")
-  private String imageUrl;
-  @EdmProperty(name = "EntryDate", type = EdmType.DATE_TIME,
-      facets = @EdmFacets(nullable = true))
-  private Calendar entryDate;
-  @EdmProperty(name = "Location", facets = @EdmFacets(nullable = false))
-  private Location location;
-
-  public String getId() {
-    return employeeId;
-  }
-
-  public void setEmployeeName(final String employeeName) {
-    this.employeeName = employeeName;
-  }
-
-  public String getEmployeeName() {
-    return employeeName;
-  }
-
-  public void setAge(final int age) {
-    this.age = age;
-  }
-
-  public int getAge() {
-    return age;
-  }
-
-  public void setManager(final Manager manager) {
-    this.manager = manager;
-  }
-
-  public Manager getManager() {
-    return manager;
-  }
-
-  public void setTeam(final Team team) {
-    this.team = team;
-  }
-
-  public Team getTeam() {
-    return team;
-  }
-
-  public void setRoom(final Room room) {
-    this.room = room;
-  }
-
-  public Room getRoom() {
-    return room;
-  }
-
-  public void setImageUri(final String imageUri) {
-    imageUrl = imageUri;
-  }
-
-  public String getImageUri() {
-    return imageUrl;
-  }
-
-  public void setLocation(final Location location) {
-    this.location = location;
-  }
-
-  public Location getLocation() {
-    return location;
-  }
-
-  public void setEntryDate(final Calendar date) {
-    entryDate = date;
-  }
-
-  public Calendar getEntryDate() {
-    return entryDate;
-  }
-
-  public void setImageType(final String imageType) {
-    this.imageType = imageType;
-  }
-
-  public String getImageType() {
-    return imageType;
-  }
-
-  public void setImage(final byte[] image) {
-    this.image = image;
-  }
-
-  public void setImage(final String imageUrl) {
-    image = loadImage(imageUrl);
-  }
-
-  private static byte[] loadImage(final String imageUrl) {
-    return ResourceHelper.loadAsByte(imageUrl);
-  }
-
-  public byte[] getImage() {
-    if (image == null) {
-      return null;
-    }
-    return image.clone();
-  }
-
-  @Override
-  public int hashCode() {
-    if (employeeId == null) {
-      return 0;
-    }
-    return employeeId.hashCode();
-  }
-
-  @Override
-  public boolean equals(final Object obj) {
-    return this == obj
-        || obj != null && getClass() == obj.getClass() && employeeId == ((Employee) obj).employeeId;
-  }
-
-  @Override
-  public String toString() {
-    return "{\"EmployeeId\":\"" + employeeId + "\","
-        + "\"EmployeeName\":\"" + employeeName + "\","
-        + "\"ManagerId\":" + (manager == null ? "null" : "\"" + manager.getId() + "\"") + ","
-        + "\"RoomId\":" + (room == null ? "null" : "\"" + room.getId() + "\"") + ","
-        + "\"TeamId\":" + (team == null ? "null" : "\"" + team.getId() + "\"") + ","
-        + "\"Location\":"
-        + (location == null ? "null" :
-            "{\"City\":" + (location.getCity() == null ? "null" :
-                "{\"PostalCode\":\"" + location.getCity().getPostalCode() + "\","
-                    + "\"CityName\":\"" + location.getCity().getCityName() + "\"}") + ","
-                + "\"Country\":\"" + location.getCountry() + "\"}") + ","
-        + "\"Age\":" + age + ","
-        + "\"EntryDate\":"
-        + (entryDate == null ? "null" : "\"" + DateFormat.getInstance().format(entryDate.getTime()) + "\"") + ","
-        + "\"ImageUrl\":\"" + imageUrl + "\"}";
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
deleted file mode 100644
index 9b0785c..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************************
- * 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.odata2.ref.annotation.model;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-
-/**
- *  
- */
-@EdmComplexType(name = "c_Location", namespace = ModelSharedConstants.NAMESPACE_1)
-public class Location {
-  @EdmProperty
-  private String country;
-  @EdmProperty
-  private City city;
-
-  public Location(final String country, final String postalCode, final String cityName) {
-    this.country = country;
-    city = new City(postalCode, cityName);
-  }
-
-  public void setCountry(final String country) {
-    this.country = country;
-  }
-
-  public String getCountry() {
-    return country;
-  }
-
-  public void setCity(final City city) {
-    this.city = city;
-  }
-
-  public City getCity() {
-    return city;
-  }
-
-  @Override
-  public String toString() {
-    return String.format("%s, %s", country, city.toString());
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
deleted file mode 100644
index 57e6d78..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * 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.odata2.ref.annotation.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
-
-/**
- *
- */
-@EdmEntityType(name = "Manager", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Managers")
-public class Manager extends Employee {
-
-  @EdmNavigationProperty(name = "nm_Employees", association = "ManagerEmployees",
-      toMultiplicity = Multiplicity.MANY)
-  private List<Employee> employees = new ArrayList<Employee>();
-
-  public List<Employee> getEmployees() {
-    return employees;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
deleted file mode 100644
index ab17fbb..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*******************************************************************************
- * 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.odata2.ref.annotation.model;
-
-public interface ModelSharedConstants {
-
-  String NAMESPACE_1 = "RefScenario";
-  String CONTAINER_1 = "Container1";
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
deleted file mode 100644
index 52971cd..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*******************************************************************************
- * 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.odata2.ref.annotation.model;
-
-import java.util.Arrays;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceSource;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *  
- */
-@EdmEntityType(name = "Photo", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Photos")
-public class Photo {
-  @EdmKey
-  @EdmProperty
-  private String name;
-  @EdmKey
-  @EdmProperty
-  private String type;
-  @EdmProperty
-  @EdmMediaResourceMimeType
-  private String mimeType;
-  @EdmProperty
-  @EdmMediaResourceSource
-  private String imageUrl = "http://localhost/someResource.png";
-  @EdmProperty(type = EdmType.BINARY)
-  @EdmMediaResourceContent
-  private byte[] image = ResourceHelper.generateImage();
-
-  public String getName() {
-    return name;
-  }
-
-  public void setName(final String name) {
-    this.name = name;
-  }
-
-  public String getType() {
-    return type;
-  }
-
-  public void setType(final String type) {
-    this.type = type;
-  }
-
-  public String getImageUri() {
-    return imageUrl;
-  }
-
-  public void setImageUri(final String uri) {
-    imageUrl = uri;
-  }
-
-  public byte[] getImage() {
-    return image.clone();
-  }
-
-  public void setImage(final byte[] image) {
-    this.image = image;
-  }
-
-  public String getImageType() {
-    return mimeType;
-  }
-
-  public void setImageType(final String imageType) {
-    this.mimeType = imageType;
-  }
-
-  @Override
-  public int hashCode() {
-    int hash = 5;
-    hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
-    hash = 83 * hash + (this.type != null ? this.type.hashCode() : 0);
-    return hash;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (obj == null) {
-      return false;
-    }
-    if (getClass() != obj.getClass()) {
-      return false;
-    }
-    final Photo other = (Photo) obj;
-    if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
-      return false;
-    }
-    if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) {
-      return false;
-    }
-    return true;
-  }
-  
-  @Override
-  public String toString() {
-    return "{\"Name\":\"" + name + "\","
-        + "\"Type\":\"" + type + "\","
-        + "\"ImageUrl\":\"" + imageUrl + "\","
-        + "\"Image\":\"" + Arrays.toString(image) + "\","
-        + "\"MimeType\":\"" + mimeType + "\"";
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
deleted file mode 100644
index 727b8c3..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*******************************************************************************
- * 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.odata2.ref.annotation.model;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *
- */
-@EdmEntityType(name="Base", namespace=ModelSharedConstants.NAMESPACE_1)
-public abstract class RefBase {
-  @EdmProperty(name="Name")
-  protected String name;
-  @EdmProperty(name="Id", type = EdmType.STRING)
-  @EdmKey
-  protected String id;
-
-  public String getName() {
-    return name;
-  }
-
-  public String getId() {
-    return id;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public void setId(int id) {
-    this.id = String.valueOf(id);
-  }
-
-  @Override
-  public int hashCode() {
-    if(id == null) {
-      return -1;
-    }
-    return id.hashCode();
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (obj == null) {
-      return false;
-    }
-    if (getClass() != obj.getClass()) {
-      return false;
-    }
-    final RefBase other = (RefBase) obj;
-    if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
-      return false;
-    }
-    if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) {
-      return false;
-    }
-    return true;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
deleted file mode 100644
index 3d2bb88..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*******************************************************************************
- * 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.odata2.ref.annotation.model;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.WritableRaster;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import javax.imageio.ImageIO;
-
-/**
- *
- */
-public class ResourceHelper {
-
-  public static byte[] loadAsByte(String resource) {
-    return load(resource, new byte[0]);
-  }
-
-  public static byte[] load(String resource, byte[] defaultResult) {
-    InputStream instream = null;
-    try {
-      instream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
-      if (instream == null) {
-        return defaultResult;
-      }
-      ByteArrayOutputStream stream = new ByteArrayOutputStream();
-      int b = 0;
-      while ((b = instream.read()) != -1) {
-        stream.write(b);
-      }
-
-      return stream.toByteArray();
-    } catch (IOException e) {
-      throw new RuntimeException(e);
-    } finally {
-      if(instream != null) {
-        try {
-          instream.close();
-        } catch (IOException ex) { }
-      }
-    }
-  }
-
-  public enum Format {BMP, JPEG, PNG, GIF};
-  
-  public static byte[] generateImage() {
-    return generateImage(Format.PNG);
-  }
-  
-  public static byte[] generateImage(Format format) {
-    try {
-      int width = 320;
-      int height = 320;
-      BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
-      WritableRaster raster = image.getRaster();
-      
-      int mod = format.ordinal() + 2;
-      for (int h = 0; h < height; h++) {
-        for (int w = 0; w < width; w++) {
-          if (((h / 32) + (w / 32)) % mod == 0) {
-            raster.setSample(w, h, 0, 0);
-          } else {
-            raster.setSample(w, h, 0, 1);
-          }
-        }
-      }
-      
-      ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
-      ImageIO.write(image, format.name(), out);
-      return out.toByteArray();
-    } catch (IOException ex) {
-      return new byte[0];
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
deleted file mode 100644
index 2d9f48e..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*******************************************************************************
- * 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.odata2.ref.annotation.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-
-/**
- *
- */
-@EdmEntityType(name = "Room", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Rooms")
-public class Room extends RefBase {
-
-  @EdmProperty
-  private Integer seats;
-  @EdmProperty
-  private Integer version;
-  @EdmNavigationProperty(name = "nr_Building", association = "BuildingRooms")
-  private Building building;
-  @EdmNavigationProperty(name = "nr_Employees")
-  private List<Employee> employees = new ArrayList<Employee>();
-
-  public void setSeats(final int seats) {
-    this.seats = seats;
-  }
-
-  public int getSeats() {
-    return seats;
-  }
-
-  public void setVersion(final int version) {
-    this.version = version;
-  }
-
-  public int getVersion() {
-    return version;
-  }
-
-  public void setBuilding(final Building building) {
-    this.building = building;
-  }
-
-  public Building getBuilding() {
-    return building;
-  }
-
-  public List<Employee> getEmployees() {
-    return employees;
-  }
-
-  @Override
-  public int hashCode() {
-    return super.hashCode();
-  }
-
-  @Override
-  public boolean equals(final Object obj) {
-    return this == obj
-        || obj != null && getClass() == obj.getClass() && id == ((Room) obj).id;
-  }
-
-  @Override
-  public String toString() {
-    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Seats\":" + seats + ",\"Version\":" + version + "}";
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
deleted file mode 100644
index 50d2ad2..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************
- * 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.odata2.ref.annotation.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
-*  
-*/
-@EdmEntityType(name = "Team", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Teams")
-public class Team extends RefBase {
-  @EdmProperty(type = EdmType.BOOLEAN)
-  private Boolean isScrumTeam;
-  @EdmNavigationProperty(name = "nt_Employees", association = "TeamEmployees", toMultiplicity = Multiplicity.MANY)
-  private List<Employee> employees = new ArrayList<Employee>();
-
-  public Boolean isScrumTeam() {
-    return isScrumTeam;
-  }
-
-  public void setScrumTeam(final Boolean isScrumTeam) {
-    this.isScrumTeam = isScrumTeam;
-  }
-
-  public void addEmployee(Employee e) {
-    this.employees.add(e);
-  }
-
-  public List<Employee> getEmployees() {
-    return employees;
-  }
-
-  @Override
-  public int hashCode() {
-    return super.hashCode();
-  }
-
-  @Override
-  public boolean equals(final Object obj) {
-    return this == obj
-        || obj != null && getClass() == obj.getClass() && id == ((Team) obj).id;
-  }
-
-  @Override
-  public String toString() {
-    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"IsScrumTeam\":" + isScrumTeam + "}";
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
deleted file mode 100644
index 3870119..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * *****************************************************************************
- * 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.odata2.ref.annotation.processor;
-
-import java.util.Calendar;
-
-import org.apache.olingo.odata2.api.ODataCallback;
-import org.apache.olingo.odata2.api.ODataDebugCallback;
-import org.apache.olingo.odata2.api.ODataService;
-import org.apache.olingo.odata2.api.ODataServiceFactory;
-import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
-import org.apache.olingo.odata2.api.ep.EntityProvider;
-import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.api.processor.ODataErrorCallback;
-import org.apache.olingo.odata2.api.processor.ODataErrorContext;
-import org.apache.olingo.odata2.api.processor.ODataResponse;
-import org.apache.olingo.odata2.core.annotation.data.AnnotationInMemoryDs;
-import org.apache.olingo.odata2.core.annotation.data.AnnotationValueAccess;
-import org.apache.olingo.odata2.core.annotation.data.DataStore;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationEdmProvider;
-import org.apache.olingo.odata2.core.annotation.processor.ListsProcessor;
-import org.apache.olingo.odata2.ref.annotation.model.Building;
-import org.apache.olingo.odata2.ref.annotation.model.Employee;
-import org.apache.olingo.odata2.ref.annotation.model.Location;
-import org.apache.olingo.odata2.ref.annotation.model.Manager;
-import org.apache.olingo.odata2.ref.annotation.model.Photo;
-import org.apache.olingo.odata2.ref.annotation.model.ResourceHelper;
-import org.apache.olingo.odata2.ref.annotation.model.Room;
-import org.apache.olingo.odata2.ref.annotation.model.Team;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- */
-public class AnnotationPocServiceFactory extends ODataServiceFactory {
-
-  private static boolean isInitialized = false;
-
-  @Override
-  public ODataService createService(final ODataContext context) throws ODataException {
-
-    String modelPackage = "org.apache.olingo.odata2.ref.annotation.model";
-    AnnotationEdmProvider annotationEdmProvider = new AnnotationEdmProvider(modelPackage);
-    AnnotationInMemoryDs annotationScenarioDs = new AnnotationInMemoryDs(modelPackage);
-    AnnotationValueAccess annotationValueAccess = new AnnotationValueAccess();
-
-    if (!isInitialized) {
-      initializeSampleData(annotationScenarioDs);
-      isInitialized = true;
-    }
-
-    // Edm via Annotations and ListProcessor via AnnotationDS with AnnotationsValueAccess
-    return createODataSingleProcessorService(annotationEdmProvider,
-            new ListsProcessor(annotationScenarioDs, annotationValueAccess));
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
-    return (T) (callbackInterface.isAssignableFrom(ScenarioErrorCallback.class)
-            ? new ScenarioErrorCallback() : callbackInterface.isAssignableFrom(ODataDebugCallback.class)
-            ? new ScenarioDebugCallback() : super.getCallback(callbackInterface));
-  }
-
-  /*
-  * Helper classes and methods
-  */
-
-  /**
-   * 
-   */
-  private final class ScenarioDebugCallback implements ODataDebugCallback {
-
-    @Override
-    public boolean isDebugEnabled() {
-      return true;
-    }
-  }
-
-  private class ScenarioErrorCallback implements ODataErrorCallback {
-
-    private final Logger LOG = LoggerFactory.getLogger(ScenarioErrorCallback.class);
-
-    @Override
-    public ODataResponse handleError(final ODataErrorContext context) throws ODataApplicationException {
-      if (context.getHttpStatus() == HttpStatusCodes.INTERNAL_SERVER_ERROR) {
-        LOG.error("Internal Server Error", context.getException());
-      }
-
-      return EntityProvider.writeErrorDocument(context);
-    }
-
-  }
-
-  private void initializeSampleData(AnnotationInMemoryDs dataSource) throws ODataApplicationException {
-    DataStore<Team> teamDs = dataSource.getDataStore(Team.class);
-    teamDs.create(createTeam("Team Alpha", true));
-    teamDs.create(createTeam("Team Beta", false));
-    teamDs.create(createTeam("Team Gamma", false));
-    teamDs.create(createTeam("Team Omega", true));
-    teamDs.create(createTeam("Team Zeta", true));
-
-    DataStore<Building> buildingsDs = dataSource.getDataStore(Building.class);
-    Building redBuilding = createBuilding("Red Building");
-    buildingsDs.create(redBuilding);
-    Building greenBuilding = createBuilding("Green Building");
-    buildingsDs.create(greenBuilding);
-    Building blueBuilding = createBuilding("Blue Building");
-    buildingsDs.create(blueBuilding);
-    Building yellowBuilding = createBuilding("Yellow Building");
-    buildingsDs.create(yellowBuilding);
-
-    DataStore<Photo> photoDs = dataSource.getDataStore(Photo.class);
-    photoDs.create(createPhoto("Small picture", ResourceHelper.Format.GIF));
-    photoDs.create(createPhoto("Medium picture", ResourceHelper.Format.PNG));
-    photoDs.create(createPhoto("Big picture", ResourceHelper.Format.JPEG));
-    photoDs.create(createPhoto("Huge picture", ResourceHelper.Format.BMP));
-
-    DataStore<Room> roomDs = dataSource.getDataStore(Room.class);
-    roomDs.create(createRoom("Tiny red room", 5, 1, redBuilding));
-    roomDs.create(createRoom("Small red room", 20, 1, redBuilding));
-    roomDs.create(createRoom("Small green room", 20, 1, greenBuilding));
-    roomDs.create(createRoom("Big blue room", 40, 1, blueBuilding));
-    roomDs.create(createRoom("Huge blue room", 120, 1, blueBuilding));
-    roomDs.create(createRoom("Huge yellow room", 120, 1, yellowBuilding));
-
-    DataStore<Employee> employeeDataStore = dataSource.getDataStore(Employee.class);
-    employeeDataStore.create(createEmployee("first Employee",
-        new Location("Norge", "8392", "Ä"), 42, null,
-        photoDs.read().iterator().next().getImage(), photoDs.read().iterator().next().getImageType(),
-        "http://localhost/image/first.png",
-        null, teamDs.read().iterator().next(), roomDs.read().iterator().next()));
-  }
-
-  private Employee createEmployee(final String name,
-      Location location, final int age, final Calendar date,
-      final byte[] image, final String imageType, final String imageUrl,
-      Manager manager, Team team, Room room) {
-    Employee employee = new Employee();
-    employee.setEmployeeName(name);
-    employee.setLocation(location);
-    employee.setAge(age);
-    employee.setEntryDate(date);
-    employee.setImage(image);
-    employee.setImageType(imageType);
-    employee.setImageUri(imageUrl);
-    employee.setManager(manager);
-    employee.setTeam(team);
-    employee.setRoom(room);
-    return employee;
-  }
-
-  private Team createTeam(String teamName, boolean isScrumTeam) {
-    Team team = new Team();
-    team.setName(teamName);
-    team.setScrumTeam(isScrumTeam);
-    return team;
-  }
-
-  private Building createBuilding(String buildingName) {
-    Building b = new Building();
-    b.setName(buildingName);
-    return b;
-  }
-
-  private Photo createPhoto(String name, ResourceHelper.Format format) {
-    Photo p = new Photo();
-    p.setName(name);
-    p.setImageUri("http://localhost/image/" + name);
-    p.setType(format.name());
-    p.setImageType("image/" + format.name().toLowerCase());
-    p.setImage(ResourceHelper.generateImage(format));
-    return p;
-  }
-
-  private Room createRoom(String name, int seats, int version, Building building) {
-    Room r = new Room();
-    r.setName(name);
-    r.setSeats(seats);
-    r.setVersion(version);
-    r.setBuilding(building);
-    
-    building.addRoom(r);
-    
-    return r;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/resources/log4j.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/resources/log4j.xml b/odata2-edm-annotation/edm-annotation-webref/src/main/resources/log4j.xml
deleted file mode 100644
index 90a4706..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/resources/log4j.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
-  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.
--->
-<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
-
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
-    <appender name="console" class="org.apache.log4j.ConsoleAppender">
-        <param name="Target" value="System.out" />
-        <layout class="org.apache.log4j.PatternLayout">
-            <param name="ConversionPattern" value="%-5p %c{1} - %m%n" />
-        </layout>
-    </appender>
-
-    <logger name="org.apache.olingo.odata2.ref" additivity="false">
-        <level value="trace" />
-        <appender-ref ref="console" />
-    </logger>
-    
-    <root>
-        <priority value="error" />
-        <appender-ref ref="console" />
-    </root>
-</log4j:configuration>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/version/version.html
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/version/version.html b/odata2-edm-annotation/edm-annotation-webref/src/main/version/version.html
deleted file mode 100644
index 6d76d0b..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/version/version.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-
- 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.
-
--->
-
-<table border="1">
-<tr><td>name</td><td>${name}</td></tr>
-<tr><td>version</td><td>${version}</td></tr>
-<tr><td>timestamp</td><td>${timestamp}</td></tr>
-<tr><td>project.build.finalName</td><td>${project.build.finalName}</td></tr>
-</table>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/WEB-INF/web.xml b/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 5f7264c..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
--->
-<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
-	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
-	id="WebApp_ID" version="2.5">
-	<display-name>org.apache.olingo.odata2.ref.annotations.web</display-name>
-	<welcome-file-list>
-		<welcome-file>index.jsp</welcome-file>
-	</welcome-file-list>
-	
-	<servlet>
-		<servlet-name>ReferenceScenarioServlet</servlet-name>
-		<servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
-		<init-param>
-			<param-name>javax.ws.rs.Application</param-name>
-			<param-value>org.apache.olingo.odata2.core.rest.app.ODataApplication</param-value>
-		</init-param>
-		<init-param>
-			<param-name>org.apache.olingo.odata2.service.factory</param-name>
-			<param-value>org.apache.olingo.odata2.ref.annotation.processor.AnnotationPocServiceFactory</param-value>
-		</init-param>
-		<load-on-startup>1</load-on-startup>
-	</servlet>
-
-	<servlet-mapping>
-		<servlet-name>ReferenceScenarioServlet</servlet-name>
-		<url-pattern>/ReferenceScenario.svc/*</url-pattern>
-	</servlet-mapping>
-
-</web-app>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp b/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp
deleted file mode 100644
index 49cf364..0000000
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp
+++ /dev/null
@@ -1,116 +0,0 @@
-<%@ page language="java" contentType="text/html; UTF-8" pageEncoding="UTF-8"%>
-<!--
-  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.
--->
-<!DOCTYPE html>
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<title>Apache Olingo - OData2 Library</title>
-<style type="text/css">
-body { font-family: Arial, sans-serif; font-size: 13px; line-height: 18px;
-       color: blue; background-color: #ffffff; }
-a { color: blue; text-decoration: none; }
-a:focus { outline: thin dotted #4076cb; outline-offset: -1px; }
-a:hover, a:active { outline: 0; }
-a:hover { color: #404a7e; text-decoration: underline; }
-h1, h2, h3, h4, h5, h6 { margin: 9px 0; font-family: inherit; font-weight: bold;
-                         line-height: 1; color: blue; }
-h1 { font-size: 36px; line-height: 40px; }
-h2 { font-size: 30px; line-height: 40px; }
-h3 { font-size: 24px; line-height: 40px; }
-h4 { font-size: 18px; line-height: 20px; }
-h5 { font-size: 14px; line-height: 20px; }
-h6 { font-size: 12px; line-height: 20px; }
-.logo { float: right; }
-ul { padding: 0; margin: 0 0 9px 25px; }
-ul ul { margin-bottom: 0; }
-li { line-height: 18px; }
-hr { margin: 18px 0;
-     border: 0; border-top: 1px solid #cccccc; border-bottom: 1px solid #ffffff; }
-table { border-collapse: collapse; border-spacing: 10px; }
-th, td { border: 1px solid; padding: 20px; }
-.code { font-family: "Courier New", monospace; font-size: 13px; line-height: 18px; }
-</style>
-</head>
-<body>
-	<h1>Apache Olingo - OData2 Library</h1>
-	<hr />
-	<h2>Reference Scenario</h2>
-	<table>
-		<tr>
-			<td valign="top">
-				<h3>Service Document and Metadata</h3>
-				<ul>
-					<li><a href="ReferenceScenario.svc?_wadl" target="_blank">wadl</a></li>
-					<li><a href="ReferenceScenario.svc/" target="_blank">service
-							document</a></li>
-					<li><a href="ReferenceScenario.svc/$metadata" target="_blank">metadata</a></li>
-				</ul>
-				<h3>EntitySets</h3>
-				<ul>
-					<li><a href="ReferenceScenario.svc/Employees" target="_blank">Employees</a></li>
-					<li><a href="ReferenceScenario.svc/Managers" target="_blank">Managers</a></li>
-					<li><a href="ReferenceScenario.svc/Buildings" target="_blank">Buildings</a></li>
-					<li><a href="ReferenceScenario.svc/Buildings/?$expand=nb_Rooms" 
-                 target="_blank">Buildings/?$expand=nb_Rooms</a></li>
-					<li><a href="ReferenceScenario.svc/Rooms" target="_blank">Rooms</a></li>
-					<li><a href="ReferenceScenario.svc/Rooms/?$orderby=Name" target="_blank">Rooms/?$orderby=Name</a></li>
-					<li><a href="ReferenceScenario.svc/Photos" target="_blank">Photos</a></li>
-					<li><a href="ReferenceScenario.svc/Photos/?$filter=Type%20eq%20'PNG'" 
-                 target="_blank">Photos/?$filter=Type eq 'PNG'</a></li>
-        </ul>
-				<h3>Entities</h3>
-				<ul>
-					<li><a href="ReferenceScenario.svc/Employees('1')" target="_blank">Employees('1')</a></li>
-					<li><a href="ReferenceScenario.svc/Managers('1')" target="_blank">Managers('1')</a></li>
-					<li><a href="ReferenceScenario.svc/Buildings(1)" target="_blank">Buildings(1)</a></li>
-					<li><a href="ReferenceScenario.svc/Buildings(1)/nb_Rooms" target="_blank">Buildings(1)/nb_Rooms</a></li>
-					<li><a href="ReferenceScenario.svc/Rooms('1')" target="_blank">Rooms('1')</a></li>
-					<li><a href="ReferenceScenario.svc/Rooms('1')/nr_Building" target="_blank">Rooms('1')/nr_Building</a></li>
- 					<li><a href="ReferenceScenario.svc/Photos(Name='Small%20picture',Type='GIF')"
-                           target="_blank">Photos(Name='Small%20picture',Type='GIF')</a></li>
- 					<li><a href="ReferenceScenario.svc/Photos(Name='Big%20picture',Type='JPEG')/$value"
-                           target="_blank">Photos(Name='Big%20picture',Type='JPEG')/$value</a></li>
-        </ul>
-			</td>
-			<td valign="top">
-				&nbsp;
-			</td>
-			<td valign="bottom">
-				<div class="code">
-					<%
-					  String version = "gen/version.html";
-					%>
-					<%
-					  try {
-					%>
-					<jsp:include page='<%=version%>' />
-					<%
-					  } catch (Exception e) {
-					%>
-					<p>IDE Build</p>
-					<%
-					  }
-					%>
-				</div>
-			</td>
-		</tr>
-	</table>
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/pom.xml b/odata2-edm-annotation/pom.xml
deleted file mode 100644
index 436576f..0000000
--- a/odata2-edm-annotation/pom.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <groupId>org.apache.olingo</groupId>
-    <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
-    <packaging>pom</packaging>
-    <name>${project.artifactId}</name>
-
-    <parent>
-        <groupId>org.apache.olingo</groupId>
-        <artifactId>olingo-odata2-parent-incubating</artifactId>
-        <version>1.1.0-SNAPSHOT</version>
-        <relativePath>..</relativePath>
-    </parent>
-
-    <modules>
-        <module>edm-annotation-api</module>
-        <module>edm-annotation-core</module>
-        <module>edm-annotation-webref</module>
-    </modules>
-</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-lib/odata-ref/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-ref/pom.xml b/odata2-lib/odata-ref/pom.xml
index 7b71a66..27cc47c 100644
--- a/odata2-lib/odata-ref/pom.xml
+++ b/odata2-lib/odata-ref/pom.xml
@@ -93,7 +93,7 @@
 		</dependency>
         <dependency>
           <groupId>org.apache.olingo</groupId>
-          <artifactId>olingo-odata2-edm-annotation-core-incubating</artifactId>
+          <artifactId>olingo-odata2-annotation-processor-core-incubating</artifactId>
           <version>${project.version}</version>
         </dependency>
 		<dependency>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index a195e82..19c21a0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -75,7 +75,7 @@
     <modules>
         <module>odata2-lib</module>
         <module>odata2-processor-jpa</module>
-        <module>odata2-edm-annotation</module>
+        <module>odata2-annotation-processor</module>
         <module>odata2-dist</module>
         <module>odata2-sample</module>
     </modules>


[07/12] Renamed project

Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
deleted file mode 100644
index 2be5663..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * 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.odata2.api.data;
-
-import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
-
-/**
- * Abstract class for implementation of the centralized parts of OData processing,
- * allowing to use the simplified {@link DataSource} and {@link ValueAccess} for the
- * actual data handling.
- * <br/>
- * Extend this class and implement a DataSourceProcessor if the default implementation
- * (<code>ListProcessor</code> found in <code>annotation-processor-core module</code>) has to be overwritten.
- */
-public abstract class DataSourceProcessor extends ODataSingleProcessor {
-
-  protected final DataSource dataSource;
-  protected final ValueAccess valueAccess;
-  
-  /**
-   * Initialize a {@link DataSourceProcessor} in combination with given {@link DataSource} (providing data objects)
-   * and {@link ValueAccess} (accessing values of data objects).
-   * 
-   * @param dataSource used for accessing the data objects
-   * @param valueAccess for accessing the values provided by the data objects
-   */
-  public DataSourceProcessor(final DataSource dataSource, final ValueAccess valueAccess) {
-    this.dataSource = dataSource;
-    this.valueAccess = valueAccess;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java
deleted file mode 100644
index 685e1b6..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*******************************************************************************
- * 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.odata2.api.data;
-
-import org.apache.olingo.odata2.api.edm.EdmMapping;
-import org.apache.olingo.odata2.api.edm.EdmProperty;
-import org.apache.olingo.odata2.api.exception.ODataException;
-
-/**
- * This interface is intended to access values in a Java object.
- */
-public interface ValueAccess {
-
-  /**
-   * Retrieves the value of an EDM property for the given data object.
-   * @param data     the Java data object
-   * @param property the requested {@link EdmProperty}
-   * @return the requested property value
-   */
-  public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException;
-
-  /**
-   * Sets the value of an EDM property for the given data object.
-   * @param data     the Java data object
-   * @param property the {@link EdmProperty}
-   * @param value    the new value of the property
-   */
-  public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException;
-
-  /**
-   * Retrieves the Java type of an EDM property for the given data object.
-   * @param data     the Java data object
-   * @param property the requested {@link EdmProperty}
-   * @return the requested Java type
-   */
-  public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException;
-
-  /**
-   * Retrieves the value defined by a mapping object for the given data object.
-   * @param data     the Java data object
-   * @param mapping  the requested {@link EdmMapping}
-   * @return the requested value
-   */
-  public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException;
-
-  /**
-   * Sets the value defined by a mapping object for the given data object.
-   * @param data     the Java data object
-   * @param mapping  the {@link EdmMapping}
-   * @param value    the new value
-   */
-  public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException;
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/pom.xml b/odata2-edm-annotation/edm-annotation-core/pom.xml
deleted file mode 100644
index 4e408f7..0000000
--- a/odata2-edm-annotation/edm-annotation-core/pom.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>olingo-odata2-edm-annotation-core-incubating</artifactId>
-  <packaging>jar</packaging>
-  <name>${project.artifactId}</name>
-
-  <parent>
-    <groupId>org.apache.olingo</groupId>
-    <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
-    <version>1.1.0-SNAPSHOT</version>
-    <relativePath>..</relativePath>
-  </parent>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.olingo</groupId>
-      <artifactId>olingo-odata2-edm-annotation-api-incubating</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.olingo</groupId>
-      <artifactId>olingo-odata2-api-incubating</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.olingo</groupId>
-      <artifactId>olingo-odata2-api-annotation-incubating</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.olingo</groupId>
-      <artifactId>olingo-odata2-core-incubating</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  
-
-</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
deleted file mode 100644
index db03a4c..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/**
- * *****************************************************************************
- * 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.odata2.core.annotation.data;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.data.DataSource;
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
-import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
-import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
-import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
-import org.apache.olingo.odata2.core.annotation.util.ClassHelper;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.AnnotatedNavInfo;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.ODataAnnotationException;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-public class AnnotationInMemoryDs implements DataSource {
-
-  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
-  private final Map<String, DataStore<Object>> dataStores = new HashMap<String, DataStore<Object>>();
-  private final boolean persistInMemory;
-
-  public AnnotationInMemoryDs(String packageToScan) {
-    this(packageToScan, true);
-  }
-  
-  public AnnotationInMemoryDs(String packageToScan, boolean persistInMemory) {
-    this.persistInMemory = persistInMemory;
-    List<Class<?>> foundClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
-      @Override
-      public boolean isClassValid(Class<?> c) {
-        return null != c.getAnnotation(org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet.class);
-      }
-    });
-
-    init(foundClasses);
-  }
-
-  @SuppressWarnings("unchecked")
-  private void init(List<Class<?>> foundClasses) {
-    for (Class<?> clz : foundClasses) {
-
-      DataStore<Object> dhs = (DataStore<Object>) getDataStore(clz);
-      org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet entitySet =
-          clz.getAnnotation(org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet.class);
-      dataStores.put(entitySet.name(), dhs);
-    }
-  }
-
-  public <T> DataStore<T> getDataStore(Class<T> clazz) {
-    return DataStore.createInMemory(clazz, persistInMemory);
-  }
-
-  @Override
-  public List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException,
-      ODataNotFoundException, EdmException, ODataApplicationException {
-
-    DataStore<Object> holder = getDataStore(entitySet);
-    if (holder != null) {
-      return new ArrayList<Object>(holder.read());
-    }
-
-    throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-  }
-
-  @Override
-  public Object readData(EdmEntitySet entitySet, Map<String, Object> keys)
-      throws ODataNotFoundException, EdmException, ODataApplicationException {
-
-    DataStore<Object> store = getDataStore(entitySet);
-    if (store != null) {
-      Object keyInstance = store.createInstance();
-      ANNOTATION_HELPER.setKeyFields(keyInstance, keys);
-
-      Object result = store.read(keyInstance);
-      if (result != null) {
-        return result;
-      }
-    }
-
-    throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-  }
-
-  @Override
-  public Object readData(EdmFunctionImport function, Map<String, Object> parameters, Map<String, Object> keys)
-      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-  }
-
-  @Override
-  public Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
-      Map<String, Object> targetKeys)
-      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-
-    DataStore<?> sourceStore = dataStores.get(sourceEntitySet.getName());
-    DataStore<?> targetStore = dataStores.get(targetEntitySet.getName());
-
-    AnnotatedNavInfo navInfo = ANNOTATION_HELPER.getCommonNavigationInfo(
-        sourceStore.getDataTypeClass(), targetStore.getDataTypeClass());
-    Field sourceField = navInfo.getFromField();
-    if (sourceField == null) {
-      throw new ODataRuntimeException("Missing source field for related data (sourceStore='" + sourceStore
-              + "', targetStore='" + targetStore + "').");
-    }
-
-    Object navigationInstance = getValue(sourceField, sourceData);
-    List<Object> resultData = new ArrayList<Object>();
-    for (Object targetInstance : targetStore.read()) {
-      if (navigationInstance instanceof Collection) {
-        for (Object object : (Collection<?>) navigationInstance) {
-          if (ANNOTATION_HELPER.keyMatch(targetInstance, object)) {
-            resultData.add(targetInstance);
-          }
-        }
-      } else if (ANNOTATION_HELPER.keyMatch(targetInstance, navigationInstance)) {
-        resultData.add(targetInstance);
-      }
-    }
-
-    if (navInfo.getToMultiplicity() == EdmMultiplicity.MANY) {
-      if (targetKeys.isEmpty()) {
-        return resultData;
-      } else {
-        for (Object result : resultData) {
-          if (ANNOTATION_HELPER.keyMatch(result, targetKeys)) {
-            return result;
-          }
-        }
-        return null;
-      }
-    } else {
-      if (resultData.isEmpty()) {
-        return null;
-      }
-      return resultData.get(0);
-    }
-  }
-
-  @Override
-  public BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData)
-      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-
-    Object data = ANNOTATION_HELPER.getValueForField(mediaLinkEntryData, EdmMediaResourceContent.class);
-    Object mimeType = ANNOTATION_HELPER.getValueForField(mediaLinkEntryData, EdmMediaResourceMimeType.class);
-
-    BinaryData db = new BinaryData((byte[]) data, String.valueOf(mimeType));
-    return db;
-  }
-
-  @Override
-  public Object newDataObject(EdmEntitySet entitySet)
-      throws ODataNotImplementedException, EdmException, ODataApplicationException {
-
-    DataStore<Object> dataStore = getDataStore(entitySet);
-    if (dataStore != null) {
-      return dataStore.createInstance();
-    }
-
-    throw new ODataRuntimeException("No DataStore found for entitySet with name: " + entitySet.getName());
-  }
-
-  @Override
-  public void writeBinaryData(EdmEntitySet entitySet, Object mediaEntityInstance, BinaryData binaryData)
-      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-
-    try {
-      ANNOTATION_HELPER.setValueForAnnotatedField(
-          mediaEntityInstance, EdmMediaResourceContent.class, binaryData.getData());
-      ANNOTATION_HELPER.setValueForAnnotatedField(
-          mediaEntityInstance, EdmMediaResourceMimeType.class, binaryData.getMimeType());
-    } catch (ODataAnnotationException e) {
-      throw new ODataRuntimeException("Invalid media resource annotation at entity set '" + entitySet.getName() 
-          + "' with message '" + e.getMessage() + "'.", e);
-    }
-  }
-
-  /**
-   * <p>Updates a single data object identified by the specified entity set and key fields of
-   * the data object.</p>
-   * @param entitySet the {@link EdmEntitySet} the object must correspond to
-   * @param data the data object of the new entity
-   * @return updated data object instance
-   * @throws org.apache.olingo.odata2.api.exception.ODataNotImplementedException
-   * @throws org.apache.olingo.odata2.api.edm.EdmException
-   * @throws org.apache.olingo.odata2.api.exception.ODataApplicationException
-   */
-  public Object updateData(EdmEntitySet entitySet, Object data)
-          throws ODataNotImplementedException, EdmException, ODataApplicationException {
-
-    DataStore<Object> dataStore = getDataStore(entitySet);
-    return dataStore.update(data);
-  }
-
-  @Override
-  public void deleteData(EdmEntitySet entitySet, Map<String, Object> keys)
-      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-    DataStore<Object> dataStore = getDataStore(entitySet);
-    Object keyInstance = dataStore.createInstance();
-    ANNOTATION_HELPER.setKeyFields(keyInstance, keys);
-    dataStore.delete(keyInstance);
-  }
-
-  @Override
-  public void createData(EdmEntitySet entitySet, Object data)
-      throws ODataNotImplementedException, EdmException, ODataApplicationException {
-
-    DataStore<Object> dataStore = getDataStore(entitySet);
-    dataStore.create(data);
-  }
-
-  @Override
-  public void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
-      Map<String, Object> targetKeys)
-      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-  }
-
-  @Override
-  public void writeRelation(EdmEntitySet sourceEntitySet, Object sourceEntity, EdmEntitySet targetEntitySet,
-      Map<String, Object> targetEntityValues)
-      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-    // get common data
-    DataStore<Object> sourceStore = dataStores.get(sourceEntitySet.getName());
-    DataStore<Object> targetStore = dataStores.get(targetEntitySet.getName());
-
-    AnnotatedNavInfo commonNavInfo = ANNOTATION_HELPER.getCommonNavigationInfo(
-        sourceStore.getDataTypeClass(), targetStore.getDataTypeClass());
-    
-    // get and validate source fields
-    Field sourceField = commonNavInfo.getFromField();
-    if (sourceField == null) {
-      throw new ODataRuntimeException("Missing source field for related data (sourceStore='" + sourceStore
-              + "', targetStore='" + targetStore + "').");
-    }
-    
-    // get related target entity
-    Object targetEntity = targetStore.createInstance();
-    ANNOTATION_HELPER.setKeyFields(targetEntity, targetEntityValues);
-    targetEntity = targetStore.read(targetEntity);
-    
-    // set at source
-    setValueAtNavigationField(sourceEntity, sourceField, targetEntity);
-    // set at target
-    Field targetField = commonNavInfo.getToField();
-    if(targetField != null) {
-      setValueAtNavigationField(targetEntity, targetField, sourceEntity);
-    }
-  }
-
-  /**
-   * Set (Multiplicity != *) or add (Multiplicity == *) <code>value</code> at <code>field</code>
-   * of <code>instance</code>. 
-   * 
-   * @param instance
-   * @param field
-   * @param value
-   * @throws EdmException
-   */
-  private void setValueAtNavigationField(Object instance, Field field, Object value) 
-      throws EdmException {
-    Class<?> fieldTypeClass = field.getType();
-    if (Collection.class.isAssignableFrom(fieldTypeClass)) {
-      @SuppressWarnings("unchecked")
-      Collection<Object> collection = (Collection<Object>) ANNOTATION_HELPER.getValueForField(
-          instance, field.getName(), EdmNavigationProperty.class);
-      if(collection == null) {
-        collection = new ArrayList<Object>();
-        setValue(instance, field, collection);
-      }
-      collection.add(value);
-    } else if(fieldTypeClass.isArray()) {
-      throw new ODataRuntimeException("Write relations for internal used arrays is not supported.");
-    } else {
-      setValue(instance, field, value);
-    }
-  }
-
-  /**
-   * Returns corresponding DataStore for EdmEntitySet or if no data store is registered an
-   * ODataRuntimeException is thrown.
-   * Never returns NULL.
-   * 
-   * @param entitySet for which the corresponding DataStore is returned
-   * @return a DataStore object 
-   * @throws EdmException 
-   * @throws  ODataRuntimeException if no DataStore is found
-   */
-  private DataStore<Object> getDataStore(EdmEntitySet entitySet) throws EdmException {
-    final String name = entitySet.getName();
-    DataStore<Object> dataStore = dataStores.get(name);
-    if (dataStore == null) {
-      throw new ODataRuntimeException("No DataStore found for entity set '" + entitySet + "'.");
-    }
-    return dataStore;
-  }
-
-  private Object getValue(Field field, Object instance) {
-    try {
-      boolean access = field.isAccessible();
-      field.setAccessible(true);
-      Object value = field.get(instance);
-      field.setAccessible(access);
-      return value;
-    } catch (IllegalArgumentException e) {
-      throw new ODataRuntimeException("Error for getting value of field '"
-          + field + "' at instance '" + instance + "'.", e);
-    } catch (IllegalAccessException e) {
-      throw new ODataRuntimeException("Error for getting value of field '"
-          + field + "' at instance '" + instance + "'.", e);
-    }
-  }
-
-  private void setValue(Object instance, Field field, Object value) {
-    try {
-      boolean access = field.isAccessible();
-      field.setAccessible(true);
-      field.set(instance, value);
-      field.setAccessible(access);
-    } catch (IllegalArgumentException e) {
-      throw new ODataRuntimeException("Error for setting value of field: '"
-          + field + "' at instance: '" + instance + "'.", e);
-    } catch (IllegalAccessException e) {
-      throw new ODataRuntimeException("Error for setting value of field: '"
-          + field + "' at instance: '" + instance + "'.", e);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
deleted file mode 100644
index 14183bf..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.data;
-
-import org.apache.olingo.odata2.api.data.ValueAccess;
-import org.apache.olingo.odata2.api.edm.EdmMapping;
-import org.apache.olingo.odata2.api.edm.EdmProperty;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
-
-/**
- *
- */
-public class AnnotationValueAccess implements ValueAccess {
-  private final AnnotationHelper annotationHelper = new AnnotationHelper();
-
-  /**
-   * Retrieves the value of an EDM property for the given data object.
-   * @param data     the Java data object
-   * @param property the requested {@link EdmProperty}
-   * @return the requested property value
-   */
-  @Override
-  public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException {
-    if(data == null) {
-      return null;
-    } else if (annotationHelper.isEdmAnnotated(data)) {
-      return annotationHelper.getValueForProperty(data, property.getName());
-    }
-    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-  }
-
-  /**
-   * Sets the value of an EDM property for the given data object.
-   * @param data     the Java data object
-   * @param property the {@link EdmProperty}
-   * @param value    the new value of the property
-   */
-  @Override
-  public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException {
-    if (annotationHelper.isEdmAnnotated(data)) {
-      annotationHelper.setValueForProperty(data, property.getName(), value);
-    } else {
-      throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-    }
-  }
-
-  /**
-   * Retrieves the Java type of an EDM property for the given data object.
-   * @param data     the Java data object
-   * @param property the requested {@link EdmProperty}
-   * @return the requested Java type
-   */
-  public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException {
-    if (annotationHelper.isEdmAnnotated(data)) {
-      Class<?> fieldType = annotationHelper.getFieldTypeForProperty(data, property.getName());
-      if (fieldType == null) {
-        throw new ODataException("No field type found for property " + property);
-      }
-      return fieldType;
-    }
-    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-  }
-
-  /**
-   * Retrieves the value defined by a mapping object for the given data object.
-   * @param data     the Java data object
-   * @param mapping  the requested {@link EdmMapping}
-   * @return the requested value
-   */
-  public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException {
-    if (mapping != null && mapping.getMediaResourceMimeTypeKey() != null) {
-      return annotationHelper.getValueForProperty(data, mapping.getMediaResourceMimeTypeKey());
-    }
-    return null;
-  }
-
-  /**
-   * Sets the value defined by a mapping object for the given data object.
-   * @param data     the Java data object
-   * @param mapping  the {@link EdmMapping}
-   * @param value    the new value
-   */
-  public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException {
-    if (mapping != null && mapping.getMediaResourceMimeTypeKey() != null) {
-      annotationHelper.setValueForProperty(data, mapping.getMediaResourceMimeTypeKey(), value);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
deleted file mode 100644
index be3baac..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.data;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-
-import org.apache.olingo.odata2.api.data.ValueAccess;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmMapping;
-import org.apache.olingo.odata2.api.edm.EdmProperty;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.exception.ODataHttpException;
-import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
-
-/**
- * Data access.
- */
-public class BeanPropertyAccess implements ValueAccess {
-
-  @Override
-  public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException {
-    return getValue(data, getGetterMethodName(property));
-  }
-
-  @Override
-  public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException {
-    final String methodName = getSetterMethodName(getGetterMethodName(property));
-    if (methodName != null) {
-      setValue(data, methodName, value);
-    }
-  }
-
-  @Override
-  public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException {
-    return getType(data, getGetterMethodName(property));
-  }
-
-  @Override
-  public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException {
-    if (mapping != null && mapping.getMimeType() != null) {
-      return getValue(data, mapping.getMimeType());
-    }
-    return null;
-  }
-
-  @Override
-  public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException {
-    if (mapping != null && mapping.getMimeType() != null) {
-      setValue(data, getSetterMethodName(mapping.getMimeType()), value);
-    }
-  }
-
-  private String getGetterMethodName(final EdmProperty property) throws EdmException {
-    final String prefix = isBooleanProperty(property) ? "is" : "get";
-    final String defaultMethodName = prefix + property.getName();
-    return property.getMapping() == null || property.getMapping().getInternalName() == null ?
-        defaultMethodName : property.getMapping().getInternalName();
-  }
-
-  private boolean isBooleanProperty(final EdmProperty property) throws EdmException {
-    return property.isSimple() 
-        && property.getType() == EdmSimpleTypeKind.Boolean.getEdmSimpleTypeInstance();
-  }
-
-  private String getSetterMethodName(final String getterMethodName) {
-    return getterMethodName.contains(".") ?
-        null : getterMethodName.replaceFirst("^is", "set").replaceFirst("^get", "set");
-  }
-
-  private <T> Object getValue(final T data, final String methodName) throws ODataNotFoundException {
-    Object dataObject = data;
-
-    for (final String method : methodName.split("\\.", -1)) {
-      if (dataObject != null) {
-        try {
-          dataObject = dataObject.getClass().getMethod(method).invoke(dataObject);
-        } catch (SecurityException e) {
-          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-        } catch (NoSuchMethodException e) {
-          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-        } catch (IllegalArgumentException e) {
-          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-        } catch (IllegalAccessException e) {
-          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-        } catch (InvocationTargetException e) {
-          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-        }
-      }
-    }
-
-    return dataObject;
-  }
-
-  private <T, V> void setValue(final T data, final String methodName, final V value)
-      throws ODataNotFoundException {
-    try {
-      boolean found = false;
-      for (final Method method : Arrays.asList(data.getClass().getMethods())) {
-        if (method.getName().equals(methodName)) {
-          found = true;
-          final Class<?> type = method.getParameterTypes()[0];
-          if (value == null) {
-            if (type.equals(byte.class) || type.equals(short.class) || type.equals(int.class)
-                || type.equals(long.class) || type.equals(char.class)) {
-              method.invoke(data, 0);
-            } else if (type.equals(float.class) || type.equals(double.class)) {
-              method.invoke(data, 0.0);
-            } else if (type.equals(boolean.class)) {
-              method.invoke(data, false);
-            } else {
-              method.invoke(data, value);
-            }
-          } else {
-            method.invoke(data, value);
-          }
-          break;
-        }
-      }
-      if (!found) {
-        throw new ODataNotFoundException(null);
-      }
-    } catch (SecurityException e) {
-      throw new ODataNotFoundException(null, e);
-    } catch (IllegalArgumentException e) {
-      throw new ODataNotFoundException(null, e);
-    } catch (IllegalAccessException e) {
-      throw new ODataNotFoundException(null, e);
-    } catch (InvocationTargetException e) {
-      throw new ODataNotFoundException(null, e);
-    }
-  }
-
-  private <T> Class<?> getType(final T data, final String methodName) throws ODataNotFoundException {
-    if (data == null) {
-      throw new ODataNotFoundException(ODataHttpException.COMMON);
-    }
-
-    Class<?> type = data.getClass();
-    for (final String method : methodName.split("\\.", -1)) {
-      try {
-        type = type.getMethod(method).getReturnType();
-        if (type.isPrimitive()) {
-          if (type == boolean.class) {
-            type = Boolean.class;
-          } else if (type == byte.class) {
-            type = Byte.class;
-          } else if (type == short.class) {
-            type = Short.class;
-          } else if (type == int.class) {
-            type = Integer.class;
-          } else if (type == long.class) {
-            type = Long.class;
-          } else if (type == float.class) {
-            type = Float.class;
-          } else if (type == double.class) {
-            type = Double.class;
-          }
-        }
-      } catch (final SecurityException e) {
-        throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-      } catch (final NoSuchMethodException e) {
-        throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-      }
-    }
-    return type;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
deleted file mode 100644
index 696ab9a..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.data;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-/**
- *
- */
-public class DataStore<T> {
-
-  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
-  private final List<T> dataStore;
-  private final Class<T> dataTypeClass;
-
-  private int idCounter = 1;
-
-  private static class InMemoryDataStore {
-    private static final Map<Class<?>, DataStore<?>> c2ds = new HashMap<Class<?>, DataStore<?>>();
-
-    @SuppressWarnings("unchecked")
-    static DataStore<?> getInstance(Class<?> clz, boolean createNewInstance) {
-      DataStore<?> ds = c2ds.get(clz);
-      if (createNewInstance || ds == null) {
-        ds = new DataStore<Object>((Class<Object>) clz);
-        c2ds.put(clz, ds);
-      }
-      return ds;
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  public static <T> DataStore<T> createInMemory(Class<T> clazz) {
-    return (DataStore<T>) InMemoryDataStore.getInstance(clazz, true);
-  }
-
-  @SuppressWarnings("unchecked")
-  public static <T> DataStore<T> createInMemory(Class<T> clazz, boolean keepExisting) {
-    return (DataStore<T>) InMemoryDataStore.getInstance(clazz, !keepExisting);
-  }
-
-  private DataStore(List<T> wrapStore, Class<T> clz) {
-    dataStore = Collections.synchronizedList(wrapStore);
-    dataTypeClass = clz;
-  }
-
-  private DataStore(Class<T> clz) {
-    this(new ArrayList<T>(), clz);
-  }
-
-  public Class<T> getDataTypeClass() {
-    return dataTypeClass;
-  }
-
-  public String getEntityTypeName() {
-    return ANNOTATION_HELPER.extractEntityTypeName(dataTypeClass);
-  }
-
-  public T createInstance() {
-    try {
-      return dataTypeClass.newInstance();
-    } catch (InstantiationException e) {
-      throw new ODataRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
-    } catch (IllegalAccessException e) {
-      throw new ODataRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
-    }
-  }
-
-  public T read(T obj) {
-    List<Object> objKeys = getKeys(obj);
-    for (T stored : dataStore) {
-      if (objKeys.equals(getKeys(stored))) {
-        return stored;
-      }
-    }
-    return null;
-  }
-
-  public Collection<T> read() {
-    return Collections.unmodifiableCollection(dataStore);
-  }
-
-  public T create(T object) throws DataStoreException {
-    synchronized (dataStore) {
-      if (read(object) != null || getKeys(object).contains(null)) {
-        createKeys(object);
-        return this.create(object);
-      }
-      dataStore.add(object);
-    }
-    return object;
-  }
-
-  public T update(T object) {
-    synchronized (dataStore) {
-      T stored = read(object);
-      dataStore.remove(stored);
-      dataStore.add(object);
-    }
-    return object;
-  }
-
-  public T delete(T object) {
-    synchronized (dataStore) {
-      T stored = read(object);
-      if (stored != null) {
-        dataStore.remove(stored);
-      }
-      return stored;
-    }
-  }
-
-  private List<Object> getKeys(T object) {
-    Map<String, Object> keys = ANNOTATION_HELPER.getValueForAnnotatedFields(object, EdmKey.class);
-
-    // XXX: list should be in a defined order -> better to create an 'Key' object which is comparable 
-    List<Object> keyList = new ArrayList<Object>(keys.values());
-    return keyList;
-  }
-
-  private T createKeys(T object) throws DataStoreException {
-    List<Field> fields = ANNOTATION_HELPER.getAnnotatedFields(object, EdmKey.class);
-    if (fields.isEmpty()) {
-      throw new DataStoreException("No EdmKey annotated fields found for class " + object.getClass());
-    }
-    Map<String, Object> fieldName2KeyValue = new HashMap<String, Object>();
-
-    for (Field field : fields) {
-      Object key = createKey(field);
-      fieldName2KeyValue.put(ANNOTATION_HELPER.getCanonicalName(field), key);
-    }
-
-    ANNOTATION_HELPER.setValuesToAnnotatedFields(object, EdmKey.class, fieldName2KeyValue);
-
-    return object;
-  }
-
-  private Object createKey(Field field) {
-    Class<?> type = field.getType();
-
-    if (type == String.class) {
-      return String.valueOf(idCounter++);
-    } else if (type == Integer.class || type == int.class) {
-      return Integer.valueOf(idCounter++);
-    } else if (type == Long.class || type == long.class) {
-      return Long.valueOf(idCounter++);
-    }
-
-    throw new UnsupportedOperationException("Automated key generation for type '" + type
-        + "' is not supported (caused on field '" + field + "').");
-  }
-
-  public static class DataStoreException extends ODataApplicationException {
-    private static final long serialVersionUID = 42L;
-
-    public DataStoreException(String message) {
-      this(message, null);
-    }
-
-    public DataStoreException(String message, Throwable cause) {
-      super(message, Locale.ENGLISH, cause);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
deleted file mode 100644
index 97f5b53..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
+++ /dev/null
@@ -1,773 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.edm;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
-import org.apache.olingo.odata2.api.edm.FullQualifiedName;
-import org.apache.olingo.odata2.api.edm.provider.AnnotationAttribute;
-import org.apache.olingo.odata2.api.edm.provider.AnnotationElement;
-import org.apache.olingo.odata2.api.edm.provider.Association;
-import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
-import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
-import org.apache.olingo.odata2.api.edm.provider.AssociationSetEnd;
-import org.apache.olingo.odata2.api.edm.provider.ComplexProperty;
-import org.apache.olingo.odata2.api.edm.provider.ComplexType;
-import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
-import org.apache.olingo.odata2.api.edm.provider.EntityContainer;
-import org.apache.olingo.odata2.api.edm.provider.EntityContainerInfo;
-import org.apache.olingo.odata2.api.edm.provider.EntitySet;
-import org.apache.olingo.odata2.api.edm.provider.EntityType;
-import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
-import org.apache.olingo.odata2.api.edm.provider.Key;
-import org.apache.olingo.odata2.api.edm.provider.NavigationProperty;
-import org.apache.olingo.odata2.api.edm.provider.Property;
-import org.apache.olingo.odata2.api.edm.provider.PropertyRef;
-import org.apache.olingo.odata2.api.edm.provider.Schema;
-import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
-import org.apache.olingo.odata2.api.edm.provider.Using;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
-import org.apache.olingo.odata2.core.annotation.util.ClassHelper;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-/**
- * Provider for the entity data model used in the reference scenario
- *
- */
-public class AnnotationEdmProvider extends EdmProvider {
-
-  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
-
-  private final List<Class<?>> annotatedClasses;
-  private final Map<String, EntityContainer> name2Container = new HashMap<String, EntityContainer>();
-  private final Map<String, ContainerBuilder> containerName2ContainerBuilder = new HashMap<String, ContainerBuilder>();
-  private final Map<String, Schema> namespace2Schema = new HashMap<String, Schema>();
-  private EntityContainer defaultContainer;
-
-  public AnnotationEdmProvider(Collection<Class<?>> annotatedClasses) {
-
-    this.annotatedClasses = new ArrayList<Class<?>>(annotatedClasses.size());
-    for (Class<?> aClass : annotatedClasses) {
-      if (ANNOTATION_HELPER.isEdmAnnotated(aClass)) {
-        this.annotatedClasses.add(aClass);
-      }
-    }
-
-    init();
-  }
-
-  public AnnotationEdmProvider(String packageToScan) {
-    this.annotatedClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
-      @Override
-      public boolean isClassValid(Class<?> c) {
-        return ANNOTATION_HELPER.isEdmAnnotated(c);
-      }
-    });
-
-    init();
-  }
-
-  private void init() {
-    for (Class<?> aClass : annotatedClasses) {
-      updateSchema(aClass);
-      handleEntityContainer(aClass);
-    }
-
-    finish();
-  }
-
-  @Override
-  public Association getAssociation(FullQualifiedName edmFQName) throws ODataException {
-    Schema schema = namespace2Schema.get(edmFQName.getNamespace());
-    if (schema != null) {
-      List<Association> associations = schema.getAssociations();
-      for (Association association : associations) {
-        if (association.getName().equals(edmFQName.getName())) {
-          return association;
-        }
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public AssociationSet getAssociationSet(String entityContainer, FullQualifiedName association,
-      String sourceEntitySetName, String sourceEntitySetRole) throws ODataException {
-    EntityContainer container = name2Container.get(entityContainer);
-    if (container != null) {
-      List<AssociationSet> associations = container.getAssociationSets();
-      for (AssociationSet associationSet : associations) {
-        if (associationSet.getAssociation().equals(association)) {
-          final AssociationSetEnd endOne = associationSet.getEnd1();
-          if (endOne.getRole().equals(sourceEntitySetRole)
-              && endOne.getEntitySet().equals(sourceEntitySetName)) {
-            return associationSet;
-          }
-          final AssociationSetEnd endTwo = associationSet.getEnd2();
-          if (endTwo.getRole().equals(sourceEntitySetRole)
-              && endTwo.getEntitySet().equals(sourceEntitySetName)) {
-            return associationSet;
-          }
-        }
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public ComplexType getComplexType(FullQualifiedName edmFQName) throws ODataException {
-    Schema schema = namespace2Schema.get(edmFQName.getNamespace());
-    if (schema != null) {
-      List<ComplexType> complexTypes = schema.getComplexTypes();
-      for (ComplexType complexType : complexTypes) {
-        if (complexType.getName().equals(edmFQName.getName())) {
-          return complexType;
-        }
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public EntityContainerInfo getEntityContainerInfo(String name) throws ODataException {
-    EntityContainer container = name2Container.get(name);
-    if (container == null) {
-      // use default container (if set)
-      container = defaultContainer;
-    }
-    if (container != null) {
-      EntityContainerInfo info = new EntityContainerInfo();
-      info.setName(container.getName());
-      info.setDefaultEntityContainer(container.isDefaultEntityContainer());
-      info.setExtendz(container.getExtendz());
-      info.setAnnotationAttributes(container.getAnnotationAttributes());
-      info.setAnnotationElements(container.getAnnotationElements());
-
-      return info;
-    }
-
-    return null;
-  }
-
-  @Override
-  public EntitySet getEntitySet(String entityContainer, String name) throws ODataException {
-    EntityContainer container = name2Container.get(entityContainer);
-    if (container != null) {
-      List<EntitySet> entitySets = container.getEntitySets();
-      for (EntitySet entitySet : entitySets) {
-        if (entitySet.getName().equals(name)) {
-          return entitySet;
-        }
-      }
-    }
-
-    return null;
-  }
-
-  @Override
-  public EntityType getEntityType(FullQualifiedName edmFQName) throws ODataException {
-    Schema schema = namespace2Schema.get(edmFQName.getNamespace());
-    if (schema != null) {
-      List<EntityType> complexTypes = schema.getEntityTypes();
-      for (EntityType complexType : complexTypes) {
-        if (complexType.getName().equals(edmFQName.getName())) {
-          return complexType;
-        }
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public FunctionImport getFunctionImport(String entityContainer, String name) throws ODataException {
-    EntityContainer container = name2Container.get(entityContainer);
-    if (container != null) {
-      List<FunctionImport> functionImports = container.getFunctionImports();
-      for (FunctionImport functionImport : functionImports) {
-        if (functionImport.getName().equals(name)) {
-          return functionImport;
-        }
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public List<Schema> getSchemas() throws ODataException {
-    return new ArrayList<Schema>(namespace2Schema.values());
-  }
-
-  //
-  //
-  //
-  private Map<String, SchemaBuilder> namespace2SchemaBuilder = new HashMap<String, SchemaBuilder>();
-
-  private void updateSchema(Class<?> aClass) {
-    EdmEntityType et = aClass.getAnnotation(EdmEntityType.class);
-    if (et != null) {
-      updateSchema(aClass, et);
-    }
-    EdmComplexType ect = aClass.getAnnotation(EdmComplexType.class);
-    if (ect != null) {
-      updateSchema(aClass, ect);
-    }
-  }
-
-  private void updateSchema(Class<?> aClass, EdmEntityType et) {
-    SchemaBuilder b = getSchemaBuilder(et.namespace(), aClass);
-    TypeBuilder typeBuilder = TypeBuilder.init(et, aClass);
-    b.addEntityType(typeBuilder.buildEntityType());
-    b.addAssociations(typeBuilder.buildAssociations());
-  }
-
-  private SchemaBuilder getSchemaBuilder(String namespace, Class<?> aClass) {
-    String usedNamespace = namespace;
-    if(usedNamespace.isEmpty()) {
-      usedNamespace = ANNOTATION_HELPER.getCanonicalNamespace(aClass);
-    }
-    SchemaBuilder builder = namespace2SchemaBuilder.get(usedNamespace);
-    if (builder == null) {
-      builder = SchemaBuilder.init(usedNamespace);
-      namespace2SchemaBuilder.put(usedNamespace, builder);
-    }
-    return builder;
-  }
-
-  private void updateSchema(Class<?> aClass, EdmComplexType et) {
-    SchemaBuilder b = getSchemaBuilder(et.namespace(), aClass);
-    TypeBuilder typeBuilder = TypeBuilder.init(et, aClass);
-    b.addComplexType(typeBuilder.buildComplexType());
-  }
-
-  private void handleEntityContainer(Class<?> aClass) {
-    EdmEntityType entityType = aClass.getAnnotation(EdmEntityType.class);
-    if (entityType != null) {
-      FullQualifiedName typeName = createFqnForEntityType(aClass, entityType);
-      String containerName = ANNOTATION_HELPER.extractContainerName(aClass);
-      ContainerBuilder builder = containerName2ContainerBuilder.get(containerName);
-      if (builder == null) {
-        builder = ContainerBuilder.init(typeName.getNamespace(), containerName);
-        containerName2ContainerBuilder.put(containerName, builder);
-      }
-      EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
-      if (entitySet != null) {
-        builder.addEntitySet(createEntitySet(typeName, entitySet));
-      }
-    }
-  }
-
-  private EntitySet createEntitySet(FullQualifiedName typeName, EdmEntitySet entitySet) {
-    return new EntitySet().setName(entitySet.name()).setEntityType(typeName);
-  }
-
-  private FullQualifiedName createFqnForEntityType(Class<?> annotatedClass, EdmEntityType entityType) {
-    return ANNOTATION_HELPER.extractEntityTypeFqn(annotatedClass);
-  }
-
-  private void finish() {
-    //
-    Collection<ContainerBuilder> containers = containerName2ContainerBuilder.values();
-    for (ContainerBuilder containerBuilder : containers) {
-      SchemaBuilder schemaBuilder = namespace2SchemaBuilder.get(containerBuilder.getNamespace());
-      containerBuilder.addAssociationSets(schemaBuilder.name2Associations.values());
-      final EntityContainer container = containerBuilder.build();
-      schemaBuilder.addEntityContainer(container);
-      name2Container.put(container.getName(), container);
-      if (container.isDefaultEntityContainer()) {
-        defaultContainer = container;
-      }
-    }
-    //
-    Collection<SchemaBuilder> schemaBuilders = namespace2SchemaBuilder.values();
-    for (SchemaBuilder schemaBuilder : schemaBuilders) {
-      final Schema schema = schemaBuilder.build();
-      namespace2Schema.put(schema.getNamespace(), schema);
-    }
-  }
-
-  //
-  //
-  //
-  static class TypeBuilder {
-
-    final private String namespace;
-    final private String name;
-    private boolean isAbstract = false;
-    private boolean isMediaResource = false;
-    private FullQualifiedName baseEntityType = null;
-    private final List<PropertyRef> keyProperties = new ArrayList<PropertyRef>();
-    private final List<Property> properties = new ArrayList<Property>();
-    private final List<NavigationProperty> navProperties = new ArrayList<NavigationProperty>();
-    private final List<Association> associations = new ArrayList<Association>();
-
-    public TypeBuilder(FullQualifiedName fqn) {
-      this.namespace = fqn.getNamespace();
-      this.name = fqn.getName();
-    }
-
-    public static TypeBuilder init(EdmEntityType entity, Class<?> aClass) {
-      return new TypeBuilder(ANNOTATION_HELPER.extractEntityTypeFqn(entity, aClass)).withClass(aClass);
-    }
-
-    public static TypeBuilder init(EdmComplexType entity, Class<?> aClass) {
-      return new TypeBuilder(ANNOTATION_HELPER.extractComplexTypeFqn(entity, aClass)).withClass(aClass);
-    }
-
-    private TypeBuilder withClass(Class<?> aClass) {
-      baseEntityType = createBaseEntityFqn(aClass);
-
-      if (Modifier.isAbstract(aClass.getModifiers())) {
-        this.isAbstract = true;
-      }
-
-      Field[] fields = aClass.getDeclaredFields();
-      for (Field field : fields) {
-        EdmProperty ep = field.getAnnotation(EdmProperty.class);
-        if (ep != null) {
-          properties.add(createProperty(ep, field, namespace));
-          EdmKey eti = field.getAnnotation(EdmKey.class);
-          if (eti != null) {
-            keyProperties.add(createKeyProperty(ep, field));
-          }
-        }
-        EdmNavigationProperty enp = field.getAnnotation(EdmNavigationProperty.class);
-        if (enp != null) {
-          final NavigationProperty navProperty = createNavigationProperty(namespace, enp, field);
-          navProperties.add(navProperty);
-          Association association = createAssociation(field, navProperty);
-          associations.add(association);
-        }
-        EdmMediaResourceContent emrc = field.getAnnotation(EdmMediaResourceContent.class);
-        if (emrc != null) {
-          isMediaResource = true;
-        }
-      }
-
-      return this;
-    }
-
-    public TypeBuilder addProperty(PropertyRef property) {
-      keyProperties.add(property);
-      return this;
-    }
-
-    public TypeBuilder addProperty(Property property) {
-      properties.add(property);
-      return this;
-    }
-
-    public TypeBuilder addNavigationProperty(NavigationProperty property) {
-      navProperties.add(property);
-      return this;
-    }
-
-    public TypeBuilder setAbstract(boolean isAbstract) {
-      this.isAbstract = isAbstract;
-      return this;
-    }
-
-    public ComplexType buildComplexType() {
-      ComplexType complexType = new ComplexType();
-      if (baseEntityType != null) {
-        complexType.setBaseType(baseEntityType);
-      }
-      return complexType.setName(name).setProperties(properties);
-    }
-
-    public EntityType buildEntityType() {
-      EntityType entityType = new EntityType();
-      if (baseEntityType != null) {
-        entityType.setBaseType(baseEntityType);
-      }
-      if (!keyProperties.isEmpty()) {
-        entityType.setKey(new Key().setKeys(keyProperties));
-      }
-      if (!navProperties.isEmpty()) {
-        entityType.setNavigationProperties(navProperties);
-      }
-      return entityType.setName(name)
-          .setAbstract(isAbstract)
-          .setHasStream(isMediaResource)
-          .setProperties(properties);
-    }
-
-    public Collection<Association> buildAssociations() {
-      return Collections.unmodifiableCollection(associations);
-    }
-
-    private PropertyRef createKeyProperty(EdmProperty et, Field field) {
-      PropertyRef keyProperty = new PropertyRef();
-      String entityName = et.name();
-      if (entityName.isEmpty()) {
-        entityName = getCanonicalName(field);
-      }
-      return keyProperty.setName(entityName);
-    }
-
-    private Property createProperty(EdmProperty ep, Field field, String defaultNamespace) {
-      if (isAnnotatedEntity(field.getType())) {
-        return createComplexProperty(field, defaultNamespace);
-      } else {
-        return createSimpleProperty(ep, field);
-      }
-    }
-
-    private Property createSimpleProperty(EdmProperty ep, Field field) {
-      SimpleProperty sp = new SimpleProperty();
-      String entityName = ANNOTATION_HELPER.getPropertyName(field);
-      sp.setName(entityName);
-      //
-      EdmType type = ep.type();
-      if (type == EdmType.NULL) {
-        type = getEdmType(field.getType());
-      }
-      sp.setType(ANNOTATION_HELPER.mapTypeKind(type));
-
-      return sp;
-    }
-
-    private Property createComplexProperty(Field field, String defaultNamespace) {
-      ComplexProperty cp = new ComplexProperty();
-      // settings from property
-      String entityName = ANNOTATION_HELPER.getPropertyName(field);
-      cp.setName(entityName);
-
-      // settings from related complex entity
-      EdmComplexType ece = field.getType().getAnnotation(EdmComplexType.class);
-      String complexEntityNamespace = ece.namespace();
-      if (complexEntityNamespace.isEmpty()) {
-        complexEntityNamespace = defaultNamespace;
-      }
-      cp.setType(new FullQualifiedName(complexEntityNamespace, ece.name()));
-
-      return cp;
-    }
-
-    private NavigationProperty createNavigationProperty(String namespace, EdmNavigationProperty enp, Field field) {
-      NavigationProperty navProp = new NavigationProperty();
-      navProp.setName(ANNOTATION_HELPER.getPropertyName(field));
-      String fromRole = ANNOTATION_HELPER.extractFromRoleName(enp, field);
-      navProp.setFromRole(fromRole);
-
-      String toRole = ANNOTATION_HELPER.extractToRoleName(enp, field);
-      navProp.setToRole(toRole);
-
-      String relationshipName = ANNOTATION_HELPER.extractRelationshipName(enp, field);
-      navProp.setRelationship(new FullQualifiedName(namespace, relationshipName));
-
-      return navProp;
-    }
-
-//    private EdmSimpleTypeKind getEdmSimpleType(Class<?> type) {
-//      if (type == String.class) {
-//        return EdmType.String;
-//      } else if (type == boolean.class || type == Boolean.class) {
-//        return EdmType.Boolean;
-//      } else if (type == byte.class || type == Byte.class) {
-//        return EdmType.SByte;
-//      } else if (type == short.class || type == Short.class) {
-//        return EdmType.Int16;
-//      } else if (type == int.class || type == Integer.class) {
-//        return EdmType.Int32;
-//      } else if (type == long.class || type == Long.class) {
-//        return EdmType.Int64;
-//      } else if (type == double.class || type == Double.class) {
-//        return EdmType.Double;
-//      } else if (type == float.class || type == Float.class) {
-//        return EdmType.Single;
-//      } else if (type == BigInteger.class || type == BigDecimal.class) {
-//        return EdmType.Decimal;
-//      } else if (type == Byte[].class || type == byte[].class) {
-//        return EdmType.Binary;
-//      } else if (type == Date.class) {
-//        return EdmType.DateTime;
-//      } else if (type == Calendar.class) {
-//        return EdmType.DateTimeOffset;
-//      } else if (type == UUID.class) {
-//        return EdmType.Guid;
-//      } else {
-//        throw new UnsupportedOperationException("Not yet supported type '" + type + "'.");
-//      }
-//    }
-    
-    private EdmType getEdmType(Class<?> type) {
-      if (type == String.class) {
-        return EdmType.STRING;
-      } else if (type == boolean.class || type == Boolean.class) {
-        return EdmType.BOOLEAN;
-      } else if (type == byte.class || type == Byte.class) {
-        return EdmType.SBYTE;
-      } else if (type == short.class || type == Short.class) {
-        return EdmType.INT16;
-      } else if (type == int.class || type == Integer.class) {
-        return EdmType.INT32;
-      } else if (type == long.class || type == Long.class) {
-        return EdmType.INT64;
-      } else if (type == double.class || type == Double.class) {
-        return EdmType.DOUBLE;
-      } else if (type == float.class || type == Float.class) {
-        return EdmType.SINGLE;
-      } else if (type == BigInteger.class || type == BigDecimal.class) {
-        return EdmType.DECIMAL;
-      } else if (type == Byte[].class || type == byte[].class) {
-        return EdmType.BINARY;
-      } else if (type == Date.class) {
-        return EdmType.DATE_TIME;
-      } else if (type == Calendar.class) {
-        return EdmType.DATE_TIME_OFFSET;
-      } else if (type == UUID.class) {
-        return EdmType.GUID;
-      } else {
-        throw new UnsupportedOperationException("Not yet supported type '" + type + "'.");
-      }
-    }
-
-
-    private Class<?> checkForBaseEntityClass(Class<?> aClass) {
-      Class<?> superClass = aClass.getSuperclass();
-      if (superClass == Object.class) {
-        return null;
-      } else {
-        EdmEntityType edmEntity = superClass.getAnnotation(EdmEntityType.class);
-        if (edmEntity == null) {
-          return checkForBaseEntityClass(superClass);
-        } else {
-          return superClass;
-        }
-      }
-    }
-
-    private FullQualifiedName createBaseEntityFqn(Class<?> aClass) {
-      Class<?> baseEntityClass = checkForBaseEntityClass(aClass);
-      if (baseEntityClass == null) {
-        return null;
-      }
-      return ANNOTATION_HELPER.extractEntityTypeFqn(baseEntityClass);
-    }
-
-    private Association createAssociation(Field field, NavigationProperty navProperty) {
-      Association association = new Association();
-      EdmNavigationProperty navigation = field.getAnnotation(EdmNavigationProperty.class);
-
-      AssociationEnd fromEnd = new AssociationEnd();
-      fromEnd.setRole(navProperty.getFromRole());
-      String typeName = ANNOTATION_HELPER.extractEntityTypeName(field.getDeclaringClass());
-      fromEnd.setType(new FullQualifiedName(namespace, typeName));
-      fromEnd.setMultiplicity(EdmMultiplicity.ONE);
-      association.setEnd1(fromEnd);
-
-      AssociationEnd toEnd = new AssociationEnd();
-      toEnd.setRole(navProperty.getToRole());
-      String toTypeName = ANNOTATION_HELPER.extractEntitTypeName(navigation, field);
-      toEnd.setType(new FullQualifiedName(namespace, toTypeName));
-      toEnd.setMultiplicity(ANNOTATION_HELPER.getMultiplicity(navigation, field));
-      association.setEnd2(toEnd);
-
-      String associationName = navProperty.getRelationship().getName();
-      association.setName(associationName);
-      return association;
-    }
-
-    private String getCanonicalName(Field field) {
-      return ANNOTATION_HELPER.getCanonicalName(field);
-    }
-
-    private boolean isAnnotatedEntity(Class<?> clazz) {
-      return ANNOTATION_HELPER.isEdmTypeAnnotated(clazz);
-    }
-  }
-
-  static class SchemaBuilder {
-
-    final private String namespace;
-    //    private String alias;
-    private final List<Using> usings = new ArrayList<Using>();
-    private final List<EntityType> entityTypes = new ArrayList<EntityType>();
-    private final List<ComplexType> complexTypes = new ArrayList<ComplexType>();
-    private final Map<String, Association> name2Associations = new HashMap<String, Association>();
-    private final List<EntityContainer> entityContainers = new ArrayList<EntityContainer>();
-    private final List<AnnotationAttribute> annotationAttributes = new ArrayList<AnnotationAttribute>();
-    private final List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
-
-    private SchemaBuilder(String namespace) {
-      this.namespace = namespace;
-    }
-
-    public static SchemaBuilder init(String namespace) {
-      return new SchemaBuilder(namespace);
-    }
-
-    public SchemaBuilder addEntityType(EntityType type) {
-      entityTypes.add(type);
-      return this;
-    }
-
-    public SchemaBuilder addEntityContainer(EntityContainer container) {
-      entityContainers.add(container);
-      return this;
-    }
-
-    public SchemaBuilder addComplexType(ComplexType createEntityType) {
-      complexTypes.add(createEntityType);
-      return this;
-    }
-
-    public void addAssociations(Collection<Association> associations) {
-      for (Association association : associations) {
-        final String relationshipName = association.getName();
-        if (name2Associations.containsKey(relationshipName)) {
-          association = mergeAssociations(name2Associations.get(relationshipName), association);
-        }
-        name2Associations.put(relationshipName, association);
-      }
-    }
-
-    private Association mergeAssociations(Association associationOne, Association associationTwo) {
-      AssociationEnd oneEnd1 = associationOne.getEnd1();
-      AssociationEnd oneEnd2 = associationOne.getEnd2();
-      AssociationEnd twoEnd1 = associationTwo.getEnd1();
-      AssociationEnd twoEnd2 = associationTwo.getEnd2();
-      AssociationEnd[] oneEnds = new AssociationEnd[] { oneEnd1, oneEnd2 };
-
-      for (AssociationEnd associationEnd : oneEnds) {
-        if (associationEnd.getRole().equals(twoEnd1.getRole())) {
-          if (twoEnd1.getMultiplicity() == EdmMultiplicity.MANY) {
-            associationEnd.setMultiplicity(EdmMultiplicity.MANY);
-          }
-        } else if (associationEnd.getRole().equals(twoEnd2.getRole())) {
-          if (twoEnd2.getMultiplicity() == EdmMultiplicity.MANY) {
-            associationEnd.setMultiplicity(EdmMultiplicity.MANY);
-          }
-        }
-      }
-
-      return associationOne;
-    }
-
-    public Schema build() {
-      Schema s = new Schema();
-      s.setUsings(usings);
-      s.setEntityTypes(entityTypes);
-      s.setComplexTypes(complexTypes);
-      s.setAssociations(new ArrayList<Association>(name2Associations.values()));
-      s.setEntityContainers(entityContainers);
-      s.setAnnotationAttributes(annotationAttributes);
-      s.setAnnotationElements(annotationElements);
-      s.setNamespace(namespace);
-      return s;
-    }
-  }
-
-  private static class ContainerBuilder {
-
-    final private String name;
-    final private String namespace;
-    private boolean defaultContainer = true;
-    private final List<EntitySet> entitySets = new ArrayList<EntitySet>();
-    private final List<AssociationSet> associationSets = new ArrayList<AssociationSet>();
-    private final List<FunctionImport> functionImports = new ArrayList<FunctionImport>();
-
-    //    private Documentation documentation;
-
-    private ContainerBuilder(String namespace, String containerName) {
-      this.namespace = namespace;
-      name = containerName;
-    }
-
-    public String getNamespace() {
-      return namespace;
-    }
-
-    public static ContainerBuilder init(String namespace, String containerName) {
-      return new ContainerBuilder(namespace, containerName);
-    }
-
-    public ContainerBuilder setDefaultContainer(boolean isDefault) {
-      defaultContainer = isDefault;
-      return this;
-    }
-
-    public ContainerBuilder addEntitySet(EntitySet entitySet) {
-      entitySets.add(entitySet);
-      return this;
-    }
-
-    public void addAssociationSets(Collection<Association> associations) {
-      for (Association association : associations) {
-        AssociationSet as = new AssociationSet();
-        as.setName(association.getName());
-        FullQualifiedName asAssociationFqn = new FullQualifiedName(namespace, association.getName());
-        as.setAssociation(asAssociationFqn);
-
-        AssociationSetEnd asEnd1 = new AssociationSetEnd();
-        asEnd1.setEntitySet(getEntitySetName(association.getEnd1()));
-        asEnd1.setRole(association.getEnd1().getRole());
-        as.setEnd1(asEnd1);
-
-        AssociationSetEnd asEnd2 = new AssociationSetEnd();
-        asEnd2.setEntitySet(getEntitySetName(association.getEnd2()));
-        asEnd2.setRole(association.getEnd2().getRole());
-        as.setEnd2(asEnd2);
-
-        associationSets.add(as);
-      }
-    }
-
-    public EntityContainer build() {
-      EntityContainer ec = new EntityContainer();
-      ec.setName(name);
-      ec.setDefaultEntityContainer(defaultContainer);
-      ec.setEntitySets(entitySets);
-      ec.setAssociationSets(associationSets);
-      ec.setFunctionImports(functionImports);
-      return ec;
-    }
-
-    private String getEntitySetName(AssociationEnd end) {
-      for (EntitySet entitySet : entitySets) {
-        if (entitySet.getEntityType().equals(end.getType())) {
-          return entitySet.getName();
-        }
-      }
-      throw new ODataRuntimeException("No entity set found for " + end.getType());
-    }
-  }
-}


[08/12] Renamed project

Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
new file mode 100644
index 0000000..73d1218
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.model;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.imageio.ImageIO;
+
+/**
+ *
+ */
+public class ResourceHelper {
+
+  public enum Format {BMP, JPEG, PNG, GIF};
+  
+  public static byte[] generateImage() {
+    return generateImage(Format.PNG);
+  }
+  
+  public static byte[] generateImage(Format format) {
+    try {
+      int width = 320;
+      int height = 320;
+      BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
+      WritableRaster raster = image.getRaster();
+      
+      int mod = format.ordinal() + 2;
+      for (int h = 0; h < height; h++) {
+        for (int w = 0; w < width; w++) {
+          if (((h / 32) + (w / 32)) % mod == 0) {
+            raster.setSample(w, h, 0, 0);
+          } else {
+            raster.setSample(w, h, 0, 1);
+          }
+        }
+      }
+      
+      ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
+      ImageIO.write(image, format.name(), out);
+      return out.toByteArray();
+    } catch (IOException ex) {
+      return new byte[0];
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
new file mode 100644
index 0000000..7c9e486
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.odata2.core.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Room", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Rooms")
+public class Room extends RefBase {
+
+  @EdmProperty
+  private Integer seats;
+  @EdmProperty
+  private Integer version;
+  @EdmNavigationProperty(name = "nr_Building", association = "BuildingRooms")
+  private Building building;
+  @EdmNavigationProperty(name = "nr_Employees")
+  private List<Employee> employees = new ArrayList<Employee>();
+
+  public Room(final int id, final String name) {
+    super(id, name);
+  }
+
+  public void setSeats(final int seats) {
+    this.seats = seats;
+  }
+
+  public int getSeats() {
+    return seats;
+  }
+
+  public void setVersion(final int version) {
+    this.version = version;
+  }
+
+  public int getVersion() {
+    return version;
+  }
+
+  public void setBuilding(final Building building) {
+    this.building = building;
+  }
+
+  public Building getBuilding() {
+    return building;
+  }
+
+  public List<Employee> getEmployees() {
+    return employees;
+  }
+
+  @Override
+  public int hashCode() {
+    return id;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+        || obj != null && getClass() == obj.getClass() && id == ((Room) obj).id;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Seats\":" + seats + ",\"Version\":" + version + "}";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
new file mode 100644
index 0000000..e9b296f
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+*  
+*/
+@EdmEntityType(name = "Team", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Teams")
+public class Team extends RefBase {
+  @EdmProperty(type = EdmType.BOOLEAN)
+  private Boolean isScrumTeam;
+  @EdmNavigationProperty(name = "nt_Employees", association = "TeamEmployees", toMultiplicity = Multiplicity.MANY)
+  private List<Employee> employees = new ArrayList<Employee>();
+
+  public Team() {
+    super(-1, null);
+  }
+
+  public Team(final int id, final String name) {
+    super(id, name);
+  }
+
+  public Boolean isScrumTeam() {
+    return isScrumTeam;
+  }
+
+  public void setScrumTeam(final Boolean isScrumTeam) {
+    this.isScrumTeam = isScrumTeam;
+  }
+
+  public void addEmployee(Employee e) {
+    this.employees.add(e);
+  }
+
+  public List<Employee> getEmployees() {
+    return employees;
+  }
+
+  @Override
+  public int hashCode() {
+    return id;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+        || obj != null && getClass() == obj.getClass() && id == ((Team) obj).id;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"IsScrumTeam\":" + isScrumTeam + "}";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/pom.xml b/odata2-annotation-processor/annotation-processor-webref/pom.xml
new file mode 100644
index 0000000..9f31106
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/pom.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>olingo-odata2-annotation-processor-webref-incubating</artifactId>
+  <packaging>war</packaging>
+  <name>${project.artifactId}</name>
+
+  <parent>
+    <groupId>org.apache.olingo</groupId>
+    <artifactId>olingo-odata2-annotation-processor-incubating</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <properties>
+      <version.slf4j>1.7.1</version.slf4j>
+  </properties>
+
+  <build>
+    <finalName>${project.artifactId}</finalName>
+    <resources>
+      <resource>
+        <directory>src/main/version</directory>
+        <filtering>true</filtering>
+        <targetPath>../${project.build.finalName}/gen</targetPath>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+      </resource>
+      <resource>
+        <directory>target/maven-shared-archive-resources</directory>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <groupId>com.sap.research</groupId>
+        <artifactId>nwcloud-maven-plugin</artifactId>
+        <version>1.0.0.RELEASE</version>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+
+  </build>
+
+  <dependencies>
+    <dependency>
+      <!-- required because of auto detection of web facet 2.5 -->
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>2.5</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+      <version>${cxf.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-api-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-core-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-annotation-processor-api-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-annotation-processor-core-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <version>${version.slf4j}</version>
+    </dependency>
+  </dependencies>
+
+  <profiles>
+    <profile>
+      <id>dev</id>
+
+      <build>
+        <defaultGoal>cargo:run</defaultGoal>
+
+        <plugins>
+          <plugin>
+            <groupId>org.codehaus.cargo</groupId>
+            <artifactId>cargo-maven2-plugin</artifactId>
+            <version>1.4.2</version>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
new file mode 100644
index 0000000..668ac86
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * 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.odata2.ref.annotation.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *  
+ */
+@EdmEntityType(name = "Building", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Buildings")
+public class Building {
+  @EdmKey
+  @EdmProperty(type = EdmType.INT32)
+  private int id;
+  @EdmProperty
+  private String name;
+  @EdmProperty(name = "Image", type = EdmType.BINARY)
+  private byte[] image;
+  @EdmNavigationProperty(name = "nb_Rooms", toType = Room.class,
+      association = "BuildingRooms", toMultiplicity = Multiplicity.MANY)
+  private List<Room> rooms = new ArrayList<Room>();
+
+  public String getId() {
+    return Integer.toString(id);
+  }
+
+  public void setName(final String name) {
+    this.name = name;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setImage(final byte[] byteArray) {
+    image = byteArray;
+  }
+
+  public byte[] getImage() {
+    if (image == null) {
+      return null;
+    } else {
+      return image.clone();
+    }
+  }
+
+  public void addRoom(Room room) {
+    rooms.add(room);
+  }
+
+  public List<Room> getRooms() {
+    return rooms;
+  }
+
+  @Override
+  public int hashCode() {
+    return id;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+        || obj != null && getClass() == obj.getClass() && id == ((Building) obj).id;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Image\":\"" + Arrays.toString(image) + "\"}";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
new file mode 100644
index 0000000..a4d5a56
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * 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.odata2.ref.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+/**
+ *  
+ */
+@EdmComplexType(name="c_City", namespace = ModelSharedConstants.NAMESPACE_1)
+public class City {
+
+  @EdmProperty
+  private String postalCode;
+  @EdmProperty
+  private String cityName;
+
+  public City(final String postalCode, final String name) {
+    this.postalCode = postalCode;
+    cityName = name;
+  }
+
+  public void setPostalCode(final String postalCode) {
+    this.postalCode = postalCode;
+  }
+
+  public String getPostalCode() {
+    return postalCode;
+  }
+
+  public void setCityName(final String cityName) {
+    this.cityName = cityName;
+  }
+
+  public String getCityName() {
+    return cityName;
+  }
+
+  @Override
+  public String toString() {
+    return String.format("%s, %s", cityName, postalCode);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
new file mode 100644
index 0000000..2204ee8
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
@@ -0,0 +1,192 @@
+/*******************************************************************************
+ * 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.odata2.ref.annotation.model;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmFacets;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *  
+ */
+@EdmEntityType(name = "Employee", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Employees")
+public class Employee {
+  @EdmKey
+  @EdmProperty(name = "EmployeeId", type = EdmType.STRING)
+  private String employeeId;
+  @EdmProperty(name = "EmployeeName")
+  private String employeeName;
+  @EdmProperty
+  private int age;
+  @EdmNavigationProperty(name = "ne_Manager", association = "ManagerEmployees")
+  private Manager manager;
+  @EdmNavigationProperty(name = "ne_Team", association = "TeamEmployees")
+  private Team team;
+  @EdmNavigationProperty(name = "ne_Room")
+  private Room room;
+  @EdmMediaResourceMimeType
+  private String imageType;
+  @EdmMediaResourceContent
+  private byte[] image;
+  @EdmProperty(name = "ImageUrl")
+  private String imageUrl;
+  @EdmProperty(name = "EntryDate", type = EdmType.DATE_TIME,
+      facets = @EdmFacets(nullable = true))
+  private Calendar entryDate;
+  @EdmProperty(name = "Location", facets = @EdmFacets(nullable = false))
+  private Location location;
+
+  public String getId() {
+    return employeeId;
+  }
+
+  public void setEmployeeName(final String employeeName) {
+    this.employeeName = employeeName;
+  }
+
+  public String getEmployeeName() {
+    return employeeName;
+  }
+
+  public void setAge(final int age) {
+    this.age = age;
+  }
+
+  public int getAge() {
+    return age;
+  }
+
+  public void setManager(final Manager manager) {
+    this.manager = manager;
+  }
+
+  public Manager getManager() {
+    return manager;
+  }
+
+  public void setTeam(final Team team) {
+    this.team = team;
+  }
+
+  public Team getTeam() {
+    return team;
+  }
+
+  public void setRoom(final Room room) {
+    this.room = room;
+  }
+
+  public Room getRoom() {
+    return room;
+  }
+
+  public void setImageUri(final String imageUri) {
+    imageUrl = imageUri;
+  }
+
+  public String getImageUri() {
+    return imageUrl;
+  }
+
+  public void setLocation(final Location location) {
+    this.location = location;
+  }
+
+  public Location getLocation() {
+    return location;
+  }
+
+  public void setEntryDate(final Calendar date) {
+    entryDate = date;
+  }
+
+  public Calendar getEntryDate() {
+    return entryDate;
+  }
+
+  public void setImageType(final String imageType) {
+    this.imageType = imageType;
+  }
+
+  public String getImageType() {
+    return imageType;
+  }
+
+  public void setImage(final byte[] image) {
+    this.image = image;
+  }
+
+  public void setImage(final String imageUrl) {
+    image = loadImage(imageUrl);
+  }
+
+  private static byte[] loadImage(final String imageUrl) {
+    return ResourceHelper.loadAsByte(imageUrl);
+  }
+
+  public byte[] getImage() {
+    if (image == null) {
+      return null;
+    }
+    return image.clone();
+  }
+
+  @Override
+  public int hashCode() {
+    if (employeeId == null) {
+      return 0;
+    }
+    return employeeId.hashCode();
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+        || obj != null && getClass() == obj.getClass() && employeeId == ((Employee) obj).employeeId;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"EmployeeId\":\"" + employeeId + "\","
+        + "\"EmployeeName\":\"" + employeeName + "\","
+        + "\"ManagerId\":" + (manager == null ? "null" : "\"" + manager.getId() + "\"") + ","
+        + "\"RoomId\":" + (room == null ? "null" : "\"" + room.getId() + "\"") + ","
+        + "\"TeamId\":" + (team == null ? "null" : "\"" + team.getId() + "\"") + ","
+        + "\"Location\":"
+        + (location == null ? "null" :
+            "{\"City\":" + (location.getCity() == null ? "null" :
+                "{\"PostalCode\":\"" + location.getCity().getPostalCode() + "\","
+                    + "\"CityName\":\"" + location.getCity().getCityName() + "\"}") + ","
+                + "\"Country\":\"" + location.getCountry() + "\"}") + ","
+        + "\"Age\":" + age + ","
+        + "\"EntryDate\":"
+        + (entryDate == null ? "null" : "\"" + DateFormat.getInstance().format(entryDate.getTime()) + "\"") + ","
+        + "\"ImageUrl\":\"" + imageUrl + "\"}";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
new file mode 100644
index 0000000..9b0785c
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * 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.odata2.ref.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+/**
+ *  
+ */
+@EdmComplexType(name = "c_Location", namespace = ModelSharedConstants.NAMESPACE_1)
+public class Location {
+  @EdmProperty
+  private String country;
+  @EdmProperty
+  private City city;
+
+  public Location(final String country, final String postalCode, final String cityName) {
+    this.country = country;
+    city = new City(postalCode, cityName);
+  }
+
+  public void setCountry(final String country) {
+    this.country = country;
+  }
+
+  public String getCountry() {
+    return country;
+  }
+
+  public void setCity(final City city) {
+    this.city = city;
+  }
+
+  public City getCity() {
+    return city;
+  }
+
+  @Override
+  public String toString() {
+    return String.format("%s, %s", country, city.toString());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
new file mode 100644
index 0000000..57e6d78
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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.odata2.ref.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Manager", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Managers")
+public class Manager extends Employee {
+
+  @EdmNavigationProperty(name = "nm_Employees", association = "ManagerEmployees",
+      toMultiplicity = Multiplicity.MANY)
+  private List<Employee> employees = new ArrayList<Employee>();
+
+  public List<Employee> getEmployees() {
+    return employees;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
new file mode 100644
index 0000000..ab17fbb
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.odata2.ref.annotation.model;
+
+public interface ModelSharedConstants {
+
+  String NAMESPACE_1 = "RefScenario";
+  String CONTAINER_1 = "Container1";
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
new file mode 100644
index 0000000..52971cd
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * 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.odata2.ref.annotation.model;
+
+import java.util.Arrays;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceSource;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *  
+ */
+@EdmEntityType(name = "Photo", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Photos")
+public class Photo {
+  @EdmKey
+  @EdmProperty
+  private String name;
+  @EdmKey
+  @EdmProperty
+  private String type;
+  @EdmProperty
+  @EdmMediaResourceMimeType
+  private String mimeType;
+  @EdmProperty
+  @EdmMediaResourceSource
+  private String imageUrl = "http://localhost/someResource.png";
+  @EdmProperty(type = EdmType.BINARY)
+  @EdmMediaResourceContent
+  private byte[] image = ResourceHelper.generateImage();
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(final String name) {
+    this.name = name;
+  }
+
+  public String getType() {
+    return type;
+  }
+
+  public void setType(final String type) {
+    this.type = type;
+  }
+
+  public String getImageUri() {
+    return imageUrl;
+  }
+
+  public void setImageUri(final String uri) {
+    imageUrl = uri;
+  }
+
+  public byte[] getImage() {
+    return image.clone();
+  }
+
+  public void setImage(final byte[] image) {
+    this.image = image;
+  }
+
+  public String getImageType() {
+    return mimeType;
+  }
+
+  public void setImageType(final String imageType) {
+    this.mimeType = imageType;
+  }
+
+  @Override
+  public int hashCode() {
+    int hash = 5;
+    hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
+    hash = 83 * hash + (this.type != null ? this.type.hashCode() : 0);
+    return hash;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    final Photo other = (Photo) obj;
+    if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
+      return false;
+    }
+    if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) {
+      return false;
+    }
+    return true;
+  }
+  
+  @Override
+  public String toString() {
+    return "{\"Name\":\"" + name + "\","
+        + "\"Type\":\"" + type + "\","
+        + "\"ImageUrl\":\"" + imageUrl + "\","
+        + "\"Image\":\"" + Arrays.toString(image) + "\","
+        + "\"MimeType\":\"" + mimeType + "\"";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
new file mode 100644
index 0000000..727b8c3
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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.odata2.ref.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *
+ */
+@EdmEntityType(name="Base", namespace=ModelSharedConstants.NAMESPACE_1)
+public abstract class RefBase {
+  @EdmProperty(name="Name")
+  protected String name;
+  @EdmProperty(name="Id", type = EdmType.STRING)
+  @EdmKey
+  protected String id;
+
+  public String getName() {
+    return name;
+  }
+
+  public String getId() {
+    return id;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public void setId(int id) {
+    this.id = String.valueOf(id);
+  }
+
+  @Override
+  public int hashCode() {
+    if(id == null) {
+      return -1;
+    }
+    return id.hashCode();
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    final RefBase other = (RefBase) obj;
+    if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
+      return false;
+    }
+    if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) {
+      return false;
+    }
+    return true;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
new file mode 100644
index 0000000..3d2bb88
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * 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.odata2.ref.annotation.model;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.imageio.ImageIO;
+
+/**
+ *
+ */
+public class ResourceHelper {
+
+  public static byte[] loadAsByte(String resource) {
+    return load(resource, new byte[0]);
+  }
+
+  public static byte[] load(String resource, byte[] defaultResult) {
+    InputStream instream = null;
+    try {
+      instream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
+      if (instream == null) {
+        return defaultResult;
+      }
+      ByteArrayOutputStream stream = new ByteArrayOutputStream();
+      int b = 0;
+      while ((b = instream.read()) != -1) {
+        stream.write(b);
+      }
+
+      return stream.toByteArray();
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    } finally {
+      if(instream != null) {
+        try {
+          instream.close();
+        } catch (IOException ex) { }
+      }
+    }
+  }
+
+  public enum Format {BMP, JPEG, PNG, GIF};
+  
+  public static byte[] generateImage() {
+    return generateImage(Format.PNG);
+  }
+  
+  public static byte[] generateImage(Format format) {
+    try {
+      int width = 320;
+      int height = 320;
+      BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
+      WritableRaster raster = image.getRaster();
+      
+      int mod = format.ordinal() + 2;
+      for (int h = 0; h < height; h++) {
+        for (int w = 0; w < width; w++) {
+          if (((h / 32) + (w / 32)) % mod == 0) {
+            raster.setSample(w, h, 0, 0);
+          } else {
+            raster.setSample(w, h, 0, 1);
+          }
+        }
+      }
+      
+      ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
+      ImageIO.write(image, format.name(), out);
+      return out.toByteArray();
+    } catch (IOException ex) {
+      return new byte[0];
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
new file mode 100644
index 0000000..2d9f48e
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * 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.odata2.ref.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Room", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Rooms")
+public class Room extends RefBase {
+
+  @EdmProperty
+  private Integer seats;
+  @EdmProperty
+  private Integer version;
+  @EdmNavigationProperty(name = "nr_Building", association = "BuildingRooms")
+  private Building building;
+  @EdmNavigationProperty(name = "nr_Employees")
+  private List<Employee> employees = new ArrayList<Employee>();
+
+  public void setSeats(final int seats) {
+    this.seats = seats;
+  }
+
+  public int getSeats() {
+    return seats;
+  }
+
+  public void setVersion(final int version) {
+    this.version = version;
+  }
+
+  public int getVersion() {
+    return version;
+  }
+
+  public void setBuilding(final Building building) {
+    this.building = building;
+  }
+
+  public Building getBuilding() {
+    return building;
+  }
+
+  public List<Employee> getEmployees() {
+    return employees;
+  }
+
+  @Override
+  public int hashCode() {
+    return super.hashCode();
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+        || obj != null && getClass() == obj.getClass() && id == ((Room) obj).id;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Seats\":" + seats + ",\"Version\":" + version + "}";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
new file mode 100644
index 0000000..50d2ad2
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * 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.odata2.ref.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+*  
+*/
+@EdmEntityType(name = "Team", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Teams")
+public class Team extends RefBase {
+  @EdmProperty(type = EdmType.BOOLEAN)
+  private Boolean isScrumTeam;
+  @EdmNavigationProperty(name = "nt_Employees", association = "TeamEmployees", toMultiplicity = Multiplicity.MANY)
+  private List<Employee> employees = new ArrayList<Employee>();
+
+  public Boolean isScrumTeam() {
+    return isScrumTeam;
+  }
+
+  public void setScrumTeam(final Boolean isScrumTeam) {
+    this.isScrumTeam = isScrumTeam;
+  }
+
+  public void addEmployee(Employee e) {
+    this.employees.add(e);
+  }
+
+  public List<Employee> getEmployees() {
+    return employees;
+  }
+
+  @Override
+  public int hashCode() {
+    return super.hashCode();
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+        || obj != null && getClass() == obj.getClass() && id == ((Team) obj).id;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"IsScrumTeam\":" + isScrumTeam + "}";
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
new file mode 100644
index 0000000..3870119
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
@@ -0,0 +1,202 @@
+/**
+ * *****************************************************************************
+ * 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.odata2.ref.annotation.processor;
+
+import java.util.Calendar;
+
+import org.apache.olingo.odata2.api.ODataCallback;
+import org.apache.olingo.odata2.api.ODataDebugCallback;
+import org.apache.olingo.odata2.api.ODataService;
+import org.apache.olingo.odata2.api.ODataServiceFactory;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.ep.EntityProvider;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.processor.ODataErrorCallback;
+import org.apache.olingo.odata2.api.processor.ODataErrorContext;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.core.annotation.data.AnnotationInMemoryDs;
+import org.apache.olingo.odata2.core.annotation.data.AnnotationValueAccess;
+import org.apache.olingo.odata2.core.annotation.data.DataStore;
+import org.apache.olingo.odata2.core.annotation.edm.AnnotationEdmProvider;
+import org.apache.olingo.odata2.core.annotation.processor.ListsProcessor;
+import org.apache.olingo.odata2.ref.annotation.model.Building;
+import org.apache.olingo.odata2.ref.annotation.model.Employee;
+import org.apache.olingo.odata2.ref.annotation.model.Location;
+import org.apache.olingo.odata2.ref.annotation.model.Manager;
+import org.apache.olingo.odata2.ref.annotation.model.Photo;
+import org.apache.olingo.odata2.ref.annotation.model.ResourceHelper;
+import org.apache.olingo.odata2.ref.annotation.model.Room;
+import org.apache.olingo.odata2.ref.annotation.model.Team;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ */
+public class AnnotationPocServiceFactory extends ODataServiceFactory {
+
+  private static boolean isInitialized = false;
+
+  @Override
+  public ODataService createService(final ODataContext context) throws ODataException {
+
+    String modelPackage = "org.apache.olingo.odata2.ref.annotation.model";
+    AnnotationEdmProvider annotationEdmProvider = new AnnotationEdmProvider(modelPackage);
+    AnnotationInMemoryDs annotationScenarioDs = new AnnotationInMemoryDs(modelPackage);
+    AnnotationValueAccess annotationValueAccess = new AnnotationValueAccess();
+
+    if (!isInitialized) {
+      initializeSampleData(annotationScenarioDs);
+      isInitialized = true;
+    }
+
+    // Edm via Annotations and ListProcessor via AnnotationDS with AnnotationsValueAccess
+    return createODataSingleProcessorService(annotationEdmProvider,
+            new ListsProcessor(annotationScenarioDs, annotationValueAccess));
+  }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+    return (T) (callbackInterface.isAssignableFrom(ScenarioErrorCallback.class)
+            ? new ScenarioErrorCallback() : callbackInterface.isAssignableFrom(ODataDebugCallback.class)
+            ? new ScenarioDebugCallback() : super.getCallback(callbackInterface));
+  }
+
+  /*
+  * Helper classes and methods
+  */
+
+  /**
+   * 
+   */
+  private final class ScenarioDebugCallback implements ODataDebugCallback {
+
+    @Override
+    public boolean isDebugEnabled() {
+      return true;
+    }
+  }
+
+  private class ScenarioErrorCallback implements ODataErrorCallback {
+
+    private final Logger LOG = LoggerFactory.getLogger(ScenarioErrorCallback.class);
+
+    @Override
+    public ODataResponse handleError(final ODataErrorContext context) throws ODataApplicationException {
+      if (context.getHttpStatus() == HttpStatusCodes.INTERNAL_SERVER_ERROR) {
+        LOG.error("Internal Server Error", context.getException());
+      }
+
+      return EntityProvider.writeErrorDocument(context);
+    }
+
+  }
+
+  private void initializeSampleData(AnnotationInMemoryDs dataSource) throws ODataApplicationException {
+    DataStore<Team> teamDs = dataSource.getDataStore(Team.class);
+    teamDs.create(createTeam("Team Alpha", true));
+    teamDs.create(createTeam("Team Beta", false));
+    teamDs.create(createTeam("Team Gamma", false));
+    teamDs.create(createTeam("Team Omega", true));
+    teamDs.create(createTeam("Team Zeta", true));
+
+    DataStore<Building> buildingsDs = dataSource.getDataStore(Building.class);
+    Building redBuilding = createBuilding("Red Building");
+    buildingsDs.create(redBuilding);
+    Building greenBuilding = createBuilding("Green Building");
+    buildingsDs.create(greenBuilding);
+    Building blueBuilding = createBuilding("Blue Building");
+    buildingsDs.create(blueBuilding);
+    Building yellowBuilding = createBuilding("Yellow Building");
+    buildingsDs.create(yellowBuilding);
+
+    DataStore<Photo> photoDs = dataSource.getDataStore(Photo.class);
+    photoDs.create(createPhoto("Small picture", ResourceHelper.Format.GIF));
+    photoDs.create(createPhoto("Medium picture", ResourceHelper.Format.PNG));
+    photoDs.create(createPhoto("Big picture", ResourceHelper.Format.JPEG));
+    photoDs.create(createPhoto("Huge picture", ResourceHelper.Format.BMP));
+
+    DataStore<Room> roomDs = dataSource.getDataStore(Room.class);
+    roomDs.create(createRoom("Tiny red room", 5, 1, redBuilding));
+    roomDs.create(createRoom("Small red room", 20, 1, redBuilding));
+    roomDs.create(createRoom("Small green room", 20, 1, greenBuilding));
+    roomDs.create(createRoom("Big blue room", 40, 1, blueBuilding));
+    roomDs.create(createRoom("Huge blue room", 120, 1, blueBuilding));
+    roomDs.create(createRoom("Huge yellow room", 120, 1, yellowBuilding));
+
+    DataStore<Employee> employeeDataStore = dataSource.getDataStore(Employee.class);
+    employeeDataStore.create(createEmployee("first Employee",
+        new Location("Norge", "8392", "Ä"), 42, null,
+        photoDs.read().iterator().next().getImage(), photoDs.read().iterator().next().getImageType(),
+        "http://localhost/image/first.png",
+        null, teamDs.read().iterator().next(), roomDs.read().iterator().next()));
+  }
+
+  private Employee createEmployee(final String name,
+      Location location, final int age, final Calendar date,
+      final byte[] image, final String imageType, final String imageUrl,
+      Manager manager, Team team, Room room) {
+    Employee employee = new Employee();
+    employee.setEmployeeName(name);
+    employee.setLocation(location);
+    employee.setAge(age);
+    employee.setEntryDate(date);
+    employee.setImage(image);
+    employee.setImageType(imageType);
+    employee.setImageUri(imageUrl);
+    employee.setManager(manager);
+    employee.setTeam(team);
+    employee.setRoom(room);
+    return employee;
+  }
+
+  private Team createTeam(String teamName, boolean isScrumTeam) {
+    Team team = new Team();
+    team.setName(teamName);
+    team.setScrumTeam(isScrumTeam);
+    return team;
+  }
+
+  private Building createBuilding(String buildingName) {
+    Building b = new Building();
+    b.setName(buildingName);
+    return b;
+  }
+
+  private Photo createPhoto(String name, ResourceHelper.Format format) {
+    Photo p = new Photo();
+    p.setName(name);
+    p.setImageUri("http://localhost/image/" + name);
+    p.setType(format.name());
+    p.setImageType("image/" + format.name().toLowerCase());
+    p.setImage(ResourceHelper.generateImage(format));
+    return p;
+  }
+
+  private Room createRoom(String name, int seats, int version, Building building) {
+    Room r = new Room();
+    r.setName(name);
+    r.setSeats(seats);
+    r.setVersion(version);
+    r.setBuilding(building);
+    
+    building.addRoom(r);
+    
+    return r;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/resources/log4j.xml
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/resources/log4j.xml b/odata2-annotation-processor/annotation-processor-webref/src/main/resources/log4j.xml
new file mode 100644
index 0000000..90a4706
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/resources/log4j.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+-->
+<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+    <appender name="console" class="org.apache.log4j.ConsoleAppender">
+        <param name="Target" value="System.out" />
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%-5p %c{1} - %m%n" />
+        </layout>
+    </appender>
+
+    <logger name="org.apache.olingo.odata2.ref" additivity="false">
+        <level value="trace" />
+        <appender-ref ref="console" />
+    </logger>
+    
+    <root>
+        <priority value="error" />
+        <appender-ref ref="console" />
+    </root>
+</log4j:configuration>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/version/version.html
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/version/version.html b/odata2-annotation-processor/annotation-processor-webref/src/main/version/version.html
new file mode 100644
index 0000000..6d76d0b
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/version/version.html
@@ -0,0 +1,27 @@
+<!--
+
+ 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.
+
+-->
+
+<table border="1">
+<tr><td>name</td><td>${name}</td></tr>
+<tr><td>version</td><td>${version}</td></tr>
+<tr><td>timestamp</td><td>${timestamp}</td></tr>
+<tr><td>project.build.finalName</td><td>${project.build.finalName}</td></tr>
+</table>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/WEB-INF/web.xml b/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..5f7264c
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+	id="WebApp_ID" version="2.5">
+	<display-name>org.apache.olingo.odata2.ref.annotations.web</display-name>
+	<welcome-file-list>
+		<welcome-file>index.jsp</welcome-file>
+	</welcome-file-list>
+	
+	<servlet>
+		<servlet-name>ReferenceScenarioServlet</servlet-name>
+		<servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
+		<init-param>
+			<param-name>javax.ws.rs.Application</param-name>
+			<param-value>org.apache.olingo.odata2.core.rest.app.ODataApplication</param-value>
+		</init-param>
+		<init-param>
+			<param-name>org.apache.olingo.odata2.service.factory</param-name>
+			<param-value>org.apache.olingo.odata2.ref.annotation.processor.AnnotationPocServiceFactory</param-value>
+		</init-param>
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+
+	<servlet-mapping>
+		<servlet-name>ReferenceScenarioServlet</servlet-name>
+		<url-pattern>/ReferenceScenario.svc/*</url-pattern>
+	</servlet-mapping>
+
+</web-app>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/index.jsp b/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/index.jsp
new file mode 100644
index 0000000..49cf364
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/webapp/index.jsp
@@ -0,0 +1,116 @@
+<%@ page language="java" contentType="text/html; UTF-8" pageEncoding="UTF-8"%>
+<!--
+  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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<title>Apache Olingo - OData2 Library</title>
+<style type="text/css">
+body { font-family: Arial, sans-serif; font-size: 13px; line-height: 18px;
+       color: blue; background-color: #ffffff; }
+a { color: blue; text-decoration: none; }
+a:focus { outline: thin dotted #4076cb; outline-offset: -1px; }
+a:hover, a:active { outline: 0; }
+a:hover { color: #404a7e; text-decoration: underline; }
+h1, h2, h3, h4, h5, h6 { margin: 9px 0; font-family: inherit; font-weight: bold;
+                         line-height: 1; color: blue; }
+h1 { font-size: 36px; line-height: 40px; }
+h2 { font-size: 30px; line-height: 40px; }
+h3 { font-size: 24px; line-height: 40px; }
+h4 { font-size: 18px; line-height: 20px; }
+h5 { font-size: 14px; line-height: 20px; }
+h6 { font-size: 12px; line-height: 20px; }
+.logo { float: right; }
+ul { padding: 0; margin: 0 0 9px 25px; }
+ul ul { margin-bottom: 0; }
+li { line-height: 18px; }
+hr { margin: 18px 0;
+     border: 0; border-top: 1px solid #cccccc; border-bottom: 1px solid #ffffff; }
+table { border-collapse: collapse; border-spacing: 10px; }
+th, td { border: 1px solid; padding: 20px; }
+.code { font-family: "Courier New", monospace; font-size: 13px; line-height: 18px; }
+</style>
+</head>
+<body>
+	<h1>Apache Olingo - OData2 Library</h1>
+	<hr />
+	<h2>Reference Scenario</h2>
+	<table>
+		<tr>
+			<td valign="top">
+				<h3>Service Document and Metadata</h3>
+				<ul>
+					<li><a href="ReferenceScenario.svc?_wadl" target="_blank">wadl</a></li>
+					<li><a href="ReferenceScenario.svc/" target="_blank">service
+							document</a></li>
+					<li><a href="ReferenceScenario.svc/$metadata" target="_blank">metadata</a></li>
+				</ul>
+				<h3>EntitySets</h3>
+				<ul>
+					<li><a href="ReferenceScenario.svc/Employees" target="_blank">Employees</a></li>
+					<li><a href="ReferenceScenario.svc/Managers" target="_blank">Managers</a></li>
+					<li><a href="ReferenceScenario.svc/Buildings" target="_blank">Buildings</a></li>
+					<li><a href="ReferenceScenario.svc/Buildings/?$expand=nb_Rooms" 
+                 target="_blank">Buildings/?$expand=nb_Rooms</a></li>
+					<li><a href="ReferenceScenario.svc/Rooms" target="_blank">Rooms</a></li>
+					<li><a href="ReferenceScenario.svc/Rooms/?$orderby=Name" target="_blank">Rooms/?$orderby=Name</a></li>
+					<li><a href="ReferenceScenario.svc/Photos" target="_blank">Photos</a></li>
+					<li><a href="ReferenceScenario.svc/Photos/?$filter=Type%20eq%20'PNG'" 
+                 target="_blank">Photos/?$filter=Type eq 'PNG'</a></li>
+        </ul>
+				<h3>Entities</h3>
+				<ul>
+					<li><a href="ReferenceScenario.svc/Employees('1')" target="_blank">Employees('1')</a></li>
+					<li><a href="ReferenceScenario.svc/Managers('1')" target="_blank">Managers('1')</a></li>
+					<li><a href="ReferenceScenario.svc/Buildings(1)" target="_blank">Buildings(1)</a></li>
+					<li><a href="ReferenceScenario.svc/Buildings(1)/nb_Rooms" target="_blank">Buildings(1)/nb_Rooms</a></li>
+					<li><a href="ReferenceScenario.svc/Rooms('1')" target="_blank">Rooms('1')</a></li>
+					<li><a href="ReferenceScenario.svc/Rooms('1')/nr_Building" target="_blank">Rooms('1')/nr_Building</a></li>
+ 					<li><a href="ReferenceScenario.svc/Photos(Name='Small%20picture',Type='GIF')"
+                           target="_blank">Photos(Name='Small%20picture',Type='GIF')</a></li>
+ 					<li><a href="ReferenceScenario.svc/Photos(Name='Big%20picture',Type='JPEG')/$value"
+                           target="_blank">Photos(Name='Big%20picture',Type='JPEG')/$value</a></li>
+        </ul>
+			</td>
+			<td valign="top">
+				&nbsp;
+			</td>
+			<td valign="bottom">
+				<div class="code">
+					<%
+					  String version = "gen/version.html";
+					%>
+					<%
+					  try {
+					%>
+					<jsp:include page='<%=version%>' />
+					<%
+					  } catch (Exception e) {
+					%>
+					<p>IDE Build</p>
+					<%
+					  }
+					%>
+				</div>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/pom.xml b/odata2-annotation-processor/pom.xml
new file mode 100644
index 0000000..d763047
--- /dev/null
+++ b/odata2-annotation-processor/pom.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.olingo</groupId>
+    <artifactId>olingo-odata2-annotation-processor-incubating</artifactId>
+    <packaging>pom</packaging>
+    <name>${project.artifactId}</name>
+
+    <parent>
+        <groupId>org.apache.olingo</groupId>
+        <artifactId>olingo-odata2-parent-incubating</artifactId>
+        <version>1.1.0-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <modules>
+        <module>annotation-processor-api</module>
+        <module>annotation-processor-core</module>
+        <module>annotation-processor-webref</module>
+    </modules>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-api/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/pom.xml b/odata2-edm-annotation/edm-annotation-api/pom.xml
deleted file mode 100644
index 5d697f2..0000000
--- a/odata2-edm-annotation/edm-annotation-api/pom.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0"?>
-<!--
-  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.
--->
-<project
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
-  xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <modelVersion>4.0.0</modelVersion>
-	
-  <parent>
-    <groupId>org.apache.olingo</groupId>
-    <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
-    <version>1.1.0-SNAPSHOT</version>
-    <relativePath>..</relativePath>
-  </parent>
-
-  <artifactId>olingo-odata2-edm-annotation-api-incubating</artifactId>
-  <name>${project.artifactId}</name>
-        
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.olingo</groupId>
-      <artifactId>olingo-odata2-api-incubating</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
deleted file mode 100644
index 694f199..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*******************************************************************************
- * 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.odata2.api.data;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
-import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
-import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-
-/**
- * <p>This interface is intended to make it easier to implement an OData
- * service in cases where all data for each entity set can be provided as a {@link List} of objects from which all
- * properties described in the
- * Entity Data Model can be retrieved and set.</p>
- * <p>By obeying these restrictions, data-source implementations get the
- * following advantages:
- * <ul>
- * <li>All system query options can be handled centrally.</li>
- * <li>Following navigation paths must only be done step by step.</li>
- * </ul>
- * </p>
- * 
- */
-public interface DataSource {
-
-  /**
-   * Retrieves the whole data list for the specified entity set.
-   * @param entitySet the requested {@link EdmEntitySet}
-   * @return the requested data list
-   */
-  List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
-      ODataApplicationException;
-
-  /**
-   * Retrieves a single data object for the specified entity set and key.
-   * @param entitySet the requested {@link EdmEntitySet}
-   * @param keys the entity key as map of key names to key values
-   * @return the requested data object
-   */
-  Object readData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
-      ODataNotFoundException, EdmException, ODataApplicationException;
-
-  /**
-   * <p>Retrieves data for the specified function import and key.</p>
-   * <p>This method is called also for function imports that have defined in
-   * their metadata an other HTTP method than <code>GET</code>.</p>
-   * @param function the requested {@link EdmFunctionImport}
-   * @param parameters the parameters of the function import
-   * as map of parameter names to parameter values
-   * @param keys the key of the returned entity set, as map of key names to key values,
-   * if the return type of the function import is a collection of entities
-   * (optional)
-   * @return the requested data object, either a list or a single object;
-   * if the function import's return type is of type <code>Binary</code>,
-   * the returned object(s) must be of type {@link BinaryData}
-   */
-  Object readData(EdmFunctionImport function, Map<String, Object> parameters, Map<String, Object> keys)
-      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
-
-  /**
-   * <p>Retrieves related data for the specified source data, entity set, and key.</p>
-   * <p>If the underlying association of the EDM is specified to have target
-   * multiplicity '*' and no target key is given, this method returns a list of
-   * related data, otherwise it returns a single data object.</p>
-   * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
-   * @param sourceData the data object of the source entity
-   * @param targetEntitySet the requested target {@link EdmEntitySet}
-   * @param targetKeys the key of the target entity as map of key names to key values
-   * (optional)
-   * @return the requested releated data object, either a list or a single object
-   */
-  Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
-      Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
-      ODataApplicationException;
-
-  /**
-   * Retrieves the binary data and the MIME type for the media resource
-   * associated to the specified media-link entry.
-   * @param entitySet the {@link EdmEntitySet} of the media-link entry
-   * @param mediaLinkEntryData the data object of the media-link entry
-   * @return the binary data and the MIME type of the media resource
-   */
-  BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData) throws ODataNotImplementedException,
-      ODataNotFoundException, EdmException, ODataApplicationException;
-
-  /**
-   * <p>Creates and returns a new instance of the requested data-object type.</p>
-   * <p>This instance must not be part of the corresponding list and should
-   * have empty content, apart from the key and other mandatory properties.
-   * However, intermediate objects to access complex properties must not be
-   * <code>null</code>.</p>
-   * @param entitySet the {@link EdmEntitySet} the object must correspond to
-   * @return the new data object
-   */
-  Object newDataObject(EdmEntitySet entitySet) throws ODataNotImplementedException, EdmException,
-      ODataApplicationException;
-
-  /**
-   * Writes the binary data for the media resource associated to the
-   * specified media-link entry.
-   * @param entitySet the {@link EdmEntitySet} of the media-link entry
-   * @param mediaLinkEntryData the data object of the media-link entry
-   * @param binaryData the binary data of the media resource along with
-   * the MIME type of the binary data
-   */
-  void writeBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData, BinaryData binaryData)
-      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
-
-  /**
-   * Deletes a single data object identified by the specified entity set and key.
-   * @param entitySet the {@link EdmEntitySet} of the entity to be deleted
-   * @param keys the entity key as map of key names to key values
-   */
-  void deleteData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
-      ODataNotFoundException, EdmException, ODataApplicationException;
-
-  /**
-   * <p>Inserts an instance into the entity list of the specified entity set.</p>
-   * <p>If {@link #newDataObject} has not set the key and other mandatory
-   * properties already, this method must set them before inserting the
-   * instance into the list.</p>
-   * @param entitySet the {@link EdmEntitySet} the object must correspond to
-   * @param data the data object of the new entity
-   */
-  void createData(EdmEntitySet entitySet, Object data) throws ODataNotImplementedException, EdmException,
-      ODataApplicationException;
-
-  /**
-   * Deletes the relation from the specified source data to a target entity
-   * specified by entity set and key.
-   * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
-   * @param sourceData the data object of the source entity
-   * @param targetEntitySet the {@link EdmEntitySet} of the target entity
-   * @param targetKeys the key of the target entity as map of key names to key values
-   * (optional)
-   */
-  void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
-      Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
-      ODataApplicationException;
-
-  /**
-   * Writes a relation from the specified source data to a target entity
-   * specified by entity set and key.
-   * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
-   * @param sourceData the data object of the source entity
-   * @param targetEntitySet the {@link EdmEntitySet} of the relation target
-   * @param targetKeys the key of the target entity as map of key names to key values
-   */
-  void writeRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
-      Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
-      ODataApplicationException;
-
-  /**
-   * Container to store binary data (as byte array) and the associated MIME type.
-   */
-  public class BinaryData {
-    private final byte[] data;
-    private final String mimeType;
-
-    public BinaryData(final byte[] data, final String mimeType) {
-      this.data = data;
-      this.mimeType = mimeType;
-    }
-
-    public byte[] getData() {
-      return data;
-    }
-
-    public String getMimeType() {
-      return mimeType;
-    }
-
-    @Override
-    public String toString() {
-      return "data=" + Arrays.toString(data) + ", mimeType=" + mimeType;
-    }
-  }
-}


[02/12] git commit: Removed not to merge PoC parts

Posted by mi...@apache.org.
Removed not to merge PoC parts


Project: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/commit/8764e11a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/tree/8764e11a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/diff/8764e11a

Branch: refs/heads/PocEdmAnnotationsExtension
Commit: 8764e11a6d70099a93e2da110fe47ffe06c4baaa
Parents: a73d197
Author: Michael Bolz <mi...@apache.org>
Authored: Thu Dec 5 08:46:31 2013 +0100
Committer: Michael Bolz <mi...@apache.org>
Committed: Thu Dec 5 08:46:31 2013 +0100

----------------------------------------------------------------------
 .../api/annotation/edm/ds/EntityCreate.java     |  29 -
 .../api/annotation/edm/ds/EntityDataSource.java |  31 -
 .../api/annotation/edm/ds/EntityDelete.java     |  29 -
 .../api/annotation/edm/ds/EntityRead.java       |  29 -
 .../api/annotation/edm/ds/EntitySetRead.java    |  29 -
 .../api/annotation/edm/ds/EntityUpdate.java     |  29 -
 .../annotation/data/AnnotationInMemoryDs.java   |   8 +-
 .../annotation/data/AnnotationValueAccess.java  |   2 +-
 .../core/annotation/data/DataSourceHolder.java  | 212 ------
 .../odata2/core/annotation/data/DataStore.java  |   2 +-
 .../annotation/edm/AnnotationEdmProvider.java   |   2 +
 .../core/annotation/edm/AnnotationHelper.java   | 726 -------------------
 .../odata2/core/annotation/edm/ClassHelper.java | 105 ---
 .../processor/AnnotationProcessor.java          | 309 --------
 .../processor/json/EdmAnnotationSerializer.java | 260 -------
 .../annotation/processor/json/JsonConsumer.java | 138 ----
 .../annotation/processor/json/JsonWriter.java   | 204 ------
 .../core/annotation/util/AnnotationHelper.java  | 726 +++++++++++++++++++
 .../core/annotation/util/ClassHelper.java       | 105 +++
 .../src/main/resources/log4j.xml                |  39 -
 .../data/AnnotationsInMemoryDsTest.java         |   2 +-
 .../processor/json/JsonConsumerTest.java        |  85 ---
 .../edm-annotation-webref/pom.xml               |  12 +-
 23 files changed, 845 insertions(+), 2268 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java
deleted file mode 100644
index 529ee63..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * 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.odata2.api.annotation.edm.ds;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface EntityCreate {
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java
deleted file mode 100644
index e21c81f..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*******************************************************************************
- * 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.odata2.api.annotation.edm.ds;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface EntityDataSource {
-  String name() default "";
-  Class<?> entityType();
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java
deleted file mode 100644
index f852307..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * 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.odata2.api.annotation.edm.ds;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface EntityDelete {
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java
deleted file mode 100644
index 76333ca..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * 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.odata2.api.annotation.edm.ds;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface EntityRead {
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java
deleted file mode 100644
index 79cb80c..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * 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.odata2.api.annotation.edm.ds;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface EntitySetRead {
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java
deleted file mode 100644
index 6aea1eb..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * 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.odata2.api.annotation.edm.ds;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface EntityUpdate {
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
index 7c41945..030cc93 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
@@ -32,10 +32,10 @@ import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
 import org.apache.olingo.odata2.api.exception.ODataApplicationException;
 import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
 import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper.AnnotatedNavInfo;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper.ODataAnnotationException;
-import org.apache.olingo.odata2.core.annotation.edm.ClassHelper;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.util.ClassHelper;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.AnnotatedNavInfo;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.ODataAnnotationException;
 import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
 
 public class AnnotationInMemoryDs implements ListsDataSource {

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
index c29ac39..14183bf 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
@@ -23,7 +23,7 @@ import org.apache.olingo.odata2.api.edm.EdmMapping;
 import org.apache.olingo.odata2.api.edm.EdmProperty;
 import org.apache.olingo.odata2.api.exception.ODataException;
 import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
 
 /**
  *

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataSourceHolder.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataSourceHolder.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataSourceHolder.java
deleted file mode 100644
index d4c6f98..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataSourceHolder.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.data;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityCreate;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDataSource;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDelete;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityRead;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntitySetRead;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityUpdate;
-import org.apache.olingo.odata2.api.uri.KeyPredicate;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
-
-/**
- *
- */
-public final class DataSourceHolder {
-
-  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
-  private static final Object[] EMPTY_ARRAY = new Object[0];
-  
-  private final String name;
-  private final Object dataSourceInstance;
-  private final Class<?> entityTypeClass;
-  private Method readMethod;
-  private Method createMethod;
-  private Method updateMethod;
-  private Method deleteMethod;
-  private Method readSetMethod;
-
-  public DataSourceHolder(Class<?> clz) {
-    EntityDataSource eds = clz.getAnnotation(EntityDataSource.class);
-    entityTypeClass = eds.entityType();
-    EdmEntityType entityType = entityTypeClass.getAnnotation(EdmEntityType.class);
-    if (entityType == null) {
-      throw new IllegalArgumentException("Missing EdmEntityType Annotation at class " + clz);
-    }
-
-    if (entityType.name().isEmpty()) {
-      name = ANNOTATION_HELPER.getCanonicalName(entityTypeClass);
-    } else {
-      name = entityType.name();
-    }
-    dataSourceInstance = createInstance(clz);
-    initMethods(clz);
-  }
-
-  private void initMethods(Class<?> clz) throws IllegalArgumentException, SecurityException {
-    Method[] methods = clz.getDeclaredMethods();
-    for (Method method : methods) {
-      EntityRead ec = method.getAnnotation(EntityRead.class);
-      if (ec != null) {
-        readMethod = method;
-      }
-      EntityCreate ep = method.getAnnotation(EntityCreate.class);
-      if (ep != null) {
-        createMethod = method;
-      }
-      EntityUpdate update = method.getAnnotation(EntityUpdate.class);
-      if (update != null) {
-        updateMethod = method;
-      }
-      EntityDelete delete = method.getAnnotation(EntityDelete.class);
-      if (delete != null) {
-        deleteMethod = method;
-      }
-      EntitySetRead readSet = method.getAnnotation(EntitySetRead.class);
-      if (readSet != null) {
-        readSetMethod = method;
-      }
-    }
-
-    validateMethods(clz);
-  }
-
-  private void validateMethods(Class<?> clz) throws IllegalArgumentException {
-    //
-    if (readMethod == null) {
-      throw new IllegalArgumentException("Missing " + EntityRead.class
-              + " annotation at " + EntityDataSource.class + " annotated class " + clz);
-    }
-    if (updateMethod == null) {
-      throw new IllegalArgumentException("Missing " + EntityUpdate.class
-              + " annotation at " + EntityDataSource.class + " annotated class " + clz);
-    }
-    if (createMethod == null) {
-      throw new IllegalArgumentException("Missing " + EntityCreate.class
-              + " annotation at " + EntityDataSource.class + " annotated class " + clz);
-    }
-    
-    if(readSetMethod != null) {
-      if(!Collection.class.isAssignableFrom(readSetMethod.getReturnType())) {
-        throw new IllegalArgumentException("Read set method must have a return type which is assignable to " 
-            + Collection.class + " but return type for annotated method " + readSetMethod + " is " 
-            + readSetMethod.getReturnType());
-      }
-    }
-  }
-
-  public Object readEntity(Object[] keyValues) {
-    if (readMethod.getParameterTypes().length != keyValues.length) {
-      throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
-              + Arrays.toString(readMethod.getParameterTypes()) + " given key predicates = " 
-              + Arrays.toString(keyValues));
-    }
-
-    return invoke(readMethod, keyValues);
-  }
-
-  public Object readEntity(List<KeyPredicate> keys) {
-    Object[] parameterKeys = mapParameterKeys(readMethod, keys);
-    return invoke(readMethod, parameterKeys);
-  }
-
-  private Object[] mapParameterKeys(Method method, List<KeyPredicate> keys) throws IllegalStateException {
-    if(method == null) {
-      return EMPTY_ARRAY;
-    }
-    Class<?>[] pTypes = method.getParameterTypes();
-    if (pTypes.length != keys.size()) {
-      throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
-              + Arrays.toString(pTypes) + " given key predicates = " + keys);
-    }
-    Object[] parameterKeys = new Object[pTypes.length];
-    int i = 0;
-    for (KeyPredicate keyPredicate : keys) {
-      if (matches(pTypes[i], keyPredicate)) {
-        parameterKeys[i] = keyPredicate.getLiteral();
-      }
-      i++;
-    }
-    return parameterKeys;
-  }
-
-  public Object createEntity(Object key) {
-    return invoke(createMethod, new Object[]{key});
-  }
-
-  public Object updateEntity(Object key) {
-    return invoke(updateMethod, new Object[]{key});
-  }
-
-  public Object deleteEntity(List<KeyPredicate> keys) {
-    Object[] parameterKeys = mapParameterKeys(deleteMethod, keys);
-    return invoke(deleteMethod, parameterKeys);
-  }
-
-  public Collection<?> readEntitySet() {
-    return (Collection<?>) invoke(readSetMethod, new Object[0]);
-  }
-
-  private Object invoke(Method m, Object[] objs) {
-    try {
-      return m.invoke(dataSourceInstance, objs);
-    } catch (Exception ex) {
-      return null;
-    }
-  }
-
-  public Object createEntityInstance() {
-    return createInstance(this.entityTypeClass);
-  }
-
-  private static Object createInstance(Class<?> clz) {
-    try {
-      return clz.newInstance();
-    } catch (Exception ex) {
-      return null;
-    }
-  }
-
-  public String getEntityName() {
-    return this.name;
-  }
-
-  public Class<?> getEntityTypeClass() {
-    return entityTypeClass;
-  }
-
-  @Override
-  public String toString() {
-    return "DataSourceHolder{" + "name=" + name + ", dataSourceInstance=" + dataSourceInstance + 
-            ", entityTypeClass=" + entityTypeClass + ", consumerMethod=" + readMethod + 
-            ", createMethod=" + createMethod + ", updateMethod=" + updateMethod + '}';
-  }
-
-  private boolean matches(Class<?> aClass, KeyPredicate type) {
-    return true;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
index 834e33a..696ab9a 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
@@ -29,7 +29,7 @@ import java.util.Map;
 
 import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
 import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
 import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
index 1b53d58..97f5b53 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
@@ -64,6 +64,8 @@ import org.apache.olingo.odata2.api.edm.provider.Schema;
 import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
 import org.apache.olingo.odata2.api.edm.provider.Using;
 import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.util.ClassHelper;
 import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
deleted file mode 100644
index 2b6675f..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
+++ /dev/null
@@ -1,726 +0,0 @@
-/**
- * *****************************************************************************
- * 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.odata2.core.annotation.edm;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.ParameterizedType;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
-import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
-import org.apache.olingo.odata2.api.edm.FullQualifiedName;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-/**
- *
- */
-public class AnnotationHelper {
-
-  public static final String DEFAULT_CONTAINER_NAME = "DefaultContainer";
-
-  /**
-   * Compare keys of both instances.
-   * 
-   * @param firstInstance
-   * @param secondInstance
-   * @return 
-   */
-  public boolean keyMatch(Object firstInstance, Object secondInstance) {
-    if (firstInstance == null || secondInstance == null) {
-      return false;
-    } else if (firstInstance.getClass() != secondInstance.getClass()) {
-      return false;
-    }
-
-    Map<String, Object> firstKeyFields = getValueForAnnotatedFields(firstInstance, EdmKey.class);
-    Map<String, Object> secondKeyFields = getValueForAnnotatedFields(secondInstance, EdmKey.class);
-
-    return keyValuesMatch(firstKeyFields, secondKeyFields);
-  }
-
-  /**
-   * Compare keys of instance with key values in map.
-   * 
-   * @param instance
-   * @param keyName2Value
-   * @return 
-   */
-  public boolean keyMatch(Object instance, Map<String, Object> keyName2Value) {
-    Map<String, Object> instanceKeyFields = getValueForAnnotatedFields(instance, EdmKey.class);
-    return keyValuesMatch(instanceKeyFields, keyName2Value);
-  }
-
-  private boolean keyValuesMatch(Map<String, Object> firstKeyValues, Map<String, Object> secondKeyValues) {
-    if (firstKeyValues.size() != secondKeyValues.size()) {
-      return false;
-    } else {
-      Set<Map.Entry<String, Object>> entries = firstKeyValues.entrySet();
-      for (Map.Entry<String, Object> entry : entries) {
-        Object firstKey = entry.getValue();
-        Object secondKey = secondKeyValues.get(entry.getKey());
-        if (!isEqual(firstKey, secondKey)) {
-          return false;
-        }
-      }
-      return true;
-    }
-  }
-  
-  private boolean isEqual(Object firstKey, Object secondKey) {
-    if (firstKey == null) {
-      if (secondKey == null) {
-        return true;
-      } else {
-        return secondKey.equals(firstKey);
-      }
-    } else {
-      return firstKey.equals(secondKey);
-    }
-  }
-
-  public String extractEntitTypeName(EdmNavigationProperty enp, Class<?> fallbackClass) {
-    Class<?> entityTypeClass = enp.toType();
-    return extractEntityTypeName(entityTypeClass == Object.class ? fallbackClass : entityTypeClass);
-  }
-
-  public String extractEntitTypeName(EdmNavigationProperty enp, Field field) {
-    Class<?> entityTypeClass = enp.toType();
-    if (entityTypeClass == Object.class) {
-      Class<?> toClass = field.getType();
-      return extractEntityTypeName((toClass.isArray() || Collection.class.isAssignableFrom(toClass) ?
-          (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0] : toClass));
-    } else {
-      return extractEntityTypeName(entityTypeClass);
-    }
-  }
-
-  /**
-   * Returns <code>NULL</code> if given class is not annotated. If annotated the set entity type name is returned and if
-   * no name is set the default name is generated from the simple class name.
-   *
-   * @param annotatedClass
-   * @return
-   */
-  public String extractEntityTypeName(Class<?> annotatedClass) {
-    return extractTypeName(annotatedClass, EdmEntityType.class);
-  }
-
-  public FullQualifiedName extractEntityTypeFqn(EdmEntityType type, Class<?> annotatedClass) {
-    if(type.namespace().isEmpty()) {
-      return new FullQualifiedName(generateNamespace(annotatedClass), extractEntityTypeName(annotatedClass));
-    }
-    return new FullQualifiedName(type.namespace(), extractEntityTypeName(annotatedClass));
-  }
-  
-  public FullQualifiedName extractEntityTypeFqn(Class<?> annotatedClass) {
-    EdmEntityType type = annotatedClass.getAnnotation(EdmEntityType.class);
-    if(type == null) {
-      return null;
-    }
-    return extractEntityTypeFqn(type, annotatedClass);
-  }
-
-  public FullQualifiedName extractComplexTypeFqn(Class<?> annotatedClass) {
-    EdmComplexType type = annotatedClass.getAnnotation(EdmComplexType.class);
-    if(type == null) {
-      return null;
-    }
-    return extractComplexTypeFqn(type, annotatedClass);
-  }
-
-  public FullQualifiedName extractComplexTypeFqn(EdmComplexType type, Class<?> annotatedClass) {
-    if(type.namespace().isEmpty()) {
-      return new FullQualifiedName(generateNamespace(annotatedClass), extractComplexTypeName(annotatedClass));
-    }
-    return new FullQualifiedName(type.namespace(), extractComplexTypeName(annotatedClass));
-  }
-
-  public String extractComplexTypeName(Class<?> annotatedClass) {
-    return extractTypeName(annotatedClass, EdmComplexType.class);
-  }
-  
-  public String generateNamespace(Class<?> annotatedClass) {
-    String packageName = annotatedClass.getPackage().getName();
-    return packageName;
-  }
-
-  /**
-   *
-   *
-   * @param <T> must be EdmEntityType or EdmComplexType annotation
-   * @param annotatedClass
-   * @param typeAnnotation
-   * @return null if annotatedClass is not annotated or name set via annotation or generated via
-   * {@link #getCanonicalName(java.lang.Class)}
-   */
-  private <T extends Annotation> String extractTypeName(Class<?> annotatedClass, Class<T> typeAnnotation) {
-    if (annotatedClass == Object.class) {
-      return null;
-    }
-    T type = annotatedClass.getAnnotation(typeAnnotation);
-    if (type == null) {
-      return null;
-    }
-
-    String name;
-    if (typeAnnotation == EdmEntityType.class) {
-      name = ((EdmEntityType) type).name();
-    } else if (typeAnnotation == EdmComplexType.class) {
-      name = ((EdmComplexType) type).name();
-    } else {
-      return null;
-    }
-
-    if (name.isEmpty()) {
-      return getCanonicalName(annotatedClass);
-    }
-    return name;
-  }
-
-  /**
-   * Get the set property name from an EdmProperty or EdmNavigationProperty annotation.
-   *
-   * @param field
-   * @return
-   */
-  public String getPropertyNameFromAnnotation(Field field) {
-    EdmProperty property = field.getAnnotation(EdmProperty.class);
-    if (property == null) {
-      EdmNavigationProperty navProperty = field.getAnnotation(EdmNavigationProperty.class);
-      if (navProperty == null) {
-        throw new EdmAnnotationException("Given field '" + field
-            + "' has no EdmProperty or EdmNavigationProperty annotation.");
-      }
-      return navProperty.name();
-    }
-    return property.name();
-  }
-
-  public String getPropertyName(Field field) {
-    String propertyName = getPropertyNameFromAnnotation(field);
-    if (propertyName.isEmpty()) {
-      propertyName = getCanonicalName(field);
-    }
-    return propertyName;
-  }
-
-  public String extractFromRoleName(EdmNavigationProperty enp, Field field) {
-    return getCanonicalRole(field.getDeclaringClass());
-  }
-
-  public String extractToRoleName(EdmNavigationProperty enp, Field field) {
-    String role = enp.toRole();
-    if (role.isEmpty()) {
-      role = getCanonicalRole(
-          field.getType().isArray() || Collection.class.isAssignableFrom(field.getType()) ?
-              (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0] : field.getType());
-    }
-    return role;
-  }
-
-  public String getCanonicalRole(Class<?> fallbackClass) {
-    String toRole = extractEntityTypeName(fallbackClass);
-    return "r_" + toRole;
-  }
-
-  public String extractRelationshipName(EdmNavigationProperty enp, Field field) {
-    String relationshipName = enp.association();
-    if (relationshipName.isEmpty()) {
-      final String fromRole = extractFromRoleName(enp, field);
-      final String toRole = extractToRoleName(enp, field);
-      if (fromRole.compareTo(toRole) > 0) {
-        relationshipName = toRole + "-" + fromRole;
-      } else {
-        relationshipName = fromRole + "-" + toRole;
-      }
-    }
-    return relationshipName;
-  }
-
-  public EdmMultiplicity getMultiplicity(EdmNavigationProperty enp, Field field) {
-    EdmMultiplicity multiplicity = mapMultiplicity(enp.toMultiplicity());
-    final boolean isCollectionType = field.getType().isArray() || Collection.class.isAssignableFrom(field.getType());
-
-    if (multiplicity == EdmMultiplicity.ONE && isCollectionType) {
-      return EdmMultiplicity.MANY;
-    }
-    return multiplicity;
-  }
-
-
-  /**
-   * Set key fields based on values in map.
-   * If an key field is not available or <code>NULL</code> in the map 
-   * it will be not set as <code>NULL</code> at the instance object.
-   * 
-   * @param instance
-   * @param keys
-   * @return
-   */
-  public <T> T setKeyFields(T instance, Map<String, Object> keys) {
-    List<Field> fields = getAnnotatedFields(instance, EdmKey.class);
-
-    for (Field field : fields) {
-      String propertyName = getPropertyName(field);
-      Object keyValue = keys.get(propertyName);
-      setValueForProperty(instance, propertyName, keyValue);
-    }
-
-    return instance;
-  }
-
-  public static final class ODataAnnotationException extends ODataException {
-    private static final long serialVersionUID = 1L;
-
-    public ODataAnnotationException(String message) {
-      super(message);
-    }
-  }
-
-  
-  public class AnnotatedNavInfo {
-    private final Field fromField;
-    private final Field toField;
-    private final EdmNavigationProperty fromNavigation;
-    private final EdmNavigationProperty toNavigation;
-
-    public AnnotatedNavInfo(Field fromField, Field toField, EdmNavigationProperty fromNavigation,
-        EdmNavigationProperty toNavigation) {
-      this.fromField = fromField;
-      this.toField = toField;
-      this.fromNavigation = fromNavigation;
-      this.toNavigation = toNavigation;
-    }
-
-    public Field getFromField() {
-      return fromField;
-    }
-
-    public Field getToField() {
-      return toField;
-    }
-
-    public EdmMultiplicity getFromMultiplicity() {
-      return getMultiplicity(toNavigation, toField);
-    }
-
-    public EdmMultiplicity getToMultiplicity() {
-      return getMultiplicity(fromNavigation, fromField);
-    }
-    
-    public boolean isBiDirectional() {
-      return toNavigation != null;
-    }
-  }
-
-  public AnnotatedNavInfo getCommonNavigationInfo(Class<?> sourceClass, Class<?> targetClass) {
-    List<Field> sourceFields = getAnnotatedFields(sourceClass, EdmNavigationProperty.class);
-    List<Field> targetFields = getAnnotatedFields(targetClass, EdmNavigationProperty.class);
-
-    // first try via association name to get full navigation information
-    for (Field sourceField : sourceFields) {
-      final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
-      final String sourceAssociation = extractRelationshipName(sourceNav, sourceField);
-      for (Field targetField : targetFields) {
-        final EdmNavigationProperty targetNav = targetField.getAnnotation(EdmNavigationProperty.class);
-        final String targetAssociation = extractRelationshipName(targetNav, targetField);
-        if (sourceAssociation.equals(targetAssociation)) {
-          return new AnnotatedNavInfo(sourceField, targetField, sourceNav, targetNav);
-        }
-      }
-    }
-    
-    // if nothing was found assume none bi-directinal navigation
-    String targetEntityTypeName = extractEntityTypeName(targetClass);
-    for (Field sourceField : sourceFields) {
-      final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
-      final String navTargetEntityName = extractEntitTypeName(sourceNav, sourceField);
-      
-      if (navTargetEntityName.equals(targetEntityTypeName)) {
-        return new AnnotatedNavInfo(sourceField, null, sourceNav, null);
-      }
-    }
-    
-    return null;
-  }
-
-  public Class<?> getFieldTypeForProperty(Object instance, String propertyName) throws ODataAnnotationException {
-    if (instance == null) {
-      return null;
-    }
-
-    Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
-    if (field == null) {
-      throw new ODataAnnotationException("No field for property '" + propertyName
-          + "' found at class '" + instance.getClass() + "'.");
-    }
-    return field.getType();
-  }
-
-  public Object getValueForProperty(Object instance, String propertyName) throws ODataAnnotationException {
-    if (instance == null) {
-      return null;
-    }
-
-    Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
-    if (field == null) {
-      throw new ODataAnnotationException("No field for property '" + propertyName
-          + "' found at class '" + instance.getClass() + "'.");
-    }
-    return getFieldValue(instance, field);
-  }
-
-  public void setValueForProperty(Object instance, String propertyName, Object propertyValue) {
-    if (instance != null) {
-      Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
-      if (field != null) {
-        setFieldValue(instance, field, propertyValue);
-      }
-    }
-  }
-
-  private Field getFieldForPropertyName(Object instance, String propertyName,
-      Class<?> resultClass, boolean inherited) {
-    if (instance == null) {
-      return null;
-    }
-
-    Field[] fields = resultClass.getDeclaredFields();
-    for (Field field : fields) {
-      EdmProperty property = field.getAnnotation(EdmProperty.class);
-      if (property != null) {
-        if (property.name().isEmpty() && getCanonicalName(field).equals(propertyName)) {
-          return field;
-        } else if (property.name().equals(propertyName)) {
-          return field;
-        }
-      }
-    }
-
-    Class<?> superClass = resultClass.getSuperclass();
-    if (inherited && superClass != Object.class) {
-      return getFieldForPropertyName(instance, propertyName, superClass, true);
-    }
-
-    return null;
-  }
-
-  public Object getValueForField(Object instance, String fieldName, Class<? extends Annotation> annotation) {
-    if (instance == null) {
-      return null;
-    }
-    return getValueForField(instance, fieldName, instance.getClass(), annotation, true);
-  }
-
-  public Object getValueForField(Object instance, Class<? extends Annotation> annotation) {
-    if (instance == null) {
-      return null;
-    }
-    return getValueForField(instance, instance.getClass(), annotation, true);
-  }
-
-  private Object getValueForField(Object instance, Class<?> resultClass,
-      Class<? extends Annotation> annotation, boolean inherited) {
-    return getValueForField(instance, null, resultClass, annotation, inherited);
-  }
-
-  public Map<String, Object> getValueForAnnotatedFields(Object instance,
-      Class<? extends Annotation> annotation) {
-    return getValueForAnnotatedFields(instance, instance.getClass(), annotation, true);
-  }
-
-  private Map<String, Object> getValueForAnnotatedFields(Object instance, Class<?> resultClass,
-      Class<? extends Annotation> annotation, boolean inherited) {
-    if (instance == null) {
-      return null;
-    }
-
-    Field[] fields = resultClass.getDeclaredFields();
-    Map<String, Object> fieldName2Value = new HashMap<String, Object>();
-
-    for (Field field : fields) {
-      if (field.getAnnotation(annotation) != null) {
-        Object value = getFieldValue(instance, field);
-        final EdmProperty property = field.getAnnotation(EdmProperty.class);
-        final String name = property == null || property.name().isEmpty() ? field.getName() : property.name();
-        fieldName2Value.put(name, value);
-      }
-    }
-
-    Class<?> superClass = resultClass.getSuperclass();
-    if (inherited && superClass != Object.class) {
-      Map<String, Object> tmp = getValueForAnnotatedFields(instance, superClass, annotation, true);
-      fieldName2Value.putAll(tmp);
-    }
-
-    return fieldName2Value;
-  }
-
-  public void setValueForAnnotatedField(Object instance, Class<? extends Annotation> annotation, Object value) 
-      throws ODataAnnotationException {
-    List<Field> fields = getAnnotatedFields(instance, annotation);
-
-    if(fields.isEmpty()) {
-      throw new ODataAnnotationException("No field found for annotation '" + annotation
-          + "' on instance '" + instance + "'.");
-    } else if(fields.size() > 1) {
-      throw new ODataAnnotationException("More then one field found for annotation '" + annotation
-          + "' on instance '" + instance + "'.");
-    }
-
-    setFieldValue(instance, fields.get(0), value);
-  }
-
-  public void setValuesToAnnotatedFields(Object instance,
-      Class<? extends Annotation> annotation, Map<String, Object> fieldName2Value) {
-    List<Field> fields = getAnnotatedFields(instance, annotation);
-
-    // XXX: refactore
-    for (Field field : fields) {
-      final String canonicalName = getCanonicalName(field);
-      if (fieldName2Value.containsKey(canonicalName)) {
-        Object value = fieldName2Value.get(canonicalName);
-        setFieldValue(instance, field, value);
-      }
-    }
-  }
-
-  public List<Field> getAnnotatedFields(Object instance, Class<? extends Annotation> annotation) {
-    if (instance == null) {
-      return null;
-    }
-    return getAnnotatedFields(instance.getClass(), annotation, true);
-  }
-
-  public List<Field> getAnnotatedFields(Class<?> fieldClass, Class<? extends Annotation> annotation) {
-    return getAnnotatedFields(fieldClass, annotation, true);
-  }
-
-  /**
-   *
-   * @param instance
-   * @param resultClass
-   * @param annotation
-   * @param inherited
-   * @return
-   */
-  private List<Field> getAnnotatedFields(Class<?> resultClass,
-      Class<? extends Annotation> annotation, boolean inherited) {
-    if (resultClass == null) {
-      return null;
-    }
-
-    Field[] fields = resultClass.getDeclaredFields();
-    List<Field> annotatedFields = new ArrayList<Field>();
-
-    for (Field field : fields) {
-      if (field.getAnnotation(annotation) != null) {
-        annotatedFields.add(field);
-      }
-    }
-
-    Class<?> superClass = resultClass.getSuperclass();
-    if (inherited && superClass != Object.class) {
-      List<Field> tmp = getAnnotatedFields(superClass, annotation, true);
-      annotatedFields.addAll(tmp);
-    }
-
-    return annotatedFields;
-  }
-
-  private Object getValueForField(Object instance, String fieldName, Class<?> resultClass,
-      Class<? extends Annotation> annotation, boolean inherited) {
-    if (instance == null) {
-      return null;
-    }
-
-    Field[] fields = resultClass.getDeclaredFields();
-    for (Field field : fields) {
-      if (field.getAnnotation(annotation) != null
-          && (fieldName == null || field.getName().equals(fieldName))) {
-        return getFieldValue(instance, field);
-      }
-    }
-
-    Class<?> superClass = resultClass.getSuperclass();
-    if (inherited && superClass != Object.class) {
-      return getValueForField(instance, fieldName, superClass, annotation, true);
-    }
-
-    return null;
-  }
-
-  private Object getFieldValue(Object instance, Field field) {
-    try {
-      boolean access = field.isAccessible();
-      field.setAccessible(true);
-      Object value = field.get(instance);
-      field.setAccessible(access);
-      return value;
-    } catch (IllegalArgumentException ex) { // should never happen
-      throw new ODataRuntimeException(ex);
-    } catch (IllegalAccessException ex) { // should never happen
-      throw new ODataRuntimeException(ex);
-    }
-  }
-
-  private void setFieldValue(Object instance, Field field, Object value) {
-    try {
-      Object usedValue = value;
-      if (value != null
-          && field.getType() != value.getClass()
-          && value.getClass() == String.class) {
-        usedValue = convert(field, (String) value);
-      }
-      boolean access = field.isAccessible();
-      field.setAccessible(true);
-      field.set(instance, usedValue);
-      field.setAccessible(access);
-    } catch (IllegalArgumentException ex) { // should never happen
-      throw new ODataRuntimeException(ex);
-    } catch (IllegalAccessException ex) { // should never happen
-      throw new ODataRuntimeException(ex);
-    }
-  }
-
-  public Object convert(Field field, String propertyValue) {
-    Class<?> fieldClass = field.getType();
-    try {
-      EdmProperty property = field.getAnnotation(EdmProperty.class);
-      EdmSimpleTypeKind type = mapTypeKind(property.type());
-      return type.getEdmSimpleTypeInstance().valueOfString(propertyValue,
-          EdmLiteralKind.DEFAULT, null, fieldClass);
-    } catch (EdmSimpleTypeException ex) {
-      throw new ODataRuntimeException("Conversion failed for string property with error: "
-          + ex.getMessage(), ex);
-    }
-  }
-
-  public boolean isEdmAnnotated(Object object) {
-    if (object == null) {
-      return false;
-    }
-    return isEdmAnnotated(object.getClass());
-  }
-
-  public boolean isEdmTypeAnnotated(Class<?> clazz) {
-    boolean isComplexEntity = clazz.getAnnotation(EdmComplexType.class) != null;
-    boolean isEntity = clazz.getAnnotation(EdmEntityType.class) != null;
-    return isComplexEntity || isEntity;
-  }
-
-  public boolean isEdmAnnotated(Class<?> clazz) {
-    if (clazz == null) {
-      return false;
-    } else {
-      final boolean isEntity = null != clazz.getAnnotation(EdmEntityType.class);
-      final boolean isEntitySet = null != clazz.getAnnotation(EdmEntitySet.class);
-      final boolean isComplexEntity = null != clazz.getAnnotation(EdmComplexType.class);
-      return isEntity || isComplexEntity || isEntitySet;
-    }
-  }
-
-  public String getCanonicalName(Field field) {
-    return firstCharToUpperCase(field.getName());
-  }
-
-  public String getCanonicalName(Class<?> clazz) {
-    return firstCharToUpperCase(clazz.getSimpleName());
-  }
-
-  private String firstCharToUpperCase(String content) {
-    if (content == null || content.isEmpty()) {
-      return content;
-    }
-    return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1);
-  }
-
-  public EdmSimpleTypeKind mapTypeKind(org.apache.olingo.odata2.api.annotation.edm.EdmType type) {
-    switch (type) {
-      case BINARY: return EdmSimpleTypeKind.Binary;
-      case BOOLEAN: return EdmSimpleTypeKind.Boolean;
-      case BYTE: return EdmSimpleTypeKind.Byte;
-      case COMPLEX: return EdmSimpleTypeKind.Null;
-      case DATE_TIME: return EdmSimpleTypeKind.DateTime;
-      case DATE_TIME_OFFSET: return EdmSimpleTypeKind.DateTimeOffset;
-      case DECIMAL: return EdmSimpleTypeKind.Decimal;
-      case DOUBLE: return EdmSimpleTypeKind.Double;
-      case GUID: return EdmSimpleTypeKind.Guid;
-      case INT16: return EdmSimpleTypeKind.Int16;
-      case INT32: return EdmSimpleTypeKind.Int32;
-      case INT64: return EdmSimpleTypeKind.Int64;
-      case NULL: return EdmSimpleTypeKind.Null;
-      case SBYTE: return EdmSimpleTypeKind.SByte;
-      case SINGLE: return EdmSimpleTypeKind.Single;
-      case STRING: return EdmSimpleTypeKind.String;
-      case TIME: return EdmSimpleTypeKind.Time;
-      default: throw new ODataRuntimeException("Unknown type '" + type
-        + "' for mapping to EdmSimpleTypeKind.");
-    }
-  }
-
-  public EdmMultiplicity mapMultiplicity(Multiplicity multiplicity) {
-    switch (multiplicity) {
-    case ZERO_OR_ONE: return EdmMultiplicity.ZERO_TO_ONE;
-    case ONE: return EdmMultiplicity.ONE;
-    case MANY: return EdmMultiplicity.MANY;
-    default: throw new ODataRuntimeException("Unknown type '" + multiplicity + "' for mapping to EdmMultiplicity.");
-    }
-  }
-  
-  /**
-   * 
-   */
-  private static class EdmAnnotationException extends RuntimeException {
-
-    private static final long serialVersionUID = 42L;
-
-    public EdmAnnotationException(String message) {
-      super(message);
-    }
-  }
-
-  public String getCanonicalNamespace(Class<?> aClass) {
-    return generateNamespace(aClass);
-  }
-
-  public String extractContainerName(Class<?> aClass) {
-    EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
-    if(entitySet != null) {
-      String containerName = entitySet.container();
-      if(!containerName.isEmpty()) {
-        return containerName;
-      }
-    }
-    return DEFAULT_CONTAINER_NAME;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java
deleted file mode 100644
index 2a4c706..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.edm;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FilenameFilter;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- */
-public class ClassHelper {
-  
-  private static final File[] EMPTY_FILE_ARRAY = new File[0];
-  
-  private static final FilenameFilter CLASSFILE_FILTER = new FilenameFilter() {
-    @Override
-    public boolean accept(File dir, String name) {
-      return name.endsWith(CLASSFILE_ENDING);
-    }
-    public static final String CLASSFILE_ENDING = ".class";
-  };
-  
-  private static final FileFilter FOLDER_FILTER = new FileFilter() {
-    @Override
-    public boolean accept(File pathname) {
-      return pathname.isDirectory();
-    }
-  };
-  
-  public static final List<Class<?>> loadClasses(String packageToScan, ClassValidator cv) {
-    return loadClasses(packageToScan, CLASSFILE_FILTER, cv);
-  }
-
-  
-  public static final List<Class<?>> loadClasses(String packageToScan, FilenameFilter ff, ClassValidator cv) {
-    final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-    String folderToScan = packageToScan.replace(".", "/");
-    URL url = classLoader.getResource(folderToScan);
-    if(url == null) {
-      throw new IllegalArgumentException("No folder to scan found for package '" + packageToScan + "'.");
-    }
-    File folder = new File(url.getFile());
-    File[] classFiles = folder.listFiles(ff);
-    if(classFiles == null) {
-      classFiles = EMPTY_FILE_ARRAY;
-    }
-
-    List<Class<?>> annotatedClasses = new ArrayList<Class<?>>(classFiles.length);
-    for (File file : classFiles) {
-      String name = file.getName();
-      String fqn = packageToScan + "." + name.substring(0, name.length() - 6);
-      try {
-        Class<?> c = classLoader.loadClass(fqn);
-        if (cv.isClassValid(c)) {
-          annotatedClasses.add(c);
-        }
-      } catch (ClassNotFoundException ex) {
-        throw new IllegalArgumentException("Exception during class loading of class '" + fqn + 
-                "' with message '" + ex.getMessage() + "'.");
-      }
-    }
-    
-    // recursive search
-    File[] subfolders = listSubFolder(folder);
-    for (File file : subfolders) {
-      List<Class<?>> subFolderClazzes = loadClasses(packageToScan + "." + file.getName(), ff, cv);
-      annotatedClasses.addAll(subFolderClazzes);
-    }
-    //
-    
-    return annotatedClasses;
-  }
-
-  private static File[] listSubFolder(File folder) {
-    File[] subfolders = folder.listFiles(FOLDER_FILTER);
-    if(subfolders == null) {
-      return EMPTY_FILE_ARRAY;
-    }
-    return subfolders;
-  }
-  
-  public interface ClassValidator {
-    boolean isClassValid(Class<?> c);
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
deleted file mode 100644
index b1b8730..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.processor;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Field;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDataSource;
-import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.api.processor.ODataResponse;
-import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
-import org.apache.olingo.odata2.api.uri.KeyPredicate;
-import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetMediaResourceUriInfo;
-import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
-import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
-import org.apache.olingo.odata2.core.annotation.data.DataSourceHolder;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
-import org.apache.olingo.odata2.core.annotation.edm.ClassHelper;
-import org.apache.olingo.odata2.core.annotation.processor.json.EdmAnnotationSerializer;
-import org.apache.olingo.odata2.core.annotation.processor.json.JsonConsumer;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-/**
- *
- */
-public class AnnotationProcessor extends ODataSingleProcessor {
-
-  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
-
-  private final Map<String, DataSourceHolder> dataSources = new HashMap<String, DataSourceHolder>();
-  private ODataContext odataContext;
-
-  public AnnotationProcessor(ODataContext context, String packageToScan) {
-    odataContext = context;
-
-    List<Class<?>> foundClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
-      @Override
-      public boolean isClassValid(Class<?> c) {
-        return null != c.getAnnotation(EntityDataSource.class);
-      }
-    });
-
-    init(foundClasses);
-  }
-
-  private void init(List<Class<?>> foundClasses) {
-    for (Class<?> clz : foundClasses) {
-      DataSourceHolder dhs = new DataSourceHolder(clz);
-      dataSources.put(dhs.getEntityName(), dhs);
-    }
-  }
-
-  @Override
-  public ODataResponse readEntity(GetEntityUriInfo uriInfo, String contentType) throws ODataException {
-    final String name = uriInfo.getTargetType().getName();
-
-    List<KeyPredicate> keys = uriInfo.getKeyPredicates();
-    DataSourceHolder holder = dataSources.get(name);
-    if (holder != null) {
-      Object result = holder.readEntity(keys);
-      if (result != null) {
-        return createODataResponse(result, HttpStatusCodes.OK);
-      }
-    }
-
-    return ODataResponse.status(HttpStatusCodes.NOT_FOUND).build();
-  }
-
-  @Override
-  public ODataResponse readEntitySet(GetEntitySetUriInfo uriInfo, String contentType) throws ODataException {
-    final String name = uriInfo.getTargetType().getName();
-
-    DataSourceHolder holder = dataSources.get(name);
-    if (holder != null) {
-      Object result = holder.readEntitySet();
-      if (result != null) {
-        return createODataResponse(result, HttpStatusCodes.OK);
-      }
-    }
-
-    return ODataResponse.status(HttpStatusCodes.NOT_FOUND).build();
-  }
-
-  @Override
-  public ODataResponse createEntity(PostUriInfo uriInfo, InputStream content,
-          String requestContentType, String contentType) throws ODataException {
-    final String name = uriInfo.getTargetType().getName();
-
-    DataSourceHolder dataSource = dataSources.get(name);
-    if (dataSource != null) {
-      Object instance = createInstanceFromContent(dataSource, content);
-
-      Object result = dataSource.createEntity(instance);
-      return createODataResponse(result, HttpStatusCodes.CREATED);
-    }
-
-    return ODataResponse.status(HttpStatusCodes.BAD_REQUEST).build();
-  }
-
-  @Override
-  public ODataResponse deleteEntity(DeleteUriInfo uriInfo, String contentType) throws ODataException {
-    final String name = uriInfo.getTargetType().getName();
-
-    DataSourceHolder holder = dataSources.get(name);
-    if (holder != null) {
-      List<KeyPredicate> keys = uriInfo.getKeyPredicates();
-      Object result = holder.deleteEntity(keys);
-      if (result != null) {
-        return ODataResponse.status(HttpStatusCodes.NO_CONTENT).build();
-      }
-    }
-
-    return ODataResponse.status(HttpStatusCodes.NOT_FOUND).build();
-  }
-
-  @Override
-  public ODataResponse readEntityMedia(GetMediaResourceUriInfo uriInfo, String contentType) throws ODataException {
-    final String name = uriInfo.getTargetType().getName();
-
-    List<KeyPredicate> keys = uriInfo.getKeyPredicates();
-    Object result = readEntity(name, keys);
-    if (result != null) {
-      Object content = new AnnotationHelper().getValueForField(result, EdmMediaResourceContent.class);
-      Object mimeType = new AnnotationHelper().getValueForField(result, EdmMediaResourceMimeType.class);
-    return ODataResponse.status(HttpStatusCodes.OK).entity(content).contentHeader(String.valueOf(mimeType)).build();
-    }
-
-    return ODataResponse.status(HttpStatusCodes.NOT_FOUND).build();
-  }
-  
-  private Object readEntity(String entityName, List<KeyPredicate> keys) {
-    DataSourceHolder holder = dataSources.get(entityName);
-    if (holder != null) {
-      return holder.readEntity(keys);
-    }
-    return null;
-  }
-  
-  
-  private ODataResponse createODataResponse(Object result, HttpStatusCodes statusCode) throws ODataException {
-//    StringBuilder resultAsString = new StringBuilder("{\"d\":");
-//    if (result != null) {
-//      resultAsString.append(result.toString());
-//    } else {
-//      resultAsString.append("NULL");
-//    }
-//    resultAsString.append("}");
-    EdmAnnotationSerializer jsonSerializer = 
-            new EdmAnnotationSerializer(odataContext.getPathInfo().getServiceRoot().toASCIIString());
-    InputStream resultAsString = jsonSerializer.serialize(result);
-    return ODataResponse.status(statusCode)
-            .contentHeader("application/json")
-            .entity(resultAsString).build();
-  }
-
-  private Object createInstanceFromContent(DataSourceHolder dataSource, InputStream content) 
-          throws ODataException {
-    try {
-      Object instance = dataSource.createEntityInstance();
-      Map<String, FieldHolder> propName2Field = extractPropertyFields(dataSource.getEntityTypeClass());
-      Map<String, String> contentAsMap = JsonConsumer.readContent(content);
-      Set<Map.Entry<String, String>> contentEntries = contentAsMap.entrySet();
-      for (Map.Entry<String, String> entry : contentEntries) {
-        FieldHolder fh = propName2Field.get(entry.getKey());
-        if (fh != null) {
-          fh.set(instance, entry.getValue());
-        }
-      }
-      return instance;      
-    } catch (IOException e) {
-      throw new ODataRuntimeException("Unexpected IOException with message: " + e.getMessage());
-    }
-  }
-
-  @Override
-  public ODataResponse updateEntity(PutMergePatchUriInfo uriInfo, InputStream content, 
-          String requestContentType, boolean merge, String contentType) throws ODataException {
-    final String name = uriInfo.getTargetType().getName();
-
-    DataSourceHolder dataSource = dataSources.get(name);
-    if (dataSource != null) {
-      Object instance = createInstanceFromContent(dataSource, content);
-
-      Object result = dataSource.updateEntity(instance);
-      return createODataResponse(result, HttpStatusCodes.OK);
-    }
-
-    return ODataResponse.status(HttpStatusCodes.BAD_REQUEST).build();
-  }
-
-  private Map<String, FieldHolder> extractPropertyFields(Class<?> typeClass) {
-    if (typeClass == null) {
-      return Collections.emptyMap();
-    }
-    EdmEntityType type = typeClass.getAnnotation(EdmEntityType.class);
-    if (type == null) {
-      return Collections.emptyMap();
-    }
-
-    //
-    Map<String, FieldHolder> name2Fields = new HashMap<String, FieldHolder>();
-    Field[] fields = typeClass.getDeclaredFields();
-    for (Field field : fields) {
-      FieldHolder fh = FieldHolder.create(field);
-      name2Fields.put(fh.propertyName, fh);
-    }
-
-    //
-    Class<?> superClass = typeClass.getSuperclass();
-    if (superClass != null && superClass.getAnnotation(EdmEntityType.class) != null) {
-      name2Fields.putAll(extractPropertyFields(superClass));
-    }
-    //
-
-    return name2Fields;
-  }
-
-  /**
-   *
-   */
-  static final class FieldHolder {
-
-    final String propertyName;
-    final Field propertyField;
-
-    public FieldHolder(String propertyName, Field propertyField) {
-      this.propertyName = propertyName;
-      this.propertyField = propertyField;
-    }
-
-    public static FieldHolder create(Field field) {
-      EdmProperty ep = field.getAnnotation(EdmProperty.class);
-      String name;
-      if (ep != null && !ep.name().isEmpty()) {
-        name = ep.name();
-      } else {
-        name = ANNOTATION_HELPER.getCanonicalName(field);
-      }
-      return new FieldHolder(name, field);
-    }
-
-    public void set(Object instance, Object value) {
-      set(instance, String.valueOf(value));
-    }
-
-    public void set(Object instance, String value) {
-      try {
-        boolean accessible = propertyField.isAccessible();
-        if (!accessible) {
-          propertyField.setAccessible(true);
-        }
-
-        //
-        Class<?> type = propertyField.getType();
-        if (type == Boolean.class || type == boolean.class) {
-          propertyField.set(instance, Boolean.valueOf(value));
-        } else if (type == Integer.class || type == int.class) {
-          propertyField.set(instance, Integer.valueOf(value));
-        } else if (type == Long.class || type == long.class) {
-          propertyField.set(instance, Integer.valueOf(value));
-        } else {
-          propertyField.set(instance, value);
-        }
-        //
-
-        if (!accessible) {
-          propertyField.setAccessible(false);
-        }
-      } catch (Exception ex) {
-      }
-    }
-
-    @Override
-    public String toString() {
-      return "FieldHolder{" + "propertyName=" + propertyName + ", propertyField=" + propertyField + '}';
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/EdmAnnotationSerializer.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/EdmAnnotationSerializer.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/EdmAnnotationSerializer.java
deleted file mode 100644
index 7ae9971..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/EdmAnnotationSerializer.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/**
- * *****************************************************************************
- * 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.odata2.core.annotation.processor.json;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-public class EdmAnnotationSerializer {
-
-  private final String baseUri;
-  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
-
-  public EdmAnnotationSerializer(String baseUri) {
-    this.baseUri = baseUri;
-  }
-
-  public InputStream serialize(Object obj) {
-    byte[] buf = getContent(obj).getBytes();
-    InputStream stream = new ByteArrayInputStream(buf);
-    return stream;
-  }
-
-  private String getContent(Object entity) {
-    if (entity == null) {
-      return "NULL";
-    } else if (isConsumable(entity)) {
-      try {
-        return handleEdmAnnotations(entity);
-      } catch (Exception e) {
-        throw new ODataRuntimeException("Exception with following message occured: " + e.getMessage(), e);
-      }
-    } else {
-      return entity.toString();
-    }
-  }
-
-  private String handleEdmAnnotations(Object entity)
-          throws IllegalArgumentException, IllegalAccessException, IOException {
-    //
-    Writer writer = new StringWriter();
-    JsonWriter json = new JsonWriter(writer);
-    json.start();
-    writeObject(entity, json);
-    json.finish();
-    writer.close();
-    //
-    return writer.toString();
-  }
-
-  private void writeObject(Object entity, JsonWriter json) throws IllegalAccessException {
-    if (entity.getClass().isArray()) {
-      List<Object> entities = Arrays.asList(entity);
-      writeCollection(entities, json);
-    } else if (Collection.class.isAssignableFrom(entity.getClass())) {
-      Collection<Object> entities = (Collection<Object>) entity;
-      writeCollection(entities, json);
-    } else {
-      writeSingleObject(entity, json);
-    }
-  }
-
-  private void writeCollection(Collection<Object> entities, JsonWriter json) throws IllegalAccessException {
-    json.startObject();
-    json.writeName("results");
-    json.startArray();
-    boolean writeSeperator = false;
-    for (Object object : entities) {
-      if (writeSeperator) {
-        json.writeSeparator();
-      } else {
-        writeSeperator = true;
-      }
-      writeSingleObject(object, json);
-    }
-    json.endArray();
-    json.endObject();
-  }
-
-  private void writeSingleObject(Object entity, JsonWriter json) throws IllegalAccessException {
-    List<Field> fields = getAllFields(entity.getClass());
-    json.startObject();
-    for (Field field : fields) {
-      boolean written = writeEdmProperty(entity, json, field);
-      if (!written) {
-        writeEdmNavigationProperty(entity, json, field);
-      }
-    }
-    json.endObject();
-  }
-
-  private boolean writeEdmNavigationProperty(Object entity, JsonWriter json, Field field)
-          throws IllegalArgumentException, IllegalAccessException {
-    EdmNavigationProperty navProperty = field.getAnnotation(EdmNavigationProperty.class);
-    EdmEntitySet entitySet = entity.getClass().getAnnotation(EdmEntitySet.class);
-    if (navProperty != null) {
-      field.setAccessible(true);
-      Object keyValue = extractEdmKey(entity);
-      json.writeStringProperty("uri", baseUri + entitySet.name() + "('" + keyValue.toString() + "')"
-              + "/" + navProperty.association());
-      return true;
-    }
-    return false;
-  }
-
-  private boolean writeEdmProperty(Object entity, JsonWriter json, Field field) throws IllegalAccessException {
-    EdmProperty property = field.getAnnotation(EdmProperty.class);
-    if (property != null) {
-      field.setAccessible(true);
-      Object fieldValue = field.get(entity);
-      String name = getName(property, field);
-      EdmSimpleTypeKind defaultType = getDefaultSimpleTypeKind(field, property);
-      try {
-        String value = defaultType.getEdmSimpleTypeInstance().valueToString(fieldValue, EdmLiteralKind.JSON, null);
-        write(defaultType, name, value, json);
-      } catch (EdmSimpleTypeException e) {
-        throw new IllegalArgumentException("Illegal argument for valueToString for EdmSimpleType = '"
-                + property.type() + "' with message = '" + e.getMessage() + "'.");
-      }
-      return true;
-    }
-    return false;
-  }
-
-  public void write(EdmSimpleTypeKind kind, String name, String value, JsonWriter jsonStreamWriter) {
-    switch (kind) {
-      case String:
-        jsonStreamWriter.writeStringProperty(name, value);
-        break;
-      case Boolean:
-      case Byte:
-      case SByte:
-      case Int16:
-      case Int32:
-        jsonStreamWriter.writeRawProperty(name, value);
-        break;
-      case DateTime:
-      case DateTimeOffset:
-        // Although JSON escaping is (and should be) done in the JSON
-        // serializer, we backslash-escape the forward slash here explicitly
-        // because it is not required to escape it in JSON but in OData.
-        jsonStreamWriter.writeRawStringProperty(name, value == null ? null : value.replace("/", "\\/"));
-        break;
-      default:
-        jsonStreamWriter.writeRawStringProperty(name, value);
-        break;
-    }
-  }
-
-  private EdmSimpleTypeKind getDefaultSimpleTypeKind(Field field, EdmProperty property) {
-    final EdmType type = property.type();
-    if (type == EdmType.NULL) {
-      Class<?> fieldType = field.getType();
-      if (fieldType == String.class) {
-        return EdmSimpleTypeKind.String;
-      } else if (fieldType == Long.class) {
-        return EdmSimpleTypeKind.Int64;
-      } else if (fieldType == Integer.class) {
-        return EdmSimpleTypeKind.Int32;
-      }
-    }
-    return ANNOTATION_HELPER.mapTypeKind(type);
-  }
-
-  private Class<?> getType(EdmProperty property) {
-    EdmSimpleTypeKind type = ANNOTATION_HELPER.mapTypeKind(property.type());
-    Class<?> defaultType = type.getEdmSimpleTypeInstance().getDefaultType();
-    return defaultType;
-  }
-
-  private Object extractEdmKey(Object value) throws IllegalArgumentException, IllegalAccessException {
-    Field idField = getFieldWithAnnotation(value.getClass(), EdmKey.class);
-    if (idField == null) {
-      return "NULL";
-    }
-    idField.setAccessible(true);
-    return idField.get(value);
-  }
-
-  private Field getFieldWithAnnotation(Class<?> clazz, Class<? extends Annotation> annotationClazz) {
-
-    Field[] fields = clazz.getDeclaredFields();
-    for (Field field : fields) {
-      if (field.getAnnotation(annotationClazz) != null) {
-        return field;
-      }
-    }
-
-    Class<?> superclass = clazz.getSuperclass();
-    if (superclass != Object.class) {
-      return getFieldWithAnnotation(superclass, annotationClazz);
-    }
-
-    return null;
-  }
-
-  private List<Field> getAllFields(Class<?> clazz) {
-    Field[] fields = clazz.getDeclaredFields();
-    List<Field> allFields = new ArrayList<Field>(Arrays.asList(fields));
-
-    final Class<?> superclass = clazz.getSuperclass();
-    if (superclass != Object.class) {
-      allFields.addAll(getAllFields(superclass));
-    }
-
-    return allFields;
-  }
-
-  private boolean isConsumable(Object entity) {
-    if (entity == null) {
-      return false;
-    } else if (ANNOTATION_HELPER.isEdmAnnotated(entity)) {
-      return true;
-    } else if (entity.getClass().isArray() || entity.getClass().isAssignableFrom(Collection.class)) {
-      return true;
-    } else if (Collection.class.isAssignableFrom(entity.getClass())) {
-      return true;
-    }
-    return false;
-  }
-
-  private String getName(EdmProperty property, Field field) {
-    String name = property.name();
-    if (name.isEmpty()) {
-      name = ANNOTATION_HELPER.getCanonicalName(field);
-    }
-    return name;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/8764e11a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumer.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumer.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumer.java
deleted file mode 100644
index 265484d..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumer.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.processor.json;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.olingo.odata2.core.ep.util.FormatJson;
-
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-
-/**
- *
- */
-public class JsonConsumer {
-
-  private final JsonReader reader;
-  private final Map<String, String> properties;
-
-  public JsonConsumer(InputStream content) {
-    reader = new JsonReader(new InputStreamReader(content));
-    properties = new HashMap<String, String>();
-  }
-
-  public static Map<String, String> readContent(InputStream content) throws IOException {
-    JsonConsumer jc = new JsonConsumer(content);
-    return jc.read();
-  }
-
-  public Map<String, String> read() throws IOException {
-
-    reader.beginObject();
-    String nextName = reader.nextName();
-    if (FormatJson.D.equals(nextName)) {
-      reader.beginObject();
-      readEntryContent();
-      reader.endObject();
-    } else {
-      handleName(nextName);
-      readEntryContent();
-    }
-    reader.endObject();
-
-    return properties;
-  }
-
-  private void readEntryContent() throws IOException {
-    while (reader.hasNext()) {
-      final String name = reader.nextName();
-      handleName(name);
-    }
-  }
-
-  private void handleName(final String name) throws IOException {
-    if (FormatJson.METADATA.equals(name)) {
-      readMetadata();
-    } else {
-      readPropertyValue(name);
-    }
-  }
-
-  private void readPropertyValue(final String name) throws IOException {
-    final JsonToken tokenType = reader.peek();
-    final String value;
-
-    switch (tokenType) {
-      case STRING:
-        value = reader.nextString();
-        break;
-      case BOOLEAN:
-        value = String.valueOf(reader.nextBoolean());
-        break;
-      case NULL:
-        reader.nextNull();
-      default:
-        value = null;
-    }
-
-    properties.put(name, value);
-  }
-
-  private void readMetadata() throws IOException {
-    reader.beginObject();
-
-    while (reader.hasNext()) {
-      String name = reader.nextName();
-
-      if (FormatJson.PROPERTIES.equals(name)) {
-        reader.skipValue();
-        continue;
-      }
-
-      String value = reader.nextString();
-      if (FormatJson.ID.equals(name)) {
-        properties.put("md_" + name, value);
-      } else if (FormatJson.URI.equals(name)) {
-        properties.put("md_" + name, value);
-      } else if (FormatJson.TYPE.equals(name)) {
-        properties.put("md_" + name, value);
-      } else if (FormatJson.ETAG.equals(name)) {
-        properties.put("md_" + name, value);
-      } else if (FormatJson.EDIT_MEDIA.equals(name)) {
-        properties.put("md_" + name, value);
-      } else if (FormatJson.MEDIA_SRC.equals(name)) {
-        properties.put("md_" + name, value);
-      } else if (FormatJson.MEDIA_ETAG.equals(name)) {
-        properties.put("md_" + name, value);
-      } else if (FormatJson.CONTENT_TYPE.equals(name)) {
-        properties.put("md_" + name, value);
-      } else {
-        throw new IllegalStateException("Unknown metadata");
-      }
-    }
-
-    reader.endObject();
-  }
-
-}


[09/12] Renamed project

Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
new file mode 100644
index 0000000..0c81fb1
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
@@ -0,0 +1,726 @@
+/**
+ * *****************************************************************************
+ * 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.odata2.core.annotation.util;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+/**
+ *
+ */
+public class AnnotationHelper {
+
+  public static final String DEFAULT_CONTAINER_NAME = "DefaultContainer";
+
+  /**
+   * Compare keys of both instances.
+   * 
+   * @param firstInstance
+   * @param secondInstance
+   * @return 
+   */
+  public boolean keyMatch(Object firstInstance, Object secondInstance) {
+    if (firstInstance == null || secondInstance == null) {
+      return false;
+    } else if (firstInstance.getClass() != secondInstance.getClass()) {
+      return false;
+    }
+
+    Map<String, Object> firstKeyFields = getValueForAnnotatedFields(firstInstance, EdmKey.class);
+    Map<String, Object> secondKeyFields = getValueForAnnotatedFields(secondInstance, EdmKey.class);
+
+    return keyValuesMatch(firstKeyFields, secondKeyFields);
+  }
+
+  /**
+   * Compare keys of instance with key values in map.
+   * 
+   * @param instance
+   * @param keyName2Value
+   * @return 
+   */
+  public boolean keyMatch(Object instance, Map<String, Object> keyName2Value) {
+    Map<String, Object> instanceKeyFields = getValueForAnnotatedFields(instance, EdmKey.class);
+    return keyValuesMatch(instanceKeyFields, keyName2Value);
+  }
+
+  private boolean keyValuesMatch(Map<String, Object> firstKeyValues, Map<String, Object> secondKeyValues) {
+    if (firstKeyValues.size() != secondKeyValues.size()) {
+      return false;
+    } else {
+      Set<Map.Entry<String, Object>> entries = firstKeyValues.entrySet();
+      for (Map.Entry<String, Object> entry : entries) {
+        Object firstKey = entry.getValue();
+        Object secondKey = secondKeyValues.get(entry.getKey());
+        if (!isEqual(firstKey, secondKey)) {
+          return false;
+        }
+      }
+      return true;
+    }
+  }
+  
+  private boolean isEqual(Object firstKey, Object secondKey) {
+    if (firstKey == null) {
+      if (secondKey == null) {
+        return true;
+      } else {
+        return secondKey.equals(firstKey);
+      }
+    } else {
+      return firstKey.equals(secondKey);
+    }
+  }
+
+  public String extractEntitTypeName(EdmNavigationProperty enp, Class<?> fallbackClass) {
+    Class<?> entityTypeClass = enp.toType();
+    return extractEntityTypeName(entityTypeClass == Object.class ? fallbackClass : entityTypeClass);
+  }
+
+  public String extractEntitTypeName(EdmNavigationProperty enp, Field field) {
+    Class<?> entityTypeClass = enp.toType();
+    if (entityTypeClass == Object.class) {
+      Class<?> toClass = field.getType();
+      return extractEntityTypeName((toClass.isArray() || Collection.class.isAssignableFrom(toClass) ?
+          (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0] : toClass));
+    } else {
+      return extractEntityTypeName(entityTypeClass);
+    }
+  }
+
+  /**
+   * Returns <code>NULL</code> if given class is not annotated. If annotated the set entity type name is returned and if
+   * no name is set the default name is generated from the simple class name.
+   *
+   * @param annotatedClass
+   * @return
+   */
+  public String extractEntityTypeName(Class<?> annotatedClass) {
+    return extractTypeName(annotatedClass, EdmEntityType.class);
+  }
+
+  public FullQualifiedName extractEntityTypeFqn(EdmEntityType type, Class<?> annotatedClass) {
+    if(type.namespace().isEmpty()) {
+      return new FullQualifiedName(generateNamespace(annotatedClass), extractEntityTypeName(annotatedClass));
+    }
+    return new FullQualifiedName(type.namespace(), extractEntityTypeName(annotatedClass));
+  }
+  
+  public FullQualifiedName extractEntityTypeFqn(Class<?> annotatedClass) {
+    EdmEntityType type = annotatedClass.getAnnotation(EdmEntityType.class);
+    if(type == null) {
+      return null;
+    }
+    return extractEntityTypeFqn(type, annotatedClass);
+  }
+
+  public FullQualifiedName extractComplexTypeFqn(Class<?> annotatedClass) {
+    EdmComplexType type = annotatedClass.getAnnotation(EdmComplexType.class);
+    if(type == null) {
+      return null;
+    }
+    return extractComplexTypeFqn(type, annotatedClass);
+  }
+
+  public FullQualifiedName extractComplexTypeFqn(EdmComplexType type, Class<?> annotatedClass) {
+    if(type.namespace().isEmpty()) {
+      return new FullQualifiedName(generateNamespace(annotatedClass), extractComplexTypeName(annotatedClass));
+    }
+    return new FullQualifiedName(type.namespace(), extractComplexTypeName(annotatedClass));
+  }
+
+  public String extractComplexTypeName(Class<?> annotatedClass) {
+    return extractTypeName(annotatedClass, EdmComplexType.class);
+  }
+  
+  public String generateNamespace(Class<?> annotatedClass) {
+    String packageName = annotatedClass.getPackage().getName();
+    return packageName;
+  }
+
+  /**
+   *
+   *
+   * @param <T> must be EdmEntityType or EdmComplexType annotation
+   * @param annotatedClass
+   * @param typeAnnotation
+   * @return null if annotatedClass is not annotated or name set via annotation or generated via
+   * {@link #getCanonicalName(java.lang.Class)}
+   */
+  private <T extends Annotation> String extractTypeName(Class<?> annotatedClass, Class<T> typeAnnotation) {
+    if (annotatedClass == Object.class) {
+      return null;
+    }
+    T type = annotatedClass.getAnnotation(typeAnnotation);
+    if (type == null) {
+      return null;
+    }
+
+    String name;
+    if (typeAnnotation == EdmEntityType.class) {
+      name = ((EdmEntityType) type).name();
+    } else if (typeAnnotation == EdmComplexType.class) {
+      name = ((EdmComplexType) type).name();
+    } else {
+      return null;
+    }
+
+    if (name.isEmpty()) {
+      return getCanonicalName(annotatedClass);
+    }
+    return name;
+  }
+
+  /**
+   * Get the set property name from an EdmProperty or EdmNavigationProperty annotation.
+   *
+   * @param field
+   * @return
+   */
+  public String getPropertyNameFromAnnotation(Field field) {
+    EdmProperty property = field.getAnnotation(EdmProperty.class);
+    if (property == null) {
+      EdmNavigationProperty navProperty = field.getAnnotation(EdmNavigationProperty.class);
+      if (navProperty == null) {
+        throw new EdmAnnotationException("Given field '" + field
+            + "' has no EdmProperty or EdmNavigationProperty annotation.");
+      }
+      return navProperty.name();
+    }
+    return property.name();
+  }
+
+  public String getPropertyName(Field field) {
+    String propertyName = getPropertyNameFromAnnotation(field);
+    if (propertyName.isEmpty()) {
+      propertyName = getCanonicalName(field);
+    }
+    return propertyName;
+  }
+
+  public String extractFromRoleName(EdmNavigationProperty enp, Field field) {
+    return getCanonicalRole(field.getDeclaringClass());
+  }
+
+  public String extractToRoleName(EdmNavigationProperty enp, Field field) {
+    String role = enp.toRole();
+    if (role.isEmpty()) {
+      role = getCanonicalRole(
+          field.getType().isArray() || Collection.class.isAssignableFrom(field.getType()) ?
+              (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0] : field.getType());
+    }
+    return role;
+  }
+
+  public String getCanonicalRole(Class<?> fallbackClass) {
+    String toRole = extractEntityTypeName(fallbackClass);
+    return "r_" + toRole;
+  }
+
+  public String extractRelationshipName(EdmNavigationProperty enp, Field field) {
+    String relationshipName = enp.association();
+    if (relationshipName.isEmpty()) {
+      final String fromRole = extractFromRoleName(enp, field);
+      final String toRole = extractToRoleName(enp, field);
+      if (fromRole.compareTo(toRole) > 0) {
+        relationshipName = toRole + "-" + fromRole;
+      } else {
+        relationshipName = fromRole + "-" + toRole;
+      }
+    }
+    return relationshipName;
+  }
+
+  public EdmMultiplicity getMultiplicity(EdmNavigationProperty enp, Field field) {
+    EdmMultiplicity multiplicity = mapMultiplicity(enp.toMultiplicity());
+    final boolean isCollectionType = field.getType().isArray() || Collection.class.isAssignableFrom(field.getType());
+
+    if (multiplicity == EdmMultiplicity.ONE && isCollectionType) {
+      return EdmMultiplicity.MANY;
+    }
+    return multiplicity;
+  }
+
+
+  /**
+   * Set key fields based on values in map.
+   * If an key field is not available or <code>NULL</code> in the map 
+   * it will be not set as <code>NULL</code> at the instance object.
+   * 
+   * @param instance
+   * @param keys
+   * @return
+   */
+  public <T> T setKeyFields(T instance, Map<String, Object> keys) {
+    List<Field> fields = getAnnotatedFields(instance, EdmKey.class);
+
+    for (Field field : fields) {
+      String propertyName = getPropertyName(field);
+      Object keyValue = keys.get(propertyName);
+      setValueForProperty(instance, propertyName, keyValue);
+    }
+
+    return instance;
+  }
+
+  public static final class ODataAnnotationException extends ODataException {
+    private static final long serialVersionUID = 1L;
+
+    public ODataAnnotationException(String message) {
+      super(message);
+    }
+  }
+
+  
+  public class AnnotatedNavInfo {
+    private final Field fromField;
+    private final Field toField;
+    private final EdmNavigationProperty fromNavigation;
+    private final EdmNavigationProperty toNavigation;
+
+    public AnnotatedNavInfo(Field fromField, Field toField, EdmNavigationProperty fromNavigation,
+        EdmNavigationProperty toNavigation) {
+      this.fromField = fromField;
+      this.toField = toField;
+      this.fromNavigation = fromNavigation;
+      this.toNavigation = toNavigation;
+    }
+
+    public Field getFromField() {
+      return fromField;
+    }
+
+    public Field getToField() {
+      return toField;
+    }
+
+    public EdmMultiplicity getFromMultiplicity() {
+      return getMultiplicity(toNavigation, toField);
+    }
+
+    public EdmMultiplicity getToMultiplicity() {
+      return getMultiplicity(fromNavigation, fromField);
+    }
+    
+    public boolean isBiDirectional() {
+      return toNavigation != null;
+    }
+  }
+
+  public AnnotatedNavInfo getCommonNavigationInfo(Class<?> sourceClass, Class<?> targetClass) {
+    List<Field> sourceFields = getAnnotatedFields(sourceClass, EdmNavigationProperty.class);
+    List<Field> targetFields = getAnnotatedFields(targetClass, EdmNavigationProperty.class);
+
+    // first try via association name to get full navigation information
+    for (Field sourceField : sourceFields) {
+      final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
+      final String sourceAssociation = extractRelationshipName(sourceNav, sourceField);
+      for (Field targetField : targetFields) {
+        final EdmNavigationProperty targetNav = targetField.getAnnotation(EdmNavigationProperty.class);
+        final String targetAssociation = extractRelationshipName(targetNav, targetField);
+        if (sourceAssociation.equals(targetAssociation)) {
+          return new AnnotatedNavInfo(sourceField, targetField, sourceNav, targetNav);
+        }
+      }
+    }
+    
+    // if nothing was found assume none bi-directinal navigation
+    String targetEntityTypeName = extractEntityTypeName(targetClass);
+    for (Field sourceField : sourceFields) {
+      final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
+      final String navTargetEntityName = extractEntitTypeName(sourceNav, sourceField);
+      
+      if (navTargetEntityName.equals(targetEntityTypeName)) {
+        return new AnnotatedNavInfo(sourceField, null, sourceNav, null);
+      }
+    }
+    
+    return null;
+  }
+
+  public Class<?> getFieldTypeForProperty(Object instance, String propertyName) throws ODataAnnotationException {
+    if (instance == null) {
+      return null;
+    }
+
+    Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
+    if (field == null) {
+      throw new ODataAnnotationException("No field for property '" + propertyName
+          + "' found at class '" + instance.getClass() + "'.");
+    }
+    return field.getType();
+  }
+
+  public Object getValueForProperty(Object instance, String propertyName) throws ODataAnnotationException {
+    if (instance == null) {
+      return null;
+    }
+
+    Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
+    if (field == null) {
+      throw new ODataAnnotationException("No field for property '" + propertyName
+          + "' found at class '" + instance.getClass() + "'.");
+    }
+    return getFieldValue(instance, field);
+  }
+
+  public void setValueForProperty(Object instance, String propertyName, Object propertyValue) {
+    if (instance != null) {
+      Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
+      if (field != null) {
+        setFieldValue(instance, field, propertyValue);
+      }
+    }
+  }
+
+  private Field getFieldForPropertyName(Object instance, String propertyName,
+      Class<?> resultClass, boolean inherited) {
+    if (instance == null) {
+      return null;
+    }
+
+    Field[] fields = resultClass.getDeclaredFields();
+    for (Field field : fields) {
+      EdmProperty property = field.getAnnotation(EdmProperty.class);
+      if (property != null) {
+        if (property.name().isEmpty() && getCanonicalName(field).equals(propertyName)) {
+          return field;
+        } else if (property.name().equals(propertyName)) {
+          return field;
+        }
+      }
+    }
+
+    Class<?> superClass = resultClass.getSuperclass();
+    if (inherited && superClass != Object.class) {
+      return getFieldForPropertyName(instance, propertyName, superClass, true);
+    }
+
+    return null;
+  }
+
+  public Object getValueForField(Object instance, String fieldName, Class<? extends Annotation> annotation) {
+    if (instance == null) {
+      return null;
+    }
+    return getValueForField(instance, fieldName, instance.getClass(), annotation, true);
+  }
+
+  public Object getValueForField(Object instance, Class<? extends Annotation> annotation) {
+    if (instance == null) {
+      return null;
+    }
+    return getValueForField(instance, instance.getClass(), annotation, true);
+  }
+
+  private Object getValueForField(Object instance, Class<?> resultClass,
+      Class<? extends Annotation> annotation, boolean inherited) {
+    return getValueForField(instance, null, resultClass, annotation, inherited);
+  }
+
+  public Map<String, Object> getValueForAnnotatedFields(Object instance,
+      Class<? extends Annotation> annotation) {
+    return getValueForAnnotatedFields(instance, instance.getClass(), annotation, true);
+  }
+
+  private Map<String, Object> getValueForAnnotatedFields(Object instance, Class<?> resultClass,
+      Class<? extends Annotation> annotation, boolean inherited) {
+    if (instance == null) {
+      return null;
+    }
+
+    Field[] fields = resultClass.getDeclaredFields();
+    Map<String, Object> fieldName2Value = new HashMap<String, Object>();
+
+    for (Field field : fields) {
+      if (field.getAnnotation(annotation) != null) {
+        Object value = getFieldValue(instance, field);
+        final EdmProperty property = field.getAnnotation(EdmProperty.class);
+        final String name = property == null || property.name().isEmpty() ? field.getName() : property.name();
+        fieldName2Value.put(name, value);
+      }
+    }
+
+    Class<?> superClass = resultClass.getSuperclass();
+    if (inherited && superClass != Object.class) {
+      Map<String, Object> tmp = getValueForAnnotatedFields(instance, superClass, annotation, true);
+      fieldName2Value.putAll(tmp);
+    }
+
+    return fieldName2Value;
+  }
+
+  public void setValueForAnnotatedField(Object instance, Class<? extends Annotation> annotation, Object value) 
+      throws ODataAnnotationException {
+    List<Field> fields = getAnnotatedFields(instance, annotation);
+
+    if(fields.isEmpty()) {
+      throw new ODataAnnotationException("No field found for annotation '" + annotation
+          + "' on instance '" + instance + "'.");
+    } else if(fields.size() > 1) {
+      throw new ODataAnnotationException("More then one field found for annotation '" + annotation
+          + "' on instance '" + instance + "'.");
+    }
+
+    setFieldValue(instance, fields.get(0), value);
+  }
+
+  public void setValuesToAnnotatedFields(Object instance,
+      Class<? extends Annotation> annotation, Map<String, Object> fieldName2Value) {
+    List<Field> fields = getAnnotatedFields(instance, annotation);
+
+    // XXX: refactore
+    for (Field field : fields) {
+      final String canonicalName = getCanonicalName(field);
+      if (fieldName2Value.containsKey(canonicalName)) {
+        Object value = fieldName2Value.get(canonicalName);
+        setFieldValue(instance, field, value);
+      }
+    }
+  }
+
+  public List<Field> getAnnotatedFields(Object instance, Class<? extends Annotation> annotation) {
+    if (instance == null) {
+      return null;
+    }
+    return getAnnotatedFields(instance.getClass(), annotation, true);
+  }
+
+  public List<Field> getAnnotatedFields(Class<?> fieldClass, Class<? extends Annotation> annotation) {
+    return getAnnotatedFields(fieldClass, annotation, true);
+  }
+
+  /**
+   *
+   * @param instance
+   * @param resultClass
+   * @param annotation
+   * @param inherited
+   * @return
+   */
+  private List<Field> getAnnotatedFields(Class<?> resultClass,
+      Class<? extends Annotation> annotation, boolean inherited) {
+    if (resultClass == null) {
+      return null;
+    }
+
+    Field[] fields = resultClass.getDeclaredFields();
+    List<Field> annotatedFields = new ArrayList<Field>();
+
+    for (Field field : fields) {
+      if (field.getAnnotation(annotation) != null) {
+        annotatedFields.add(field);
+      }
+    }
+
+    Class<?> superClass = resultClass.getSuperclass();
+    if (inherited && superClass != Object.class) {
+      List<Field> tmp = getAnnotatedFields(superClass, annotation, true);
+      annotatedFields.addAll(tmp);
+    }
+
+    return annotatedFields;
+  }
+
+  private Object getValueForField(Object instance, String fieldName, Class<?> resultClass,
+      Class<? extends Annotation> annotation, boolean inherited) {
+    if (instance == null) {
+      return null;
+    }
+
+    Field[] fields = resultClass.getDeclaredFields();
+    for (Field field : fields) {
+      if (field.getAnnotation(annotation) != null
+          && (fieldName == null || field.getName().equals(fieldName))) {
+        return getFieldValue(instance, field);
+      }
+    }
+
+    Class<?> superClass = resultClass.getSuperclass();
+    if (inherited && superClass != Object.class) {
+      return getValueForField(instance, fieldName, superClass, annotation, true);
+    }
+
+    return null;
+  }
+
+  private Object getFieldValue(Object instance, Field field) {
+    try {
+      boolean access = field.isAccessible();
+      field.setAccessible(true);
+      Object value = field.get(instance);
+      field.setAccessible(access);
+      return value;
+    } catch (IllegalArgumentException ex) { // should never happen
+      throw new ODataRuntimeException(ex);
+    } catch (IllegalAccessException ex) { // should never happen
+      throw new ODataRuntimeException(ex);
+    }
+  }
+
+  private void setFieldValue(Object instance, Field field, Object value) {
+    try {
+      Object usedValue = value;
+      if (value != null
+          && field.getType() != value.getClass()
+          && value.getClass() == String.class) {
+        usedValue = convert(field, (String) value);
+      }
+      boolean access = field.isAccessible();
+      field.setAccessible(true);
+      field.set(instance, usedValue);
+      field.setAccessible(access);
+    } catch (IllegalArgumentException ex) { // should never happen
+      throw new ODataRuntimeException(ex);
+    } catch (IllegalAccessException ex) { // should never happen
+      throw new ODataRuntimeException(ex);
+    }
+  }
+
+  public Object convert(Field field, String propertyValue) {
+    Class<?> fieldClass = field.getType();
+    try {
+      EdmProperty property = field.getAnnotation(EdmProperty.class);
+      EdmSimpleTypeKind type = mapTypeKind(property.type());
+      return type.getEdmSimpleTypeInstance().valueOfString(propertyValue,
+          EdmLiteralKind.DEFAULT, null, fieldClass);
+    } catch (EdmSimpleTypeException ex) {
+      throw new ODataRuntimeException("Conversion failed for string property with error: "
+          + ex.getMessage(), ex);
+    }
+  }
+
+  public boolean isEdmAnnotated(Object object) {
+    if (object == null) {
+      return false;
+    }
+    return isEdmAnnotated(object.getClass());
+  }
+
+  public boolean isEdmTypeAnnotated(Class<?> clazz) {
+    boolean isComplexEntity = clazz.getAnnotation(EdmComplexType.class) != null;
+    boolean isEntity = clazz.getAnnotation(EdmEntityType.class) != null;
+    return isComplexEntity || isEntity;
+  }
+
+  public boolean isEdmAnnotated(Class<?> clazz) {
+    if (clazz == null) {
+      return false;
+    } else {
+      final boolean isEntity = null != clazz.getAnnotation(EdmEntityType.class);
+      final boolean isEntitySet = null != clazz.getAnnotation(EdmEntitySet.class);
+      final boolean isComplexEntity = null != clazz.getAnnotation(EdmComplexType.class);
+      return isEntity || isComplexEntity || isEntitySet;
+    }
+  }
+
+  public String getCanonicalName(Field field) {
+    return firstCharToUpperCase(field.getName());
+  }
+
+  public String getCanonicalName(Class<?> clazz) {
+    return firstCharToUpperCase(clazz.getSimpleName());
+  }
+
+  private String firstCharToUpperCase(String content) {
+    if (content == null || content.isEmpty()) {
+      return content;
+    }
+    return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1);
+  }
+
+  public EdmSimpleTypeKind mapTypeKind(org.apache.olingo.odata2.api.annotation.edm.EdmType type) {
+    switch (type) {
+      case BINARY: return EdmSimpleTypeKind.Binary;
+      case BOOLEAN: return EdmSimpleTypeKind.Boolean;
+      case BYTE: return EdmSimpleTypeKind.Byte;
+      case COMPLEX: return EdmSimpleTypeKind.Null;
+      case DATE_TIME: return EdmSimpleTypeKind.DateTime;
+      case DATE_TIME_OFFSET: return EdmSimpleTypeKind.DateTimeOffset;
+      case DECIMAL: return EdmSimpleTypeKind.Decimal;
+      case DOUBLE: return EdmSimpleTypeKind.Double;
+      case GUID: return EdmSimpleTypeKind.Guid;
+      case INT16: return EdmSimpleTypeKind.Int16;
+      case INT32: return EdmSimpleTypeKind.Int32;
+      case INT64: return EdmSimpleTypeKind.Int64;
+      case NULL: return EdmSimpleTypeKind.Null;
+      case SBYTE: return EdmSimpleTypeKind.SByte;
+      case SINGLE: return EdmSimpleTypeKind.Single;
+      case STRING: return EdmSimpleTypeKind.String;
+      case TIME: return EdmSimpleTypeKind.Time;
+      default: throw new ODataRuntimeException("Unknown type '" + type
+        + "' for mapping to EdmSimpleTypeKind.");
+    }
+  }
+
+  public EdmMultiplicity mapMultiplicity(Multiplicity multiplicity) {
+    switch (multiplicity) {
+    case ZERO_OR_ONE: return EdmMultiplicity.ZERO_TO_ONE;
+    case ONE: return EdmMultiplicity.ONE;
+    case MANY: return EdmMultiplicity.MANY;
+    default: throw new ODataRuntimeException("Unknown type '" + multiplicity + "' for mapping to EdmMultiplicity.");
+    }
+  }
+  
+  /**
+   * 
+   */
+  private static class EdmAnnotationException extends RuntimeException {
+
+    private static final long serialVersionUID = 42L;
+
+    public EdmAnnotationException(String message) {
+      super(message);
+    }
+  }
+
+  public String getCanonicalNamespace(Class<?> aClass) {
+    return generateNamespace(aClass);
+  }
+
+  public String extractContainerName(Class<?> aClass) {
+    EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
+    if(entitySet != null) {
+      String containerName = entitySet.container();
+      if(!containerName.isEmpty()) {
+        return containerName;
+      }
+    }
+    return DEFAULT_CONTAINER_NAME;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
new file mode 100644
index 0000000..5e9fcdb
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.util;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ */
+public class ClassHelper {
+  
+  private static final File[] EMPTY_FILE_ARRAY = new File[0];
+  
+  private static final FilenameFilter CLASSFILE_FILTER = new FilenameFilter() {
+    @Override
+    public boolean accept(File dir, String name) {
+      return name.endsWith(CLASSFILE_ENDING);
+    }
+    public static final String CLASSFILE_ENDING = ".class";
+  };
+  
+  private static final FileFilter FOLDER_FILTER = new FileFilter() {
+    @Override
+    public boolean accept(File pathname) {
+      return pathname.isDirectory();
+    }
+  };
+  
+  public static final List<Class<?>> loadClasses(String packageToScan, ClassValidator cv) {
+    return loadClasses(packageToScan, CLASSFILE_FILTER, cv);
+  }
+
+  
+  public static final List<Class<?>> loadClasses(String packageToScan, FilenameFilter ff, ClassValidator cv) {
+    final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+    String folderToScan = packageToScan.replace(".", "/");
+    URL url = classLoader.getResource(folderToScan);
+    if(url == null) {
+      throw new IllegalArgumentException("No folder to scan found for package '" + packageToScan + "'.");
+    }
+    File folder = new File(url.getFile());
+    File[] classFiles = folder.listFiles(ff);
+    if(classFiles == null) {
+      classFiles = EMPTY_FILE_ARRAY;
+    }
+
+    List<Class<?>> annotatedClasses = new ArrayList<Class<?>>(classFiles.length);
+    for (File file : classFiles) {
+      String name = file.getName();
+      String fqn = packageToScan + "." + name.substring(0, name.length() - 6);
+      try {
+        Class<?> c = classLoader.loadClass(fqn);
+        if (cv.isClassValid(c)) {
+          annotatedClasses.add(c);
+        }
+      } catch (ClassNotFoundException ex) {
+        throw new IllegalArgumentException("Exception during class loading of class '" + fqn + 
+                "' with message '" + ex.getMessage() + "'.");
+      }
+    }
+    
+    // recursive search
+    File[] subfolders = listSubFolder(folder);
+    for (File file : subfolders) {
+      List<Class<?>> subFolderClazzes = loadClasses(packageToScan + "." + file.getName(), ff, cv);
+      annotatedClasses.addAll(subFolderClazzes);
+    }
+    //
+    
+    return annotatedClasses;
+  }
+
+  private static File[] listSubFolder(File folder) {
+    File[] subfolders = folder.listFiles(FOLDER_FILTER);
+    if(subfolders == null) {
+      return EMPTY_FILE_ARRAY;
+    }
+    return subfolders;
+  }
+  
+  public interface ClassValidator {
+    boolean isClassValid(Class<?> c);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
new file mode 100644
index 0000000..04dbefc
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.odata2.core.annotation.data;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.EntitySet;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.annotation.edm.AnnotationEdmProvider;
+import org.apache.olingo.odata2.core.annotation.model.Building;
+import org.apache.olingo.odata2.core.annotation.model.ModelSharedConstants;
+import org.apache.olingo.odata2.core.annotation.model.Photo;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ *
+ */
+public class AnnotationsInMemoryDsTest {
+
+  private final AnnotationInMemoryDs datasource;
+  private AnnotationEdmProvider edmProvider;
+  private static final String DEFAULT_CONTAINER = ModelSharedConstants.CONTAINER_1;
+
+  public AnnotationsInMemoryDsTest() {
+    datasource = new AnnotationInMemoryDs(Building.class.getPackage().getName(), false);
+    edmProvider = new AnnotationEdmProvider(Building.class.getPackage().getName());
+  }
+
+  @Test
+  public void createSimpleEntity() throws Exception {
+    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
+
+    Building building = new Building();
+    building.setName("Common Building");
+    datasource.createData(edmEntitySet, building);
+
+    Map<String, Object> keys = new HashMap<String, Object>();
+    keys.put("Id", "1");
+
+    Building read = (Building) datasource.readData(edmEntitySet, keys);
+    Assert.assertEquals("Common Building", read.getName());
+    Assert.assertEquals("1", read.getId());
+  }
+
+  
+  @Test
+  public void createSimpleEntityWithOwnKey() throws Exception {
+    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
+
+    Building building = new Building();
+    building.setName("Common Building");
+    AnnotationHelper ah = new AnnotationHelper();
+    ah.setValueForProperty(building, "Id", "42");
+    datasource.createData(edmEntitySet, building);
+
+    Map<String, Object> keys = new HashMap<String, Object>();
+    keys.put("Id", "42");
+
+    Building read = (Building) datasource.readData(edmEntitySet, keys);
+    Assert.assertEquals("Common Building", read.getName());
+    Assert.assertEquals("42", read.getId());
+  }
+
+  @Test
+  public void createSimpleEntityWithDuplicateKey() throws Exception {
+    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
+    AnnotationHelper ah = new AnnotationHelper();
+
+    Building building = new Building();
+    building.setName("Common Building");
+    ah.setValueForProperty(building, "Id", "42");
+    datasource.createData(edmEntitySet, building);
+    //
+    Building buildingDuplicate = new Building();
+    buildingDuplicate.setName("Duplicate Building");
+    ah.setValueForProperty(buildingDuplicate, "Id", "42");
+    datasource.createData(edmEntitySet, buildingDuplicate);
+
+    Map<String, Object> keys42 = new HashMap<String, Object>();
+    keys42.put("Id", "42");
+    Building read42 = (Building) datasource.readData(edmEntitySet, keys42);
+    Assert.assertEquals("Common Building", read42.getName());
+    Assert.assertEquals("42", read42.getId());
+
+    Map<String, Object> keys = new HashMap<String, Object>();
+    keys.put("Id", "1");
+    Building read = (Building) datasource.readData(edmEntitySet, keys);
+    Assert.assertEquals("Duplicate Building", read.getName());
+    Assert.assertEquals("1", read.getId());
+}
+
+  
+  @Test
+  public void createEntityTwoKeys() throws Exception {
+    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Photos");
+
+    Photo photo = new Photo();
+    photo.setName("BigPicture");
+    photo.setType("PNG");
+    photo.setImageUri("https://localhost/image.png");
+    photo.setImageType("image/png");
+    datasource.createData(edmEntitySet, photo);
+
+    Map<String, Object> keys = new HashMap<String, Object>();
+    keys.put("ImageFormat", "PNG");
+    keys.put("Name", "BigPicture");
+
+    Photo read = (Photo) datasource.readData(edmEntitySet, keys);
+    Assert.assertEquals("BigPicture", read.getName());
+    Assert.assertEquals("PNG", read.getType());
+    Assert.assertEquals("image/png", read.getImageType());
+    Assert.assertEquals("https://localhost/image.png", read.getImageUri());
+  }
+
+  @Test
+  //  @Ignore("Rethink update method")
+  public void createAndUpdateEntityTwoKeys() throws Exception {
+    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Photos");
+
+    Photo photo = new Photo();
+    final String nameKeyValue = "BigPicture";
+    final String typeKeyValue = "PNG";
+    photo.setName(nameKeyValue);
+    photo.setType(typeKeyValue);
+    photo.setImageUri("https://localhost/image.png");
+    photo.setImageType("image/png");
+    datasource.createData(edmEntitySet, photo);
+
+    Map<String, Object> keys = new HashMap<String, Object>();
+    keys.put("Name", "BigPicture");
+    keys.put("ImageFormat", "PNG");
+
+    Photo read = (Photo) datasource.readData(edmEntitySet, keys);
+    Assert.assertEquals("BigPicture", read.getName());
+    Assert.assertEquals("PNG", read.getType());
+    Assert.assertEquals("image/png", read.getImageType());
+    Assert.assertEquals("https://localhost/image.png", read.getImageUri());
+
+    // update
+    Photo updatedPhoto = new Photo();
+    updatedPhoto.setName(nameKeyValue);
+    updatedPhoto.setType(typeKeyValue);
+    updatedPhoto.setImageUri("https://localhost/image.jpg");
+    updatedPhoto.setImageType("image/jpg");
+    datasource.updateData(edmEntitySet, updatedPhoto);
+
+    Map<String, Object> updatedKeys = new HashMap<String, Object>();
+    updatedKeys.put("Name", nameKeyValue);
+    updatedKeys.put("ImageFormat", typeKeyValue);
+
+    Photo readUpdated = (Photo) datasource.readData(edmEntitySet, updatedKeys);
+    Assert.assertEquals("BigPicture", readUpdated.getName());
+    Assert.assertEquals("PNG", readUpdated.getType());
+    Assert.assertEquals("image/jpg", readUpdated.getImageType());
+    Assert.assertEquals("https://localhost/image.jpg", readUpdated.getImageUri());
+  }
+
+  private EdmEntitySet createMockedEdmEntitySet(String entitySetName) throws ODataException {
+    EntitySet entitySet = edmProvider.getEntitySet(DEFAULT_CONTAINER, entitySetName);
+    FullQualifiedName entityType = entitySet.getEntityType();
+
+    EdmEntitySet edmEntitySet = Mockito.mock(EdmEntitySet.class);
+    Mockito.when(edmEntitySet.getName()).thenReturn(entitySetName);
+    EdmEntityType edmEntityType = Mockito.mock(EdmEntityType.class);
+    Mockito.when(edmEntitySet.getEntityType()).thenReturn(edmEntityType);
+    Mockito.when(edmEntityType.getName()).thenReturn(entityType.getName());
+
+    return edmEntitySet;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
new file mode 100644
index 0000000..494a090
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
@@ -0,0 +1,463 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.odata2.core.annotation.edm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
+import org.apache.olingo.odata2.api.edm.provider.ComplexType;
+import org.apache.olingo.odata2.api.edm.provider.EntityContainer;
+import org.apache.olingo.odata2.api.edm.provider.EntityContainerInfo;
+import org.apache.olingo.odata2.api.edm.provider.EntitySet;
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
+import org.apache.olingo.odata2.api.edm.provider.Key;
+import org.apache.olingo.odata2.api.edm.provider.NavigationProperty;
+import org.apache.olingo.odata2.api.edm.provider.Property;
+import org.apache.olingo.odata2.api.edm.provider.PropertyRef;
+import org.apache.olingo.odata2.api.edm.provider.Schema;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.annotation.model.Building;
+import org.apache.olingo.odata2.core.annotation.model.City;
+import org.apache.olingo.odata2.core.annotation.model.Employee;
+import org.apache.olingo.odata2.core.annotation.model.Location;
+import org.apache.olingo.odata2.core.annotation.model.Manager;
+import org.apache.olingo.odata2.core.annotation.model.ModelSharedConstants;
+import org.apache.olingo.odata2.core.annotation.model.Photo;
+import org.apache.olingo.odata2.core.annotation.model.RefBase;
+import org.apache.olingo.odata2.core.annotation.model.Room;
+import org.apache.olingo.odata2.core.annotation.model.Team;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class AnnotationEdmProviderTest {
+
+  @EdmEntityType
+  @EdmEntitySet
+  private static final class GeneratedNamesTestClass {}
+
+  @EdmComplexType
+  private static final class GeneratedNamesComplexTestClass {}
+
+  @EdmEntityType(namespace="MyTestNamespace")
+  @EdmEntitySet(container="MyTestContainer")
+  private static final class DefinedNamesTestClass {}
+
+  private final AnnotationEdmProvider aep;
+  private final Collection<Class<?>> annotatedClasses = new ArrayList<Class<?>>();
+
+  public AnnotationEdmProviderTest() {
+    annotatedClasses.add(RefBase.class);
+    annotatedClasses.add(Building.class);
+    annotatedClasses.add(City.class);
+    annotatedClasses.add(Employee.class);
+    annotatedClasses.add(Location.class);
+    annotatedClasses.add(Manager.class);
+    annotatedClasses.add(Photo.class);
+    annotatedClasses.add(Room.class);
+    annotatedClasses.add(Team.class);
+
+    aep = new AnnotationEdmProvider(annotatedClasses);
+  }
+
+  @Test
+  public void defaultNamespaceGeneration() throws ODataException {
+    Collection<Class<?>> localAnnotatedClasses = new ArrayList<Class<?>>();
+    localAnnotatedClasses.add(GeneratedNamesTestClass.class); 
+    AnnotationEdmProvider localAep = new AnnotationEdmProvider(localAnnotatedClasses);
+    // validate 
+    EntityType testType = localAep.getEntityType(new FullQualifiedName(
+            GeneratedNamesTestClass.class.getPackage().getName(), 
+            GeneratedNamesTestClass.class.getSimpleName()));
+    assertNotNull("Requested entity not found.", testType);
+    assertEquals("GeneratedNamesTestClass", testType.getName());
+    assertNull("This should not have a base type", testType.getBaseType());
+  }
+
+  @Test
+  public void defaultNamespaceGenerationComplexType() throws ODataException {
+    Collection<Class<?>> localAnnotatedClasses = new ArrayList<Class<?>>();
+    localAnnotatedClasses.add(GeneratedNamesComplexTestClass.class); 
+    AnnotationEdmProvider localAep = new AnnotationEdmProvider(localAnnotatedClasses);
+    // validate 
+    ComplexType testType = localAep.getComplexType(new FullQualifiedName(
+            GeneratedNamesComplexTestClass.class.getPackage().getName(), 
+            GeneratedNamesComplexTestClass.class.getSimpleName()));
+    assertNotNull("Requested entity not found.", testType);
+    assertEquals("GeneratedNamesComplexTestClass", testType.getName());
+    assertNull("This should not have a base type", testType.getBaseType());
+  }
+
+  @Test
+  public void defaultContainerNameGeneration() throws ODataException {
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    AnnotationEdmProvider localAep = 
+      new AnnotationEdmProvider((Collection) Arrays.asList(GeneratedNamesTestClass.class));
+    
+    EntityContainerInfo containerInfo = localAep.getEntityContainerInfo(null);
+    assertNotNull(containerInfo);
+    assertEquals("DefaultContainer", containerInfo.getName());
+  }
+
+
+  @Test
+  public void defaultNamespaceDefined() throws ODataException {
+    Collection<Class<?>> localAnnotatedClasses = new ArrayList<Class<?>>();
+    localAnnotatedClasses.add(DefinedNamesTestClass.class); 
+    AnnotationEdmProvider localAep = new AnnotationEdmProvider(localAnnotatedClasses);
+    // validate 
+    EntityType testClass = localAep.getEntityType(new FullQualifiedName("MyTestNamespace",
+        DefinedNamesTestClass.class.getSimpleName()));
+    assertNotNull("Requested entity not found.", testClass);
+    assertEquals("DefinedNamesTestClass", testClass.getName());
+    assertNull("This should not have a base type", testClass.getBaseType());
+  }
+
+  @Test
+  public void defaultContainerNameDefined() throws ODataException {
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    AnnotationEdmProvider localAep = new AnnotationEdmProvider((Collection) Arrays.asList(DefinedNamesTestClass.class));
+    
+    EntityContainerInfo containerInfo = localAep.getEntityContainerInfo(null);
+    assertNotNull(containerInfo);
+    assertEquals("MyTestContainer", containerInfo.getName());
+  }
+
+  @Test
+  public void loadAnnotatedClassesFromPackage() throws Exception {
+    AnnotationEdmProvider localAep = new AnnotationEdmProvider("org.apache.olingo.odata2.core.annotation.model");
+
+    // validate employee
+    EntityType employee = localAep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Employee"));
+    assertEquals("Employee", employee.getName());
+    final List<PropertyRef> employeeKeys = employee.getKey().getKeys();
+    assertEquals(1, employeeKeys.size());
+    assertEquals("EmployeeId", employeeKeys.get(0).getName());
+    assertEquals(6, employee.getProperties().size());
+    assertEquals(3, employee.getNavigationProperties().size());
+
+    List<Schema> schemas = localAep.getSchemas();
+    assertEquals(1, schemas.size());
+    EntityContainerInfo info = localAep.getEntityContainerInfo(ModelSharedConstants.CONTAINER_1);
+    assertTrue(info.isDefaultEntityContainer());
+  }
+
+  @Test
+  public void annotationProviderBasic() throws Exception {
+    assertNotNull(aep);
+
+    List<Schema> schemas = aep.getSchemas();
+    assertEquals(1, schemas.size());
+    EntityContainerInfo info = aep.getEntityContainerInfo(ModelSharedConstants.CONTAINER_1);
+    assertTrue(info.isDefaultEntityContainer());
+    
+    FunctionImport funImp = aep.getFunctionImport(ModelSharedConstants.CONTAINER_1, "NoImport");
+    assertNull(funImp);
+
+    final FullQualifiedName associationFqn = new FullQualifiedName(
+            ModelSharedConstants.NAMESPACE_1, "NoAssociation");
+    Association noAssociation = aep.getAssociation(associationFqn);
+    assertNull(noAssociation);
+    
+    AssociationSet noAssociationSet = aep.getAssociationSet(
+            ModelSharedConstants.CONTAINER_1, associationFqn, "NoSrc", "NoSrcEntity");
+    assertNull(noAssociationSet);
+    
+    AssociationSet asBuildingRooms = aep.getAssociationSet(
+            ModelSharedConstants.CONTAINER_1, defaultFqn("BuildingRooms"), "Buildings", "r_Building");
+    assertNotNull(asBuildingRooms);
+    assertEquals("Buildings", asBuildingRooms.getEnd1().getEntitySet());
+    assertEquals("r_Building", asBuildingRooms.getEnd1().getRole());
+    assertEquals("Rooms", asBuildingRooms.getEnd2().getEntitySet());
+    assertEquals("r_Room", asBuildingRooms.getEnd2().getRole());
+  }
+
+  @Test
+  public void annotationProviderGetDefaultContainer() throws Exception {
+    assertNotNull(aep);
+
+    List<Schema> schemas = aep.getSchemas();
+    assertEquals(1, schemas.size());
+    EntityContainerInfo info = aep.getEntityContainerInfo(null);
+    assertTrue(info.isDefaultEntityContainer());
+    assertEquals(ModelSharedConstants.CONTAINER_1, info.getName());
+  }
+
+  @Test
+  public void schemaBasic() throws Exception {
+    assertNotNull(aep);
+
+    List<Schema> schemas = aep.getSchemas();
+    assertEquals(1, schemas.size());
+
+    Schema schema = schemas.get(0);
+    List<EntityContainer> containers = schema.getEntityContainers();
+    assertEquals(1, containers.size());
+    EntityContainer container = containers.get(0);
+    assertEquals(ModelSharedConstants.CONTAINER_1, container.getName());
+    final List<EntitySet> entitySets = container.getEntitySets();
+    assertEquals(6, entitySets.size());
+    
+    List<Association> associations = schema.getAssociations();
+    assertEquals(4, associations.size());
+    for (Association association : associations) {
+      assertNotNull(association.getName());
+      validateAssociation(association);
+    }
+  }
+  
+  private FullQualifiedName defaultFqn(String name) {
+    return new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, name);
+  }
+
+  private void validateAssociation(Association association) {
+    String name = association.getName();
+    if(name.equals("r_Employee-r_Room")) {
+      validateAssociation(association, 
+              "r_Room", EdmMultiplicity.ONE, defaultFqn("Room"),
+              "r_Employee", EdmMultiplicity.MANY, defaultFqn("Employee"));
+    } else if(name.equals("BuildingRooms")) {
+        validateAssociation(association, 
+                "r_Building", EdmMultiplicity.ONE, defaultFqn("Building"),
+                "r_Room", EdmMultiplicity.MANY, defaultFqn("Room"));
+    } else if(name.equals("ManagerEmployees")) {
+        validateAssociation(association, 
+                "r_Manager", EdmMultiplicity.ONE, defaultFqn("Manager"),
+                "r_Employee", EdmMultiplicity.MANY, defaultFqn("Employee"));
+    } else if(name.equals("TeamEmployees")) {
+        validateAssociation(association, 
+                "r_Team", EdmMultiplicity.ONE, defaultFqn("Team"),
+                "r_Employee", EdmMultiplicity.MANY, defaultFqn("Employee"));
+    } else {
+        fail("Got unknown association to validate with name '" + name + "'.");
+    }
+  }
+
+  private void validateAssociation(Association association, 
+          String fromRole, EdmMultiplicity fromMulti, FullQualifiedName fromType, 
+          String toRole, EdmMultiplicity toMulti, FullQualifiedName toType) {
+
+    AssociationEnd[] ends = new AssociationEnd[]{association.getEnd1(),association.getEnd2()};
+    for (AssociationEnd associationEnd : ends) {
+      if(associationEnd.getRole().equals(fromRole)) {
+        validateAssociationEnd(associationEnd, fromRole, fromMulti, fromType);
+      } else if(associationEnd.getRole().equals(toRole)) {
+        validateAssociationEnd(associationEnd, toRole, toMulti, toType);
+      } else {
+        fail("Unexpected navigation end '" + associationEnd.getRole() 
+                + "' for association with name '" + association.getName() + "'.");
+      }
+    }
+  }
+
+    private void validateAssociationEnd(AssociationEnd associationEnd, 
+          String role, EdmMultiplicity multiplicity, FullQualifiedName type) {
+    assertEquals(role, associationEnd.getRole());
+    assertEquals(multiplicity, associationEnd.getMultiplicity());
+    assertEquals(type, associationEnd.getType());
+  }
+
+
+  @Test
+  public void entitySetTeams() throws Exception {
+    // validate teams
+    EntitySet teams = aep.getEntitySet(ModelSharedConstants.CONTAINER_1, "Teams");
+    assertEquals(ModelSharedConstants.NAMESPACE_1, teams.getEntityType().getNamespace());
+    assertEquals("Team", teams.getEntityType().getName());
+  }
+
+  @Test
+  public void entityTypeEmployee() throws Exception {
+    // validate employee
+    EntityType employee = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Employee"));
+    assertEquals("Employee", employee.getName());
+    final List<PropertyRef> employeeKeys = employee.getKey().getKeys();
+    assertEquals(1, employeeKeys.size());
+    assertEquals("EmployeeId", employeeKeys.get(0).getName());
+    assertEquals(6, employee.getProperties().size());
+    assertEquals(3, employee.getNavigationProperties().size());
+
+    for (NavigationProperty navigationProperty : employee.getNavigationProperties()) {
+      if (navigationProperty.getName().equals("ne_Manager")) {
+        validateNavProperty(navigationProperty, "ManagerEmployees", "r_Employee", "r_Manager");
+      } else if (navigationProperty.getName().equals("ne_Team")) {
+        validateNavProperty(navigationProperty, "TeamEmployees", "r_Employee", "r_Team");
+      } else if (navigationProperty.getName().equals("ne_Room")) {
+        validateNavProperty(navigationProperty, "r_Employee-r_Room", "r_Employee", "r_Room");
+      } else {
+        fail("Got unexpected navigation property with name '" + navigationProperty.getName() + "'.");
+      }
+    }
+}
+
+  @Test
+  public void entityTypeTeam() throws Exception {
+    // validate team
+    EntityType team = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Team"));
+    assertEquals("Team", team.getName());
+    assertEquals("Base", team.getBaseType().getName());
+    assertEquals(ModelSharedConstants.NAMESPACE_1, team.getBaseType().getNamespace());
+
+    assertEquals(1, team.getProperties().size());
+    assertEquals(1, team.getNavigationProperties().size());
+    NavigationProperty navigationProperty= team.getNavigationProperties().get(0);
+    validateNavProperty(navigationProperty, "TeamEmployees", "r_Team", "r_Employee");
+  }
+
+  @Test
+  public void entityTypePhotoWithTwoKeyProperties() throws Exception {
+    // validate team
+    EntityType photo = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Photo"));
+    assertEquals("Photo", photo.getName());
+    final List<Property> properties = photo.getProperties();
+    assertEquals(5, properties.size());
+    assertTrue(containsProperty(properties, "Name"));
+    assertTrue(containsProperty(properties, "ImageFormat"));
+    assertTrue(containsProperty(properties, "MimeType"));
+    assertTrue(containsProperty(properties, "ImageUrl"));
+    assertTrue(containsProperty(properties, "Image"));
+    assertFalse(photo.isAbstract());
+    assertTrue(photo.isHasStream());
+
+    Key photoKey = photo.getKey();
+    List<PropertyRef> keyReferences = photoKey.getKeys();
+    assertEquals(2, keyReferences.size());
+    PropertyRef name = getPropertyRef(keyReferences, "Name");
+    assertEquals("Name", name.getName());
+    PropertyRef imageFormat = getPropertyRef(keyReferences, "ImageFormat");
+    assertEquals("ImageFormat", imageFormat.getName());
+    
+//    assertEquals(0, photo.getNavigationProperties().size());
+    assertNull(photo.getNavigationProperties());
+  }
+
+  @Test
+  public void entityTypeAbstractBaseType() throws Exception {
+    // validate employee
+    EntityType baseType = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Base"));
+    assertEquals("Base", baseType.getName());
+    final List<PropertyRef> keys = baseType.getKey().getKeys();
+    assertEquals(1, keys.size());
+    assertEquals("Id", keys.get(0).getName());
+    assertEquals(2, baseType.getProperties().size());
+    assertTrue(baseType.isAbstract());
+
+    // validate base for team
+    EntityType team = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Team"));
+    assertEquals("Team", team.getName());
+    assertEquals("Base", team.getBaseType().getName());
+    assertEquals(ModelSharedConstants.NAMESPACE_1, team.getBaseType().getNamespace());
+  }
+
+  @Test
+  public void complexTypeLocation() throws Exception {
+    // validate employee
+    EntityType employee = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Employee"));
+    final List<Property> properties = employee.getProperties();
+    Property location = null;
+    for (Property property : properties) {
+      if (property.getName().equals("Location")) {
+        location = property;
+      }
+    }
+    assertNotNull(location);
+    assertEquals("Location", location.getName());
+
+    // validate location complex type
+    ComplexType locationType = aep.getComplexType(
+            new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "c_Location"));
+    assertEquals("c_Location", locationType.getName());
+    assertEquals(2, locationType.getProperties().size());
+  }
+
+  @Test
+  public void entityTypeRoomWithNavigation() throws Exception {
+    // validate employee
+    EntityType room = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Room"));
+    assertEquals("Room", room.getName());
+    assertEquals("Base", room.getBaseType().getName());
+    assertEquals(2, room.getProperties().size());
+    final List<NavigationProperty> navigationProperties = room.getNavigationProperties();
+    assertEquals(2, navigationProperties.size());
+    
+    for (NavigationProperty navigationProperty : navigationProperties) {
+      if(navigationProperty.getName().equals("nr_Employees")) {
+        validateNavProperty(navigationProperty, "r_Employee-r_Room", "r_Room", "r_Employee");
+      } else if(navigationProperty.getName().equals("nr_Building")) {
+        validateNavProperty(navigationProperty, "BuildingRooms", "r_Room", "r_Building");
+      } else {
+        fail("Got unexpected navigation property with name '" + navigationProperty.getName() + "'.");
+      }
+    }
+  }
+  
+  private void validateNavProperty(NavigationProperty navigationProperty, String name,
+          String relationship, String fromRole, String toRole) {
+    if(name != null) {
+      assertEquals(name, navigationProperty.getName());
+    }
+    FullQualifiedName fqn = new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, relationship);
+    assertEquals("Wrong relationship for navigation property.", fqn, navigationProperty.getRelationship());
+    assertEquals("Wrong fromRole for navigation property.", fromRole, navigationProperty.getFromRole());
+    assertEquals("Wrong toRole for navigation property.", toRole, navigationProperty.getToRole());
+  }
+  
+  private void validateNavProperty(NavigationProperty navigationProperty, 
+          String relationship, String fromRole, String toRole) {
+    validateNavProperty(navigationProperty, null, relationship, fromRole, toRole);
+  }
+  
+  private boolean containsProperty(List<Property> properties, String propertyName) {
+    return getProperty(properties, propertyName) != null;
+  }
+
+  private Property getProperty(List<Property> properties, String name) {
+    for (Property property : properties) {
+      if(name.equals(property.getName())) {
+        return property;
+      }
+    }
+    return null;
+  }
+  
+  private PropertyRef getPropertyRef(List<PropertyRef> properties, String name) {
+    for (PropertyRef property : properties) {
+      if(name.equals(property.getName())) {
+        return property;
+      }
+    }
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
new file mode 100644
index 0000000..737b5e2
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *  
+ */
+@EdmEntityType(name = "Building", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Buildings")
+public class Building {
+  @EdmKey
+  @EdmProperty(type = EdmType.INT32)
+  private String id;
+  @EdmProperty
+  private String name;
+  @EdmProperty(name = "Image", type = EdmType.BINARY)
+  private byte[] image;
+  @EdmNavigationProperty(name = "nb_Rooms", toType = Room.class,
+      association = "BuildingRooms", toMultiplicity = Multiplicity.MANY)
+  private List<Room> rooms = new ArrayList<Room>();
+
+  public Building() {}
+
+  public String getId() {
+    return id;
+  }
+
+  public void setName(final String name) {
+    this.name = name;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setImage(final byte[] byteArray) {
+    image = byteArray;
+  }
+
+  public byte[] getImage() {
+    if (image == null) {
+      return null;
+    } else {
+      return image.clone();
+    }
+  }
+
+  public List<Room> getRooms() {
+    return rooms;
+  }
+
+  @Override
+  public int hashCode() {
+      return id == null ? 0 : id.hashCode();
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+        || obj != null && getClass() == obj.getClass() && id == ((Building) obj).id;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Image\":\"" + Arrays.toString(image) + "\"}";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
new file mode 100644
index 0000000..7b866a3
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+
+/**
+ *  
+ */
+@EdmComplexType(name="c_City", namespace = ModelSharedConstants.NAMESPACE_1)
+public class City {
+
+  @EdmProperty
+  private String postalCode;
+  @EdmProperty
+  private String cityName;
+
+  public City(final String postalCode, final String name) {
+    this.postalCode = postalCode;
+    cityName = name;
+  }
+
+  public void setPostalCode(final String postalCode) {
+    this.postalCode = postalCode;
+  }
+
+  public String getPostalCode() {
+    return postalCode;
+  }
+
+  public void setCityName(final String cityName) {
+    this.cityName = cityName;
+  }
+
+  public String getCityName() {
+    return cityName;
+  }
+
+  @Override
+  public String toString() {
+    return String.format("%s, %s", cityName, postalCode);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
new file mode 100644
index 0000000..63b8a76
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.model;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *  
+ */
+@EdmEntityType(name = "Employee", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Employees")
+public class Employee {
+  @EdmKey
+  @EdmProperty(name = "EmployeeId", type = EdmType.STRING)
+  private String employeeId;
+  @EdmProperty(name = "EmployeeName")
+  private String employeeName;
+  @EdmProperty
+  private int age;
+  @EdmNavigationProperty(name = "ne_Manager", association = "ManagerEmployees")
+  private Manager manager;
+  @EdmNavigationProperty(name = "ne_Team", association = "TeamEmployees")
+  private Team team;
+  @EdmNavigationProperty(name = "ne_Room")
+  private Room room;
+  @EdmMediaResourceMimeType
+  private String imageType;
+  @EdmMediaResourceContent
+  private byte[] image;
+  @EdmProperty(name = "ImageUrl")
+  private String imageUrl;
+  @EdmProperty(name = "EntryDate", type = EdmType.DATE_TIME)
+  private Calendar entryDate;
+  @EdmProperty(name = "Location")
+  private Location location;
+
+  public Employee(final String employeeId, final String name) {
+    this.employeeId = employeeId;
+    setEmployeeName(name);
+  }
+
+  public String getId() {
+    return employeeId;
+  }
+
+  public void setEmployeeName(final String employeeName) {
+    this.employeeName = employeeName;
+  }
+
+  public String getEmployeeName() {
+    return employeeName;
+  }
+
+  public void setAge(final int age) {
+    this.age = age;
+  }
+
+  public int getAge() {
+    return age;
+  }
+
+  public void setManager(final Manager manager) {
+    this.manager = manager;
+  }
+
+  public Manager getManager() {
+    return manager;
+  }
+
+  public void setTeam(final Team team) {
+    this.team = team;
+  }
+
+  public Team getTeam() {
+    return team;
+  }
+
+  public void setRoom(final Room room) {
+    this.room = room;
+  }
+
+  public Room getRoom() {
+    return room;
+  }
+
+  public void setImageUri(final String imageUri) {
+    imageUrl = imageUri;
+  }
+
+  public String getImageUri() {
+    return imageUrl;
+  }
+
+  public void setLocation(final Location location) {
+    this.location = location;
+  }
+
+  public Location getLocation() {
+    return location;
+  }
+
+  public void setEntryDate(final Calendar date) {
+    entryDate = date;
+  }
+
+  public Calendar getEntryDate() {
+    return entryDate;
+  }
+
+  public void setImageType(final String imageType) {
+    this.imageType = imageType;
+  }
+
+  public String getImageType() {
+    return imageType;
+  }
+
+  public void setImage(final byte[] image) {
+    this.image = image;
+  }
+
+  public byte[] getImage() {
+    if (image == null) {
+      return null;
+    }
+    return image.clone();
+  }
+
+  @Override
+  public int hashCode() {
+    if (employeeId == null) {
+      return 0;
+    }
+    return employeeId.hashCode();
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+        || obj != null && getClass() == obj.getClass() && employeeId == ((Employee) obj).employeeId;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"EmployeeId\":\"" + employeeId + "\","
+        + "\"EmployeeName\":\"" + employeeName + "\","
+        + "\"ManagerId\":" + (manager == null ? "null" : "\"" + manager.getId() + "\"") + ","
+        + "\"RoomId\":" + (room == null ? "null" : "\"" + room.getId() + "\"") + ","
+        + "\"TeamId\":" + (team == null ? "null" : "\"" + team.getId() + "\"") + ","
+        + "\"Location\":"
+        + (location == null ? "null" :
+            "{\"City\":" + (location.getCity() == null ? "null" :
+                "{\"PostalCode\":\"" + location.getCity().getPostalCode() + "\","
+                    + "\"CityName\":\"" + location.getCity().getCityName() + "\"}") + ","
+                + "\"Country\":\"" + location.getCountry() + "\"}") + ","
+        + "\"Age\":" + age + ","
+        + "\"EntryDate\":"
+        + (entryDate == null ? "null" : "\"" + DateFormat.getInstance().format(entryDate.getTime()) + "\"") + ","
+        + "\"ImageUrl\":\"" + imageUrl + "\"}";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
new file mode 100644
index 0000000..7f3f082
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+
+/**
+ *  
+ */
+@EdmComplexType(name = "c_Location", namespace = ModelSharedConstants.NAMESPACE_1)
+public class Location {
+  @EdmProperty
+  private String country;
+  @EdmProperty
+  private City city;
+
+  public Location(final String country, final String postalCode, final String cityName) {
+    this.country = country;
+    city = new City(postalCode, cityName);
+  }
+
+  public void setCountry(final String country) {
+    this.country = country;
+  }
+
+  public String getCountry() {
+    return country;
+  }
+
+  public void setCity(final City city) {
+    this.city = city;
+  }
+
+  public City getCity() {
+    return city;
+  }
+
+  @Override
+  public String toString() {
+    return String.format("%s, %s", country, city.toString());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
new file mode 100644
index 0000000..e3edbd0
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Manager", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Managers")
+public class Manager extends Employee {
+
+  @EdmNavigationProperty(name = "nm_Employees", association = "ManagerEmployees",
+      toMultiplicity = Multiplicity.MANY)
+  private List<Employee> employees = new ArrayList<Employee>();
+
+  public Manager(final String id, final String name) {
+    super(id, name);
+  }
+
+  public List<Employee> getEmployees() {
+    return employees;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
new file mode 100644
index 0000000..1d44498
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.model;
+
+public interface ModelSharedConstants {
+
+  String NAMESPACE_1 = "RefScenario";
+  String CONTAINER_1 = "DefaultContainer";
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
new file mode 100644
index 0000000..520216a
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.model;
+
+import java.util.Arrays;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceSource;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *  
+ */
+@EdmEntityType(name = "Photo", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Photos")
+public class Photo {
+  @EdmProperty
+  @EdmKey
+  private String name;
+  @EdmProperty(name = "ImageFormat")
+  @EdmKey
+  private String type;
+  @EdmProperty
+  @EdmMediaResourceMimeType
+  private String mimeType;
+  @EdmProperty
+  @EdmMediaResourceSource
+  private String imageUrl = "http://localhost/someResource.png";
+  @EdmProperty(type = EdmType.BINARY)
+  @EdmMediaResourceContent
+  private byte[] image = ResourceHelper.generateImage();
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(final String name) {
+    this.name = name;
+  }
+
+  public String getType() {
+    return type;
+  }
+
+  public void setType(final String type) {
+    this.type = type;
+  }
+
+  public String getImageUri() {
+    return imageUrl;
+  }
+
+  public void setImageUri(final String uri) {
+    imageUrl = uri;
+  }
+
+  public byte[] getImage() {
+    return image.clone();
+  }
+
+  public void setImage(final byte[] image) {
+    this.image = image;
+  }
+
+  public String getImageType() {
+    return mimeType;
+  }
+
+  public void setImageType(final String imageType) {
+    this.mimeType = imageType;
+  }
+
+  @Override
+  public int hashCode() {
+    int hash = 5;
+    hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
+    hash = 83 * hash + (this.type != null ? this.type.hashCode() : 0);
+    return hash;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    final Photo other = (Photo) obj;
+    if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
+      return false;
+    }
+    if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) {
+      return false;
+    }
+    return true;
+  }
+  
+  @Override
+  public String toString() {
+    return "{\"Name\":\"" + name + "\","
+        + "\"Type\":\"" + type + "\","
+        + "\"ImageUrl\":\"" + imageUrl + "\","
+        + "\"Image\":\"" + Arrays.toString(image) + "\","
+        + "\"MimeType\":\"" + mimeType + "\"";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
new file mode 100644
index 0000000..6f3002f
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.odata2.core.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+
+/**
+ *
+ */
+@EdmEntityType(name="Base", namespace=ModelSharedConstants.NAMESPACE_1)
+public abstract class RefBase {
+  @EdmProperty(name="Name")
+  protected String name;
+  @EdmProperty(name="Id", type = EdmType.STRING)
+  @EdmKey
+  protected int id;
+
+  public RefBase(int id, String name) {
+    this.name = name;
+    this.id = id;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public String getId() {
+    return Integer.toString(id);
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public void setId(int id) {
+    this.id = id;
+  }
+}


[05/12] Renamed project

Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
deleted file mode 100644
index 0c81fb1..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
+++ /dev/null
@@ -1,726 +0,0 @@
-/**
- * *****************************************************************************
- * 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.odata2.core.annotation.util;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.ParameterizedType;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
-import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
-import org.apache.olingo.odata2.api.edm.FullQualifiedName;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-/**
- *
- */
-public class AnnotationHelper {
-
-  public static final String DEFAULT_CONTAINER_NAME = "DefaultContainer";
-
-  /**
-   * Compare keys of both instances.
-   * 
-   * @param firstInstance
-   * @param secondInstance
-   * @return 
-   */
-  public boolean keyMatch(Object firstInstance, Object secondInstance) {
-    if (firstInstance == null || secondInstance == null) {
-      return false;
-    } else if (firstInstance.getClass() != secondInstance.getClass()) {
-      return false;
-    }
-
-    Map<String, Object> firstKeyFields = getValueForAnnotatedFields(firstInstance, EdmKey.class);
-    Map<String, Object> secondKeyFields = getValueForAnnotatedFields(secondInstance, EdmKey.class);
-
-    return keyValuesMatch(firstKeyFields, secondKeyFields);
-  }
-
-  /**
-   * Compare keys of instance with key values in map.
-   * 
-   * @param instance
-   * @param keyName2Value
-   * @return 
-   */
-  public boolean keyMatch(Object instance, Map<String, Object> keyName2Value) {
-    Map<String, Object> instanceKeyFields = getValueForAnnotatedFields(instance, EdmKey.class);
-    return keyValuesMatch(instanceKeyFields, keyName2Value);
-  }
-
-  private boolean keyValuesMatch(Map<String, Object> firstKeyValues, Map<String, Object> secondKeyValues) {
-    if (firstKeyValues.size() != secondKeyValues.size()) {
-      return false;
-    } else {
-      Set<Map.Entry<String, Object>> entries = firstKeyValues.entrySet();
-      for (Map.Entry<String, Object> entry : entries) {
-        Object firstKey = entry.getValue();
-        Object secondKey = secondKeyValues.get(entry.getKey());
-        if (!isEqual(firstKey, secondKey)) {
-          return false;
-        }
-      }
-      return true;
-    }
-  }
-  
-  private boolean isEqual(Object firstKey, Object secondKey) {
-    if (firstKey == null) {
-      if (secondKey == null) {
-        return true;
-      } else {
-        return secondKey.equals(firstKey);
-      }
-    } else {
-      return firstKey.equals(secondKey);
-    }
-  }
-
-  public String extractEntitTypeName(EdmNavigationProperty enp, Class<?> fallbackClass) {
-    Class<?> entityTypeClass = enp.toType();
-    return extractEntityTypeName(entityTypeClass == Object.class ? fallbackClass : entityTypeClass);
-  }
-
-  public String extractEntitTypeName(EdmNavigationProperty enp, Field field) {
-    Class<?> entityTypeClass = enp.toType();
-    if (entityTypeClass == Object.class) {
-      Class<?> toClass = field.getType();
-      return extractEntityTypeName((toClass.isArray() || Collection.class.isAssignableFrom(toClass) ?
-          (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0] : toClass));
-    } else {
-      return extractEntityTypeName(entityTypeClass);
-    }
-  }
-
-  /**
-   * Returns <code>NULL</code> if given class is not annotated. If annotated the set entity type name is returned and if
-   * no name is set the default name is generated from the simple class name.
-   *
-   * @param annotatedClass
-   * @return
-   */
-  public String extractEntityTypeName(Class<?> annotatedClass) {
-    return extractTypeName(annotatedClass, EdmEntityType.class);
-  }
-
-  public FullQualifiedName extractEntityTypeFqn(EdmEntityType type, Class<?> annotatedClass) {
-    if(type.namespace().isEmpty()) {
-      return new FullQualifiedName(generateNamespace(annotatedClass), extractEntityTypeName(annotatedClass));
-    }
-    return new FullQualifiedName(type.namespace(), extractEntityTypeName(annotatedClass));
-  }
-  
-  public FullQualifiedName extractEntityTypeFqn(Class<?> annotatedClass) {
-    EdmEntityType type = annotatedClass.getAnnotation(EdmEntityType.class);
-    if(type == null) {
-      return null;
-    }
-    return extractEntityTypeFqn(type, annotatedClass);
-  }
-
-  public FullQualifiedName extractComplexTypeFqn(Class<?> annotatedClass) {
-    EdmComplexType type = annotatedClass.getAnnotation(EdmComplexType.class);
-    if(type == null) {
-      return null;
-    }
-    return extractComplexTypeFqn(type, annotatedClass);
-  }
-
-  public FullQualifiedName extractComplexTypeFqn(EdmComplexType type, Class<?> annotatedClass) {
-    if(type.namespace().isEmpty()) {
-      return new FullQualifiedName(generateNamespace(annotatedClass), extractComplexTypeName(annotatedClass));
-    }
-    return new FullQualifiedName(type.namespace(), extractComplexTypeName(annotatedClass));
-  }
-
-  public String extractComplexTypeName(Class<?> annotatedClass) {
-    return extractTypeName(annotatedClass, EdmComplexType.class);
-  }
-  
-  public String generateNamespace(Class<?> annotatedClass) {
-    String packageName = annotatedClass.getPackage().getName();
-    return packageName;
-  }
-
-  /**
-   *
-   *
-   * @param <T> must be EdmEntityType or EdmComplexType annotation
-   * @param annotatedClass
-   * @param typeAnnotation
-   * @return null if annotatedClass is not annotated or name set via annotation or generated via
-   * {@link #getCanonicalName(java.lang.Class)}
-   */
-  private <T extends Annotation> String extractTypeName(Class<?> annotatedClass, Class<T> typeAnnotation) {
-    if (annotatedClass == Object.class) {
-      return null;
-    }
-    T type = annotatedClass.getAnnotation(typeAnnotation);
-    if (type == null) {
-      return null;
-    }
-
-    String name;
-    if (typeAnnotation == EdmEntityType.class) {
-      name = ((EdmEntityType) type).name();
-    } else if (typeAnnotation == EdmComplexType.class) {
-      name = ((EdmComplexType) type).name();
-    } else {
-      return null;
-    }
-
-    if (name.isEmpty()) {
-      return getCanonicalName(annotatedClass);
-    }
-    return name;
-  }
-
-  /**
-   * Get the set property name from an EdmProperty or EdmNavigationProperty annotation.
-   *
-   * @param field
-   * @return
-   */
-  public String getPropertyNameFromAnnotation(Field field) {
-    EdmProperty property = field.getAnnotation(EdmProperty.class);
-    if (property == null) {
-      EdmNavigationProperty navProperty = field.getAnnotation(EdmNavigationProperty.class);
-      if (navProperty == null) {
-        throw new EdmAnnotationException("Given field '" + field
-            + "' has no EdmProperty or EdmNavigationProperty annotation.");
-      }
-      return navProperty.name();
-    }
-    return property.name();
-  }
-
-  public String getPropertyName(Field field) {
-    String propertyName = getPropertyNameFromAnnotation(field);
-    if (propertyName.isEmpty()) {
-      propertyName = getCanonicalName(field);
-    }
-    return propertyName;
-  }
-
-  public String extractFromRoleName(EdmNavigationProperty enp, Field field) {
-    return getCanonicalRole(field.getDeclaringClass());
-  }
-
-  public String extractToRoleName(EdmNavigationProperty enp, Field field) {
-    String role = enp.toRole();
-    if (role.isEmpty()) {
-      role = getCanonicalRole(
-          field.getType().isArray() || Collection.class.isAssignableFrom(field.getType()) ?
-              (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0] : field.getType());
-    }
-    return role;
-  }
-
-  public String getCanonicalRole(Class<?> fallbackClass) {
-    String toRole = extractEntityTypeName(fallbackClass);
-    return "r_" + toRole;
-  }
-
-  public String extractRelationshipName(EdmNavigationProperty enp, Field field) {
-    String relationshipName = enp.association();
-    if (relationshipName.isEmpty()) {
-      final String fromRole = extractFromRoleName(enp, field);
-      final String toRole = extractToRoleName(enp, field);
-      if (fromRole.compareTo(toRole) > 0) {
-        relationshipName = toRole + "-" + fromRole;
-      } else {
-        relationshipName = fromRole + "-" + toRole;
-      }
-    }
-    return relationshipName;
-  }
-
-  public EdmMultiplicity getMultiplicity(EdmNavigationProperty enp, Field field) {
-    EdmMultiplicity multiplicity = mapMultiplicity(enp.toMultiplicity());
-    final boolean isCollectionType = field.getType().isArray() || Collection.class.isAssignableFrom(field.getType());
-
-    if (multiplicity == EdmMultiplicity.ONE && isCollectionType) {
-      return EdmMultiplicity.MANY;
-    }
-    return multiplicity;
-  }
-
-
-  /**
-   * Set key fields based on values in map.
-   * If an key field is not available or <code>NULL</code> in the map 
-   * it will be not set as <code>NULL</code> at the instance object.
-   * 
-   * @param instance
-   * @param keys
-   * @return
-   */
-  public <T> T setKeyFields(T instance, Map<String, Object> keys) {
-    List<Field> fields = getAnnotatedFields(instance, EdmKey.class);
-
-    for (Field field : fields) {
-      String propertyName = getPropertyName(field);
-      Object keyValue = keys.get(propertyName);
-      setValueForProperty(instance, propertyName, keyValue);
-    }
-
-    return instance;
-  }
-
-  public static final class ODataAnnotationException extends ODataException {
-    private static final long serialVersionUID = 1L;
-
-    public ODataAnnotationException(String message) {
-      super(message);
-    }
-  }
-
-  
-  public class AnnotatedNavInfo {
-    private final Field fromField;
-    private final Field toField;
-    private final EdmNavigationProperty fromNavigation;
-    private final EdmNavigationProperty toNavigation;
-
-    public AnnotatedNavInfo(Field fromField, Field toField, EdmNavigationProperty fromNavigation,
-        EdmNavigationProperty toNavigation) {
-      this.fromField = fromField;
-      this.toField = toField;
-      this.fromNavigation = fromNavigation;
-      this.toNavigation = toNavigation;
-    }
-
-    public Field getFromField() {
-      return fromField;
-    }
-
-    public Field getToField() {
-      return toField;
-    }
-
-    public EdmMultiplicity getFromMultiplicity() {
-      return getMultiplicity(toNavigation, toField);
-    }
-
-    public EdmMultiplicity getToMultiplicity() {
-      return getMultiplicity(fromNavigation, fromField);
-    }
-    
-    public boolean isBiDirectional() {
-      return toNavigation != null;
-    }
-  }
-
-  public AnnotatedNavInfo getCommonNavigationInfo(Class<?> sourceClass, Class<?> targetClass) {
-    List<Field> sourceFields = getAnnotatedFields(sourceClass, EdmNavigationProperty.class);
-    List<Field> targetFields = getAnnotatedFields(targetClass, EdmNavigationProperty.class);
-
-    // first try via association name to get full navigation information
-    for (Field sourceField : sourceFields) {
-      final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
-      final String sourceAssociation = extractRelationshipName(sourceNav, sourceField);
-      for (Field targetField : targetFields) {
-        final EdmNavigationProperty targetNav = targetField.getAnnotation(EdmNavigationProperty.class);
-        final String targetAssociation = extractRelationshipName(targetNav, targetField);
-        if (sourceAssociation.equals(targetAssociation)) {
-          return new AnnotatedNavInfo(sourceField, targetField, sourceNav, targetNav);
-        }
-      }
-    }
-    
-    // if nothing was found assume none bi-directinal navigation
-    String targetEntityTypeName = extractEntityTypeName(targetClass);
-    for (Field sourceField : sourceFields) {
-      final EdmNavigationProperty sourceNav = sourceField.getAnnotation(EdmNavigationProperty.class);
-      final String navTargetEntityName = extractEntitTypeName(sourceNav, sourceField);
-      
-      if (navTargetEntityName.equals(targetEntityTypeName)) {
-        return new AnnotatedNavInfo(sourceField, null, sourceNav, null);
-      }
-    }
-    
-    return null;
-  }
-
-  public Class<?> getFieldTypeForProperty(Object instance, String propertyName) throws ODataAnnotationException {
-    if (instance == null) {
-      return null;
-    }
-
-    Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
-    if (field == null) {
-      throw new ODataAnnotationException("No field for property '" + propertyName
-          + "' found at class '" + instance.getClass() + "'.");
-    }
-    return field.getType();
-  }
-
-  public Object getValueForProperty(Object instance, String propertyName) throws ODataAnnotationException {
-    if (instance == null) {
-      return null;
-    }
-
-    Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
-    if (field == null) {
-      throw new ODataAnnotationException("No field for property '" + propertyName
-          + "' found at class '" + instance.getClass() + "'.");
-    }
-    return getFieldValue(instance, field);
-  }
-
-  public void setValueForProperty(Object instance, String propertyName, Object propertyValue) {
-    if (instance != null) {
-      Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
-      if (field != null) {
-        setFieldValue(instance, field, propertyValue);
-      }
-    }
-  }
-
-  private Field getFieldForPropertyName(Object instance, String propertyName,
-      Class<?> resultClass, boolean inherited) {
-    if (instance == null) {
-      return null;
-    }
-
-    Field[] fields = resultClass.getDeclaredFields();
-    for (Field field : fields) {
-      EdmProperty property = field.getAnnotation(EdmProperty.class);
-      if (property != null) {
-        if (property.name().isEmpty() && getCanonicalName(field).equals(propertyName)) {
-          return field;
-        } else if (property.name().equals(propertyName)) {
-          return field;
-        }
-      }
-    }
-
-    Class<?> superClass = resultClass.getSuperclass();
-    if (inherited && superClass != Object.class) {
-      return getFieldForPropertyName(instance, propertyName, superClass, true);
-    }
-
-    return null;
-  }
-
-  public Object getValueForField(Object instance, String fieldName, Class<? extends Annotation> annotation) {
-    if (instance == null) {
-      return null;
-    }
-    return getValueForField(instance, fieldName, instance.getClass(), annotation, true);
-  }
-
-  public Object getValueForField(Object instance, Class<? extends Annotation> annotation) {
-    if (instance == null) {
-      return null;
-    }
-    return getValueForField(instance, instance.getClass(), annotation, true);
-  }
-
-  private Object getValueForField(Object instance, Class<?> resultClass,
-      Class<? extends Annotation> annotation, boolean inherited) {
-    return getValueForField(instance, null, resultClass, annotation, inherited);
-  }
-
-  public Map<String, Object> getValueForAnnotatedFields(Object instance,
-      Class<? extends Annotation> annotation) {
-    return getValueForAnnotatedFields(instance, instance.getClass(), annotation, true);
-  }
-
-  private Map<String, Object> getValueForAnnotatedFields(Object instance, Class<?> resultClass,
-      Class<? extends Annotation> annotation, boolean inherited) {
-    if (instance == null) {
-      return null;
-    }
-
-    Field[] fields = resultClass.getDeclaredFields();
-    Map<String, Object> fieldName2Value = new HashMap<String, Object>();
-
-    for (Field field : fields) {
-      if (field.getAnnotation(annotation) != null) {
-        Object value = getFieldValue(instance, field);
-        final EdmProperty property = field.getAnnotation(EdmProperty.class);
-        final String name = property == null || property.name().isEmpty() ? field.getName() : property.name();
-        fieldName2Value.put(name, value);
-      }
-    }
-
-    Class<?> superClass = resultClass.getSuperclass();
-    if (inherited && superClass != Object.class) {
-      Map<String, Object> tmp = getValueForAnnotatedFields(instance, superClass, annotation, true);
-      fieldName2Value.putAll(tmp);
-    }
-
-    return fieldName2Value;
-  }
-
-  public void setValueForAnnotatedField(Object instance, Class<? extends Annotation> annotation, Object value) 
-      throws ODataAnnotationException {
-    List<Field> fields = getAnnotatedFields(instance, annotation);
-
-    if(fields.isEmpty()) {
-      throw new ODataAnnotationException("No field found for annotation '" + annotation
-          + "' on instance '" + instance + "'.");
-    } else if(fields.size() > 1) {
-      throw new ODataAnnotationException("More then one field found for annotation '" + annotation
-          + "' on instance '" + instance + "'.");
-    }
-
-    setFieldValue(instance, fields.get(0), value);
-  }
-
-  public void setValuesToAnnotatedFields(Object instance,
-      Class<? extends Annotation> annotation, Map<String, Object> fieldName2Value) {
-    List<Field> fields = getAnnotatedFields(instance, annotation);
-
-    // XXX: refactore
-    for (Field field : fields) {
-      final String canonicalName = getCanonicalName(field);
-      if (fieldName2Value.containsKey(canonicalName)) {
-        Object value = fieldName2Value.get(canonicalName);
-        setFieldValue(instance, field, value);
-      }
-    }
-  }
-
-  public List<Field> getAnnotatedFields(Object instance, Class<? extends Annotation> annotation) {
-    if (instance == null) {
-      return null;
-    }
-    return getAnnotatedFields(instance.getClass(), annotation, true);
-  }
-
-  public List<Field> getAnnotatedFields(Class<?> fieldClass, Class<? extends Annotation> annotation) {
-    return getAnnotatedFields(fieldClass, annotation, true);
-  }
-
-  /**
-   *
-   * @param instance
-   * @param resultClass
-   * @param annotation
-   * @param inherited
-   * @return
-   */
-  private List<Field> getAnnotatedFields(Class<?> resultClass,
-      Class<? extends Annotation> annotation, boolean inherited) {
-    if (resultClass == null) {
-      return null;
-    }
-
-    Field[] fields = resultClass.getDeclaredFields();
-    List<Field> annotatedFields = new ArrayList<Field>();
-
-    for (Field field : fields) {
-      if (field.getAnnotation(annotation) != null) {
-        annotatedFields.add(field);
-      }
-    }
-
-    Class<?> superClass = resultClass.getSuperclass();
-    if (inherited && superClass != Object.class) {
-      List<Field> tmp = getAnnotatedFields(superClass, annotation, true);
-      annotatedFields.addAll(tmp);
-    }
-
-    return annotatedFields;
-  }
-
-  private Object getValueForField(Object instance, String fieldName, Class<?> resultClass,
-      Class<? extends Annotation> annotation, boolean inherited) {
-    if (instance == null) {
-      return null;
-    }
-
-    Field[] fields = resultClass.getDeclaredFields();
-    for (Field field : fields) {
-      if (field.getAnnotation(annotation) != null
-          && (fieldName == null || field.getName().equals(fieldName))) {
-        return getFieldValue(instance, field);
-      }
-    }
-
-    Class<?> superClass = resultClass.getSuperclass();
-    if (inherited && superClass != Object.class) {
-      return getValueForField(instance, fieldName, superClass, annotation, true);
-    }
-
-    return null;
-  }
-
-  private Object getFieldValue(Object instance, Field field) {
-    try {
-      boolean access = field.isAccessible();
-      field.setAccessible(true);
-      Object value = field.get(instance);
-      field.setAccessible(access);
-      return value;
-    } catch (IllegalArgumentException ex) { // should never happen
-      throw new ODataRuntimeException(ex);
-    } catch (IllegalAccessException ex) { // should never happen
-      throw new ODataRuntimeException(ex);
-    }
-  }
-
-  private void setFieldValue(Object instance, Field field, Object value) {
-    try {
-      Object usedValue = value;
-      if (value != null
-          && field.getType() != value.getClass()
-          && value.getClass() == String.class) {
-        usedValue = convert(field, (String) value);
-      }
-      boolean access = field.isAccessible();
-      field.setAccessible(true);
-      field.set(instance, usedValue);
-      field.setAccessible(access);
-    } catch (IllegalArgumentException ex) { // should never happen
-      throw new ODataRuntimeException(ex);
-    } catch (IllegalAccessException ex) { // should never happen
-      throw new ODataRuntimeException(ex);
-    }
-  }
-
-  public Object convert(Field field, String propertyValue) {
-    Class<?> fieldClass = field.getType();
-    try {
-      EdmProperty property = field.getAnnotation(EdmProperty.class);
-      EdmSimpleTypeKind type = mapTypeKind(property.type());
-      return type.getEdmSimpleTypeInstance().valueOfString(propertyValue,
-          EdmLiteralKind.DEFAULT, null, fieldClass);
-    } catch (EdmSimpleTypeException ex) {
-      throw new ODataRuntimeException("Conversion failed for string property with error: "
-          + ex.getMessage(), ex);
-    }
-  }
-
-  public boolean isEdmAnnotated(Object object) {
-    if (object == null) {
-      return false;
-    }
-    return isEdmAnnotated(object.getClass());
-  }
-
-  public boolean isEdmTypeAnnotated(Class<?> clazz) {
-    boolean isComplexEntity = clazz.getAnnotation(EdmComplexType.class) != null;
-    boolean isEntity = clazz.getAnnotation(EdmEntityType.class) != null;
-    return isComplexEntity || isEntity;
-  }
-
-  public boolean isEdmAnnotated(Class<?> clazz) {
-    if (clazz == null) {
-      return false;
-    } else {
-      final boolean isEntity = null != clazz.getAnnotation(EdmEntityType.class);
-      final boolean isEntitySet = null != clazz.getAnnotation(EdmEntitySet.class);
-      final boolean isComplexEntity = null != clazz.getAnnotation(EdmComplexType.class);
-      return isEntity || isComplexEntity || isEntitySet;
-    }
-  }
-
-  public String getCanonicalName(Field field) {
-    return firstCharToUpperCase(field.getName());
-  }
-
-  public String getCanonicalName(Class<?> clazz) {
-    return firstCharToUpperCase(clazz.getSimpleName());
-  }
-
-  private String firstCharToUpperCase(String content) {
-    if (content == null || content.isEmpty()) {
-      return content;
-    }
-    return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1);
-  }
-
-  public EdmSimpleTypeKind mapTypeKind(org.apache.olingo.odata2.api.annotation.edm.EdmType type) {
-    switch (type) {
-      case BINARY: return EdmSimpleTypeKind.Binary;
-      case BOOLEAN: return EdmSimpleTypeKind.Boolean;
-      case BYTE: return EdmSimpleTypeKind.Byte;
-      case COMPLEX: return EdmSimpleTypeKind.Null;
-      case DATE_TIME: return EdmSimpleTypeKind.DateTime;
-      case DATE_TIME_OFFSET: return EdmSimpleTypeKind.DateTimeOffset;
-      case DECIMAL: return EdmSimpleTypeKind.Decimal;
-      case DOUBLE: return EdmSimpleTypeKind.Double;
-      case GUID: return EdmSimpleTypeKind.Guid;
-      case INT16: return EdmSimpleTypeKind.Int16;
-      case INT32: return EdmSimpleTypeKind.Int32;
-      case INT64: return EdmSimpleTypeKind.Int64;
-      case NULL: return EdmSimpleTypeKind.Null;
-      case SBYTE: return EdmSimpleTypeKind.SByte;
-      case SINGLE: return EdmSimpleTypeKind.Single;
-      case STRING: return EdmSimpleTypeKind.String;
-      case TIME: return EdmSimpleTypeKind.Time;
-      default: throw new ODataRuntimeException("Unknown type '" + type
-        + "' for mapping to EdmSimpleTypeKind.");
-    }
-  }
-
-  public EdmMultiplicity mapMultiplicity(Multiplicity multiplicity) {
-    switch (multiplicity) {
-    case ZERO_OR_ONE: return EdmMultiplicity.ZERO_TO_ONE;
-    case ONE: return EdmMultiplicity.ONE;
-    case MANY: return EdmMultiplicity.MANY;
-    default: throw new ODataRuntimeException("Unknown type '" + multiplicity + "' for mapping to EdmMultiplicity.");
-    }
-  }
-  
-  /**
-   * 
-   */
-  private static class EdmAnnotationException extends RuntimeException {
-
-    private static final long serialVersionUID = 42L;
-
-    public EdmAnnotationException(String message) {
-      super(message);
-    }
-  }
-
-  public String getCanonicalNamespace(Class<?> aClass) {
-    return generateNamespace(aClass);
-  }
-
-  public String extractContainerName(Class<?> aClass) {
-    EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
-    if(entitySet != null) {
-      String containerName = entitySet.container();
-      if(!containerName.isEmpty()) {
-        return containerName;
-      }
-    }
-    return DEFAULT_CONTAINER_NAME;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
deleted file mode 100644
index 5e9fcdb..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.util;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FilenameFilter;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- */
-public class ClassHelper {
-  
-  private static final File[] EMPTY_FILE_ARRAY = new File[0];
-  
-  private static final FilenameFilter CLASSFILE_FILTER = new FilenameFilter() {
-    @Override
-    public boolean accept(File dir, String name) {
-      return name.endsWith(CLASSFILE_ENDING);
-    }
-    public static final String CLASSFILE_ENDING = ".class";
-  };
-  
-  private static final FileFilter FOLDER_FILTER = new FileFilter() {
-    @Override
-    public boolean accept(File pathname) {
-      return pathname.isDirectory();
-    }
-  };
-  
-  public static final List<Class<?>> loadClasses(String packageToScan, ClassValidator cv) {
-    return loadClasses(packageToScan, CLASSFILE_FILTER, cv);
-  }
-
-  
-  public static final List<Class<?>> loadClasses(String packageToScan, FilenameFilter ff, ClassValidator cv) {
-    final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-    String folderToScan = packageToScan.replace(".", "/");
-    URL url = classLoader.getResource(folderToScan);
-    if(url == null) {
-      throw new IllegalArgumentException("No folder to scan found for package '" + packageToScan + "'.");
-    }
-    File folder = new File(url.getFile());
-    File[] classFiles = folder.listFiles(ff);
-    if(classFiles == null) {
-      classFiles = EMPTY_FILE_ARRAY;
-    }
-
-    List<Class<?>> annotatedClasses = new ArrayList<Class<?>>(classFiles.length);
-    for (File file : classFiles) {
-      String name = file.getName();
-      String fqn = packageToScan + "." + name.substring(0, name.length() - 6);
-      try {
-        Class<?> c = classLoader.loadClass(fqn);
-        if (cv.isClassValid(c)) {
-          annotatedClasses.add(c);
-        }
-      } catch (ClassNotFoundException ex) {
-        throw new IllegalArgumentException("Exception during class loading of class '" + fqn + 
-                "' with message '" + ex.getMessage() + "'.");
-      }
-    }
-    
-    // recursive search
-    File[] subfolders = listSubFolder(folder);
-    for (File file : subfolders) {
-      List<Class<?>> subFolderClazzes = loadClasses(packageToScan + "." + file.getName(), ff, cv);
-      annotatedClasses.addAll(subFolderClazzes);
-    }
-    //
-    
-    return annotatedClasses;
-  }
-
-  private static File[] listSubFolder(File folder) {
-    File[] subfolders = folder.listFiles(FOLDER_FILTER);
-    if(subfolders == null) {
-      return EMPTY_FILE_ARRAY;
-    }
-    return subfolders;
-  }
-  
-  public interface ClassValidator {
-    boolean isClassValid(Class<?> c);
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
deleted file mode 100644
index 04dbefc..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright 2013 The Apache Software Foundation.
- *
- * Licensed 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.odata2.core.annotation.data;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.edm.FullQualifiedName;
-import org.apache.olingo.odata2.api.edm.provider.EntitySet;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationEdmProvider;
-import org.apache.olingo.odata2.core.annotation.model.Building;
-import org.apache.olingo.odata2.core.annotation.model.ModelSharedConstants;
-import org.apache.olingo.odata2.core.annotation.model.Photo;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-/**
- *
- */
-public class AnnotationsInMemoryDsTest {
-
-  private final AnnotationInMemoryDs datasource;
-  private AnnotationEdmProvider edmProvider;
-  private static final String DEFAULT_CONTAINER = ModelSharedConstants.CONTAINER_1;
-
-  public AnnotationsInMemoryDsTest() {
-    datasource = new AnnotationInMemoryDs(Building.class.getPackage().getName(), false);
-    edmProvider = new AnnotationEdmProvider(Building.class.getPackage().getName());
-  }
-
-  @Test
-  public void createSimpleEntity() throws Exception {
-    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
-
-    Building building = new Building();
-    building.setName("Common Building");
-    datasource.createData(edmEntitySet, building);
-
-    Map<String, Object> keys = new HashMap<String, Object>();
-    keys.put("Id", "1");
-
-    Building read = (Building) datasource.readData(edmEntitySet, keys);
-    Assert.assertEquals("Common Building", read.getName());
-    Assert.assertEquals("1", read.getId());
-  }
-
-  
-  @Test
-  public void createSimpleEntityWithOwnKey() throws Exception {
-    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
-
-    Building building = new Building();
-    building.setName("Common Building");
-    AnnotationHelper ah = new AnnotationHelper();
-    ah.setValueForProperty(building, "Id", "42");
-    datasource.createData(edmEntitySet, building);
-
-    Map<String, Object> keys = new HashMap<String, Object>();
-    keys.put("Id", "42");
-
-    Building read = (Building) datasource.readData(edmEntitySet, keys);
-    Assert.assertEquals("Common Building", read.getName());
-    Assert.assertEquals("42", read.getId());
-  }
-
-  @Test
-  public void createSimpleEntityWithDuplicateKey() throws Exception {
-    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
-    AnnotationHelper ah = new AnnotationHelper();
-
-    Building building = new Building();
-    building.setName("Common Building");
-    ah.setValueForProperty(building, "Id", "42");
-    datasource.createData(edmEntitySet, building);
-    //
-    Building buildingDuplicate = new Building();
-    buildingDuplicate.setName("Duplicate Building");
-    ah.setValueForProperty(buildingDuplicate, "Id", "42");
-    datasource.createData(edmEntitySet, buildingDuplicate);
-
-    Map<String, Object> keys42 = new HashMap<String, Object>();
-    keys42.put("Id", "42");
-    Building read42 = (Building) datasource.readData(edmEntitySet, keys42);
-    Assert.assertEquals("Common Building", read42.getName());
-    Assert.assertEquals("42", read42.getId());
-
-    Map<String, Object> keys = new HashMap<String, Object>();
-    keys.put("Id", "1");
-    Building read = (Building) datasource.readData(edmEntitySet, keys);
-    Assert.assertEquals("Duplicate Building", read.getName());
-    Assert.assertEquals("1", read.getId());
-}
-
-  
-  @Test
-  public void createEntityTwoKeys() throws Exception {
-    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Photos");
-
-    Photo photo = new Photo();
-    photo.setName("BigPicture");
-    photo.setType("PNG");
-    photo.setImageUri("https://localhost/image.png");
-    photo.setImageType("image/png");
-    datasource.createData(edmEntitySet, photo);
-
-    Map<String, Object> keys = new HashMap<String, Object>();
-    keys.put("ImageFormat", "PNG");
-    keys.put("Name", "BigPicture");
-
-    Photo read = (Photo) datasource.readData(edmEntitySet, keys);
-    Assert.assertEquals("BigPicture", read.getName());
-    Assert.assertEquals("PNG", read.getType());
-    Assert.assertEquals("image/png", read.getImageType());
-    Assert.assertEquals("https://localhost/image.png", read.getImageUri());
-  }
-
-  @Test
-  //  @Ignore("Rethink update method")
-  public void createAndUpdateEntityTwoKeys() throws Exception {
-    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Photos");
-
-    Photo photo = new Photo();
-    final String nameKeyValue = "BigPicture";
-    final String typeKeyValue = "PNG";
-    photo.setName(nameKeyValue);
-    photo.setType(typeKeyValue);
-    photo.setImageUri("https://localhost/image.png");
-    photo.setImageType("image/png");
-    datasource.createData(edmEntitySet, photo);
-
-    Map<String, Object> keys = new HashMap<String, Object>();
-    keys.put("Name", "BigPicture");
-    keys.put("ImageFormat", "PNG");
-
-    Photo read = (Photo) datasource.readData(edmEntitySet, keys);
-    Assert.assertEquals("BigPicture", read.getName());
-    Assert.assertEquals("PNG", read.getType());
-    Assert.assertEquals("image/png", read.getImageType());
-    Assert.assertEquals("https://localhost/image.png", read.getImageUri());
-
-    // update
-    Photo updatedPhoto = new Photo();
-    updatedPhoto.setName(nameKeyValue);
-    updatedPhoto.setType(typeKeyValue);
-    updatedPhoto.setImageUri("https://localhost/image.jpg");
-    updatedPhoto.setImageType("image/jpg");
-    datasource.updateData(edmEntitySet, updatedPhoto);
-
-    Map<String, Object> updatedKeys = new HashMap<String, Object>();
-    updatedKeys.put("Name", nameKeyValue);
-    updatedKeys.put("ImageFormat", typeKeyValue);
-
-    Photo readUpdated = (Photo) datasource.readData(edmEntitySet, updatedKeys);
-    Assert.assertEquals("BigPicture", readUpdated.getName());
-    Assert.assertEquals("PNG", readUpdated.getType());
-    Assert.assertEquals("image/jpg", readUpdated.getImageType());
-    Assert.assertEquals("https://localhost/image.jpg", readUpdated.getImageUri());
-  }
-
-  private EdmEntitySet createMockedEdmEntitySet(String entitySetName) throws ODataException {
-    EntitySet entitySet = edmProvider.getEntitySet(DEFAULT_CONTAINER, entitySetName);
-    FullQualifiedName entityType = entitySet.getEntityType();
-
-    EdmEntitySet edmEntitySet = Mockito.mock(EdmEntitySet.class);
-    Mockito.when(edmEntitySet.getName()).thenReturn(entitySetName);
-    EdmEntityType edmEntityType = Mockito.mock(EdmEntityType.class);
-    Mockito.when(edmEntitySet.getEntityType()).thenReturn(edmEntityType);
-    Mockito.when(edmEntityType.getName()).thenReturn(entityType.getName());
-
-    return edmEntitySet;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
deleted file mode 100644
index 494a090..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * Copyright 2013 The Apache Software Foundation.
- *
- * Licensed 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.odata2.core.annotation.edm;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
-import org.apache.olingo.odata2.api.edm.FullQualifiedName;
-import org.apache.olingo.odata2.api.edm.provider.Association;
-import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
-import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
-import org.apache.olingo.odata2.api.edm.provider.ComplexType;
-import org.apache.olingo.odata2.api.edm.provider.EntityContainer;
-import org.apache.olingo.odata2.api.edm.provider.EntityContainerInfo;
-import org.apache.olingo.odata2.api.edm.provider.EntitySet;
-import org.apache.olingo.odata2.api.edm.provider.EntityType;
-import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
-import org.apache.olingo.odata2.api.edm.provider.Key;
-import org.apache.olingo.odata2.api.edm.provider.NavigationProperty;
-import org.apache.olingo.odata2.api.edm.provider.Property;
-import org.apache.olingo.odata2.api.edm.provider.PropertyRef;
-import org.apache.olingo.odata2.api.edm.provider.Schema;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.core.annotation.model.Building;
-import org.apache.olingo.odata2.core.annotation.model.City;
-import org.apache.olingo.odata2.core.annotation.model.Employee;
-import org.apache.olingo.odata2.core.annotation.model.Location;
-import org.apache.olingo.odata2.core.annotation.model.Manager;
-import org.apache.olingo.odata2.core.annotation.model.ModelSharedConstants;
-import org.apache.olingo.odata2.core.annotation.model.Photo;
-import org.apache.olingo.odata2.core.annotation.model.RefBase;
-import org.apache.olingo.odata2.core.annotation.model.Room;
-import org.apache.olingo.odata2.core.annotation.model.Team;
-import org.junit.Test;
-
-/**
- *
- */
-public class AnnotationEdmProviderTest {
-
-  @EdmEntityType
-  @EdmEntitySet
-  private static final class GeneratedNamesTestClass {}
-
-  @EdmComplexType
-  private static final class GeneratedNamesComplexTestClass {}
-
-  @EdmEntityType(namespace="MyTestNamespace")
-  @EdmEntitySet(container="MyTestContainer")
-  private static final class DefinedNamesTestClass {}
-
-  private final AnnotationEdmProvider aep;
-  private final Collection<Class<?>> annotatedClasses = new ArrayList<Class<?>>();
-
-  public AnnotationEdmProviderTest() {
-    annotatedClasses.add(RefBase.class);
-    annotatedClasses.add(Building.class);
-    annotatedClasses.add(City.class);
-    annotatedClasses.add(Employee.class);
-    annotatedClasses.add(Location.class);
-    annotatedClasses.add(Manager.class);
-    annotatedClasses.add(Photo.class);
-    annotatedClasses.add(Room.class);
-    annotatedClasses.add(Team.class);
-
-    aep = new AnnotationEdmProvider(annotatedClasses);
-  }
-
-  @Test
-  public void defaultNamespaceGeneration() throws ODataException {
-    Collection<Class<?>> localAnnotatedClasses = new ArrayList<Class<?>>();
-    localAnnotatedClasses.add(GeneratedNamesTestClass.class); 
-    AnnotationEdmProvider localAep = new AnnotationEdmProvider(localAnnotatedClasses);
-    // validate 
-    EntityType testType = localAep.getEntityType(new FullQualifiedName(
-            GeneratedNamesTestClass.class.getPackage().getName(), 
-            GeneratedNamesTestClass.class.getSimpleName()));
-    assertNotNull("Requested entity not found.", testType);
-    assertEquals("GeneratedNamesTestClass", testType.getName());
-    assertNull("This should not have a base type", testType.getBaseType());
-  }
-
-  @Test
-  public void defaultNamespaceGenerationComplexType() throws ODataException {
-    Collection<Class<?>> localAnnotatedClasses = new ArrayList<Class<?>>();
-    localAnnotatedClasses.add(GeneratedNamesComplexTestClass.class); 
-    AnnotationEdmProvider localAep = new AnnotationEdmProvider(localAnnotatedClasses);
-    // validate 
-    ComplexType testType = localAep.getComplexType(new FullQualifiedName(
-            GeneratedNamesComplexTestClass.class.getPackage().getName(), 
-            GeneratedNamesComplexTestClass.class.getSimpleName()));
-    assertNotNull("Requested entity not found.", testType);
-    assertEquals("GeneratedNamesComplexTestClass", testType.getName());
-    assertNull("This should not have a base type", testType.getBaseType());
-  }
-
-  @Test
-  public void defaultContainerNameGeneration() throws ODataException {
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    AnnotationEdmProvider localAep = 
-      new AnnotationEdmProvider((Collection) Arrays.asList(GeneratedNamesTestClass.class));
-    
-    EntityContainerInfo containerInfo = localAep.getEntityContainerInfo(null);
-    assertNotNull(containerInfo);
-    assertEquals("DefaultContainer", containerInfo.getName());
-  }
-
-
-  @Test
-  public void defaultNamespaceDefined() throws ODataException {
-    Collection<Class<?>> localAnnotatedClasses = new ArrayList<Class<?>>();
-    localAnnotatedClasses.add(DefinedNamesTestClass.class); 
-    AnnotationEdmProvider localAep = new AnnotationEdmProvider(localAnnotatedClasses);
-    // validate 
-    EntityType testClass = localAep.getEntityType(new FullQualifiedName("MyTestNamespace",
-        DefinedNamesTestClass.class.getSimpleName()));
-    assertNotNull("Requested entity not found.", testClass);
-    assertEquals("DefinedNamesTestClass", testClass.getName());
-    assertNull("This should not have a base type", testClass.getBaseType());
-  }
-
-  @Test
-  public void defaultContainerNameDefined() throws ODataException {
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    AnnotationEdmProvider localAep = new AnnotationEdmProvider((Collection) Arrays.asList(DefinedNamesTestClass.class));
-    
-    EntityContainerInfo containerInfo = localAep.getEntityContainerInfo(null);
-    assertNotNull(containerInfo);
-    assertEquals("MyTestContainer", containerInfo.getName());
-  }
-
-  @Test
-  public void loadAnnotatedClassesFromPackage() throws Exception {
-    AnnotationEdmProvider localAep = new AnnotationEdmProvider("org.apache.olingo.odata2.core.annotation.model");
-
-    // validate employee
-    EntityType employee = localAep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Employee"));
-    assertEquals("Employee", employee.getName());
-    final List<PropertyRef> employeeKeys = employee.getKey().getKeys();
-    assertEquals(1, employeeKeys.size());
-    assertEquals("EmployeeId", employeeKeys.get(0).getName());
-    assertEquals(6, employee.getProperties().size());
-    assertEquals(3, employee.getNavigationProperties().size());
-
-    List<Schema> schemas = localAep.getSchemas();
-    assertEquals(1, schemas.size());
-    EntityContainerInfo info = localAep.getEntityContainerInfo(ModelSharedConstants.CONTAINER_1);
-    assertTrue(info.isDefaultEntityContainer());
-  }
-
-  @Test
-  public void annotationProviderBasic() throws Exception {
-    assertNotNull(aep);
-
-    List<Schema> schemas = aep.getSchemas();
-    assertEquals(1, schemas.size());
-    EntityContainerInfo info = aep.getEntityContainerInfo(ModelSharedConstants.CONTAINER_1);
-    assertTrue(info.isDefaultEntityContainer());
-    
-    FunctionImport funImp = aep.getFunctionImport(ModelSharedConstants.CONTAINER_1, "NoImport");
-    assertNull(funImp);
-
-    final FullQualifiedName associationFqn = new FullQualifiedName(
-            ModelSharedConstants.NAMESPACE_1, "NoAssociation");
-    Association noAssociation = aep.getAssociation(associationFqn);
-    assertNull(noAssociation);
-    
-    AssociationSet noAssociationSet = aep.getAssociationSet(
-            ModelSharedConstants.CONTAINER_1, associationFqn, "NoSrc", "NoSrcEntity");
-    assertNull(noAssociationSet);
-    
-    AssociationSet asBuildingRooms = aep.getAssociationSet(
-            ModelSharedConstants.CONTAINER_1, defaultFqn("BuildingRooms"), "Buildings", "r_Building");
-    assertNotNull(asBuildingRooms);
-    assertEquals("Buildings", asBuildingRooms.getEnd1().getEntitySet());
-    assertEquals("r_Building", asBuildingRooms.getEnd1().getRole());
-    assertEquals("Rooms", asBuildingRooms.getEnd2().getEntitySet());
-    assertEquals("r_Room", asBuildingRooms.getEnd2().getRole());
-  }
-
-  @Test
-  public void annotationProviderGetDefaultContainer() throws Exception {
-    assertNotNull(aep);
-
-    List<Schema> schemas = aep.getSchemas();
-    assertEquals(1, schemas.size());
-    EntityContainerInfo info = aep.getEntityContainerInfo(null);
-    assertTrue(info.isDefaultEntityContainer());
-    assertEquals(ModelSharedConstants.CONTAINER_1, info.getName());
-  }
-
-  @Test
-  public void schemaBasic() throws Exception {
-    assertNotNull(aep);
-
-    List<Schema> schemas = aep.getSchemas();
-    assertEquals(1, schemas.size());
-
-    Schema schema = schemas.get(0);
-    List<EntityContainer> containers = schema.getEntityContainers();
-    assertEquals(1, containers.size());
-    EntityContainer container = containers.get(0);
-    assertEquals(ModelSharedConstants.CONTAINER_1, container.getName());
-    final List<EntitySet> entitySets = container.getEntitySets();
-    assertEquals(6, entitySets.size());
-    
-    List<Association> associations = schema.getAssociations();
-    assertEquals(4, associations.size());
-    for (Association association : associations) {
-      assertNotNull(association.getName());
-      validateAssociation(association);
-    }
-  }
-  
-  private FullQualifiedName defaultFqn(String name) {
-    return new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, name);
-  }
-
-  private void validateAssociation(Association association) {
-    String name = association.getName();
-    if(name.equals("r_Employee-r_Room")) {
-      validateAssociation(association, 
-              "r_Room", EdmMultiplicity.ONE, defaultFqn("Room"),
-              "r_Employee", EdmMultiplicity.MANY, defaultFqn("Employee"));
-    } else if(name.equals("BuildingRooms")) {
-        validateAssociation(association, 
-                "r_Building", EdmMultiplicity.ONE, defaultFqn("Building"),
-                "r_Room", EdmMultiplicity.MANY, defaultFqn("Room"));
-    } else if(name.equals("ManagerEmployees")) {
-        validateAssociation(association, 
-                "r_Manager", EdmMultiplicity.ONE, defaultFqn("Manager"),
-                "r_Employee", EdmMultiplicity.MANY, defaultFqn("Employee"));
-    } else if(name.equals("TeamEmployees")) {
-        validateAssociation(association, 
-                "r_Team", EdmMultiplicity.ONE, defaultFqn("Team"),
-                "r_Employee", EdmMultiplicity.MANY, defaultFqn("Employee"));
-    } else {
-        fail("Got unknown association to validate with name '" + name + "'.");
-    }
-  }
-
-  private void validateAssociation(Association association, 
-          String fromRole, EdmMultiplicity fromMulti, FullQualifiedName fromType, 
-          String toRole, EdmMultiplicity toMulti, FullQualifiedName toType) {
-
-    AssociationEnd[] ends = new AssociationEnd[]{association.getEnd1(),association.getEnd2()};
-    for (AssociationEnd associationEnd : ends) {
-      if(associationEnd.getRole().equals(fromRole)) {
-        validateAssociationEnd(associationEnd, fromRole, fromMulti, fromType);
-      } else if(associationEnd.getRole().equals(toRole)) {
-        validateAssociationEnd(associationEnd, toRole, toMulti, toType);
-      } else {
-        fail("Unexpected navigation end '" + associationEnd.getRole() 
-                + "' for association with name '" + association.getName() + "'.");
-      }
-    }
-  }
-
-    private void validateAssociationEnd(AssociationEnd associationEnd, 
-          String role, EdmMultiplicity multiplicity, FullQualifiedName type) {
-    assertEquals(role, associationEnd.getRole());
-    assertEquals(multiplicity, associationEnd.getMultiplicity());
-    assertEquals(type, associationEnd.getType());
-  }
-
-
-  @Test
-  public void entitySetTeams() throws Exception {
-    // validate teams
-    EntitySet teams = aep.getEntitySet(ModelSharedConstants.CONTAINER_1, "Teams");
-    assertEquals(ModelSharedConstants.NAMESPACE_1, teams.getEntityType().getNamespace());
-    assertEquals("Team", teams.getEntityType().getName());
-  }
-
-  @Test
-  public void entityTypeEmployee() throws Exception {
-    // validate employee
-    EntityType employee = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Employee"));
-    assertEquals("Employee", employee.getName());
-    final List<PropertyRef> employeeKeys = employee.getKey().getKeys();
-    assertEquals(1, employeeKeys.size());
-    assertEquals("EmployeeId", employeeKeys.get(0).getName());
-    assertEquals(6, employee.getProperties().size());
-    assertEquals(3, employee.getNavigationProperties().size());
-
-    for (NavigationProperty navigationProperty : employee.getNavigationProperties()) {
-      if (navigationProperty.getName().equals("ne_Manager")) {
-        validateNavProperty(navigationProperty, "ManagerEmployees", "r_Employee", "r_Manager");
-      } else if (navigationProperty.getName().equals("ne_Team")) {
-        validateNavProperty(navigationProperty, "TeamEmployees", "r_Employee", "r_Team");
-      } else if (navigationProperty.getName().equals("ne_Room")) {
-        validateNavProperty(navigationProperty, "r_Employee-r_Room", "r_Employee", "r_Room");
-      } else {
-        fail("Got unexpected navigation property with name '" + navigationProperty.getName() + "'.");
-      }
-    }
-}
-
-  @Test
-  public void entityTypeTeam() throws Exception {
-    // validate team
-    EntityType team = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Team"));
-    assertEquals("Team", team.getName());
-    assertEquals("Base", team.getBaseType().getName());
-    assertEquals(ModelSharedConstants.NAMESPACE_1, team.getBaseType().getNamespace());
-
-    assertEquals(1, team.getProperties().size());
-    assertEquals(1, team.getNavigationProperties().size());
-    NavigationProperty navigationProperty= team.getNavigationProperties().get(0);
-    validateNavProperty(navigationProperty, "TeamEmployees", "r_Team", "r_Employee");
-  }
-
-  @Test
-  public void entityTypePhotoWithTwoKeyProperties() throws Exception {
-    // validate team
-    EntityType photo = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Photo"));
-    assertEquals("Photo", photo.getName());
-    final List<Property> properties = photo.getProperties();
-    assertEquals(5, properties.size());
-    assertTrue(containsProperty(properties, "Name"));
-    assertTrue(containsProperty(properties, "ImageFormat"));
-    assertTrue(containsProperty(properties, "MimeType"));
-    assertTrue(containsProperty(properties, "ImageUrl"));
-    assertTrue(containsProperty(properties, "Image"));
-    assertFalse(photo.isAbstract());
-    assertTrue(photo.isHasStream());
-
-    Key photoKey = photo.getKey();
-    List<PropertyRef> keyReferences = photoKey.getKeys();
-    assertEquals(2, keyReferences.size());
-    PropertyRef name = getPropertyRef(keyReferences, "Name");
-    assertEquals("Name", name.getName());
-    PropertyRef imageFormat = getPropertyRef(keyReferences, "ImageFormat");
-    assertEquals("ImageFormat", imageFormat.getName());
-    
-//    assertEquals(0, photo.getNavigationProperties().size());
-    assertNull(photo.getNavigationProperties());
-  }
-
-  @Test
-  public void entityTypeAbstractBaseType() throws Exception {
-    // validate employee
-    EntityType baseType = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Base"));
-    assertEquals("Base", baseType.getName());
-    final List<PropertyRef> keys = baseType.getKey().getKeys();
-    assertEquals(1, keys.size());
-    assertEquals("Id", keys.get(0).getName());
-    assertEquals(2, baseType.getProperties().size());
-    assertTrue(baseType.isAbstract());
-
-    // validate base for team
-    EntityType team = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Team"));
-    assertEquals("Team", team.getName());
-    assertEquals("Base", team.getBaseType().getName());
-    assertEquals(ModelSharedConstants.NAMESPACE_1, team.getBaseType().getNamespace());
-  }
-
-  @Test
-  public void complexTypeLocation() throws Exception {
-    // validate employee
-    EntityType employee = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Employee"));
-    final List<Property> properties = employee.getProperties();
-    Property location = null;
-    for (Property property : properties) {
-      if (property.getName().equals("Location")) {
-        location = property;
-      }
-    }
-    assertNotNull(location);
-    assertEquals("Location", location.getName());
-
-    // validate location complex type
-    ComplexType locationType = aep.getComplexType(
-            new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "c_Location"));
-    assertEquals("c_Location", locationType.getName());
-    assertEquals(2, locationType.getProperties().size());
-  }
-
-  @Test
-  public void entityTypeRoomWithNavigation() throws Exception {
-    // validate employee
-    EntityType room = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Room"));
-    assertEquals("Room", room.getName());
-    assertEquals("Base", room.getBaseType().getName());
-    assertEquals(2, room.getProperties().size());
-    final List<NavigationProperty> navigationProperties = room.getNavigationProperties();
-    assertEquals(2, navigationProperties.size());
-    
-    for (NavigationProperty navigationProperty : navigationProperties) {
-      if(navigationProperty.getName().equals("nr_Employees")) {
-        validateNavProperty(navigationProperty, "r_Employee-r_Room", "r_Room", "r_Employee");
-      } else if(navigationProperty.getName().equals("nr_Building")) {
-        validateNavProperty(navigationProperty, "BuildingRooms", "r_Room", "r_Building");
-      } else {
-        fail("Got unexpected navigation property with name '" + navigationProperty.getName() + "'.");
-      }
-    }
-  }
-  
-  private void validateNavProperty(NavigationProperty navigationProperty, String name,
-          String relationship, String fromRole, String toRole) {
-    if(name != null) {
-      assertEquals(name, navigationProperty.getName());
-    }
-    FullQualifiedName fqn = new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, relationship);
-    assertEquals("Wrong relationship for navigation property.", fqn, navigationProperty.getRelationship());
-    assertEquals("Wrong fromRole for navigation property.", fromRole, navigationProperty.getFromRole());
-    assertEquals("Wrong toRole for navigation property.", toRole, navigationProperty.getToRole());
-  }
-  
-  private void validateNavProperty(NavigationProperty navigationProperty, 
-          String relationship, String fromRole, String toRole) {
-    validateNavProperty(navigationProperty, null, relationship, fromRole, toRole);
-  }
-  
-  private boolean containsProperty(List<Property> properties, String propertyName) {
-    return getProperty(properties, propertyName) != null;
-  }
-
-  private Property getProperty(List<Property> properties, String name) {
-    for (Property property : properties) {
-      if(name.equals(property.getName())) {
-        return property;
-      }
-    }
-    return null;
-  }
-  
-  private PropertyRef getPropertyRef(List<PropertyRef> properties, String name) {
-    for (PropertyRef property : properties) {
-      if(name.equals(property.getName())) {
-        return property;
-      }
-    }
-    return null;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
deleted file mode 100644
index 737b5e2..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.model;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *  
- */
-@EdmEntityType(name = "Building", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Buildings")
-public class Building {
-  @EdmKey
-  @EdmProperty(type = EdmType.INT32)
-  private String id;
-  @EdmProperty
-  private String name;
-  @EdmProperty(name = "Image", type = EdmType.BINARY)
-  private byte[] image;
-  @EdmNavigationProperty(name = "nb_Rooms", toType = Room.class,
-      association = "BuildingRooms", toMultiplicity = Multiplicity.MANY)
-  private List<Room> rooms = new ArrayList<Room>();
-
-  public Building() {}
-
-  public String getId() {
-    return id;
-  }
-
-  public void setName(final String name) {
-    this.name = name;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public void setImage(final byte[] byteArray) {
-    image = byteArray;
-  }
-
-  public byte[] getImage() {
-    if (image == null) {
-      return null;
-    } else {
-      return image.clone();
-    }
-  }
-
-  public List<Room> getRooms() {
-    return rooms;
-  }
-
-  @Override
-  public int hashCode() {
-      return id == null ? 0 : id.hashCode();
-  }
-
-  @Override
-  public boolean equals(final Object obj) {
-    return this == obj
-        || obj != null && getClass() == obj.getClass() && id == ((Building) obj).id;
-  }
-
-  @Override
-  public String toString() {
-    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Image\":\"" + Arrays.toString(image) + "\"}";
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
deleted file mode 100644
index 7b866a3..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.model;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-
-
-/**
- *  
- */
-@EdmComplexType(name="c_City", namespace = ModelSharedConstants.NAMESPACE_1)
-public class City {
-
-  @EdmProperty
-  private String postalCode;
-  @EdmProperty
-  private String cityName;
-
-  public City(final String postalCode, final String name) {
-    this.postalCode = postalCode;
-    cityName = name;
-  }
-
-  public void setPostalCode(final String postalCode) {
-    this.postalCode = postalCode;
-  }
-
-  public String getPostalCode() {
-    return postalCode;
-  }
-
-  public void setCityName(final String cityName) {
-    this.cityName = cityName;
-  }
-
-  public String getCityName() {
-    return cityName;
-  }
-
-  @Override
-  public String toString() {
-    return String.format("%s, %s", cityName, postalCode);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
deleted file mode 100644
index 63b8a76..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.model;
-
-import java.text.DateFormat;
-import java.util.Calendar;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *  
- */
-@EdmEntityType(name = "Employee", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Employees")
-public class Employee {
-  @EdmKey
-  @EdmProperty(name = "EmployeeId", type = EdmType.STRING)
-  private String employeeId;
-  @EdmProperty(name = "EmployeeName")
-  private String employeeName;
-  @EdmProperty
-  private int age;
-  @EdmNavigationProperty(name = "ne_Manager", association = "ManagerEmployees")
-  private Manager manager;
-  @EdmNavigationProperty(name = "ne_Team", association = "TeamEmployees")
-  private Team team;
-  @EdmNavigationProperty(name = "ne_Room")
-  private Room room;
-  @EdmMediaResourceMimeType
-  private String imageType;
-  @EdmMediaResourceContent
-  private byte[] image;
-  @EdmProperty(name = "ImageUrl")
-  private String imageUrl;
-  @EdmProperty(name = "EntryDate", type = EdmType.DATE_TIME)
-  private Calendar entryDate;
-  @EdmProperty(name = "Location")
-  private Location location;
-
-  public Employee(final String employeeId, final String name) {
-    this.employeeId = employeeId;
-    setEmployeeName(name);
-  }
-
-  public String getId() {
-    return employeeId;
-  }
-
-  public void setEmployeeName(final String employeeName) {
-    this.employeeName = employeeName;
-  }
-
-  public String getEmployeeName() {
-    return employeeName;
-  }
-
-  public void setAge(final int age) {
-    this.age = age;
-  }
-
-  public int getAge() {
-    return age;
-  }
-
-  public void setManager(final Manager manager) {
-    this.manager = manager;
-  }
-
-  public Manager getManager() {
-    return manager;
-  }
-
-  public void setTeam(final Team team) {
-    this.team = team;
-  }
-
-  public Team getTeam() {
-    return team;
-  }
-
-  public void setRoom(final Room room) {
-    this.room = room;
-  }
-
-  public Room getRoom() {
-    return room;
-  }
-
-  public void setImageUri(final String imageUri) {
-    imageUrl = imageUri;
-  }
-
-  public String getImageUri() {
-    return imageUrl;
-  }
-
-  public void setLocation(final Location location) {
-    this.location = location;
-  }
-
-  public Location getLocation() {
-    return location;
-  }
-
-  public void setEntryDate(final Calendar date) {
-    entryDate = date;
-  }
-
-  public Calendar getEntryDate() {
-    return entryDate;
-  }
-
-  public void setImageType(final String imageType) {
-    this.imageType = imageType;
-  }
-
-  public String getImageType() {
-    return imageType;
-  }
-
-  public void setImage(final byte[] image) {
-    this.image = image;
-  }
-
-  public byte[] getImage() {
-    if (image == null) {
-      return null;
-    }
-    return image.clone();
-  }
-
-  @Override
-  public int hashCode() {
-    if (employeeId == null) {
-      return 0;
-    }
-    return employeeId.hashCode();
-  }
-
-  @Override
-  public boolean equals(final Object obj) {
-    return this == obj
-        || obj != null && getClass() == obj.getClass() && employeeId == ((Employee) obj).employeeId;
-  }
-
-  @Override
-  public String toString() {
-    return "{\"EmployeeId\":\"" + employeeId + "\","
-        + "\"EmployeeName\":\"" + employeeName + "\","
-        + "\"ManagerId\":" + (manager == null ? "null" : "\"" + manager.getId() + "\"") + ","
-        + "\"RoomId\":" + (room == null ? "null" : "\"" + room.getId() + "\"") + ","
-        + "\"TeamId\":" + (team == null ? "null" : "\"" + team.getId() + "\"") + ","
-        + "\"Location\":"
-        + (location == null ? "null" :
-            "{\"City\":" + (location.getCity() == null ? "null" :
-                "{\"PostalCode\":\"" + location.getCity().getPostalCode() + "\","
-                    + "\"CityName\":\"" + location.getCity().getCityName() + "\"}") + ","
-                + "\"Country\":\"" + location.getCountry() + "\"}") + ","
-        + "\"Age\":" + age + ","
-        + "\"EntryDate\":"
-        + (entryDate == null ? "null" : "\"" + DateFormat.getInstance().format(entryDate.getTime()) + "\"") + ","
-        + "\"ImageUrl\":\"" + imageUrl + "\"}";
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
deleted file mode 100644
index 7f3f082..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.model;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-
-
-/**
- *  
- */
-@EdmComplexType(name = "c_Location", namespace = ModelSharedConstants.NAMESPACE_1)
-public class Location {
-  @EdmProperty
-  private String country;
-  @EdmProperty
-  private City city;
-
-  public Location(final String country, final String postalCode, final String cityName) {
-    this.country = country;
-    city = new City(postalCode, cityName);
-  }
-
-  public void setCountry(final String country) {
-    this.country = country;
-  }
-
-  public String getCountry() {
-    return country;
-  }
-
-  public void setCity(final City city) {
-    this.city = city;
-  }
-
-  public City getCity() {
-    return city;
-  }
-
-  @Override
-  public String toString() {
-    return String.format("%s, %s", country, city.toString());
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
deleted file mode 100644
index e3edbd0..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty.Multiplicity;
-
-/**
- *
- */
-@EdmEntityType(name = "Manager", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Managers")
-public class Manager extends Employee {
-
-  @EdmNavigationProperty(name = "nm_Employees", association = "ManagerEmployees",
-      toMultiplicity = Multiplicity.MANY)
-  private List<Employee> employees = new ArrayList<Employee>();
-
-  public Manager(final String id, final String name) {
-    super(id, name);
-  }
-
-  public List<Employee> getEmployees() {
-    return employees;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
deleted file mode 100644
index 1d44498..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.model;
-
-public interface ModelSharedConstants {
-
-  String NAMESPACE_1 = "RefScenario";
-  String CONTAINER_1 = "DefaultContainer";
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
deleted file mode 100644
index 520216a..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.model;
-
-import java.util.Arrays;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceSource;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *  
- */
-@EdmEntityType(name = "Photo", namespace = ModelSharedConstants.NAMESPACE_1)
-@EdmEntitySet(name = "Photos")
-public class Photo {
-  @EdmProperty
-  @EdmKey
-  private String name;
-  @EdmProperty(name = "ImageFormat")
-  @EdmKey
-  private String type;
-  @EdmProperty
-  @EdmMediaResourceMimeType
-  private String mimeType;
-  @EdmProperty
-  @EdmMediaResourceSource
-  private String imageUrl = "http://localhost/someResource.png";
-  @EdmProperty(type = EdmType.BINARY)
-  @EdmMediaResourceContent
-  private byte[] image = ResourceHelper.generateImage();
-
-  public String getName() {
-    return name;
-  }
-
-  public void setName(final String name) {
-    this.name = name;
-  }
-
-  public String getType() {
-    return type;
-  }
-
-  public void setType(final String type) {
-    this.type = type;
-  }
-
-  public String getImageUri() {
-    return imageUrl;
-  }
-
-  public void setImageUri(final String uri) {
-    imageUrl = uri;
-  }
-
-  public byte[] getImage() {
-    return image.clone();
-  }
-
-  public void setImage(final byte[] image) {
-    this.image = image;
-  }
-
-  public String getImageType() {
-    return mimeType;
-  }
-
-  public void setImageType(final String imageType) {
-    this.mimeType = imageType;
-  }
-
-  @Override
-  public int hashCode() {
-    int hash = 5;
-    hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
-    hash = 83 * hash + (this.type != null ? this.type.hashCode() : 0);
-    return hash;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (obj == null) {
-      return false;
-    }
-    if (getClass() != obj.getClass()) {
-      return false;
-    }
-    final Photo other = (Photo) obj;
-    if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
-      return false;
-    }
-    if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) {
-      return false;
-    }
-    return true;
-  }
-  
-  @Override
-  public String toString() {
-    return "{\"Name\":\"" + name + "\","
-        + "\"Type\":\"" + type + "\","
-        + "\"ImageUrl\":\"" + imageUrl + "\","
-        + "\"Image\":\"" + Arrays.toString(image) + "\","
-        + "\"MimeType\":\"" + mimeType + "\"";
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
deleted file mode 100644
index 6f3002f..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2013 The Apache Software Foundation.
- *
- * Licensed 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.odata2.core.annotation.model;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.annotation.edm.EdmType;
-
-/**
- *
- */
-@EdmEntityType(name="Base", namespace=ModelSharedConstants.NAMESPACE_1)
-public abstract class RefBase {
-  @EdmProperty(name="Name")
-  protected String name;
-  @EdmProperty(name="Id", type = EdmType.STRING)
-  @EdmKey
-  protected int id;
-
-  public RefBase(int id, String name) {
-    this.name = name;
-    this.id = id;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public String getId() {
-    return Integer.toString(id);
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public void setId(int id) {
-    this.id = id;
-  }
-}


[10/12] Renamed project

Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
new file mode 100644
index 0000000..19218d7
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
@@ -0,0 +1,1630 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.processor;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.ODataCallback;
+import org.apache.olingo.odata2.api.batch.BatchHandler;
+import org.apache.olingo.odata2.api.batch.BatchRequestPart;
+import org.apache.olingo.odata2.api.batch.BatchResponsePart;
+import org.apache.olingo.odata2.api.commons.HttpContentType;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.commons.InlineCount;
+import org.apache.olingo.odata2.api.data.DataSource;
+import org.apache.olingo.odata2.api.data.DataSource.BinaryData;
+import org.apache.olingo.odata2.api.data.DataSourceProcessor;
+import org.apache.olingo.odata2.api.data.ValueAccess;
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.edm.EdmConcurrencyMode;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.edm.EdmLiteral;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.EdmStructuralType;
+import org.apache.olingo.odata2.api.edm.EdmType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.edm.EdmTyped;
+import org.apache.olingo.odata2.api.ep.EntityProvider;
+import org.apache.olingo.odata2.api.ep.EntityProviderBatchProperties;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
+import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.api.ep.callback.OnWriteEntryContent;
+import org.apache.olingo.odata2.api.ep.callback.OnWriteFeedContent;
+import org.apache.olingo.odata2.api.ep.callback.WriteCallbackContext;
+import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackContext;
+import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackResult;
+import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackContext;
+import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackResult;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.exception.ODataHttpException;
+import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
+import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.processor.ODataRequest;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
+import org.apache.olingo.odata2.api.uri.KeyPredicate;
+import org.apache.olingo.odata2.api.uri.NavigationSegment;
+import org.apache.olingo.odata2.api.uri.PathInfo;
+import org.apache.olingo.odata2.api.uri.UriParser;
+import org.apache.olingo.odata2.api.uri.expression.BinaryExpression;
+import org.apache.olingo.odata2.api.uri.expression.CommonExpression;
+import org.apache.olingo.odata2.api.uri.expression.ExpressionKind;
+import org.apache.olingo.odata2.api.uri.expression.FilterExpression;
+import org.apache.olingo.odata2.api.uri.expression.LiteralExpression;
+import org.apache.olingo.odata2.api.uri.expression.MemberExpression;
+import org.apache.olingo.odata2.api.uri.expression.MethodExpression;
+import org.apache.olingo.odata2.api.uri.expression.OrderByExpression;
+import org.apache.olingo.odata2.api.uri.expression.OrderExpression;
+import org.apache.olingo.odata2.api.uri.expression.PropertyExpression;
+import org.apache.olingo.odata2.api.uri.expression.SortOrder;
+import org.apache.olingo.odata2.api.uri.expression.UnaryExpression;
+import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetComplexPropertyUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityLinkCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityLinkUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetLinksCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetLinksUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetFunctionImportUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetMediaResourceUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetSimplePropertyUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+
+/**
+ * Implementation of the centralized parts of OData processing,
+ * allowing to use the simplified {@link DataSource} for the
+ * actual data handling.
+ * 
+ */
+public class ListsProcessor extends DataSourceProcessor {
+
+  // TODO: Paging size should be configurable.
+  private static final int SERVER_PAGING_SIZE = 100;
+
+  public ListsProcessor(final DataSource dataSource, final ValueAccess valueAccess) {
+    super(dataSource, valueAccess);
+  }
+
+  @Override
+  public ODataResponse readEntitySet(final GetEntitySetUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    ArrayList<Object> data = new ArrayList<Object>();
+    try {
+      data.addAll((List<?>) retrieveData(
+          uriInfo.getStartEntitySet(),
+          uriInfo.getKeyPredicates(),
+          uriInfo.getFunctionImport(),
+          mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+          uriInfo.getNavigationSegments()));
+    } catch (final ODataNotFoundException e) {
+      data.clear();
+    }
+
+    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+    final InlineCount inlineCountType = uriInfo.getInlineCount();
+    final Integer count = applySystemQueryOptions(
+        entitySet,
+        data,
+        uriInfo.getFilter(),
+        inlineCountType,
+        uriInfo.getOrderBy(),
+        uriInfo.getSkipToken(),
+        uriInfo.getSkip(),
+        uriInfo.getTop());
+
+    ODataContext context = getContext();
+    String nextLink = null;
+
+    // Limit the number of returned entities and provide a "next" link
+    // if there are further entities.
+    // Almost all system query options in the current request must be carried
+    // over to the URI for the "next" link, with the exception of $skiptoken
+    // and $skip.
+    if (data.size() > SERVER_PAGING_SIZE) {
+      if (uriInfo.getOrderBy() == null
+          && uriInfo.getSkipToken() == null
+          && uriInfo.getSkip() == null
+          && uriInfo.getTop() == null) {
+        sortInDefaultOrder(entitySet, data);
+      }
+
+      // TODO: Percent-encode "next" link.
+      nextLink = context.getPathInfo().getServiceRoot().relativize(context.getPathInfo().getRequestUri()).toString()
+          .replaceAll("\\$skiptoken=.+?&?", "")
+          .replaceAll("\\$skip=.+?&?", "")
+          .replaceFirst("(?:\\?|&)$", ""); // Remove potentially trailing "?" or "&" left over from remove actions
+                                           // above.
+      nextLink += (nextLink.contains("?") ? "&" : "?")
+          + "$skiptoken=" + getSkipToken(entitySet, data.get(SERVER_PAGING_SIZE));
+
+      while (data.size() > SERVER_PAGING_SIZE) {
+        data.remove(SERVER_PAGING_SIZE);
+      }
+    }
+
+    final EdmEntityType entityType = entitySet.getEntityType();
+    List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
+    for (final Object entryData : data) {
+      values.add(getStructuralTypeValueMap(entryData, entityType));
+    }
+
+    final EntityProviderWriteProperties feedProperties = EntityProviderWriteProperties
+        .serviceRoot(context.getPathInfo().getServiceRoot())
+        .inlineCountType(inlineCountType)
+        .inlineCount(count)
+        .expandSelectTree(UriParser.createExpandSelectTree(uriInfo.getSelect(), uriInfo.getExpand()))
+        .callbacks(getCallbacks(data, entityType))
+        .nextLink(nextLink)
+        .build();
+
+    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeFeed");
+    final ODataResponse response = EntityProvider.writeFeed(contentType, entitySet, values, feedProperties);
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    return ODataResponse.fromResponse(response).build();
+  }
+
+  @Override
+  public ODataResponse countEntitySet(final GetEntitySetCountUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    ArrayList<Object> data = new ArrayList<Object>();
+    try {
+      data.addAll((List<?>) retrieveData(
+          uriInfo.getStartEntitySet(),
+          uriInfo.getKeyPredicates(),
+          uriInfo.getFunctionImport(),
+          mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+          uriInfo.getNavigationSegments()));
+    } catch (final ODataNotFoundException e) {
+      data.clear();
+    }
+
+    applySystemQueryOptions(
+        uriInfo.getTargetEntitySet(),
+        data,
+        uriInfo.getFilter(),
+        null,
+        null,
+        null,
+        uriInfo.getSkip(),
+        uriInfo.getTop());
+
+    return ODataResponse.fromResponse(EntityProvider.writeText(String.valueOf(data.size()))).build();
+  }
+
+  @Override
+  public ODataResponse readEntityLinks(final GetEntitySetLinksUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    ArrayList<Object> data = new ArrayList<Object>();
+    try {
+      data.addAll((List<?>) retrieveData(
+          uriInfo.getStartEntitySet(),
+          uriInfo.getKeyPredicates(),
+          uriInfo.getFunctionImport(),
+          mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+          uriInfo.getNavigationSegments()));
+    } catch (final ODataNotFoundException e) {
+      data.clear();
+    }
+
+    final Integer count = applySystemQueryOptions(
+        uriInfo.getTargetEntitySet(),
+        data,
+        uriInfo.getFilter(),
+        uriInfo.getInlineCount(),
+        null, // uriInfo.getOrderBy(),
+        uriInfo.getSkipToken(),
+        uriInfo.getSkip(),
+        uriInfo.getTop());
+
+    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+
+    List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
+    for (final Object entryData : data) {
+      Map<String, Object> entryValues = new HashMap<String, Object>();
+      for (final EdmProperty property : entitySet.getEntityType().getKeyProperties()) {
+        entryValues.put(property.getName(), valueAccess.getPropertyValue(entryData, property));
+      }
+      values.add(entryValues);
+    }
+
+    ODataContext context = getContext();
+    final EntityProviderWriteProperties entryProperties = EntityProviderWriteProperties
+        .serviceRoot(context.getPathInfo().getServiceRoot())
+        .inlineCountType(uriInfo.getInlineCount())
+        .inlineCount(count)
+        .build();
+
+    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeLinks");
+
+    final ODataResponse response = EntityProvider.writeLinks(contentType, entitySet, values, entryProperties);
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    return ODataResponse.fromResponse(response).build();
+  }
+
+  @Override
+  public ODataResponse countEntityLinks(final GetEntitySetLinksCountUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    return countEntitySet((GetEntitySetCountUriInfo) uriInfo, contentType);
+  }
+
+  @Override
+  public ODataResponse readEntity(final GetEntityUriInfo uriInfo, final String contentType) throws ODataException {
+    final Object data = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        uriInfo.getNavigationSegments());
+
+    if (!appliesFilter(data, uriInfo.getFilter())) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    final ExpandSelectTreeNode expandSelectTreeNode =
+        UriParser.createExpandSelectTree(uriInfo.getSelect(), uriInfo.getExpand());
+    ODataResponse odr =
+        ODataResponse.fromResponse(writeEntry(uriInfo.getTargetEntitySet(), expandSelectTreeNode, data, contentType))
+            .build();
+
+    return odr;
+  }
+
+  @Override
+  public ODataResponse existsEntity(final GetEntityCountUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    final Object data = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        uriInfo.getNavigationSegments());
+
+    return ODataResponse.fromResponse(EntityProvider.writeText(appliesFilter(data, uriInfo.getFilter()) ? "1" : "0"))
+        .build();
+  }
+
+  @Override
+  public ODataResponse deleteEntity(final DeleteUriInfo uriInfo, final String contentType) throws ODataException {
+    dataSource.deleteData(
+        uriInfo.getStartEntitySet(),
+        mapKey(uriInfo.getKeyPredicates()));
+    return ODataResponse.newBuilder().build();
+  }
+
+  @Override
+  public ODataResponse createEntity(final PostUriInfo uriInfo, final InputStream content,
+      final String requestContentType, final String contentType) throws ODataException {
+    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+    final EdmEntityType entityType = entitySet.getEntityType();
+
+    Object data = dataSource.newDataObject(entitySet);
+    ExpandSelectTreeNode expandSelectTree = null;
+
+    if (entityType.hasStream()) {
+      dataSource.createData(entitySet, data);
+      dataSource.writeBinaryData(entitySet, data,
+          new BinaryData(EntityProvider.readBinary(content), requestContentType));
+
+    } else {
+      final EntityProviderReadProperties properties = EntityProviderReadProperties.init()
+          .mergeSemantic(false)
+          .addTypeMappings(getStructuralTypeTypeMap(data, entityType))
+          .build();
+      final ODataEntry entryValues = parseEntry(entitySet, content, requestContentType, properties);
+
+      setStructuralTypeValuesFromMap(data, entityType, entryValues.getProperties(), false);
+
+      dataSource.createData(entitySet, data);
+
+      createInlinedEntities(entitySet, data, entryValues);
+
+      expandSelectTree = entryValues.getExpandSelectTree();
+    }
+
+    // Link back to the entity the target entity set is related to, if any.
+    final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
+    if (!navigationSegments.isEmpty()) {
+      final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
+      final Object sourceData = retrieveData(
+          uriInfo.getStartEntitySet(),
+          uriInfo.getKeyPredicates(),
+          uriInfo.getFunctionImport(),
+          mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+          previousSegments);
+      final EdmEntitySet previousEntitySet = previousSegments.isEmpty() ?
+          uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
+      dataSource.writeRelation(previousEntitySet, sourceData, entitySet, getStructuralTypeValueMap(data, entityType));
+    }
+
+    return ODataResponse.fromResponse(writeEntry(uriInfo.getTargetEntitySet(), expandSelectTree, data, contentType))
+        .eTag(constructETag(entitySet, data)).build();
+  }
+
+  @Override
+  public ODataResponse updateEntity(final PutMergePatchUriInfo uriInfo, final InputStream content,
+      final String requestContentType, final boolean merge, final String contentType) throws ODataException {
+    Object data = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        uriInfo.getNavigationSegments());
+
+    if (!appliesFilter(data, uriInfo.getFilter())) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+    final EdmEntityType entityType = entitySet.getEntityType();
+    final EntityProviderReadProperties properties = EntityProviderReadProperties.init()
+        .mergeSemantic(merge)
+        .addTypeMappings(getStructuralTypeTypeMap(data, entityType))
+        .build();
+    final ODataEntry entryValues = parseEntry(entitySet, content, requestContentType, properties);
+
+    setStructuralTypeValuesFromMap(data, entityType, entryValues.getProperties(), merge);
+
+    return ODataResponse.newBuilder().eTag(constructETag(entitySet, data)).build();
+  }
+
+  @Override
+  public ODataResponse readEntityLink(final GetEntityLinkUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    final Object data = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        uriInfo.getNavigationSegments());
+
+    // if (!appliesFilter(data, uriInfo.getFilter()))
+    if (data == null) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+
+    Map<String, Object> values = new HashMap<String, Object>();
+    for (final EdmProperty property : entitySet.getEntityType().getKeyProperties()) {
+      values.put(property.getName(), valueAccess.getPropertyValue(data, property));
+    }
+
+    ODataContext context = getContext();
+    final EntityProviderWriteProperties entryProperties = EntityProviderWriteProperties
+        .serviceRoot(context.getPathInfo().getServiceRoot())
+        .build();
+
+    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeLink");
+
+    final ODataResponse response = EntityProvider.writeLink(contentType, entitySet, values, entryProperties);
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    return ODataResponse.fromResponse(response).build();
+  }
+
+  @Override
+  public ODataResponse existsEntityLink(final GetEntityLinkCountUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    return existsEntity((GetEntityCountUriInfo) uriInfo, contentType);
+  }
+
+  @Override
+  public ODataResponse deleteEntityLink(final DeleteUriInfo uriInfo, final String contentType) throws ODataException {
+    final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
+    final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
+
+    final Object sourceData = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        previousSegments);
+
+    final EdmEntitySet entitySet = previousSegments.isEmpty() ?
+        uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
+    final EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
+    final Map<String, Object> keys = mapKey(uriInfo.getTargetKeyPredicates());
+
+    final Object targetData = dataSource.readRelatedData(entitySet, sourceData, targetEntitySet, keys);
+
+    // if (!appliesFilter(targetData, uriInfo.getFilter()))
+    if (targetData == null) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    dataSource.deleteRelation(entitySet, sourceData, targetEntitySet, keys);
+
+    return ODataResponse.newBuilder().build();
+  }
+
+  @Override
+  public ODataResponse createEntityLink(final PostUriInfo uriInfo, final InputStream content,
+      final String requestContentType, final String contentType) throws ODataException {
+    final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
+    final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
+
+    final Object sourceData = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        previousSegments);
+
+    final EdmEntitySet entitySet = previousSegments.isEmpty() ?
+        uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
+    final EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
+
+    final Map<String, Object> targetKeys = parseLink(targetEntitySet, content, requestContentType);
+
+    dataSource.writeRelation(entitySet, sourceData, targetEntitySet, targetKeys);
+
+    return ODataResponse.newBuilder().build();
+  }
+
+  @Override
+  public ODataResponse updateEntityLink(final PutMergePatchUriInfo uriInfo, final InputStream content,
+      final String requestContentType, final String contentType) throws ODataException {
+    final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
+    final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
+
+    final Object sourceData = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        previousSegments);
+
+    final EdmEntitySet entitySet = previousSegments.isEmpty() ?
+        uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
+    final EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
+    final Map<String, Object> keys = mapKey(uriInfo.getTargetKeyPredicates());
+
+    final Object targetData = dataSource.readRelatedData(entitySet, sourceData, targetEntitySet, keys);
+
+    if (!appliesFilter(targetData, uriInfo.getFilter())) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    dataSource.deleteRelation(entitySet, sourceData, targetEntitySet, keys);
+
+    final Map<String, Object> newKeys = parseLink(targetEntitySet, content, requestContentType);
+
+    dataSource.writeRelation(entitySet, sourceData, targetEntitySet, newKeys);
+
+    return ODataResponse.newBuilder().build();
+  }
+
+  @Override
+  public ODataResponse readEntityComplexProperty(final GetComplexPropertyUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    Object data = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        uriInfo.getNavigationSegments());
+
+    // if (!appliesFilter(data, uriInfo.getFilter()))
+    if (data == null) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
+    final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
+    final Object value = property.isSimple() ?
+        property.getMapping() == null || property.getMapping().getMimeType() == null ?
+            getPropertyValue(data, propertyPath) : getSimpleTypeValueMap(data, propertyPath) :
+        getStructuralTypeValueMap(getPropertyValue(data, propertyPath), (EdmStructuralType) property.getType());
+
+    ODataContext context = getContext();
+    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeProperty");
+
+    final ODataResponse response = EntityProvider.writeProperty(contentType, property, value);
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    return ODataResponse.fromResponse(response).eTag(constructETag(uriInfo.getTargetEntitySet(), data)).build();
+  }
+
+  @Override
+  public ODataResponse readEntitySimpleProperty(final GetSimplePropertyUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    return readEntityComplexProperty((GetComplexPropertyUriInfo) uriInfo, contentType);
+  }
+
+  @Override
+  public ODataResponse readEntitySimplePropertyValue(final GetSimplePropertyUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    Object data = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        uriInfo.getNavigationSegments());
+
+    // if (!appliesFilter(data, uriInfo.getFilter()))
+    if (data == null) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
+    final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
+    final Object value = property.getMapping() == null || property.getMapping().getMimeType() == null ?
+        getPropertyValue(data, propertyPath) : getSimpleTypeValueMap(data, propertyPath);
+
+    return ODataResponse.fromResponse(EntityProvider.writePropertyValue(property, value)).eTag(
+        constructETag(uriInfo.getTargetEntitySet(), data)).build();
+  }
+
+  @Override
+  public ODataResponse deleteEntitySimplePropertyValue(final DeleteUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    Object data = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        uriInfo.getNavigationSegments());
+
+    if (data == null) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
+    final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
+
+    data = getPropertyValue(data, propertyPath.subList(0, propertyPath.size() - 1));
+    valueAccess.setPropertyValue(data, property, null);
+    valueAccess.setMappingValue(data, property.getMapping(), null);
+
+    return ODataResponse.newBuilder().build();
+  }
+
+  @Override
+  public ODataResponse updateEntityComplexProperty(final PutMergePatchUriInfo uriInfo, final InputStream content,
+      final String requestContentType, final boolean merge, final String contentType) throws ODataException {
+    Object data = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        uriInfo.getNavigationSegments());
+
+    if (!appliesFilter(data, uriInfo.getFilter())) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
+    final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
+
+    data = getPropertyValue(data, propertyPath.subList(0, propertyPath.size() - 1));
+
+    ODataContext context = getContext();
+    int timingHandle = context.startRuntimeMeasurement("EntityConsumer", "readProperty");
+
+    Map<String, Object> values;
+    try {
+      values =
+          EntityProvider.readProperty(requestContentType, property, content, EntityProviderReadProperties.init()
+              .mergeSemantic(merge).build());
+    } catch (final EntityProviderException e) {
+      throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
+    }
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    final Object value = values.get(property.getName());
+    if (property.isSimple()) {
+      valueAccess.setPropertyValue(data, property, value);
+    } else {
+      @SuppressWarnings("unchecked")
+      final Map<String, Object> propertyValue = (Map<String, Object>) value;
+      setStructuralTypeValuesFromMap(valueAccess.getPropertyValue(data, property),
+          (EdmStructuralType) property.getType(), propertyValue, merge);
+    }
+
+    return ODataResponse.newBuilder().eTag(constructETag(uriInfo.getTargetEntitySet(), data)).build();
+  }
+
+  @Override
+  public ODataResponse updateEntitySimpleProperty(final PutMergePatchUriInfo uriInfo, final InputStream content,
+      final String requestContentType, final String contentType) throws ODataException {
+    return updateEntityComplexProperty(uriInfo, content, requestContentType, false, contentType);
+  }
+
+  @Override
+  public ODataResponse updateEntitySimplePropertyValue(final PutMergePatchUriInfo uriInfo, final InputStream content,
+      final String requestContentType, final String contentType) throws ODataException {
+    Object data = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        uriInfo.getNavigationSegments());
+
+    if (!appliesFilter(data, uriInfo.getFilter())) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
+    final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
+
+    data = getPropertyValue(data, propertyPath.subList(0, propertyPath.size() - 1));
+
+    ODataContext context = getContext();
+    int timingHandle = context.startRuntimeMeasurement("EntityConsumer", "readPropertyValue");
+
+    Object value;
+    try {
+      value = EntityProvider.readPropertyValue(property, content);
+    } catch (final EntityProviderException e) {
+      throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
+    }
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    valueAccess.setPropertyValue(data, property, value);
+    valueAccess.setMappingValue(data, property.getMapping(), requestContentType);
+
+    return ODataResponse.newBuilder().eTag(constructETag(uriInfo.getTargetEntitySet(), data)).build();
+  }
+
+  @Override
+  public ODataResponse readEntityMedia(final GetMediaResourceUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    final Object data = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        uriInfo.getNavigationSegments());
+
+    if (!appliesFilter(data, uriInfo.getFilter())) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+    final BinaryData binaryData = dataSource.readBinaryData(entitySet, data);
+    if (binaryData == null) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    final String mimeType = binaryData.getMimeType() == null ?
+        HttpContentType.APPLICATION_OCTET_STREAM : binaryData.getMimeType();
+
+    return ODataResponse.fromResponse(EntityProvider.writeBinary(mimeType, binaryData.getData())).eTag(
+        constructETag(entitySet, data)).build();
+  }
+
+  @Override
+  public ODataResponse deleteEntityMedia(final DeleteUriInfo uriInfo, final String contentType) throws ODataException {
+    final Object data = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        uriInfo.getNavigationSegments());
+
+    if (data == null) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    dataSource.writeBinaryData(uriInfo.getTargetEntitySet(), data, new BinaryData(null, null));
+
+    return ODataResponse.newBuilder().build();
+  }
+
+  @Override
+  public ODataResponse updateEntityMedia(final PutMergePatchUriInfo uriInfo, final InputStream content,
+      final String requestContentType, final String contentType) throws ODataException {
+    final Object data = retrieveData(
+        uriInfo.getStartEntitySet(),
+        uriInfo.getKeyPredicates(),
+        uriInfo.getFunctionImport(),
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        uriInfo.getNavigationSegments());
+
+    if (!appliesFilter(data, uriInfo.getFilter())) {
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+    ODataContext context = getContext();
+    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "readBinary");
+
+    final byte[] value = EntityProvider.readBinary(content);
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+    dataSource.writeBinaryData(entitySet, data, new BinaryData(value, requestContentType));
+
+    return ODataResponse.newBuilder().eTag(constructETag(entitySet, data)).build();
+  }
+
+  @Override
+  public ODataResponse executeFunctionImport(final GetFunctionImportUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    final EdmFunctionImport functionImport = uriInfo.getFunctionImport();
+    final EdmType type = functionImport.getReturnType().getType();
+
+    final Object data = dataSource.readData(
+        functionImport,
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        null);
+
+    if (data == null) {
+      throw new ODataNotFoundException(ODataHttpException.COMMON);
+    }
+
+    Object value;
+    if (type.getKind() == EdmTypeKind.SIMPLE) {
+      value = type == EdmSimpleTypeKind.Binary.getEdmSimpleTypeInstance() ?
+          ((BinaryData) data).getData() : data;
+    } else if (functionImport.getReturnType().getMultiplicity() == EdmMultiplicity.MANY) {
+      List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
+      for (final Object typeData : (List<?>) data) {
+        values.add(getStructuralTypeValueMap(typeData, (EdmStructuralType) type));
+      }
+      value = values;
+    } else {
+      value = getStructuralTypeValueMap(data, (EdmStructuralType) type);
+    }
+
+    ODataContext context = getContext();
+
+    final EntityProviderWriteProperties entryProperties = EntityProviderWriteProperties
+        .serviceRoot(context.getPathInfo().getServiceRoot()).build();
+
+    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeFunctionImport");
+
+    final ODataResponse response =
+        EntityProvider.writeFunctionImport(contentType, functionImport, value, entryProperties);
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    return ODataResponse.fromResponse(response).build();
+  }
+
+  @Override
+  public ODataResponse executeFunctionImportValue(final GetFunctionImportUriInfo uriInfo, final String contentType)
+      throws ODataException {
+    final EdmFunctionImport functionImport = uriInfo.getFunctionImport();
+    final EdmSimpleType type = (EdmSimpleType) functionImport.getReturnType().getType();
+
+    final Object data = dataSource.readData(
+        functionImport,
+        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
+        null);
+
+    if (data == null) {
+      throw new ODataNotFoundException(ODataHttpException.COMMON);
+    }
+
+    ODataResponse response;
+    if (type == EdmSimpleTypeKind.Binary.getEdmSimpleTypeInstance()) {
+      response = EntityProvider.writeBinary(((BinaryData) data).getMimeType(), ((BinaryData) data).getData());
+    } else {
+      final String value = type.valueToString(data, EdmLiteralKind.DEFAULT, null);
+      response = EntityProvider.writeText(value == null ? "" : value);
+    }
+    return ODataResponse.fromResponse(response).build();
+  }
+
+  private static Map<String, Object> mapKey(final List<KeyPredicate> keys) throws EdmException {
+    Map<String, Object> keyMap = new HashMap<String, Object>();
+    for (final KeyPredicate key : keys) {
+      final EdmProperty property = key.getProperty();
+      final EdmSimpleType type = (EdmSimpleType) property.getType();
+      keyMap.put(property.getName(), type.valueOfString(key.getLiteral(), EdmLiteralKind.DEFAULT, property.getFacets(),
+          type.getDefaultType()));
+    }
+    return keyMap;
+  }
+
+  private static Map<String, Object> mapFunctionParameters(final Map<String, EdmLiteral> functionImportParameters)
+      throws EdmSimpleTypeException {
+    if (functionImportParameters == null) {
+      return Collections.emptyMap();
+    } else {
+      Map<String, Object> parameterMap = new HashMap<String, Object>();
+      for (final String parameterName : functionImportParameters.keySet()) {
+        final EdmLiteral literal = functionImportParameters.get(parameterName);
+        final EdmSimpleType type = literal.getType();
+        parameterMap.put(parameterName, type.valueOfString(literal.getLiteral(), EdmLiteralKind.DEFAULT, null, type
+            .getDefaultType()));
+      }
+      return parameterMap;
+    }
+  }
+
+  private Object retrieveData(final EdmEntitySet startEntitySet, final List<KeyPredicate> keyPredicates,
+      final EdmFunctionImport functionImport, final Map<String, Object> functionImportParameters,
+      final List<NavigationSegment> navigationSegments) throws ODataException {
+    Object data;
+    final Map<String, Object> keys = mapKey(keyPredicates);
+
+    ODataContext context = getContext();
+    final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "retrieveData");
+
+    data = functionImport == null ?
+        keys.isEmpty() ?
+            dataSource.readData(startEntitySet) : dataSource.readData(startEntitySet, keys) :
+        dataSource.readData(functionImport, functionImportParameters, keys);
+
+    EdmEntitySet currentEntitySet =
+        functionImport == null ? startEntitySet : functionImport.getEntitySet();
+    for (NavigationSegment navigationSegment : navigationSegments) {
+      data = dataSource.readRelatedData(
+          currentEntitySet,
+          data,
+          navigationSegment.getEntitySet(),
+          mapKey(navigationSegment.getKeyPredicates()));
+      currentEntitySet = navigationSegment.getEntitySet();
+    }
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    return data;
+  }
+
+  private <T> String constructETag(final EdmEntitySet entitySet, final T data) throws ODataException {
+    final EdmEntityType entityType = entitySet.getEntityType();
+    String eTag = null;
+    for (final String propertyName : entityType.getPropertyNames()) {
+      final EdmProperty property = (EdmProperty) entityType.getProperty(propertyName);
+      if (property.getFacets() != null && property.getFacets().getConcurrencyMode() == EdmConcurrencyMode.Fixed) {
+        final EdmSimpleType type = (EdmSimpleType) property.getType();
+        final String component = type.valueToString(valueAccess.getPropertyValue(data, property),
+            EdmLiteralKind.DEFAULT, property.getFacets());
+        eTag = eTag == null ? component : eTag + Edm.DELIMITER + component;
+      }
+    }
+    return eTag == null ? null : "W/\"" + eTag + "\"";
+  }
+
+  private <T> Map<String, ODataCallback> getCallbacks(final T data, final EdmEntityType entityType)
+      throws EdmException {
+    final List<String> navigationPropertyNames = entityType.getNavigationPropertyNames();
+    if (navigationPropertyNames.isEmpty()) {
+      return null;
+    } else {
+      final WriteCallback callback = new WriteCallback(data);
+      Map<String, ODataCallback> callbacks = new HashMap<String, ODataCallback>();
+      for (final String name : navigationPropertyNames) {
+        callbacks.put(name, callback);
+      }
+      return callbacks;
+    }
+  }
+
+  private class WriteCallback implements OnWriteEntryContent, OnWriteFeedContent {
+    private final Object data;
+
+    private <T> WriteCallback(final T data) {
+      this.data = data;
+    }
+
+    @Override
+    public WriteFeedCallbackResult retrieveFeedResult(final WriteFeedCallbackContext context)
+        throws ODataApplicationException {
+      try {
+        final EdmEntityType entityType =
+            context.getSourceEntitySet().getRelatedEntitySet(context.getNavigationProperty()).getEntityType();
+        List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
+        Object relatedData = null;
+        try {
+          relatedData = readRelatedData(context);
+          for (final Object entryData : (List<?>) relatedData) {
+            values.add(getStructuralTypeValueMap(entryData, entityType));
+          }
+        } catch (final ODataNotFoundException e) {
+          values.clear();
+        }
+        WriteFeedCallbackResult result = new WriteFeedCallbackResult();
+        result.setFeedData(values);
+        EntityProviderWriteProperties inlineProperties =
+            EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).callbacks(
+                getCallbacks(relatedData, entityType)).expandSelectTree(context.getCurrentExpandSelectTreeNode())
+                .selfLink(context.getSelfLink()).build();
+        result.setInlineProperties(inlineProperties);
+        return result;
+      } catch (final ODataException e) {
+        throw new ODataApplicationException(e.getLocalizedMessage(), Locale.ROOT, e);
+      }
+    }
+
+    @Override
+    public WriteEntryCallbackResult retrieveEntryResult(final WriteEntryCallbackContext context)
+        throws ODataApplicationException {
+      try {
+        final EdmEntityType entityType =
+            context.getSourceEntitySet().getRelatedEntitySet(context.getNavigationProperty()).getEntityType();
+        WriteEntryCallbackResult result = new WriteEntryCallbackResult();
+        Object relatedData;
+        try {
+          relatedData = readRelatedData(context);
+        } catch (final ODataNotFoundException e) {
+          relatedData = null;
+        }
+        
+        if (relatedData == null) {
+          result.setEntryData(Collections.<String, Object> emptyMap());
+        } else {
+          result.setEntryData(getStructuralTypeValueMap(relatedData, entityType));
+
+          EntityProviderWriteProperties inlineProperties =
+              EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).callbacks(
+                  getCallbacks(relatedData, entityType)).expandSelectTree(context.getCurrentExpandSelectTreeNode())
+                  .build();
+          result.setInlineProperties(inlineProperties);
+        }
+        return result;
+      } catch (final ODataException e) {
+        throw new ODataApplicationException(e.getLocalizedMessage(), Locale.ROOT, e);
+      }
+    }
+
+    private Object readRelatedData(final WriteCallbackContext context) throws ODataException {
+      final EdmEntitySet entitySet = context.getSourceEntitySet();
+      return dataSource.readRelatedData(
+          entitySet,
+          data instanceof List ? readEntryData((List<?>) data, entitySet.getEntityType(), context
+              .extractKeyFromEntryData()) : data,
+          entitySet.getRelatedEntitySet(context.getNavigationProperty()),
+          Collections.<String, Object> emptyMap());
+    }
+
+    private <T> T readEntryData(final List<T> data, final EdmEntityType entityType, final Map<String, Object> key)
+        throws ODataException {
+      for (final T entryData : data) {
+        boolean found = true;
+        for (final EdmProperty keyProperty : entityType.getKeyProperties()) {
+          if (!valueAccess.getPropertyValue(entryData, keyProperty).equals(key.get(keyProperty.getName()))) {
+            found = false;
+            break;
+          }
+        }
+        if (found) {
+          return entryData;
+        }
+      }
+      return null;
+    }
+  }
+
+  private <T> ODataResponse writeEntry(final EdmEntitySet entitySet, final ExpandSelectTreeNode expandSelectTree,
+      final T data, final String contentType) throws ODataException, EntityProviderException {
+    final EdmEntityType entityType = entitySet.getEntityType();
+    final Map<String, Object> values = getStructuralTypeValueMap(data, entityType);
+
+    ODataContext context = getContext();
+    EntityProviderWriteProperties writeProperties = EntityProviderWriteProperties
+        .serviceRoot(context.getPathInfo().getServiceRoot())
+        .expandSelectTree(expandSelectTree)
+        .callbacks(getCallbacks(data, entityType))
+        .build();
+
+    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeEntry");
+
+    final ODataResponse response = EntityProvider.writeEntry(contentType, entitySet, values, writeProperties);
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    return response;
+  }
+
+  private ODataEntry parseEntry(final EdmEntitySet entitySet, final InputStream content,
+      final String requestContentType, final EntityProviderReadProperties properties) throws ODataBadRequestException {
+    ODataContext context = getContext();
+    final int timingHandle = context.startRuntimeMeasurement("EntityConsumer", "readEntry");
+
+    ODataEntry entryValues;
+    try {
+      entryValues = EntityProvider.readEntry(requestContentType, entitySet, content, properties);
+    } catch (final EntityProviderException e) {
+      throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
+    }
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    return entryValues;
+  }
+
+  private Map<String, Object> parseLink(final EdmEntitySet entitySet, final InputStream content,
+      final String contentType) throws ODataException {
+    ODataContext context = getContext();
+    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "readLink");
+
+    final String uriString = EntityProvider.readLink(contentType, entitySet, content);
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    final Map<String, Object> targetKeys = parseLinkUri(entitySet, uriString);
+    if (targetKeys == null) {
+      throw new ODataBadRequestException(ODataBadRequestException.BODY);
+    }
+    return targetKeys;
+  }
+
+  private Map<String, Object> parseLinkUri(final EdmEntitySet targetEntitySet, final String uriString)
+      throws EdmException {
+    ODataContext context = getContext();
+    final int timingHandle = context.startRuntimeMeasurement("UriParser", "getKeyPredicatesFromEntityLink");
+
+    List<KeyPredicate> key = null;
+    try {
+      key = UriParser.getKeyPredicatesFromEntityLink(targetEntitySet, uriString,
+          context.getPathInfo().getServiceRoot());
+    } catch (ODataException e) {
+      // We don't understand the link target. This could also be seen as an error.
+    }
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    return key == null ? null : mapKey(key);
+  }
+
+  private <T> void createInlinedEntities(final EdmEntitySet entitySet, final T data, final ODataEntry entryValues)
+      throws ODataException {
+    final EdmEntityType entityType = entitySet.getEntityType();
+    for (final String navigationPropertyName : entityType.getNavigationPropertyNames()) {
+
+      final EdmNavigationProperty navigationProperty =
+          (EdmNavigationProperty) entityType.getProperty(navigationPropertyName);
+      final EdmEntitySet relatedEntitySet = entitySet.getRelatedEntitySet(navigationProperty);
+      final EdmEntityType relatedEntityType = relatedEntitySet.getEntityType();
+
+      final Object relatedValue = entryValues.getProperties().get(navigationPropertyName);
+      if (relatedValue == null) {
+        for (final String uriString : entryValues.getMetadata().getAssociationUris(navigationPropertyName)) {
+          final Map<String, Object> key = parseLinkUri(relatedEntitySet, uriString);
+          if (key != null) {
+            dataSource.writeRelation(entitySet, data, relatedEntitySet, key);
+          }
+        }
+
+      } else {
+        if (relatedValue instanceof ODataFeed) {
+          ODataFeed feed = (ODataFeed) relatedValue;
+          final List<ODataEntry> relatedValueList = feed.getEntries();
+          for (final ODataEntry relatedValues : relatedValueList) {
+            Object relatedData = dataSource.newDataObject(relatedEntitySet);
+            setStructuralTypeValuesFromMap(relatedData, relatedEntityType, relatedValues.getProperties(), false);
+            dataSource.createData(relatedEntitySet, relatedData);
+            dataSource.writeRelation(entitySet, data, relatedEntitySet, getStructuralTypeValueMap(relatedData,
+                relatedEntityType));
+            createInlinedEntities(relatedEntitySet, relatedData, relatedValues);
+          }
+        } else if (relatedValue instanceof ODataEntry) {
+          final ODataEntry relatedValueEntry = (ODataEntry) relatedValue;
+          Object relatedData = dataSource.newDataObject(relatedEntitySet);
+          setStructuralTypeValuesFromMap(relatedData, relatedEntityType, relatedValueEntry.getProperties(), false);
+          dataSource.createData(relatedEntitySet, relatedData);
+          dataSource.writeRelation(entitySet, data, relatedEntitySet, getStructuralTypeValueMap(relatedData,
+              relatedEntityType));
+          createInlinedEntities(relatedEntitySet, relatedData, relatedValueEntry);
+        } else {
+          throw new ODataException("Unexpected class for a related value: " + relatedValue.getClass().getSimpleName());
+        }
+
+      }
+    }
+  }
+
+  private <T> Integer applySystemQueryOptions(final EdmEntitySet entitySet, final List<T> data,
+      final FilterExpression filter, final InlineCount inlineCount, final OrderByExpression orderBy,
+      final String skipToken, final Integer skip, final Integer top) throws ODataException {
+    ODataContext context = getContext();
+    final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "applySystemQueryOptions");
+
+    if (filter != null) {
+      // Remove all elements the filter does not apply for.
+      // A for-each loop would not work with "remove", see Java documentation.
+      for (Iterator<T> iterator = data.iterator(); iterator.hasNext();) {
+        if (!appliesFilter(iterator.next(), filter)) {
+          iterator.remove();
+        }
+      }
+    }
+
+    final Integer count = inlineCount == InlineCount.ALLPAGES ? data.size() : null;
+
+    if (orderBy != null) {
+      sort(data, orderBy);
+    } else if (skipToken != null || skip != null || top != null) {
+      sortInDefaultOrder(entitySet, data);
+    }
+
+    if (skipToken != null) {
+      while (!data.isEmpty() && !getSkipToken(entitySet, data.get(0)).equals(skipToken)) {
+        data.remove(0);
+      }
+    }
+
+    if (skip != null) {
+      if (skip >= data.size()) {
+        data.clear();
+      } else {
+        for (int i = 0; i < skip; i++) {
+          data.remove(0);
+        }
+      }
+    }
+
+    if (top != null) {
+      while (data.size() > top) {
+        data.remove(top.intValue());
+      }
+    }
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    return count;
+  }
+
+  private <T> void sort(final List<T> data, final OrderByExpression orderBy) {
+    Collections.sort(data, new Comparator<T>() {
+      @Override
+      public int compare(final T entity1, final T entity2) {
+        try {
+          int result = 0;
+          for (final OrderExpression expression : orderBy.getOrders()) {
+            result = evaluateExpression(entity1, expression.getExpression()).compareTo(
+                evaluateExpression(entity2, expression.getExpression()));
+            if (expression.getSortOrder() == SortOrder.desc) {
+              result = -result;
+            }
+            if (result != 0) {
+              break;
+            }
+          }
+          return result;
+        } catch (final ODataException e) {
+          return 0;
+        }
+      }
+    });
+  }
+
+  private <T> void sortInDefaultOrder(final EdmEntitySet entitySet, final List<T> data) {
+    Collections.sort(data, new Comparator<T>() {
+      @Override
+      public int compare(final T entity1, final T entity2) {
+        try {
+          return getSkipToken(entitySet, entity1).compareTo(getSkipToken(entitySet, entity2));
+        } catch (final ODataException e) {
+          return 0;
+        }
+      }
+    });
+  }
+
+  private <T> boolean appliesFilter(final T data, final FilterExpression filter) throws ODataException {
+    ODataContext context = getContext();
+    final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "appliesFilter");
+
+    try {
+      return data != null && (filter == null || evaluateExpression(data, filter.getExpression()).equals("true"));
+    } catch (final RuntimeException e) {
+      return false;
+    } finally {
+      context.stopRuntimeMeasurement(timingHandle);
+    }
+  }
+
+  private <T> String evaluateExpression(final T data, final CommonExpression expression) throws ODataException {
+    switch (expression.getKind()) {
+    case UNARY:
+      final UnaryExpression unaryExpression = (UnaryExpression) expression;
+      final String operand = evaluateExpression(data, unaryExpression.getOperand());
+
+      switch (unaryExpression.getOperator()) {
+      case NOT:
+        return Boolean.toString(!Boolean.parseBoolean(operand));
+      case MINUS:
+        return operand.startsWith("-") ? operand.substring(1) : "-" + operand;
+      default:
+        throw new ODataNotImplementedException();
+      }
+
+    case BINARY:
+      final BinaryExpression binaryExpression = (BinaryExpression) expression;
+      final EdmSimpleType type = (EdmSimpleType) binaryExpression.getLeftOperand().getEdmType();
+      final String left = evaluateExpression(data, binaryExpression.getLeftOperand());
+      final String right = evaluateExpression(data, binaryExpression.getRightOperand());
+
+      switch (binaryExpression.getOperator()) {
+      case ADD:
+        if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
+            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
+            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
+          return Double.toString(Double.valueOf(left) + Double.valueOf(right));
+        } else {
+          return Long.toString(Long.valueOf(left) + Long.valueOf(right));
+        }
+      case SUB:
+        if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
+            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
+            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
+          return Double.toString(Double.valueOf(left) - Double.valueOf(right));
+        } else {
+          return Long.toString(Long.valueOf(left) - Long.valueOf(right));
+        }
+      case MUL:
+        if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
+            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
+            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
+          return Double.toString(Double.valueOf(left) * Double.valueOf(right));
+        } else {
+          return Long.toString(Long.valueOf(left) * Long.valueOf(right));
+        }
+      case DIV:
+        final String number = Double.toString(Double.valueOf(left) / Double.valueOf(right));
+        return number.endsWith(".0") ? number.replace(".0", "") : number;
+      case MODULO:
+        if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
+            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
+            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
+          return Double.toString(Double.valueOf(left) % Double.valueOf(right));
+        } else {
+          return Long.toString(Long.valueOf(left) % Long.valueOf(right));
+        }
+      case AND:
+        return Boolean.toString(left.equals("true") && right.equals("true"));
+      case OR:
+        return Boolean.toString(left.equals("true") || right.equals("true"));
+      case EQ:
+        return Boolean.toString(left.equals(right));
+      case NE:
+        return Boolean.toString(!left.equals(right));
+      case LT:
+        if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
+          return Boolean.toString(left.compareTo(right) < 0);
+        } else {
+          return Boolean.toString(Double.valueOf(left) < Double.valueOf(right));
+        }
+      case LE:
+        if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
+          return Boolean.toString(left.compareTo(right) <= 0);
+        } else {
+          return Boolean.toString(Double.valueOf(left) <= Double.valueOf(right));
+        }
+      case GT:
+        if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
+          return Boolean.toString(left.compareTo(right) > 0);
+        } else {
+          return Boolean.toString(Double.valueOf(left) > Double.valueOf(right));
+        }
+      case GE:
+        if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
+            || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
+          return Boolean.toString(left.compareTo(right) >= 0);
+        } else {
+          return Boolean.toString(Double.valueOf(left) >= Double.valueOf(right));
+        }
+      case PROPERTY_ACCESS:
+        throw new ODataNotImplementedException();
+      default:
+        throw new ODataNotImplementedException();
+      }
+
+    case PROPERTY:
+      final EdmProperty property = (EdmProperty) ((PropertyExpression) expression).getEdmProperty();
+      final EdmSimpleType propertyType = (EdmSimpleType) property.getType();
+      return propertyType.valueToString(valueAccess.getPropertyValue(data, property), EdmLiteralKind.DEFAULT,
+          property.getFacets());
+
+    case MEMBER:
+      final MemberExpression memberExpression = (MemberExpression) expression;
+      final PropertyExpression propertyExpression = (PropertyExpression) memberExpression.getProperty();
+      final EdmProperty memberProperty = (EdmProperty) propertyExpression.getEdmProperty();
+      final EdmSimpleType memberType = (EdmSimpleType) memberExpression.getEdmType();
+      List<EdmProperty> propertyPath = new ArrayList<EdmProperty>();
+      CommonExpression currentExpression = memberExpression;
+      while (currentExpression != null) {
+        final PropertyExpression currentPropertyExpression =
+            (PropertyExpression) (currentExpression.getKind() == ExpressionKind.MEMBER ?
+                ((MemberExpression) currentExpression).getProperty() : currentExpression);
+        final EdmTyped currentProperty = currentPropertyExpression.getEdmProperty();
+        final EdmTypeKind kind = currentProperty.getType().getKind();
+        if (kind == EdmTypeKind.SIMPLE || kind == EdmTypeKind.COMPLEX) {
+          propertyPath.add(0, (EdmProperty) currentProperty);
+        } else {
+          throw new ODataNotImplementedException();
+        }
+        currentExpression =
+            currentExpression.getKind() == ExpressionKind.MEMBER ? ((MemberExpression) currentExpression).getPath()
+                : null;
+      }
+      return memberType.valueToString(getPropertyValue(data, propertyPath), EdmLiteralKind.DEFAULT, memberProperty
+          .getFacets());
+
+    case LITERAL:
+      final LiteralExpression literal = (LiteralExpression) expression;
+      final EdmSimpleType literalType = (EdmSimpleType) literal.getEdmType();
+      return literalType.valueToString(literalType.valueOfString(literal.getUriLiteral(), EdmLiteralKind.URI, null,
+          literalType.getDefaultType()),
+          EdmLiteralKind.DEFAULT, null);
+
+    case METHOD:
+      final MethodExpression methodExpression = (MethodExpression) expression;
+      final String first = evaluateExpression(data, methodExpression.getParameters().get(0));
+      final String second = methodExpression.getParameterCount() > 1 ?
+          evaluateExpression(data, methodExpression.getParameters().get(1)) : null;
+      final String third = methodExpression.getParameterCount() > 2 ?
+          evaluateExpression(data, methodExpression.getParameters().get(2)) : null;
+
+      switch (methodExpression.getMethod()) {
+      case ENDSWITH:
+        return Boolean.toString(first.endsWith(second));
+      case INDEXOF:
+        return Integer.toString(first.indexOf(second));
+      case STARTSWITH:
+        return Boolean.toString(first.startsWith(second));
+      case TOLOWER:
+        return first.toLowerCase(Locale.ROOT);
+      case TOUPPER:
+        return first.toUpperCase(Locale.ROOT);
+      case TRIM:
+        return first.trim();
+      case SUBSTRING:
+        final int offset = Integer.parseInt(second);
+        return first.substring(offset, offset + Integer.parseInt(third));
+      case SUBSTRINGOF:
+        return Boolean.toString(second.contains(first));
+      case CONCAT:
+        return first + second;
+      case LENGTH:
+        return Integer.toString(first.length());
+      case YEAR:
+        return String.valueOf(Integer.parseInt(first.substring(0, 4)));
+      case MONTH:
+        return String.valueOf(Integer.parseInt(first.substring(5, 7)));
+      case DAY:
+        return String.valueOf(Integer.parseInt(first.substring(8, 10)));
+      case HOUR:
+        return String.valueOf(Integer.parseInt(first.substring(11, 13)));
+      case MINUTE:
+        return String.valueOf(Integer.parseInt(first.substring(14, 16)));
+      case SECOND:
+        return String.valueOf(Integer.parseInt(first.substring(17, 19)));
+      case ROUND:
+        return Long.toString(Math.round(Double.valueOf(first)));
+      case FLOOR:
+        return Long.toString(Math.round(Math.floor(Double.valueOf(first))));
+      case CEILING:
+        return Long.toString(Math.round(Math.ceil(Double.valueOf(first))));
+      default:
+        throw new ODataNotImplementedException();
+      }
+
+    default:
+      throw new ODataNotImplementedException();
+    }
+  }
+
+  private <T> String getSkipToken(final EdmEntitySet entitySet, final T data) throws ODataException {
+    String skipToken = "";
+    for (final EdmProperty property : entitySet.getEntityType().getKeyProperties()) {
+      final EdmSimpleType type = (EdmSimpleType) property.getType();
+      skipToken = skipToken.concat(type.valueToString(valueAccess.getPropertyValue(data, property),
+          EdmLiteralKind.DEFAULT, property.getFacets()));
+    }
+    return skipToken;
+  }
+
+  private <T> Object getPropertyValue(final T data, final List<EdmProperty> propertyPath) throws ODataException {
+    Object dataObject = data;
+    for (final EdmProperty property : propertyPath) {
+      if (dataObject != null) {
+        dataObject = valueAccess.getPropertyValue(dataObject, property);
+      }
+    }
+    return dataObject;
+  }
+
+  private void handleMimeType(Object data, EdmMapping mapping, Map<String, Object> valueMap)
+      throws ODataException {
+    final String mimeTypeName = mapping.getMimeType();
+    if (mimeTypeName != null) {
+      Object value = valueAccess.getMappingValue(data, mapping);
+      valueMap.put(mimeTypeName, value);
+      if (mapping.getMediaResourceMimeTypeKey() != null) {
+        valueMap.put(mapping.getMediaResourceMimeTypeKey(), value);
+      }
+    }
+  }
+
+  private <T> Map<String, Object> getSimpleTypeValueMap(final T data, final List<EdmProperty> propertyPath)
+      throws ODataException {
+    final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
+    Map<String, Object> valueWithMimeType = new HashMap<String, Object>();
+    valueWithMimeType.put(property.getName(), getPropertyValue(data, propertyPath));
+
+    handleMimeType(data, property.getMapping(), valueWithMimeType);
+
+    return valueWithMimeType;
+  }
+
+  private <T> Map<String, Object> getStructuralTypeValueMap(final T data, final EdmStructuralType type)
+      throws ODataException {
+    ODataContext context = getContext();
+    final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "getStructuralTypeValueMap");
+
+    Map<String, Object> valueMap = new HashMap<String, Object>();
+
+    EdmMapping mapping = type.getMapping();
+    if (mapping != null) {
+      handleMimeType(data, mapping, valueMap);
+    }
+
+    for (final String propertyName : type.getPropertyNames()) {
+      final EdmProperty property = (EdmProperty) type.getProperty(propertyName);
+      final Object value = valueAccess.getPropertyValue(data, property);
+
+      if (property.isSimple()) {
+        if (property.getMapping() == null || property.getMapping().getMimeType() == null) {
+          valueMap.put(propertyName, value);
+        } else {
+          // TODO: enable MIME type mapping outside the current subtree
+          valueMap.put(propertyName, getSimpleTypeValueMap(data, Arrays.asList(property)));
+        }
+      } else {
+        valueMap.put(propertyName, getStructuralTypeValueMap(value, (EdmStructuralType) property.getType()));
+      }
+    }
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    return valueMap;
+  }
+
+  private <T> Map<String, Object> getStructuralTypeTypeMap(final T data, final EdmStructuralType type)
+      throws ODataException {
+    ODataContext context = getContext();
+    final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "getStructuralTypeTypeMap");
+
+    Map<String, Object> typeMap = new HashMap<String, Object>();
+    for (final String propertyName : type.getPropertyNames()) {
+      final EdmProperty property = (EdmProperty) type.getProperty(propertyName);
+      if (property.isSimple()) {
+        typeMap.put(propertyName, valueAccess.getPropertyType(data, property));
+      } else {
+        typeMap.put(propertyName, getStructuralTypeTypeMap(valueAccess.getPropertyValue(data, property),
+            (EdmStructuralType) property.getType()));
+      }
+    }
+
+    context.stopRuntimeMeasurement(timingHandle);
+
+    return typeMap;
+  }
+
+  private <T> void setStructuralTypeValuesFromMap(final T data, final EdmStructuralType type,
+      final Map<String, Object> valueMap, final boolean merge) throws ODataException {
+    ODataContext context = getContext();
+    final int timingHandle =
+        context.startRuntimeMeasurement(getClass().getSimpleName(), "setStructuralTypeValuesFromMap");
+
+    for (final String propertyName : type.getPropertyNames()) {
+      final EdmProperty property = (EdmProperty) type.getProperty(propertyName);
+      if (type instanceof EdmEntityType && ((EdmEntityType) type).getKeyProperties().contains(property)) {
+        Object v = valueAccess.getPropertyValue(data, property);
+        if(v != null) {
+          continue;
+        }
+      }
+      
+      if (!merge || valueMap != null && valueMap.containsKey(propertyName)) {
+        final Object value = valueMap == null ? null : valueMap.get(propertyName);
+        if (property.isSimple()) {
+          valueAccess.setPropertyValue(data, property, value);
+        } else {
+          @SuppressWarnings("unchecked")
+          final Map<String, Object> values = (Map<String, Object>) value;
+          setStructuralTypeValuesFromMap(valueAccess.getPropertyValue(data, property),
+              (EdmStructuralType) property.getType(), values, merge);
+        }
+      }
+    }
+
+    context.stopRuntimeMeasurement(timingHandle);
+  }
+
+  @Override
+  public ODataResponse executeBatch(final BatchHandler handler, final String contentType, final InputStream content)
+      throws ODataException {
+    ODataResponse batchResponse;
+    List<BatchResponsePart> batchResponseParts = new ArrayList<BatchResponsePart>();
+    PathInfo pathInfo = getContext().getPathInfo();
+    EntityProviderBatchProperties batchProperties = EntityProviderBatchProperties.init().pathInfo(pathInfo).build();
+    List<BatchRequestPart> batchParts = EntityProvider.parseBatchRequest(contentType, content, batchProperties);
+    for (BatchRequestPart batchPart : batchParts) {
+      batchResponseParts.add(handler.handleBatchPart(batchPart));
+    }
+    batchResponse = EntityProvider.writeBatchResponse(batchResponseParts);
+    return batchResponse;
+  }
+
+  @Override
+  public BatchResponsePart executeChangeSet(final BatchHandler handler, final List<ODataRequest> requests)
+      throws ODataException {
+    List<ODataResponse> responses = new ArrayList<ODataResponse>();
+    for (ODataRequest request : requests) {
+      ODataResponse response = handler.handleRequest(request);
+      if (response.getStatus().getStatusCode() >= HttpStatusCodes.BAD_REQUEST.getStatusCode()) {
+        // Rollback
+        List<ODataResponse> errorResponses = new ArrayList<ODataResponse>(1);
+        errorResponses.add(response);
+        return BatchResponsePart.responses(errorResponses).changeSet(false).build();
+      }
+      responses.add(response);
+    }
+    return BatchResponsePart.responses(responses).changeSet(true).build();
+  }
+}


[06/12] Renamed project

Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
deleted file mode 100644
index 19218d7..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
+++ /dev/null
@@ -1,1630 +0,0 @@
-/*******************************************************************************
- * 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.odata2.core.annotation.processor;
-
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.ODataCallback;
-import org.apache.olingo.odata2.api.batch.BatchHandler;
-import org.apache.olingo.odata2.api.batch.BatchRequestPart;
-import org.apache.olingo.odata2.api.batch.BatchResponsePart;
-import org.apache.olingo.odata2.api.commons.HttpContentType;
-import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
-import org.apache.olingo.odata2.api.commons.InlineCount;
-import org.apache.olingo.odata2.api.data.DataSource;
-import org.apache.olingo.odata2.api.data.DataSource.BinaryData;
-import org.apache.olingo.odata2.api.data.DataSourceProcessor;
-import org.apache.olingo.odata2.api.data.ValueAccess;
-import org.apache.olingo.odata2.api.edm.Edm;
-import org.apache.olingo.odata2.api.edm.EdmConcurrencyMode;
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
-import org.apache.olingo.odata2.api.edm.EdmLiteral;
-import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
-import org.apache.olingo.odata2.api.edm.EdmMapping;
-import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
-import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.edm.EdmProperty;
-import org.apache.olingo.odata2.api.edm.EdmSimpleType;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
-import org.apache.olingo.odata2.api.edm.EdmStructuralType;
-import org.apache.olingo.odata2.api.edm.EdmType;
-import org.apache.olingo.odata2.api.edm.EdmTypeKind;
-import org.apache.olingo.odata2.api.edm.EdmTyped;
-import org.apache.olingo.odata2.api.ep.EntityProvider;
-import org.apache.olingo.odata2.api.ep.EntityProviderBatchProperties;
-import org.apache.olingo.odata2.api.ep.EntityProviderException;
-import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
-import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
-import org.apache.olingo.odata2.api.ep.callback.OnWriteEntryContent;
-import org.apache.olingo.odata2.api.ep.callback.OnWriteFeedContent;
-import org.apache.olingo.odata2.api.ep.callback.WriteCallbackContext;
-import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackContext;
-import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackResult;
-import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackContext;
-import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackResult;
-import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
-import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
-import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.exception.ODataHttpException;
-import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
-import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.api.processor.ODataRequest;
-import org.apache.olingo.odata2.api.processor.ODataResponse;
-import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
-import org.apache.olingo.odata2.api.uri.KeyPredicate;
-import org.apache.olingo.odata2.api.uri.NavigationSegment;
-import org.apache.olingo.odata2.api.uri.PathInfo;
-import org.apache.olingo.odata2.api.uri.UriParser;
-import org.apache.olingo.odata2.api.uri.expression.BinaryExpression;
-import org.apache.olingo.odata2.api.uri.expression.CommonExpression;
-import org.apache.olingo.odata2.api.uri.expression.ExpressionKind;
-import org.apache.olingo.odata2.api.uri.expression.FilterExpression;
-import org.apache.olingo.odata2.api.uri.expression.LiteralExpression;
-import org.apache.olingo.odata2.api.uri.expression.MemberExpression;
-import org.apache.olingo.odata2.api.uri.expression.MethodExpression;
-import org.apache.olingo.odata2.api.uri.expression.OrderByExpression;
-import org.apache.olingo.odata2.api.uri.expression.OrderExpression;
-import org.apache.olingo.odata2.api.uri.expression.PropertyExpression;
-import org.apache.olingo.odata2.api.uri.expression.SortOrder;
-import org.apache.olingo.odata2.api.uri.expression.UnaryExpression;
-import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetComplexPropertyUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntityCountUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntityLinkCountUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntityLinkUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntitySetLinksCountUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntitySetLinksUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetFunctionImportUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetMediaResourceUriInfo;
-import org.apache.olingo.odata2.api.uri.info.GetSimplePropertyUriInfo;
-import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
-import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
-
-/**
- * Implementation of the centralized parts of OData processing,
- * allowing to use the simplified {@link DataSource} for the
- * actual data handling.
- * 
- */
-public class ListsProcessor extends DataSourceProcessor {
-
-  // TODO: Paging size should be configurable.
-  private static final int SERVER_PAGING_SIZE = 100;
-
-  public ListsProcessor(final DataSource dataSource, final ValueAccess valueAccess) {
-    super(dataSource, valueAccess);
-  }
-
-  @Override
-  public ODataResponse readEntitySet(final GetEntitySetUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    ArrayList<Object> data = new ArrayList<Object>();
-    try {
-      data.addAll((List<?>) retrieveData(
-          uriInfo.getStartEntitySet(),
-          uriInfo.getKeyPredicates(),
-          uriInfo.getFunctionImport(),
-          mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-          uriInfo.getNavigationSegments()));
-    } catch (final ODataNotFoundException e) {
-      data.clear();
-    }
-
-    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
-    final InlineCount inlineCountType = uriInfo.getInlineCount();
-    final Integer count = applySystemQueryOptions(
-        entitySet,
-        data,
-        uriInfo.getFilter(),
-        inlineCountType,
-        uriInfo.getOrderBy(),
-        uriInfo.getSkipToken(),
-        uriInfo.getSkip(),
-        uriInfo.getTop());
-
-    ODataContext context = getContext();
-    String nextLink = null;
-
-    // Limit the number of returned entities and provide a "next" link
-    // if there are further entities.
-    // Almost all system query options in the current request must be carried
-    // over to the URI for the "next" link, with the exception of $skiptoken
-    // and $skip.
-    if (data.size() > SERVER_PAGING_SIZE) {
-      if (uriInfo.getOrderBy() == null
-          && uriInfo.getSkipToken() == null
-          && uriInfo.getSkip() == null
-          && uriInfo.getTop() == null) {
-        sortInDefaultOrder(entitySet, data);
-      }
-
-      // TODO: Percent-encode "next" link.
-      nextLink = context.getPathInfo().getServiceRoot().relativize(context.getPathInfo().getRequestUri()).toString()
-          .replaceAll("\\$skiptoken=.+?&?", "")
-          .replaceAll("\\$skip=.+?&?", "")
-          .replaceFirst("(?:\\?|&)$", ""); // Remove potentially trailing "?" or "&" left over from remove actions
-                                           // above.
-      nextLink += (nextLink.contains("?") ? "&" : "?")
-          + "$skiptoken=" + getSkipToken(entitySet, data.get(SERVER_PAGING_SIZE));
-
-      while (data.size() > SERVER_PAGING_SIZE) {
-        data.remove(SERVER_PAGING_SIZE);
-      }
-    }
-
-    final EdmEntityType entityType = entitySet.getEntityType();
-    List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
-    for (final Object entryData : data) {
-      values.add(getStructuralTypeValueMap(entryData, entityType));
-    }
-
-    final EntityProviderWriteProperties feedProperties = EntityProviderWriteProperties
-        .serviceRoot(context.getPathInfo().getServiceRoot())
-        .inlineCountType(inlineCountType)
-        .inlineCount(count)
-        .expandSelectTree(UriParser.createExpandSelectTree(uriInfo.getSelect(), uriInfo.getExpand()))
-        .callbacks(getCallbacks(data, entityType))
-        .nextLink(nextLink)
-        .build();
-
-    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeFeed");
-    final ODataResponse response = EntityProvider.writeFeed(contentType, entitySet, values, feedProperties);
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    return ODataResponse.fromResponse(response).build();
-  }
-
-  @Override
-  public ODataResponse countEntitySet(final GetEntitySetCountUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    ArrayList<Object> data = new ArrayList<Object>();
-    try {
-      data.addAll((List<?>) retrieveData(
-          uriInfo.getStartEntitySet(),
-          uriInfo.getKeyPredicates(),
-          uriInfo.getFunctionImport(),
-          mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-          uriInfo.getNavigationSegments()));
-    } catch (final ODataNotFoundException e) {
-      data.clear();
-    }
-
-    applySystemQueryOptions(
-        uriInfo.getTargetEntitySet(),
-        data,
-        uriInfo.getFilter(),
-        null,
-        null,
-        null,
-        uriInfo.getSkip(),
-        uriInfo.getTop());
-
-    return ODataResponse.fromResponse(EntityProvider.writeText(String.valueOf(data.size()))).build();
-  }
-
-  @Override
-  public ODataResponse readEntityLinks(final GetEntitySetLinksUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    ArrayList<Object> data = new ArrayList<Object>();
-    try {
-      data.addAll((List<?>) retrieveData(
-          uriInfo.getStartEntitySet(),
-          uriInfo.getKeyPredicates(),
-          uriInfo.getFunctionImport(),
-          mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-          uriInfo.getNavigationSegments()));
-    } catch (final ODataNotFoundException e) {
-      data.clear();
-    }
-
-    final Integer count = applySystemQueryOptions(
-        uriInfo.getTargetEntitySet(),
-        data,
-        uriInfo.getFilter(),
-        uriInfo.getInlineCount(),
-        null, // uriInfo.getOrderBy(),
-        uriInfo.getSkipToken(),
-        uriInfo.getSkip(),
-        uriInfo.getTop());
-
-    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
-
-    List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
-    for (final Object entryData : data) {
-      Map<String, Object> entryValues = new HashMap<String, Object>();
-      for (final EdmProperty property : entitySet.getEntityType().getKeyProperties()) {
-        entryValues.put(property.getName(), valueAccess.getPropertyValue(entryData, property));
-      }
-      values.add(entryValues);
-    }
-
-    ODataContext context = getContext();
-    final EntityProviderWriteProperties entryProperties = EntityProviderWriteProperties
-        .serviceRoot(context.getPathInfo().getServiceRoot())
-        .inlineCountType(uriInfo.getInlineCount())
-        .inlineCount(count)
-        .build();
-
-    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeLinks");
-
-    final ODataResponse response = EntityProvider.writeLinks(contentType, entitySet, values, entryProperties);
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    return ODataResponse.fromResponse(response).build();
-  }
-
-  @Override
-  public ODataResponse countEntityLinks(final GetEntitySetLinksCountUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    return countEntitySet((GetEntitySetCountUriInfo) uriInfo, contentType);
-  }
-
-  @Override
-  public ODataResponse readEntity(final GetEntityUriInfo uriInfo, final String contentType) throws ODataException {
-    final Object data = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        uriInfo.getNavigationSegments());
-
-    if (!appliesFilter(data, uriInfo.getFilter())) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    final ExpandSelectTreeNode expandSelectTreeNode =
-        UriParser.createExpandSelectTree(uriInfo.getSelect(), uriInfo.getExpand());
-    ODataResponse odr =
-        ODataResponse.fromResponse(writeEntry(uriInfo.getTargetEntitySet(), expandSelectTreeNode, data, contentType))
-            .build();
-
-    return odr;
-  }
-
-  @Override
-  public ODataResponse existsEntity(final GetEntityCountUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    final Object data = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        uriInfo.getNavigationSegments());
-
-    return ODataResponse.fromResponse(EntityProvider.writeText(appliesFilter(data, uriInfo.getFilter()) ? "1" : "0"))
-        .build();
-  }
-
-  @Override
-  public ODataResponse deleteEntity(final DeleteUriInfo uriInfo, final String contentType) throws ODataException {
-    dataSource.deleteData(
-        uriInfo.getStartEntitySet(),
-        mapKey(uriInfo.getKeyPredicates()));
-    return ODataResponse.newBuilder().build();
-  }
-
-  @Override
-  public ODataResponse createEntity(final PostUriInfo uriInfo, final InputStream content,
-      final String requestContentType, final String contentType) throws ODataException {
-    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
-    final EdmEntityType entityType = entitySet.getEntityType();
-
-    Object data = dataSource.newDataObject(entitySet);
-    ExpandSelectTreeNode expandSelectTree = null;
-
-    if (entityType.hasStream()) {
-      dataSource.createData(entitySet, data);
-      dataSource.writeBinaryData(entitySet, data,
-          new BinaryData(EntityProvider.readBinary(content), requestContentType));
-
-    } else {
-      final EntityProviderReadProperties properties = EntityProviderReadProperties.init()
-          .mergeSemantic(false)
-          .addTypeMappings(getStructuralTypeTypeMap(data, entityType))
-          .build();
-      final ODataEntry entryValues = parseEntry(entitySet, content, requestContentType, properties);
-
-      setStructuralTypeValuesFromMap(data, entityType, entryValues.getProperties(), false);
-
-      dataSource.createData(entitySet, data);
-
-      createInlinedEntities(entitySet, data, entryValues);
-
-      expandSelectTree = entryValues.getExpandSelectTree();
-    }
-
-    // Link back to the entity the target entity set is related to, if any.
-    final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
-    if (!navigationSegments.isEmpty()) {
-      final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
-      final Object sourceData = retrieveData(
-          uriInfo.getStartEntitySet(),
-          uriInfo.getKeyPredicates(),
-          uriInfo.getFunctionImport(),
-          mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-          previousSegments);
-      final EdmEntitySet previousEntitySet = previousSegments.isEmpty() ?
-          uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
-      dataSource.writeRelation(previousEntitySet, sourceData, entitySet, getStructuralTypeValueMap(data, entityType));
-    }
-
-    return ODataResponse.fromResponse(writeEntry(uriInfo.getTargetEntitySet(), expandSelectTree, data, contentType))
-        .eTag(constructETag(entitySet, data)).build();
-  }
-
-  @Override
-  public ODataResponse updateEntity(final PutMergePatchUriInfo uriInfo, final InputStream content,
-      final String requestContentType, final boolean merge, final String contentType) throws ODataException {
-    Object data = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        uriInfo.getNavigationSegments());
-
-    if (!appliesFilter(data, uriInfo.getFilter())) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
-    final EdmEntityType entityType = entitySet.getEntityType();
-    final EntityProviderReadProperties properties = EntityProviderReadProperties.init()
-        .mergeSemantic(merge)
-        .addTypeMappings(getStructuralTypeTypeMap(data, entityType))
-        .build();
-    final ODataEntry entryValues = parseEntry(entitySet, content, requestContentType, properties);
-
-    setStructuralTypeValuesFromMap(data, entityType, entryValues.getProperties(), merge);
-
-    return ODataResponse.newBuilder().eTag(constructETag(entitySet, data)).build();
-  }
-
-  @Override
-  public ODataResponse readEntityLink(final GetEntityLinkUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    final Object data = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        uriInfo.getNavigationSegments());
-
-    // if (!appliesFilter(data, uriInfo.getFilter()))
-    if (data == null) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
-
-    Map<String, Object> values = new HashMap<String, Object>();
-    for (final EdmProperty property : entitySet.getEntityType().getKeyProperties()) {
-      values.put(property.getName(), valueAccess.getPropertyValue(data, property));
-    }
-
-    ODataContext context = getContext();
-    final EntityProviderWriteProperties entryProperties = EntityProviderWriteProperties
-        .serviceRoot(context.getPathInfo().getServiceRoot())
-        .build();
-
-    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeLink");
-
-    final ODataResponse response = EntityProvider.writeLink(contentType, entitySet, values, entryProperties);
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    return ODataResponse.fromResponse(response).build();
-  }
-
-  @Override
-  public ODataResponse existsEntityLink(final GetEntityLinkCountUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    return existsEntity((GetEntityCountUriInfo) uriInfo, contentType);
-  }
-
-  @Override
-  public ODataResponse deleteEntityLink(final DeleteUriInfo uriInfo, final String contentType) throws ODataException {
-    final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
-    final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
-
-    final Object sourceData = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        previousSegments);
-
-    final EdmEntitySet entitySet = previousSegments.isEmpty() ?
-        uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
-    final EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
-    final Map<String, Object> keys = mapKey(uriInfo.getTargetKeyPredicates());
-
-    final Object targetData = dataSource.readRelatedData(entitySet, sourceData, targetEntitySet, keys);
-
-    // if (!appliesFilter(targetData, uriInfo.getFilter()))
-    if (targetData == null) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    dataSource.deleteRelation(entitySet, sourceData, targetEntitySet, keys);
-
-    return ODataResponse.newBuilder().build();
-  }
-
-  @Override
-  public ODataResponse createEntityLink(final PostUriInfo uriInfo, final InputStream content,
-      final String requestContentType, final String contentType) throws ODataException {
-    final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
-    final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
-
-    final Object sourceData = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        previousSegments);
-
-    final EdmEntitySet entitySet = previousSegments.isEmpty() ?
-        uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
-    final EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
-
-    final Map<String, Object> targetKeys = parseLink(targetEntitySet, content, requestContentType);
-
-    dataSource.writeRelation(entitySet, sourceData, targetEntitySet, targetKeys);
-
-    return ODataResponse.newBuilder().build();
-  }
-
-  @Override
-  public ODataResponse updateEntityLink(final PutMergePatchUriInfo uriInfo, final InputStream content,
-      final String requestContentType, final String contentType) throws ODataException {
-    final List<NavigationSegment> navigationSegments = uriInfo.getNavigationSegments();
-    final List<NavigationSegment> previousSegments = navigationSegments.subList(0, navigationSegments.size() - 1);
-
-    final Object sourceData = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        previousSegments);
-
-    final EdmEntitySet entitySet = previousSegments.isEmpty() ?
-        uriInfo.getStartEntitySet() : previousSegments.get(previousSegments.size() - 1).getEntitySet();
-    final EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
-    final Map<String, Object> keys = mapKey(uriInfo.getTargetKeyPredicates());
-
-    final Object targetData = dataSource.readRelatedData(entitySet, sourceData, targetEntitySet, keys);
-
-    if (!appliesFilter(targetData, uriInfo.getFilter())) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    dataSource.deleteRelation(entitySet, sourceData, targetEntitySet, keys);
-
-    final Map<String, Object> newKeys = parseLink(targetEntitySet, content, requestContentType);
-
-    dataSource.writeRelation(entitySet, sourceData, targetEntitySet, newKeys);
-
-    return ODataResponse.newBuilder().build();
-  }
-
-  @Override
-  public ODataResponse readEntityComplexProperty(final GetComplexPropertyUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    Object data = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        uriInfo.getNavigationSegments());
-
-    // if (!appliesFilter(data, uriInfo.getFilter()))
-    if (data == null) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
-    final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
-    final Object value = property.isSimple() ?
-        property.getMapping() == null || property.getMapping().getMimeType() == null ?
-            getPropertyValue(data, propertyPath) : getSimpleTypeValueMap(data, propertyPath) :
-        getStructuralTypeValueMap(getPropertyValue(data, propertyPath), (EdmStructuralType) property.getType());
-
-    ODataContext context = getContext();
-    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeProperty");
-
-    final ODataResponse response = EntityProvider.writeProperty(contentType, property, value);
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    return ODataResponse.fromResponse(response).eTag(constructETag(uriInfo.getTargetEntitySet(), data)).build();
-  }
-
-  @Override
-  public ODataResponse readEntitySimpleProperty(final GetSimplePropertyUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    return readEntityComplexProperty((GetComplexPropertyUriInfo) uriInfo, contentType);
-  }
-
-  @Override
-  public ODataResponse readEntitySimplePropertyValue(final GetSimplePropertyUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    Object data = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        uriInfo.getNavigationSegments());
-
-    // if (!appliesFilter(data, uriInfo.getFilter()))
-    if (data == null) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
-    final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
-    final Object value = property.getMapping() == null || property.getMapping().getMimeType() == null ?
-        getPropertyValue(data, propertyPath) : getSimpleTypeValueMap(data, propertyPath);
-
-    return ODataResponse.fromResponse(EntityProvider.writePropertyValue(property, value)).eTag(
-        constructETag(uriInfo.getTargetEntitySet(), data)).build();
-  }
-
-  @Override
-  public ODataResponse deleteEntitySimplePropertyValue(final DeleteUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    Object data = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        uriInfo.getNavigationSegments());
-
-    if (data == null) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
-    final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
-
-    data = getPropertyValue(data, propertyPath.subList(0, propertyPath.size() - 1));
-    valueAccess.setPropertyValue(data, property, null);
-    valueAccess.setMappingValue(data, property.getMapping(), null);
-
-    return ODataResponse.newBuilder().build();
-  }
-
-  @Override
-  public ODataResponse updateEntityComplexProperty(final PutMergePatchUriInfo uriInfo, final InputStream content,
-      final String requestContentType, final boolean merge, final String contentType) throws ODataException {
-    Object data = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        uriInfo.getNavigationSegments());
-
-    if (!appliesFilter(data, uriInfo.getFilter())) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
-    final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
-
-    data = getPropertyValue(data, propertyPath.subList(0, propertyPath.size() - 1));
-
-    ODataContext context = getContext();
-    int timingHandle = context.startRuntimeMeasurement("EntityConsumer", "readProperty");
-
-    Map<String, Object> values;
-    try {
-      values =
-          EntityProvider.readProperty(requestContentType, property, content, EntityProviderReadProperties.init()
-              .mergeSemantic(merge).build());
-    } catch (final EntityProviderException e) {
-      throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
-    }
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    final Object value = values.get(property.getName());
-    if (property.isSimple()) {
-      valueAccess.setPropertyValue(data, property, value);
-    } else {
-      @SuppressWarnings("unchecked")
-      final Map<String, Object> propertyValue = (Map<String, Object>) value;
-      setStructuralTypeValuesFromMap(valueAccess.getPropertyValue(data, property),
-          (EdmStructuralType) property.getType(), propertyValue, merge);
-    }
-
-    return ODataResponse.newBuilder().eTag(constructETag(uriInfo.getTargetEntitySet(), data)).build();
-  }
-
-  @Override
-  public ODataResponse updateEntitySimpleProperty(final PutMergePatchUriInfo uriInfo, final InputStream content,
-      final String requestContentType, final String contentType) throws ODataException {
-    return updateEntityComplexProperty(uriInfo, content, requestContentType, false, contentType);
-  }
-
-  @Override
-  public ODataResponse updateEntitySimplePropertyValue(final PutMergePatchUriInfo uriInfo, final InputStream content,
-      final String requestContentType, final String contentType) throws ODataException {
-    Object data = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        uriInfo.getNavigationSegments());
-
-    if (!appliesFilter(data, uriInfo.getFilter())) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    final List<EdmProperty> propertyPath = uriInfo.getPropertyPath();
-    final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
-
-    data = getPropertyValue(data, propertyPath.subList(0, propertyPath.size() - 1));
-
-    ODataContext context = getContext();
-    int timingHandle = context.startRuntimeMeasurement("EntityConsumer", "readPropertyValue");
-
-    Object value;
-    try {
-      value = EntityProvider.readPropertyValue(property, content);
-    } catch (final EntityProviderException e) {
-      throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
-    }
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    valueAccess.setPropertyValue(data, property, value);
-    valueAccess.setMappingValue(data, property.getMapping(), requestContentType);
-
-    return ODataResponse.newBuilder().eTag(constructETag(uriInfo.getTargetEntitySet(), data)).build();
-  }
-
-  @Override
-  public ODataResponse readEntityMedia(final GetMediaResourceUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    final Object data = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        uriInfo.getNavigationSegments());
-
-    if (!appliesFilter(data, uriInfo.getFilter())) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
-    final BinaryData binaryData = dataSource.readBinaryData(entitySet, data);
-    if (binaryData == null) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    final String mimeType = binaryData.getMimeType() == null ?
-        HttpContentType.APPLICATION_OCTET_STREAM : binaryData.getMimeType();
-
-    return ODataResponse.fromResponse(EntityProvider.writeBinary(mimeType, binaryData.getData())).eTag(
-        constructETag(entitySet, data)).build();
-  }
-
-  @Override
-  public ODataResponse deleteEntityMedia(final DeleteUriInfo uriInfo, final String contentType) throws ODataException {
-    final Object data = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        uriInfo.getNavigationSegments());
-
-    if (data == null) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    dataSource.writeBinaryData(uriInfo.getTargetEntitySet(), data, new BinaryData(null, null));
-
-    return ODataResponse.newBuilder().build();
-  }
-
-  @Override
-  public ODataResponse updateEntityMedia(final PutMergePatchUriInfo uriInfo, final InputStream content,
-      final String requestContentType, final String contentType) throws ODataException {
-    final Object data = retrieveData(
-        uriInfo.getStartEntitySet(),
-        uriInfo.getKeyPredicates(),
-        uriInfo.getFunctionImport(),
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        uriInfo.getNavigationSegments());
-
-    if (!appliesFilter(data, uriInfo.getFilter())) {
-      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-    }
-
-    ODataContext context = getContext();
-    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "readBinary");
-
-    final byte[] value = EntityProvider.readBinary(content);
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
-    dataSource.writeBinaryData(entitySet, data, new BinaryData(value, requestContentType));
-
-    return ODataResponse.newBuilder().eTag(constructETag(entitySet, data)).build();
-  }
-
-  @Override
-  public ODataResponse executeFunctionImport(final GetFunctionImportUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    final EdmFunctionImport functionImport = uriInfo.getFunctionImport();
-    final EdmType type = functionImport.getReturnType().getType();
-
-    final Object data = dataSource.readData(
-        functionImport,
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        null);
-
-    if (data == null) {
-      throw new ODataNotFoundException(ODataHttpException.COMMON);
-    }
-
-    Object value;
-    if (type.getKind() == EdmTypeKind.SIMPLE) {
-      value = type == EdmSimpleTypeKind.Binary.getEdmSimpleTypeInstance() ?
-          ((BinaryData) data).getData() : data;
-    } else if (functionImport.getReturnType().getMultiplicity() == EdmMultiplicity.MANY) {
-      List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
-      for (final Object typeData : (List<?>) data) {
-        values.add(getStructuralTypeValueMap(typeData, (EdmStructuralType) type));
-      }
-      value = values;
-    } else {
-      value = getStructuralTypeValueMap(data, (EdmStructuralType) type);
-    }
-
-    ODataContext context = getContext();
-
-    final EntityProviderWriteProperties entryProperties = EntityProviderWriteProperties
-        .serviceRoot(context.getPathInfo().getServiceRoot()).build();
-
-    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeFunctionImport");
-
-    final ODataResponse response =
-        EntityProvider.writeFunctionImport(contentType, functionImport, value, entryProperties);
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    return ODataResponse.fromResponse(response).build();
-  }
-
-  @Override
-  public ODataResponse executeFunctionImportValue(final GetFunctionImportUriInfo uriInfo, final String contentType)
-      throws ODataException {
-    final EdmFunctionImport functionImport = uriInfo.getFunctionImport();
-    final EdmSimpleType type = (EdmSimpleType) functionImport.getReturnType().getType();
-
-    final Object data = dataSource.readData(
-        functionImport,
-        mapFunctionParameters(uriInfo.getFunctionImportParameters()),
-        null);
-
-    if (data == null) {
-      throw new ODataNotFoundException(ODataHttpException.COMMON);
-    }
-
-    ODataResponse response;
-    if (type == EdmSimpleTypeKind.Binary.getEdmSimpleTypeInstance()) {
-      response = EntityProvider.writeBinary(((BinaryData) data).getMimeType(), ((BinaryData) data).getData());
-    } else {
-      final String value = type.valueToString(data, EdmLiteralKind.DEFAULT, null);
-      response = EntityProvider.writeText(value == null ? "" : value);
-    }
-    return ODataResponse.fromResponse(response).build();
-  }
-
-  private static Map<String, Object> mapKey(final List<KeyPredicate> keys) throws EdmException {
-    Map<String, Object> keyMap = new HashMap<String, Object>();
-    for (final KeyPredicate key : keys) {
-      final EdmProperty property = key.getProperty();
-      final EdmSimpleType type = (EdmSimpleType) property.getType();
-      keyMap.put(property.getName(), type.valueOfString(key.getLiteral(), EdmLiteralKind.DEFAULT, property.getFacets(),
-          type.getDefaultType()));
-    }
-    return keyMap;
-  }
-
-  private static Map<String, Object> mapFunctionParameters(final Map<String, EdmLiteral> functionImportParameters)
-      throws EdmSimpleTypeException {
-    if (functionImportParameters == null) {
-      return Collections.emptyMap();
-    } else {
-      Map<String, Object> parameterMap = new HashMap<String, Object>();
-      for (final String parameterName : functionImportParameters.keySet()) {
-        final EdmLiteral literal = functionImportParameters.get(parameterName);
-        final EdmSimpleType type = literal.getType();
-        parameterMap.put(parameterName, type.valueOfString(literal.getLiteral(), EdmLiteralKind.DEFAULT, null, type
-            .getDefaultType()));
-      }
-      return parameterMap;
-    }
-  }
-
-  private Object retrieveData(final EdmEntitySet startEntitySet, final List<KeyPredicate> keyPredicates,
-      final EdmFunctionImport functionImport, final Map<String, Object> functionImportParameters,
-      final List<NavigationSegment> navigationSegments) throws ODataException {
-    Object data;
-    final Map<String, Object> keys = mapKey(keyPredicates);
-
-    ODataContext context = getContext();
-    final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "retrieveData");
-
-    data = functionImport == null ?
-        keys.isEmpty() ?
-            dataSource.readData(startEntitySet) : dataSource.readData(startEntitySet, keys) :
-        dataSource.readData(functionImport, functionImportParameters, keys);
-
-    EdmEntitySet currentEntitySet =
-        functionImport == null ? startEntitySet : functionImport.getEntitySet();
-    for (NavigationSegment navigationSegment : navigationSegments) {
-      data = dataSource.readRelatedData(
-          currentEntitySet,
-          data,
-          navigationSegment.getEntitySet(),
-          mapKey(navigationSegment.getKeyPredicates()));
-      currentEntitySet = navigationSegment.getEntitySet();
-    }
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    return data;
-  }
-
-  private <T> String constructETag(final EdmEntitySet entitySet, final T data) throws ODataException {
-    final EdmEntityType entityType = entitySet.getEntityType();
-    String eTag = null;
-    for (final String propertyName : entityType.getPropertyNames()) {
-      final EdmProperty property = (EdmProperty) entityType.getProperty(propertyName);
-      if (property.getFacets() != null && property.getFacets().getConcurrencyMode() == EdmConcurrencyMode.Fixed) {
-        final EdmSimpleType type = (EdmSimpleType) property.getType();
-        final String component = type.valueToString(valueAccess.getPropertyValue(data, property),
-            EdmLiteralKind.DEFAULT, property.getFacets());
-        eTag = eTag == null ? component : eTag + Edm.DELIMITER + component;
-      }
-    }
-    return eTag == null ? null : "W/\"" + eTag + "\"";
-  }
-
-  private <T> Map<String, ODataCallback> getCallbacks(final T data, final EdmEntityType entityType)
-      throws EdmException {
-    final List<String> navigationPropertyNames = entityType.getNavigationPropertyNames();
-    if (navigationPropertyNames.isEmpty()) {
-      return null;
-    } else {
-      final WriteCallback callback = new WriteCallback(data);
-      Map<String, ODataCallback> callbacks = new HashMap<String, ODataCallback>();
-      for (final String name : navigationPropertyNames) {
-        callbacks.put(name, callback);
-      }
-      return callbacks;
-    }
-  }
-
-  private class WriteCallback implements OnWriteEntryContent, OnWriteFeedContent {
-    private final Object data;
-
-    private <T> WriteCallback(final T data) {
-      this.data = data;
-    }
-
-    @Override
-    public WriteFeedCallbackResult retrieveFeedResult(final WriteFeedCallbackContext context)
-        throws ODataApplicationException {
-      try {
-        final EdmEntityType entityType =
-            context.getSourceEntitySet().getRelatedEntitySet(context.getNavigationProperty()).getEntityType();
-        List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
-        Object relatedData = null;
-        try {
-          relatedData = readRelatedData(context);
-          for (final Object entryData : (List<?>) relatedData) {
-            values.add(getStructuralTypeValueMap(entryData, entityType));
-          }
-        } catch (final ODataNotFoundException e) {
-          values.clear();
-        }
-        WriteFeedCallbackResult result = new WriteFeedCallbackResult();
-        result.setFeedData(values);
-        EntityProviderWriteProperties inlineProperties =
-            EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).callbacks(
-                getCallbacks(relatedData, entityType)).expandSelectTree(context.getCurrentExpandSelectTreeNode())
-                .selfLink(context.getSelfLink()).build();
-        result.setInlineProperties(inlineProperties);
-        return result;
-      } catch (final ODataException e) {
-        throw new ODataApplicationException(e.getLocalizedMessage(), Locale.ROOT, e);
-      }
-    }
-
-    @Override
-    public WriteEntryCallbackResult retrieveEntryResult(final WriteEntryCallbackContext context)
-        throws ODataApplicationException {
-      try {
-        final EdmEntityType entityType =
-            context.getSourceEntitySet().getRelatedEntitySet(context.getNavigationProperty()).getEntityType();
-        WriteEntryCallbackResult result = new WriteEntryCallbackResult();
-        Object relatedData;
-        try {
-          relatedData = readRelatedData(context);
-        } catch (final ODataNotFoundException e) {
-          relatedData = null;
-        }
-        
-        if (relatedData == null) {
-          result.setEntryData(Collections.<String, Object> emptyMap());
-        } else {
-          result.setEntryData(getStructuralTypeValueMap(relatedData, entityType));
-
-          EntityProviderWriteProperties inlineProperties =
-              EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).callbacks(
-                  getCallbacks(relatedData, entityType)).expandSelectTree(context.getCurrentExpandSelectTreeNode())
-                  .build();
-          result.setInlineProperties(inlineProperties);
-        }
-        return result;
-      } catch (final ODataException e) {
-        throw new ODataApplicationException(e.getLocalizedMessage(), Locale.ROOT, e);
-      }
-    }
-
-    private Object readRelatedData(final WriteCallbackContext context) throws ODataException {
-      final EdmEntitySet entitySet = context.getSourceEntitySet();
-      return dataSource.readRelatedData(
-          entitySet,
-          data instanceof List ? readEntryData((List<?>) data, entitySet.getEntityType(), context
-              .extractKeyFromEntryData()) : data,
-          entitySet.getRelatedEntitySet(context.getNavigationProperty()),
-          Collections.<String, Object> emptyMap());
-    }
-
-    private <T> T readEntryData(final List<T> data, final EdmEntityType entityType, final Map<String, Object> key)
-        throws ODataException {
-      for (final T entryData : data) {
-        boolean found = true;
-        for (final EdmProperty keyProperty : entityType.getKeyProperties()) {
-          if (!valueAccess.getPropertyValue(entryData, keyProperty).equals(key.get(keyProperty.getName()))) {
-            found = false;
-            break;
-          }
-        }
-        if (found) {
-          return entryData;
-        }
-      }
-      return null;
-    }
-  }
-
-  private <T> ODataResponse writeEntry(final EdmEntitySet entitySet, final ExpandSelectTreeNode expandSelectTree,
-      final T data, final String contentType) throws ODataException, EntityProviderException {
-    final EdmEntityType entityType = entitySet.getEntityType();
-    final Map<String, Object> values = getStructuralTypeValueMap(data, entityType);
-
-    ODataContext context = getContext();
-    EntityProviderWriteProperties writeProperties = EntityProviderWriteProperties
-        .serviceRoot(context.getPathInfo().getServiceRoot())
-        .expandSelectTree(expandSelectTree)
-        .callbacks(getCallbacks(data, entityType))
-        .build();
-
-    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "writeEntry");
-
-    final ODataResponse response = EntityProvider.writeEntry(contentType, entitySet, values, writeProperties);
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    return response;
-  }
-
-  private ODataEntry parseEntry(final EdmEntitySet entitySet, final InputStream content,
-      final String requestContentType, final EntityProviderReadProperties properties) throws ODataBadRequestException {
-    ODataContext context = getContext();
-    final int timingHandle = context.startRuntimeMeasurement("EntityConsumer", "readEntry");
-
-    ODataEntry entryValues;
-    try {
-      entryValues = EntityProvider.readEntry(requestContentType, entitySet, content, properties);
-    } catch (final EntityProviderException e) {
-      throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
-    }
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    return entryValues;
-  }
-
-  private Map<String, Object> parseLink(final EdmEntitySet entitySet, final InputStream content,
-      final String contentType) throws ODataException {
-    ODataContext context = getContext();
-    final int timingHandle = context.startRuntimeMeasurement("EntityProvider", "readLink");
-
-    final String uriString = EntityProvider.readLink(contentType, entitySet, content);
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    final Map<String, Object> targetKeys = parseLinkUri(entitySet, uriString);
-    if (targetKeys == null) {
-      throw new ODataBadRequestException(ODataBadRequestException.BODY);
-    }
-    return targetKeys;
-  }
-
-  private Map<String, Object> parseLinkUri(final EdmEntitySet targetEntitySet, final String uriString)
-      throws EdmException {
-    ODataContext context = getContext();
-    final int timingHandle = context.startRuntimeMeasurement("UriParser", "getKeyPredicatesFromEntityLink");
-
-    List<KeyPredicate> key = null;
-    try {
-      key = UriParser.getKeyPredicatesFromEntityLink(targetEntitySet, uriString,
-          context.getPathInfo().getServiceRoot());
-    } catch (ODataException e) {
-      // We don't understand the link target. This could also be seen as an error.
-    }
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    return key == null ? null : mapKey(key);
-  }
-
-  private <T> void createInlinedEntities(final EdmEntitySet entitySet, final T data, final ODataEntry entryValues)
-      throws ODataException {
-    final EdmEntityType entityType = entitySet.getEntityType();
-    for (final String navigationPropertyName : entityType.getNavigationPropertyNames()) {
-
-      final EdmNavigationProperty navigationProperty =
-          (EdmNavigationProperty) entityType.getProperty(navigationPropertyName);
-      final EdmEntitySet relatedEntitySet = entitySet.getRelatedEntitySet(navigationProperty);
-      final EdmEntityType relatedEntityType = relatedEntitySet.getEntityType();
-
-      final Object relatedValue = entryValues.getProperties().get(navigationPropertyName);
-      if (relatedValue == null) {
-        for (final String uriString : entryValues.getMetadata().getAssociationUris(navigationPropertyName)) {
-          final Map<String, Object> key = parseLinkUri(relatedEntitySet, uriString);
-          if (key != null) {
-            dataSource.writeRelation(entitySet, data, relatedEntitySet, key);
-          }
-        }
-
-      } else {
-        if (relatedValue instanceof ODataFeed) {
-          ODataFeed feed = (ODataFeed) relatedValue;
-          final List<ODataEntry> relatedValueList = feed.getEntries();
-          for (final ODataEntry relatedValues : relatedValueList) {
-            Object relatedData = dataSource.newDataObject(relatedEntitySet);
-            setStructuralTypeValuesFromMap(relatedData, relatedEntityType, relatedValues.getProperties(), false);
-            dataSource.createData(relatedEntitySet, relatedData);
-            dataSource.writeRelation(entitySet, data, relatedEntitySet, getStructuralTypeValueMap(relatedData,
-                relatedEntityType));
-            createInlinedEntities(relatedEntitySet, relatedData, relatedValues);
-          }
-        } else if (relatedValue instanceof ODataEntry) {
-          final ODataEntry relatedValueEntry = (ODataEntry) relatedValue;
-          Object relatedData = dataSource.newDataObject(relatedEntitySet);
-          setStructuralTypeValuesFromMap(relatedData, relatedEntityType, relatedValueEntry.getProperties(), false);
-          dataSource.createData(relatedEntitySet, relatedData);
-          dataSource.writeRelation(entitySet, data, relatedEntitySet, getStructuralTypeValueMap(relatedData,
-              relatedEntityType));
-          createInlinedEntities(relatedEntitySet, relatedData, relatedValueEntry);
-        } else {
-          throw new ODataException("Unexpected class for a related value: " + relatedValue.getClass().getSimpleName());
-        }
-
-      }
-    }
-  }
-
-  private <T> Integer applySystemQueryOptions(final EdmEntitySet entitySet, final List<T> data,
-      final FilterExpression filter, final InlineCount inlineCount, final OrderByExpression orderBy,
-      final String skipToken, final Integer skip, final Integer top) throws ODataException {
-    ODataContext context = getContext();
-    final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "applySystemQueryOptions");
-
-    if (filter != null) {
-      // Remove all elements the filter does not apply for.
-      // A for-each loop would not work with "remove", see Java documentation.
-      for (Iterator<T> iterator = data.iterator(); iterator.hasNext();) {
-        if (!appliesFilter(iterator.next(), filter)) {
-          iterator.remove();
-        }
-      }
-    }
-
-    final Integer count = inlineCount == InlineCount.ALLPAGES ? data.size() : null;
-
-    if (orderBy != null) {
-      sort(data, orderBy);
-    } else if (skipToken != null || skip != null || top != null) {
-      sortInDefaultOrder(entitySet, data);
-    }
-
-    if (skipToken != null) {
-      while (!data.isEmpty() && !getSkipToken(entitySet, data.get(0)).equals(skipToken)) {
-        data.remove(0);
-      }
-    }
-
-    if (skip != null) {
-      if (skip >= data.size()) {
-        data.clear();
-      } else {
-        for (int i = 0; i < skip; i++) {
-          data.remove(0);
-        }
-      }
-    }
-
-    if (top != null) {
-      while (data.size() > top) {
-        data.remove(top.intValue());
-      }
-    }
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    return count;
-  }
-
-  private <T> void sort(final List<T> data, final OrderByExpression orderBy) {
-    Collections.sort(data, new Comparator<T>() {
-      @Override
-      public int compare(final T entity1, final T entity2) {
-        try {
-          int result = 0;
-          for (final OrderExpression expression : orderBy.getOrders()) {
-            result = evaluateExpression(entity1, expression.getExpression()).compareTo(
-                evaluateExpression(entity2, expression.getExpression()));
-            if (expression.getSortOrder() == SortOrder.desc) {
-              result = -result;
-            }
-            if (result != 0) {
-              break;
-            }
-          }
-          return result;
-        } catch (final ODataException e) {
-          return 0;
-        }
-      }
-    });
-  }
-
-  private <T> void sortInDefaultOrder(final EdmEntitySet entitySet, final List<T> data) {
-    Collections.sort(data, new Comparator<T>() {
-      @Override
-      public int compare(final T entity1, final T entity2) {
-        try {
-          return getSkipToken(entitySet, entity1).compareTo(getSkipToken(entitySet, entity2));
-        } catch (final ODataException e) {
-          return 0;
-        }
-      }
-    });
-  }
-
-  private <T> boolean appliesFilter(final T data, final FilterExpression filter) throws ODataException {
-    ODataContext context = getContext();
-    final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "appliesFilter");
-
-    try {
-      return data != null && (filter == null || evaluateExpression(data, filter.getExpression()).equals("true"));
-    } catch (final RuntimeException e) {
-      return false;
-    } finally {
-      context.stopRuntimeMeasurement(timingHandle);
-    }
-  }
-
-  private <T> String evaluateExpression(final T data, final CommonExpression expression) throws ODataException {
-    switch (expression.getKind()) {
-    case UNARY:
-      final UnaryExpression unaryExpression = (UnaryExpression) expression;
-      final String operand = evaluateExpression(data, unaryExpression.getOperand());
-
-      switch (unaryExpression.getOperator()) {
-      case NOT:
-        return Boolean.toString(!Boolean.parseBoolean(operand));
-      case MINUS:
-        return operand.startsWith("-") ? operand.substring(1) : "-" + operand;
-      default:
-        throw new ODataNotImplementedException();
-      }
-
-    case BINARY:
-      final BinaryExpression binaryExpression = (BinaryExpression) expression;
-      final EdmSimpleType type = (EdmSimpleType) binaryExpression.getLeftOperand().getEdmType();
-      final String left = evaluateExpression(data, binaryExpression.getLeftOperand());
-      final String right = evaluateExpression(data, binaryExpression.getRightOperand());
-
-      switch (binaryExpression.getOperator()) {
-      case ADD:
-        if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
-            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
-            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
-          return Double.toString(Double.valueOf(left) + Double.valueOf(right));
-        } else {
-          return Long.toString(Long.valueOf(left) + Long.valueOf(right));
-        }
-      case SUB:
-        if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
-            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
-            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
-          return Double.toString(Double.valueOf(left) - Double.valueOf(right));
-        } else {
-          return Long.toString(Long.valueOf(left) - Long.valueOf(right));
-        }
-      case MUL:
-        if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
-            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
-            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
-          return Double.toString(Double.valueOf(left) * Double.valueOf(right));
-        } else {
-          return Long.toString(Long.valueOf(left) * Long.valueOf(right));
-        }
-      case DIV:
-        final String number = Double.toString(Double.valueOf(left) / Double.valueOf(right));
-        return number.endsWith(".0") ? number.replace(".0", "") : number;
-      case MODULO:
-        if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
-            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
-            || binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
-          return Double.toString(Double.valueOf(left) % Double.valueOf(right));
-        } else {
-          return Long.toString(Long.valueOf(left) % Long.valueOf(right));
-        }
-      case AND:
-        return Boolean.toString(left.equals("true") && right.equals("true"));
-      case OR:
-        return Boolean.toString(left.equals("true") || right.equals("true"));
-      case EQ:
-        return Boolean.toString(left.equals(right));
-      case NE:
-        return Boolean.toString(!left.equals(right));
-      case LT:
-        if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
-          return Boolean.toString(left.compareTo(right) < 0);
-        } else {
-          return Boolean.toString(Double.valueOf(left) < Double.valueOf(right));
-        }
-      case LE:
-        if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
-          return Boolean.toString(left.compareTo(right) <= 0);
-        } else {
-          return Boolean.toString(Double.valueOf(left) <= Double.valueOf(right));
-        }
-      case GT:
-        if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
-          return Boolean.toString(left.compareTo(right) > 0);
-        } else {
-          return Boolean.toString(Double.valueOf(left) > Double.valueOf(right));
-        }
-      case GE:
-        if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()
-            || type == EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance()) {
-          return Boolean.toString(left.compareTo(right) >= 0);
-        } else {
-          return Boolean.toString(Double.valueOf(left) >= Double.valueOf(right));
-        }
-      case PROPERTY_ACCESS:
-        throw new ODataNotImplementedException();
-      default:
-        throw new ODataNotImplementedException();
-      }
-
-    case PROPERTY:
-      final EdmProperty property = (EdmProperty) ((PropertyExpression) expression).getEdmProperty();
-      final EdmSimpleType propertyType = (EdmSimpleType) property.getType();
-      return propertyType.valueToString(valueAccess.getPropertyValue(data, property), EdmLiteralKind.DEFAULT,
-          property.getFacets());
-
-    case MEMBER:
-      final MemberExpression memberExpression = (MemberExpression) expression;
-      final PropertyExpression propertyExpression = (PropertyExpression) memberExpression.getProperty();
-      final EdmProperty memberProperty = (EdmProperty) propertyExpression.getEdmProperty();
-      final EdmSimpleType memberType = (EdmSimpleType) memberExpression.getEdmType();
-      List<EdmProperty> propertyPath = new ArrayList<EdmProperty>();
-      CommonExpression currentExpression = memberExpression;
-      while (currentExpression != null) {
-        final PropertyExpression currentPropertyExpression =
-            (PropertyExpression) (currentExpression.getKind() == ExpressionKind.MEMBER ?
-                ((MemberExpression) currentExpression).getProperty() : currentExpression);
-        final EdmTyped currentProperty = currentPropertyExpression.getEdmProperty();
-        final EdmTypeKind kind = currentProperty.getType().getKind();
-        if (kind == EdmTypeKind.SIMPLE || kind == EdmTypeKind.COMPLEX) {
-          propertyPath.add(0, (EdmProperty) currentProperty);
-        } else {
-          throw new ODataNotImplementedException();
-        }
-        currentExpression =
-            currentExpression.getKind() == ExpressionKind.MEMBER ? ((MemberExpression) currentExpression).getPath()
-                : null;
-      }
-      return memberType.valueToString(getPropertyValue(data, propertyPath), EdmLiteralKind.DEFAULT, memberProperty
-          .getFacets());
-
-    case LITERAL:
-      final LiteralExpression literal = (LiteralExpression) expression;
-      final EdmSimpleType literalType = (EdmSimpleType) literal.getEdmType();
-      return literalType.valueToString(literalType.valueOfString(literal.getUriLiteral(), EdmLiteralKind.URI, null,
-          literalType.getDefaultType()),
-          EdmLiteralKind.DEFAULT, null);
-
-    case METHOD:
-      final MethodExpression methodExpression = (MethodExpression) expression;
-      final String first = evaluateExpression(data, methodExpression.getParameters().get(0));
-      final String second = methodExpression.getParameterCount() > 1 ?
-          evaluateExpression(data, methodExpression.getParameters().get(1)) : null;
-      final String third = methodExpression.getParameterCount() > 2 ?
-          evaluateExpression(data, methodExpression.getParameters().get(2)) : null;
-
-      switch (methodExpression.getMethod()) {
-      case ENDSWITH:
-        return Boolean.toString(first.endsWith(second));
-      case INDEXOF:
-        return Integer.toString(first.indexOf(second));
-      case STARTSWITH:
-        return Boolean.toString(first.startsWith(second));
-      case TOLOWER:
-        return first.toLowerCase(Locale.ROOT);
-      case TOUPPER:
-        return first.toUpperCase(Locale.ROOT);
-      case TRIM:
-        return first.trim();
-      case SUBSTRING:
-        final int offset = Integer.parseInt(second);
-        return first.substring(offset, offset + Integer.parseInt(third));
-      case SUBSTRINGOF:
-        return Boolean.toString(second.contains(first));
-      case CONCAT:
-        return first + second;
-      case LENGTH:
-        return Integer.toString(first.length());
-      case YEAR:
-        return String.valueOf(Integer.parseInt(first.substring(0, 4)));
-      case MONTH:
-        return String.valueOf(Integer.parseInt(first.substring(5, 7)));
-      case DAY:
-        return String.valueOf(Integer.parseInt(first.substring(8, 10)));
-      case HOUR:
-        return String.valueOf(Integer.parseInt(first.substring(11, 13)));
-      case MINUTE:
-        return String.valueOf(Integer.parseInt(first.substring(14, 16)));
-      case SECOND:
-        return String.valueOf(Integer.parseInt(first.substring(17, 19)));
-      case ROUND:
-        return Long.toString(Math.round(Double.valueOf(first)));
-      case FLOOR:
-        return Long.toString(Math.round(Math.floor(Double.valueOf(first))));
-      case CEILING:
-        return Long.toString(Math.round(Math.ceil(Double.valueOf(first))));
-      default:
-        throw new ODataNotImplementedException();
-      }
-
-    default:
-      throw new ODataNotImplementedException();
-    }
-  }
-
-  private <T> String getSkipToken(final EdmEntitySet entitySet, final T data) throws ODataException {
-    String skipToken = "";
-    for (final EdmProperty property : entitySet.getEntityType().getKeyProperties()) {
-      final EdmSimpleType type = (EdmSimpleType) property.getType();
-      skipToken = skipToken.concat(type.valueToString(valueAccess.getPropertyValue(data, property),
-          EdmLiteralKind.DEFAULT, property.getFacets()));
-    }
-    return skipToken;
-  }
-
-  private <T> Object getPropertyValue(final T data, final List<EdmProperty> propertyPath) throws ODataException {
-    Object dataObject = data;
-    for (final EdmProperty property : propertyPath) {
-      if (dataObject != null) {
-        dataObject = valueAccess.getPropertyValue(dataObject, property);
-      }
-    }
-    return dataObject;
-  }
-
-  private void handleMimeType(Object data, EdmMapping mapping, Map<String, Object> valueMap)
-      throws ODataException {
-    final String mimeTypeName = mapping.getMimeType();
-    if (mimeTypeName != null) {
-      Object value = valueAccess.getMappingValue(data, mapping);
-      valueMap.put(mimeTypeName, value);
-      if (mapping.getMediaResourceMimeTypeKey() != null) {
-        valueMap.put(mapping.getMediaResourceMimeTypeKey(), value);
-      }
-    }
-  }
-
-  private <T> Map<String, Object> getSimpleTypeValueMap(final T data, final List<EdmProperty> propertyPath)
-      throws ODataException {
-    final EdmProperty property = propertyPath.get(propertyPath.size() - 1);
-    Map<String, Object> valueWithMimeType = new HashMap<String, Object>();
-    valueWithMimeType.put(property.getName(), getPropertyValue(data, propertyPath));
-
-    handleMimeType(data, property.getMapping(), valueWithMimeType);
-
-    return valueWithMimeType;
-  }
-
-  private <T> Map<String, Object> getStructuralTypeValueMap(final T data, final EdmStructuralType type)
-      throws ODataException {
-    ODataContext context = getContext();
-    final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "getStructuralTypeValueMap");
-
-    Map<String, Object> valueMap = new HashMap<String, Object>();
-
-    EdmMapping mapping = type.getMapping();
-    if (mapping != null) {
-      handleMimeType(data, mapping, valueMap);
-    }
-
-    for (final String propertyName : type.getPropertyNames()) {
-      final EdmProperty property = (EdmProperty) type.getProperty(propertyName);
-      final Object value = valueAccess.getPropertyValue(data, property);
-
-      if (property.isSimple()) {
-        if (property.getMapping() == null || property.getMapping().getMimeType() == null) {
-          valueMap.put(propertyName, value);
-        } else {
-          // TODO: enable MIME type mapping outside the current subtree
-          valueMap.put(propertyName, getSimpleTypeValueMap(data, Arrays.asList(property)));
-        }
-      } else {
-        valueMap.put(propertyName, getStructuralTypeValueMap(value, (EdmStructuralType) property.getType()));
-      }
-    }
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    return valueMap;
-  }
-
-  private <T> Map<String, Object> getStructuralTypeTypeMap(final T data, final EdmStructuralType type)
-      throws ODataException {
-    ODataContext context = getContext();
-    final int timingHandle = context.startRuntimeMeasurement(getClass().getSimpleName(), "getStructuralTypeTypeMap");
-
-    Map<String, Object> typeMap = new HashMap<String, Object>();
-    for (final String propertyName : type.getPropertyNames()) {
-      final EdmProperty property = (EdmProperty) type.getProperty(propertyName);
-      if (property.isSimple()) {
-        typeMap.put(propertyName, valueAccess.getPropertyType(data, property));
-      } else {
-        typeMap.put(propertyName, getStructuralTypeTypeMap(valueAccess.getPropertyValue(data, property),
-            (EdmStructuralType) property.getType()));
-      }
-    }
-
-    context.stopRuntimeMeasurement(timingHandle);
-
-    return typeMap;
-  }
-
-  private <T> void setStructuralTypeValuesFromMap(final T data, final EdmStructuralType type,
-      final Map<String, Object> valueMap, final boolean merge) throws ODataException {
-    ODataContext context = getContext();
-    final int timingHandle =
-        context.startRuntimeMeasurement(getClass().getSimpleName(), "setStructuralTypeValuesFromMap");
-
-    for (final String propertyName : type.getPropertyNames()) {
-      final EdmProperty property = (EdmProperty) type.getProperty(propertyName);
-      if (type instanceof EdmEntityType && ((EdmEntityType) type).getKeyProperties().contains(property)) {
-        Object v = valueAccess.getPropertyValue(data, property);
-        if(v != null) {
-          continue;
-        }
-      }
-      
-      if (!merge || valueMap != null && valueMap.containsKey(propertyName)) {
-        final Object value = valueMap == null ? null : valueMap.get(propertyName);
-        if (property.isSimple()) {
-          valueAccess.setPropertyValue(data, property, value);
-        } else {
-          @SuppressWarnings("unchecked")
-          final Map<String, Object> values = (Map<String, Object>) value;
-          setStructuralTypeValuesFromMap(valueAccess.getPropertyValue(data, property),
-              (EdmStructuralType) property.getType(), values, merge);
-        }
-      }
-    }
-
-    context.stopRuntimeMeasurement(timingHandle);
-  }
-
-  @Override
-  public ODataResponse executeBatch(final BatchHandler handler, final String contentType, final InputStream content)
-      throws ODataException {
-    ODataResponse batchResponse;
-    List<BatchResponsePart> batchResponseParts = new ArrayList<BatchResponsePart>();
-    PathInfo pathInfo = getContext().getPathInfo();
-    EntityProviderBatchProperties batchProperties = EntityProviderBatchProperties.init().pathInfo(pathInfo).build();
-    List<BatchRequestPart> batchParts = EntityProvider.parseBatchRequest(contentType, content, batchProperties);
-    for (BatchRequestPart batchPart : batchParts) {
-      batchResponseParts.add(handler.handleBatchPart(batchPart));
-    }
-    batchResponse = EntityProvider.writeBatchResponse(batchResponseParts);
-    return batchResponse;
-  }
-
-  @Override
-  public BatchResponsePart executeChangeSet(final BatchHandler handler, final List<ODataRequest> requests)
-      throws ODataException {
-    List<ODataResponse> responses = new ArrayList<ODataResponse>();
-    for (ODataRequest request : requests) {
-      ODataResponse response = handler.handleRequest(request);
-      if (response.getStatus().getStatusCode() >= HttpStatusCodes.BAD_REQUEST.getStatusCode()) {
-        // Rollback
-        List<ODataResponse> errorResponses = new ArrayList<ODataResponse>(1);
-        errorResponses.add(response);
-        return BatchResponsePart.responses(errorResponses).changeSet(false).build();
-      }
-      responses.add(response);
-    }
-    return BatchResponsePart.responses(responses).changeSet(true).build();
-  }
-}


[11/12] Renamed project

Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
new file mode 100644
index 0000000..97f5b53
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
@@ -0,0 +1,773 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.edm;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmType;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationAttribute;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationElement;
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSetEnd;
+import org.apache.olingo.odata2.api.edm.provider.ComplexProperty;
+import org.apache.olingo.odata2.api.edm.provider.ComplexType;
+import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
+import org.apache.olingo.odata2.api.edm.provider.EntityContainer;
+import org.apache.olingo.odata2.api.edm.provider.EntityContainerInfo;
+import org.apache.olingo.odata2.api.edm.provider.EntitySet;
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
+import org.apache.olingo.odata2.api.edm.provider.Key;
+import org.apache.olingo.odata2.api.edm.provider.NavigationProperty;
+import org.apache.olingo.odata2.api.edm.provider.Property;
+import org.apache.olingo.odata2.api.edm.provider.PropertyRef;
+import org.apache.olingo.odata2.api.edm.provider.Schema;
+import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
+import org.apache.olingo.odata2.api.edm.provider.Using;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.util.ClassHelper;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+/**
+ * Provider for the entity data model used in the reference scenario
+ *
+ */
+public class AnnotationEdmProvider extends EdmProvider {
+
+  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+
+  private final List<Class<?>> annotatedClasses;
+  private final Map<String, EntityContainer> name2Container = new HashMap<String, EntityContainer>();
+  private final Map<String, ContainerBuilder> containerName2ContainerBuilder = new HashMap<String, ContainerBuilder>();
+  private final Map<String, Schema> namespace2Schema = new HashMap<String, Schema>();
+  private EntityContainer defaultContainer;
+
+  public AnnotationEdmProvider(Collection<Class<?>> annotatedClasses) {
+
+    this.annotatedClasses = new ArrayList<Class<?>>(annotatedClasses.size());
+    for (Class<?> aClass : annotatedClasses) {
+      if (ANNOTATION_HELPER.isEdmAnnotated(aClass)) {
+        this.annotatedClasses.add(aClass);
+      }
+    }
+
+    init();
+  }
+
+  public AnnotationEdmProvider(String packageToScan) {
+    this.annotatedClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
+      @Override
+      public boolean isClassValid(Class<?> c) {
+        return ANNOTATION_HELPER.isEdmAnnotated(c);
+      }
+    });
+
+    init();
+  }
+
+  private void init() {
+    for (Class<?> aClass : annotatedClasses) {
+      updateSchema(aClass);
+      handleEntityContainer(aClass);
+    }
+
+    finish();
+  }
+
+  @Override
+  public Association getAssociation(FullQualifiedName edmFQName) throws ODataException {
+    Schema schema = namespace2Schema.get(edmFQName.getNamespace());
+    if (schema != null) {
+      List<Association> associations = schema.getAssociations();
+      for (Association association : associations) {
+        if (association.getName().equals(edmFQName.getName())) {
+          return association;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public AssociationSet getAssociationSet(String entityContainer, FullQualifiedName association,
+      String sourceEntitySetName, String sourceEntitySetRole) throws ODataException {
+    EntityContainer container = name2Container.get(entityContainer);
+    if (container != null) {
+      List<AssociationSet> associations = container.getAssociationSets();
+      for (AssociationSet associationSet : associations) {
+        if (associationSet.getAssociation().equals(association)) {
+          final AssociationSetEnd endOne = associationSet.getEnd1();
+          if (endOne.getRole().equals(sourceEntitySetRole)
+              && endOne.getEntitySet().equals(sourceEntitySetName)) {
+            return associationSet;
+          }
+          final AssociationSetEnd endTwo = associationSet.getEnd2();
+          if (endTwo.getRole().equals(sourceEntitySetRole)
+              && endTwo.getEntitySet().equals(sourceEntitySetName)) {
+            return associationSet;
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public ComplexType getComplexType(FullQualifiedName edmFQName) throws ODataException {
+    Schema schema = namespace2Schema.get(edmFQName.getNamespace());
+    if (schema != null) {
+      List<ComplexType> complexTypes = schema.getComplexTypes();
+      for (ComplexType complexType : complexTypes) {
+        if (complexType.getName().equals(edmFQName.getName())) {
+          return complexType;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public EntityContainerInfo getEntityContainerInfo(String name) throws ODataException {
+    EntityContainer container = name2Container.get(name);
+    if (container == null) {
+      // use default container (if set)
+      container = defaultContainer;
+    }
+    if (container != null) {
+      EntityContainerInfo info = new EntityContainerInfo();
+      info.setName(container.getName());
+      info.setDefaultEntityContainer(container.isDefaultEntityContainer());
+      info.setExtendz(container.getExtendz());
+      info.setAnnotationAttributes(container.getAnnotationAttributes());
+      info.setAnnotationElements(container.getAnnotationElements());
+
+      return info;
+    }
+
+    return null;
+  }
+
+  @Override
+  public EntitySet getEntitySet(String entityContainer, String name) throws ODataException {
+    EntityContainer container = name2Container.get(entityContainer);
+    if (container != null) {
+      List<EntitySet> entitySets = container.getEntitySets();
+      for (EntitySet entitySet : entitySets) {
+        if (entitySet.getName().equals(name)) {
+          return entitySet;
+        }
+      }
+    }
+
+    return null;
+  }
+
+  @Override
+  public EntityType getEntityType(FullQualifiedName edmFQName) throws ODataException {
+    Schema schema = namespace2Schema.get(edmFQName.getNamespace());
+    if (schema != null) {
+      List<EntityType> complexTypes = schema.getEntityTypes();
+      for (EntityType complexType : complexTypes) {
+        if (complexType.getName().equals(edmFQName.getName())) {
+          return complexType;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public FunctionImport getFunctionImport(String entityContainer, String name) throws ODataException {
+    EntityContainer container = name2Container.get(entityContainer);
+    if (container != null) {
+      List<FunctionImport> functionImports = container.getFunctionImports();
+      for (FunctionImport functionImport : functionImports) {
+        if (functionImport.getName().equals(name)) {
+          return functionImport;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public List<Schema> getSchemas() throws ODataException {
+    return new ArrayList<Schema>(namespace2Schema.values());
+  }
+
+  //
+  //
+  //
+  private Map<String, SchemaBuilder> namespace2SchemaBuilder = new HashMap<String, SchemaBuilder>();
+
+  private void updateSchema(Class<?> aClass) {
+    EdmEntityType et = aClass.getAnnotation(EdmEntityType.class);
+    if (et != null) {
+      updateSchema(aClass, et);
+    }
+    EdmComplexType ect = aClass.getAnnotation(EdmComplexType.class);
+    if (ect != null) {
+      updateSchema(aClass, ect);
+    }
+  }
+
+  private void updateSchema(Class<?> aClass, EdmEntityType et) {
+    SchemaBuilder b = getSchemaBuilder(et.namespace(), aClass);
+    TypeBuilder typeBuilder = TypeBuilder.init(et, aClass);
+    b.addEntityType(typeBuilder.buildEntityType());
+    b.addAssociations(typeBuilder.buildAssociations());
+  }
+
+  private SchemaBuilder getSchemaBuilder(String namespace, Class<?> aClass) {
+    String usedNamespace = namespace;
+    if(usedNamespace.isEmpty()) {
+      usedNamespace = ANNOTATION_HELPER.getCanonicalNamespace(aClass);
+    }
+    SchemaBuilder builder = namespace2SchemaBuilder.get(usedNamespace);
+    if (builder == null) {
+      builder = SchemaBuilder.init(usedNamespace);
+      namespace2SchemaBuilder.put(usedNamespace, builder);
+    }
+    return builder;
+  }
+
+  private void updateSchema(Class<?> aClass, EdmComplexType et) {
+    SchemaBuilder b = getSchemaBuilder(et.namespace(), aClass);
+    TypeBuilder typeBuilder = TypeBuilder.init(et, aClass);
+    b.addComplexType(typeBuilder.buildComplexType());
+  }
+
+  private void handleEntityContainer(Class<?> aClass) {
+    EdmEntityType entityType = aClass.getAnnotation(EdmEntityType.class);
+    if (entityType != null) {
+      FullQualifiedName typeName = createFqnForEntityType(aClass, entityType);
+      String containerName = ANNOTATION_HELPER.extractContainerName(aClass);
+      ContainerBuilder builder = containerName2ContainerBuilder.get(containerName);
+      if (builder == null) {
+        builder = ContainerBuilder.init(typeName.getNamespace(), containerName);
+        containerName2ContainerBuilder.put(containerName, builder);
+      }
+      EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
+      if (entitySet != null) {
+        builder.addEntitySet(createEntitySet(typeName, entitySet));
+      }
+    }
+  }
+
+  private EntitySet createEntitySet(FullQualifiedName typeName, EdmEntitySet entitySet) {
+    return new EntitySet().setName(entitySet.name()).setEntityType(typeName);
+  }
+
+  private FullQualifiedName createFqnForEntityType(Class<?> annotatedClass, EdmEntityType entityType) {
+    return ANNOTATION_HELPER.extractEntityTypeFqn(annotatedClass);
+  }
+
+  private void finish() {
+    //
+    Collection<ContainerBuilder> containers = containerName2ContainerBuilder.values();
+    for (ContainerBuilder containerBuilder : containers) {
+      SchemaBuilder schemaBuilder = namespace2SchemaBuilder.get(containerBuilder.getNamespace());
+      containerBuilder.addAssociationSets(schemaBuilder.name2Associations.values());
+      final EntityContainer container = containerBuilder.build();
+      schemaBuilder.addEntityContainer(container);
+      name2Container.put(container.getName(), container);
+      if (container.isDefaultEntityContainer()) {
+        defaultContainer = container;
+      }
+    }
+    //
+    Collection<SchemaBuilder> schemaBuilders = namespace2SchemaBuilder.values();
+    for (SchemaBuilder schemaBuilder : schemaBuilders) {
+      final Schema schema = schemaBuilder.build();
+      namespace2Schema.put(schema.getNamespace(), schema);
+    }
+  }
+
+  //
+  //
+  //
+  static class TypeBuilder {
+
+    final private String namespace;
+    final private String name;
+    private boolean isAbstract = false;
+    private boolean isMediaResource = false;
+    private FullQualifiedName baseEntityType = null;
+    private final List<PropertyRef> keyProperties = new ArrayList<PropertyRef>();
+    private final List<Property> properties = new ArrayList<Property>();
+    private final List<NavigationProperty> navProperties = new ArrayList<NavigationProperty>();
+    private final List<Association> associations = new ArrayList<Association>();
+
+    public TypeBuilder(FullQualifiedName fqn) {
+      this.namespace = fqn.getNamespace();
+      this.name = fqn.getName();
+    }
+
+    public static TypeBuilder init(EdmEntityType entity, Class<?> aClass) {
+      return new TypeBuilder(ANNOTATION_HELPER.extractEntityTypeFqn(entity, aClass)).withClass(aClass);
+    }
+
+    public static TypeBuilder init(EdmComplexType entity, Class<?> aClass) {
+      return new TypeBuilder(ANNOTATION_HELPER.extractComplexTypeFqn(entity, aClass)).withClass(aClass);
+    }
+
+    private TypeBuilder withClass(Class<?> aClass) {
+      baseEntityType = createBaseEntityFqn(aClass);
+
+      if (Modifier.isAbstract(aClass.getModifiers())) {
+        this.isAbstract = true;
+      }
+
+      Field[] fields = aClass.getDeclaredFields();
+      for (Field field : fields) {
+        EdmProperty ep = field.getAnnotation(EdmProperty.class);
+        if (ep != null) {
+          properties.add(createProperty(ep, field, namespace));
+          EdmKey eti = field.getAnnotation(EdmKey.class);
+          if (eti != null) {
+            keyProperties.add(createKeyProperty(ep, field));
+          }
+        }
+        EdmNavigationProperty enp = field.getAnnotation(EdmNavigationProperty.class);
+        if (enp != null) {
+          final NavigationProperty navProperty = createNavigationProperty(namespace, enp, field);
+          navProperties.add(navProperty);
+          Association association = createAssociation(field, navProperty);
+          associations.add(association);
+        }
+        EdmMediaResourceContent emrc = field.getAnnotation(EdmMediaResourceContent.class);
+        if (emrc != null) {
+          isMediaResource = true;
+        }
+      }
+
+      return this;
+    }
+
+    public TypeBuilder addProperty(PropertyRef property) {
+      keyProperties.add(property);
+      return this;
+    }
+
+    public TypeBuilder addProperty(Property property) {
+      properties.add(property);
+      return this;
+    }
+
+    public TypeBuilder addNavigationProperty(NavigationProperty property) {
+      navProperties.add(property);
+      return this;
+    }
+
+    public TypeBuilder setAbstract(boolean isAbstract) {
+      this.isAbstract = isAbstract;
+      return this;
+    }
+
+    public ComplexType buildComplexType() {
+      ComplexType complexType = new ComplexType();
+      if (baseEntityType != null) {
+        complexType.setBaseType(baseEntityType);
+      }
+      return complexType.setName(name).setProperties(properties);
+    }
+
+    public EntityType buildEntityType() {
+      EntityType entityType = new EntityType();
+      if (baseEntityType != null) {
+        entityType.setBaseType(baseEntityType);
+      }
+      if (!keyProperties.isEmpty()) {
+        entityType.setKey(new Key().setKeys(keyProperties));
+      }
+      if (!navProperties.isEmpty()) {
+        entityType.setNavigationProperties(navProperties);
+      }
+      return entityType.setName(name)
+          .setAbstract(isAbstract)
+          .setHasStream(isMediaResource)
+          .setProperties(properties);
+    }
+
+    public Collection<Association> buildAssociations() {
+      return Collections.unmodifiableCollection(associations);
+    }
+
+    private PropertyRef createKeyProperty(EdmProperty et, Field field) {
+      PropertyRef keyProperty = new PropertyRef();
+      String entityName = et.name();
+      if (entityName.isEmpty()) {
+        entityName = getCanonicalName(field);
+      }
+      return keyProperty.setName(entityName);
+    }
+
+    private Property createProperty(EdmProperty ep, Field field, String defaultNamespace) {
+      if (isAnnotatedEntity(field.getType())) {
+        return createComplexProperty(field, defaultNamespace);
+      } else {
+        return createSimpleProperty(ep, field);
+      }
+    }
+
+    private Property createSimpleProperty(EdmProperty ep, Field field) {
+      SimpleProperty sp = new SimpleProperty();
+      String entityName = ANNOTATION_HELPER.getPropertyName(field);
+      sp.setName(entityName);
+      //
+      EdmType type = ep.type();
+      if (type == EdmType.NULL) {
+        type = getEdmType(field.getType());
+      }
+      sp.setType(ANNOTATION_HELPER.mapTypeKind(type));
+
+      return sp;
+    }
+
+    private Property createComplexProperty(Field field, String defaultNamespace) {
+      ComplexProperty cp = new ComplexProperty();
+      // settings from property
+      String entityName = ANNOTATION_HELPER.getPropertyName(field);
+      cp.setName(entityName);
+
+      // settings from related complex entity
+      EdmComplexType ece = field.getType().getAnnotation(EdmComplexType.class);
+      String complexEntityNamespace = ece.namespace();
+      if (complexEntityNamespace.isEmpty()) {
+        complexEntityNamespace = defaultNamespace;
+      }
+      cp.setType(new FullQualifiedName(complexEntityNamespace, ece.name()));
+
+      return cp;
+    }
+
+    private NavigationProperty createNavigationProperty(String namespace, EdmNavigationProperty enp, Field field) {
+      NavigationProperty navProp = new NavigationProperty();
+      navProp.setName(ANNOTATION_HELPER.getPropertyName(field));
+      String fromRole = ANNOTATION_HELPER.extractFromRoleName(enp, field);
+      navProp.setFromRole(fromRole);
+
+      String toRole = ANNOTATION_HELPER.extractToRoleName(enp, field);
+      navProp.setToRole(toRole);
+
+      String relationshipName = ANNOTATION_HELPER.extractRelationshipName(enp, field);
+      navProp.setRelationship(new FullQualifiedName(namespace, relationshipName));
+
+      return navProp;
+    }
+
+//    private EdmSimpleTypeKind getEdmSimpleType(Class<?> type) {
+//      if (type == String.class) {
+//        return EdmType.String;
+//      } else if (type == boolean.class || type == Boolean.class) {
+//        return EdmType.Boolean;
+//      } else if (type == byte.class || type == Byte.class) {
+//        return EdmType.SByte;
+//      } else if (type == short.class || type == Short.class) {
+//        return EdmType.Int16;
+//      } else if (type == int.class || type == Integer.class) {
+//        return EdmType.Int32;
+//      } else if (type == long.class || type == Long.class) {
+//        return EdmType.Int64;
+//      } else if (type == double.class || type == Double.class) {
+//        return EdmType.Double;
+//      } else if (type == float.class || type == Float.class) {
+//        return EdmType.Single;
+//      } else if (type == BigInteger.class || type == BigDecimal.class) {
+//        return EdmType.Decimal;
+//      } else if (type == Byte[].class || type == byte[].class) {
+//        return EdmType.Binary;
+//      } else if (type == Date.class) {
+//        return EdmType.DateTime;
+//      } else if (type == Calendar.class) {
+//        return EdmType.DateTimeOffset;
+//      } else if (type == UUID.class) {
+//        return EdmType.Guid;
+//      } else {
+//        throw new UnsupportedOperationException("Not yet supported type '" + type + "'.");
+//      }
+//    }
+    
+    private EdmType getEdmType(Class<?> type) {
+      if (type == String.class) {
+        return EdmType.STRING;
+      } else if (type == boolean.class || type == Boolean.class) {
+        return EdmType.BOOLEAN;
+      } else if (type == byte.class || type == Byte.class) {
+        return EdmType.SBYTE;
+      } else if (type == short.class || type == Short.class) {
+        return EdmType.INT16;
+      } else if (type == int.class || type == Integer.class) {
+        return EdmType.INT32;
+      } else if (type == long.class || type == Long.class) {
+        return EdmType.INT64;
+      } else if (type == double.class || type == Double.class) {
+        return EdmType.DOUBLE;
+      } else if (type == float.class || type == Float.class) {
+        return EdmType.SINGLE;
+      } else if (type == BigInteger.class || type == BigDecimal.class) {
+        return EdmType.DECIMAL;
+      } else if (type == Byte[].class || type == byte[].class) {
+        return EdmType.BINARY;
+      } else if (type == Date.class) {
+        return EdmType.DATE_TIME;
+      } else if (type == Calendar.class) {
+        return EdmType.DATE_TIME_OFFSET;
+      } else if (type == UUID.class) {
+        return EdmType.GUID;
+      } else {
+        throw new UnsupportedOperationException("Not yet supported type '" + type + "'.");
+      }
+    }
+
+
+    private Class<?> checkForBaseEntityClass(Class<?> aClass) {
+      Class<?> superClass = aClass.getSuperclass();
+      if (superClass == Object.class) {
+        return null;
+      } else {
+        EdmEntityType edmEntity = superClass.getAnnotation(EdmEntityType.class);
+        if (edmEntity == null) {
+          return checkForBaseEntityClass(superClass);
+        } else {
+          return superClass;
+        }
+      }
+    }
+
+    private FullQualifiedName createBaseEntityFqn(Class<?> aClass) {
+      Class<?> baseEntityClass = checkForBaseEntityClass(aClass);
+      if (baseEntityClass == null) {
+        return null;
+      }
+      return ANNOTATION_HELPER.extractEntityTypeFqn(baseEntityClass);
+    }
+
+    private Association createAssociation(Field field, NavigationProperty navProperty) {
+      Association association = new Association();
+      EdmNavigationProperty navigation = field.getAnnotation(EdmNavigationProperty.class);
+
+      AssociationEnd fromEnd = new AssociationEnd();
+      fromEnd.setRole(navProperty.getFromRole());
+      String typeName = ANNOTATION_HELPER.extractEntityTypeName(field.getDeclaringClass());
+      fromEnd.setType(new FullQualifiedName(namespace, typeName));
+      fromEnd.setMultiplicity(EdmMultiplicity.ONE);
+      association.setEnd1(fromEnd);
+
+      AssociationEnd toEnd = new AssociationEnd();
+      toEnd.setRole(navProperty.getToRole());
+      String toTypeName = ANNOTATION_HELPER.extractEntitTypeName(navigation, field);
+      toEnd.setType(new FullQualifiedName(namespace, toTypeName));
+      toEnd.setMultiplicity(ANNOTATION_HELPER.getMultiplicity(navigation, field));
+      association.setEnd2(toEnd);
+
+      String associationName = navProperty.getRelationship().getName();
+      association.setName(associationName);
+      return association;
+    }
+
+    private String getCanonicalName(Field field) {
+      return ANNOTATION_HELPER.getCanonicalName(field);
+    }
+
+    private boolean isAnnotatedEntity(Class<?> clazz) {
+      return ANNOTATION_HELPER.isEdmTypeAnnotated(clazz);
+    }
+  }
+
+  static class SchemaBuilder {
+
+    final private String namespace;
+    //    private String alias;
+    private final List<Using> usings = new ArrayList<Using>();
+    private final List<EntityType> entityTypes = new ArrayList<EntityType>();
+    private final List<ComplexType> complexTypes = new ArrayList<ComplexType>();
+    private final Map<String, Association> name2Associations = new HashMap<String, Association>();
+    private final List<EntityContainer> entityContainers = new ArrayList<EntityContainer>();
+    private final List<AnnotationAttribute> annotationAttributes = new ArrayList<AnnotationAttribute>();
+    private final List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+
+    private SchemaBuilder(String namespace) {
+      this.namespace = namespace;
+    }
+
+    public static SchemaBuilder init(String namespace) {
+      return new SchemaBuilder(namespace);
+    }
+
+    public SchemaBuilder addEntityType(EntityType type) {
+      entityTypes.add(type);
+      return this;
+    }
+
+    public SchemaBuilder addEntityContainer(EntityContainer container) {
+      entityContainers.add(container);
+      return this;
+    }
+
+    public SchemaBuilder addComplexType(ComplexType createEntityType) {
+      complexTypes.add(createEntityType);
+      return this;
+    }
+
+    public void addAssociations(Collection<Association> associations) {
+      for (Association association : associations) {
+        final String relationshipName = association.getName();
+        if (name2Associations.containsKey(relationshipName)) {
+          association = mergeAssociations(name2Associations.get(relationshipName), association);
+        }
+        name2Associations.put(relationshipName, association);
+      }
+    }
+
+    private Association mergeAssociations(Association associationOne, Association associationTwo) {
+      AssociationEnd oneEnd1 = associationOne.getEnd1();
+      AssociationEnd oneEnd2 = associationOne.getEnd2();
+      AssociationEnd twoEnd1 = associationTwo.getEnd1();
+      AssociationEnd twoEnd2 = associationTwo.getEnd2();
+      AssociationEnd[] oneEnds = new AssociationEnd[] { oneEnd1, oneEnd2 };
+
+      for (AssociationEnd associationEnd : oneEnds) {
+        if (associationEnd.getRole().equals(twoEnd1.getRole())) {
+          if (twoEnd1.getMultiplicity() == EdmMultiplicity.MANY) {
+            associationEnd.setMultiplicity(EdmMultiplicity.MANY);
+          }
+        } else if (associationEnd.getRole().equals(twoEnd2.getRole())) {
+          if (twoEnd2.getMultiplicity() == EdmMultiplicity.MANY) {
+            associationEnd.setMultiplicity(EdmMultiplicity.MANY);
+          }
+        }
+      }
+
+      return associationOne;
+    }
+
+    public Schema build() {
+      Schema s = new Schema();
+      s.setUsings(usings);
+      s.setEntityTypes(entityTypes);
+      s.setComplexTypes(complexTypes);
+      s.setAssociations(new ArrayList<Association>(name2Associations.values()));
+      s.setEntityContainers(entityContainers);
+      s.setAnnotationAttributes(annotationAttributes);
+      s.setAnnotationElements(annotationElements);
+      s.setNamespace(namespace);
+      return s;
+    }
+  }
+
+  private static class ContainerBuilder {
+
+    final private String name;
+    final private String namespace;
+    private boolean defaultContainer = true;
+    private final List<EntitySet> entitySets = new ArrayList<EntitySet>();
+    private final List<AssociationSet> associationSets = new ArrayList<AssociationSet>();
+    private final List<FunctionImport> functionImports = new ArrayList<FunctionImport>();
+
+    //    private Documentation documentation;
+
+    private ContainerBuilder(String namespace, String containerName) {
+      this.namespace = namespace;
+      name = containerName;
+    }
+
+    public String getNamespace() {
+      return namespace;
+    }
+
+    public static ContainerBuilder init(String namespace, String containerName) {
+      return new ContainerBuilder(namespace, containerName);
+    }
+
+    public ContainerBuilder setDefaultContainer(boolean isDefault) {
+      defaultContainer = isDefault;
+      return this;
+    }
+
+    public ContainerBuilder addEntitySet(EntitySet entitySet) {
+      entitySets.add(entitySet);
+      return this;
+    }
+
+    public void addAssociationSets(Collection<Association> associations) {
+      for (Association association : associations) {
+        AssociationSet as = new AssociationSet();
+        as.setName(association.getName());
+        FullQualifiedName asAssociationFqn = new FullQualifiedName(namespace, association.getName());
+        as.setAssociation(asAssociationFqn);
+
+        AssociationSetEnd asEnd1 = new AssociationSetEnd();
+        asEnd1.setEntitySet(getEntitySetName(association.getEnd1()));
+        asEnd1.setRole(association.getEnd1().getRole());
+        as.setEnd1(asEnd1);
+
+        AssociationSetEnd asEnd2 = new AssociationSetEnd();
+        asEnd2.setEntitySet(getEntitySetName(association.getEnd2()));
+        asEnd2.setRole(association.getEnd2().getRole());
+        as.setEnd2(asEnd2);
+
+        associationSets.add(as);
+      }
+    }
+
+    public EntityContainer build() {
+      EntityContainer ec = new EntityContainer();
+      ec.setName(name);
+      ec.setDefaultEntityContainer(defaultContainer);
+      ec.setEntitySets(entitySets);
+      ec.setAssociationSets(associationSets);
+      ec.setFunctionImports(functionImports);
+      return ec;
+    }
+
+    private String getEntitySetName(AssociationEnd end) {
+      for (EntitySet entitySet : entitySets) {
+        if (entitySet.getEntityType().equals(end.getType())) {
+          return entitySet.getName();
+        }
+      }
+      throw new ODataRuntimeException("No entity set found for " + end.getType());
+    }
+  }
+}


[03/12] git commit: Extract abstract, rename and refactore processor parts

Posted by mi...@apache.org.
Extract abstract, rename and refactore processor parts


Project: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/commit/28b35fff
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/tree/28b35fff
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/diff/28b35fff

Branch: refs/heads/PocEdmAnnotationsExtension
Commit: 28b35fff8c68aec2fbdac3f2f4f127cba62641b6
Parents: 8764e11
Author: Michael Bolz <mi...@apache.org>
Authored: Thu Dec 5 09:44:11 2013 +0100
Committer: Michael Bolz <mi...@apache.org>
Committed: Thu Dec 5 09:44:11 2013 +0100

----------------------------------------------------------------------
 .../olingo/odata2/api/data/DataSource.java      | 200 +++++++++++++++++++
 .../odata2/api/data/DataSourceProcessor.java    |  47 +++++
 .../olingo/odata2/api/data/ListsDataSource.java | 200 -------------------
 .../annotation/data/AnnotationInMemoryDs.java   |   4 +-
 .../annotation/processor/ListsProcessor.java    |  18 +-
 .../odata2/fit/ref/EntryXmlReadOnlyTest.java    |  15 +-
 .../ref/processor/ScenarioDataSource.java       |   4 +-
 7 files changed, 271 insertions(+), 217 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
new file mode 100644
index 0000000..694f199
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * 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.odata2.api.data;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
+import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
+
+/**
+ * <p>This interface is intended to make it easier to implement an OData
+ * service in cases where all data for each entity set can be provided as a {@link List} of objects from which all
+ * properties described in the
+ * Entity Data Model can be retrieved and set.</p>
+ * <p>By obeying these restrictions, data-source implementations get the
+ * following advantages:
+ * <ul>
+ * <li>All system query options can be handled centrally.</li>
+ * <li>Following navigation paths must only be done step by step.</li>
+ * </ul>
+ * </p>
+ * 
+ */
+public interface DataSource {
+
+  /**
+   * Retrieves the whole data list for the specified entity set.
+   * @param entitySet the requested {@link EdmEntitySet}
+   * @return the requested data list
+   */
+  List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+      ODataApplicationException;
+
+  /**
+   * Retrieves a single data object for the specified entity set and key.
+   * @param entitySet the requested {@link EdmEntitySet}
+   * @param keys the entity key as map of key names to key values
+   * @return the requested data object
+   */
+  Object readData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
+      ODataNotFoundException, EdmException, ODataApplicationException;
+
+  /**
+   * <p>Retrieves data for the specified function import and key.</p>
+   * <p>This method is called also for function imports that have defined in
+   * their metadata an other HTTP method than <code>GET</code>.</p>
+   * @param function the requested {@link EdmFunctionImport}
+   * @param parameters the parameters of the function import
+   * as map of parameter names to parameter values
+   * @param keys the key of the returned entity set, as map of key names to key values,
+   * if the return type of the function import is a collection of entities
+   * (optional)
+   * @return the requested data object, either a list or a single object;
+   * if the function import's return type is of type <code>Binary</code>,
+   * the returned object(s) must be of type {@link BinaryData}
+   */
+  Object readData(EdmFunctionImport function, Map<String, Object> parameters, Map<String, Object> keys)
+      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
+
+  /**
+   * <p>Retrieves related data for the specified source data, entity set, and key.</p>
+   * <p>If the underlying association of the EDM is specified to have target
+   * multiplicity '*' and no target key is given, this method returns a list of
+   * related data, otherwise it returns a single data object.</p>
+   * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
+   * @param sourceData the data object of the source entity
+   * @param targetEntitySet the requested target {@link EdmEntitySet}
+   * @param targetKeys the key of the target entity as map of key names to key values
+   * (optional)
+   * @return the requested releated data object, either a list or a single object
+   */
+  Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+      Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+      ODataApplicationException;
+
+  /**
+   * Retrieves the binary data and the MIME type for the media resource
+   * associated to the specified media-link entry.
+   * @param entitySet the {@link EdmEntitySet} of the media-link entry
+   * @param mediaLinkEntryData the data object of the media-link entry
+   * @return the binary data and the MIME type of the media resource
+   */
+  BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData) throws ODataNotImplementedException,
+      ODataNotFoundException, EdmException, ODataApplicationException;
+
+  /**
+   * <p>Creates and returns a new instance of the requested data-object type.</p>
+   * <p>This instance must not be part of the corresponding list and should
+   * have empty content, apart from the key and other mandatory properties.
+   * However, intermediate objects to access complex properties must not be
+   * <code>null</code>.</p>
+   * @param entitySet the {@link EdmEntitySet} the object must correspond to
+   * @return the new data object
+   */
+  Object newDataObject(EdmEntitySet entitySet) throws ODataNotImplementedException, EdmException,
+      ODataApplicationException;
+
+  /**
+   * Writes the binary data for the media resource associated to the
+   * specified media-link entry.
+   * @param entitySet the {@link EdmEntitySet} of the media-link entry
+   * @param mediaLinkEntryData the data object of the media-link entry
+   * @param binaryData the binary data of the media resource along with
+   * the MIME type of the binary data
+   */
+  void writeBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData, BinaryData binaryData)
+      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
+
+  /**
+   * Deletes a single data object identified by the specified entity set and key.
+   * @param entitySet the {@link EdmEntitySet} of the entity to be deleted
+   * @param keys the entity key as map of key names to key values
+   */
+  void deleteData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
+      ODataNotFoundException, EdmException, ODataApplicationException;
+
+  /**
+   * <p>Inserts an instance into the entity list of the specified entity set.</p>
+   * <p>If {@link #newDataObject} has not set the key and other mandatory
+   * properties already, this method must set them before inserting the
+   * instance into the list.</p>
+   * @param entitySet the {@link EdmEntitySet} the object must correspond to
+   * @param data the data object of the new entity
+   */
+  void createData(EdmEntitySet entitySet, Object data) throws ODataNotImplementedException, EdmException,
+      ODataApplicationException;
+
+  /**
+   * Deletes the relation from the specified source data to a target entity
+   * specified by entity set and key.
+   * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
+   * @param sourceData the data object of the source entity
+   * @param targetEntitySet the {@link EdmEntitySet} of the target entity
+   * @param targetKeys the key of the target entity as map of key names to key values
+   * (optional)
+   */
+  void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+      Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+      ODataApplicationException;
+
+  /**
+   * Writes a relation from the specified source data to a target entity
+   * specified by entity set and key.
+   * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
+   * @param sourceData the data object of the source entity
+   * @param targetEntitySet the {@link EdmEntitySet} of the relation target
+   * @param targetKeys the key of the target entity as map of key names to key values
+   */
+  void writeRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+      Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+      ODataApplicationException;
+
+  /**
+   * Container to store binary data (as byte array) and the associated MIME type.
+   */
+  public class BinaryData {
+    private final byte[] data;
+    private final String mimeType;
+
+    public BinaryData(final byte[] data, final String mimeType) {
+      this.data = data;
+      this.mimeType = mimeType;
+    }
+
+    public byte[] getData() {
+      return data;
+    }
+
+    public String getMimeType() {
+      return mimeType;
+    }
+
+    @Override
+    public String toString() {
+      return "data=" + Arrays.toString(data) + ", mimeType=" + mimeType;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
new file mode 100644
index 0000000..2be5663
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.odata2.api.data;
+
+import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
+
+/**
+ * Abstract class for implementation of the centralized parts of OData processing,
+ * allowing to use the simplified {@link DataSource} and {@link ValueAccess} for the
+ * actual data handling.
+ * <br/>
+ * Extend this class and implement a DataSourceProcessor if the default implementation
+ * (<code>ListProcessor</code> found in <code>annotation-processor-core module</code>) has to be overwritten.
+ */
+public abstract class DataSourceProcessor extends ODataSingleProcessor {
+
+  protected final DataSource dataSource;
+  protected final ValueAccess valueAccess;
+  
+  /**
+   * Initialize a {@link DataSourceProcessor} in combination with given {@link DataSource} (providing data objects)
+   * and {@link ValueAccess} (accessing values of data objects).
+   * 
+   * @param dataSource used for accessing the data objects
+   * @param valueAccess for accessing the values provided by the data objects
+   */
+  public DataSourceProcessor(final DataSource dataSource, final ValueAccess valueAccess) {
+    this.dataSource = dataSource;
+    this.valueAccess = valueAccess;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ListsDataSource.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ListsDataSource.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ListsDataSource.java
deleted file mode 100644
index e9229e3..0000000
--- a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/data/ListsDataSource.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*******************************************************************************
- * 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.odata2.api.data;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
-import org.apache.olingo.odata2.api.exception.ODataApplicationException;
-import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
-import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-
-/**
- * <p>This interface is intended to make it easier to implement an OData
- * service in cases where all data for each entity set can be provided as a {@link List} of objects from which all
- * properties described in the
- * Entity Data Model can be retrieved and set.</p>
- * <p>By obeying these restrictions, data-source implementations get the
- * following advantages:
- * <ul>
- * <li>All system query options can be handled centrally.</li>
- * <li>Following navigation paths must only be done step by step.</li>
- * </ul>
- * </p>
- * 
- */
-public interface ListsDataSource {
-
-  /**
-   * Retrieves the whole data list for the specified entity set.
-   * @param entitySet the requested {@link EdmEntitySet}
-   * @return the requested data list
-   */
-  List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
-      ODataApplicationException;
-
-  /**
-   * Retrieves a single data object for the specified entity set and key.
-   * @param entitySet the requested {@link EdmEntitySet}
-   * @param keys the entity key as map of key names to key values
-   * @return the requested data object
-   */
-  Object readData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
-      ODataNotFoundException, EdmException, ODataApplicationException;
-
-  /**
-   * <p>Retrieves data for the specified function import and key.</p>
-   * <p>This method is called also for function imports that have defined in
-   * their metadata an other HTTP method than <code>GET</code>.</p>
-   * @param function the requested {@link EdmFunctionImport}
-   * @param parameters the parameters of the function import
-   * as map of parameter names to parameter values
-   * @param keys the key of the returned entity set, as map of key names to key values,
-   * if the return type of the function import is a collection of entities
-   * (optional)
-   * @return the requested data object, either a list or a single object;
-   * if the function import's return type is of type <code>Binary</code>,
-   * the returned object(s) must be of type {@link BinaryData}
-   */
-  Object readData(EdmFunctionImport function, Map<String, Object> parameters, Map<String, Object> keys)
-      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
-
-  /**
-   * <p>Retrieves related data for the specified source data, entity set, and key.</p>
-   * <p>If the underlying association of the EDM is specified to have target
-   * multiplicity '*' and no target key is given, this method returns a list of
-   * related data, otherwise it returns a single data object.</p>
-   * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
-   * @param sourceData the data object of the source entity
-   * @param targetEntitySet the requested target {@link EdmEntitySet}
-   * @param targetKeys the key of the target entity as map of key names to key values
-   * (optional)
-   * @return the requested releated data object, either a list or a single object
-   */
-  Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
-      Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
-      ODataApplicationException;
-
-  /**
-   * Retrieves the binary data and the MIME type for the media resource
-   * associated to the specified media-link entry.
-   * @param entitySet the {@link EdmEntitySet} of the media-link entry
-   * @param mediaLinkEntryData the data object of the media-link entry
-   * @return the binary data and the MIME type of the media resource
-   */
-  BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData) throws ODataNotImplementedException,
-      ODataNotFoundException, EdmException, ODataApplicationException;
-
-  /**
-   * <p>Creates and returns a new instance of the requested data-object type.</p>
-   * <p>This instance must not be part of the corresponding list and should
-   * have empty content, apart from the key and other mandatory properties.
-   * However, intermediate objects to access complex properties must not be
-   * <code>null</code>.</p>
-   * @param entitySet the {@link EdmEntitySet} the object must correspond to
-   * @return the new data object
-   */
-  Object newDataObject(EdmEntitySet entitySet) throws ODataNotImplementedException, EdmException,
-      ODataApplicationException;
-
-  /**
-   * Writes the binary data for the media resource associated to the
-   * specified media-link entry.
-   * @param entitySet the {@link EdmEntitySet} of the media-link entry
-   * @param mediaLinkEntryData the data object of the media-link entry
-   * @param binaryData the binary data of the media resource along with
-   * the MIME type of the binary data
-   */
-  void writeBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData, BinaryData binaryData)
-      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
-
-  /**
-   * Deletes a single data object identified by the specified entity set and key.
-   * @param entitySet the {@link EdmEntitySet} of the entity to be deleted
-   * @param keys the entity key as map of key names to key values
-   */
-  void deleteData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
-      ODataNotFoundException, EdmException, ODataApplicationException;
-
-  /**
-   * <p>Inserts an instance into the entity list of the specified entity set.</p>
-   * <p>If {@link #newDataObject} has not set the key and other mandatory
-   * properties already, this method must set them before inserting the
-   * instance into the list.</p>
-   * @param entitySet the {@link EdmEntitySet} the object must correspond to
-   * @param data the data object of the new entity
-   */
-  void createData(EdmEntitySet entitySet, Object data) throws ODataNotImplementedException, EdmException,
-      ODataApplicationException;
-
-  /**
-   * Deletes the relation from the specified source data to a target entity
-   * specified by entity set and key.
-   * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
-   * @param sourceData the data object of the source entity
-   * @param targetEntitySet the {@link EdmEntitySet} of the target entity
-   * @param targetKeys the key of the target entity as map of key names to key values
-   * (optional)
-   */
-  void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
-      Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
-      ODataApplicationException;
-
-  /**
-   * Writes a relation from the specified source data to a target entity
-   * specified by entity set and key.
-   * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
-   * @param sourceData the data object of the source entity
-   * @param targetEntitySet the {@link EdmEntitySet} of the relation target
-   * @param targetKeys the key of the target entity as map of key names to key values
-   */
-  void writeRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
-      Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
-      ODataApplicationException;
-
-  /**
-   * Container to store binary data (as byte array) and the associated MIME type.
-   */
-  public class BinaryData {
-    private final byte[] data;
-    private final String mimeType;
-
-    public BinaryData(final byte[] data, final String mimeType) {
-      this.data = data;
-      this.mimeType = mimeType;
-    }
-
-    public byte[] getData() {
-      return data;
-    }
-
-    public String getMimeType() {
-      return mimeType;
-    }
-
-    @Override
-    public String toString() {
-      return "data=" + Arrays.toString(data) + ", mimeType=" + mimeType;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
index 030cc93..db03a4c 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
@@ -24,7 +24,7 @@ import java.util.Map;
 import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
 import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
 import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.data.ListsDataSource;
+import org.apache.olingo.odata2.api.data.DataSource;
 import org.apache.olingo.odata2.api.edm.EdmEntitySet;
 import org.apache.olingo.odata2.api.edm.EdmException;
 import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
@@ -38,7 +38,7 @@ import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.AnnotatedN
 import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.ODataAnnotationException;
 import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
 
-public class AnnotationInMemoryDs implements ListsDataSource {
+public class AnnotationInMemoryDs implements DataSource {
 
   private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
   private final Map<String, DataStore<Object>> dataStores = new HashMap<String, DataStore<Object>>();

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
index 16e1eab..19218d7 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/ListsProcessor.java
@@ -36,8 +36,9 @@ import org.apache.olingo.odata2.api.batch.BatchResponsePart;
 import org.apache.olingo.odata2.api.commons.HttpContentType;
 import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
 import org.apache.olingo.odata2.api.commons.InlineCount;
-import org.apache.olingo.odata2.api.data.ListsDataSource;
-import org.apache.olingo.odata2.api.data.ListsDataSource.BinaryData;
+import org.apache.olingo.odata2.api.data.DataSource;
+import org.apache.olingo.odata2.api.data.DataSource.BinaryData;
+import org.apache.olingo.odata2.api.data.DataSourceProcessor;
 import org.apache.olingo.odata2.api.data.ValueAccess;
 import org.apache.olingo.odata2.api.edm.Edm;
 import org.apache.olingo.odata2.api.edm.EdmConcurrencyMode;
@@ -81,7 +82,6 @@ import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
 import org.apache.olingo.odata2.api.processor.ODataContext;
 import org.apache.olingo.odata2.api.processor.ODataRequest;
 import org.apache.olingo.odata2.api.processor.ODataResponse;
-import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
 import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
 import org.apache.olingo.odata2.api.uri.KeyPredicate;
 import org.apache.olingo.odata2.api.uri.NavigationSegment;
@@ -117,21 +117,17 @@ import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
 
 /**
  * Implementation of the centralized parts of OData processing,
- * allowing to use the simplified {@link ListsDataSource} for the
+ * allowing to use the simplified {@link DataSource} for the
  * actual data handling.
  * 
  */
-public class ListsProcessor extends ODataSingleProcessor {
+public class ListsProcessor extends DataSourceProcessor {
 
   // TODO: Paging size should be configurable.
   private static final int SERVER_PAGING_SIZE = 100;
 
-  private final ListsDataSource dataSource;
-  private final ValueAccess valueAccess;
-
-  public ListsProcessor(final ListsDataSource dataSource, final ValueAccess valueAccess) {
-    this.dataSource = dataSource;
-    this.valueAccess = valueAccess;
+  public ListsProcessor(final DataSource dataSource, final ValueAccess valueAccess) {
+    super(dataSource, valueAccess);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/EntryXmlReadOnlyTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/EntryXmlReadOnlyTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/EntryXmlReadOnlyTest.java
index eec1f42..6e319c6 100644
--- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/EntryXmlReadOnlyTest.java
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/EntryXmlReadOnlyTest.java
@@ -96,10 +96,10 @@ public class EntryXmlReadOnlyTest extends AbstractRefXmlTest {
   public void entryWithSpecialKey() throws Exception {
     // Ugly hack to create an entity with a key containing special characters just for this test.
     ListsProcessor processor = (ListsProcessor) getService().getEntityProcessor();
-    Field field = processor.getClass().getDeclaredField("dataSource");
+    Field field = getField(processor.getClass(), "dataSource");
     field.setAccessible(true);
     ScenarioDataSource dataSource = (ScenarioDataSource) field.get(processor);
-    field = dataSource.getClass().getDeclaredField("dataContainer");
+    field = getField(dataSource.getClass(), "dataContainer");
     field.setAccessible(true);
     DataContainer dataContainer = (DataContainer) field.get(dataSource);
     // Add a new Photo where the "Type" property is set to, space-separated,
@@ -118,6 +118,17 @@ public class EntryXmlReadOnlyTest extends AbstractRefXmlTest {
     assertXpathEvaluatesTo(expected + "/$value", "/atom:entry/atom:link[@rel=\"edit-media\"]/@href", body);
   }
 
+  private Field getField(Class<?> clazz, String string) throws Exception {
+    try {
+      return clazz.getDeclaredField(string);
+    } catch (NoSuchFieldException e) {
+      if(clazz == Object.class) {
+        throw e;
+      }
+      return getField(clazz.getSuperclass(), string);
+    }
+  }
+
   @Test
   public void expand() throws Exception {
     HttpResponse response = callUri("Employees('5')?$expand=ne_Manager");

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/28b35fff/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioDataSource.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioDataSource.java b/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioDataSource.java
index 0047226..cc70639 100644
--- a/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioDataSource.java
+++ b/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioDataSource.java
@@ -28,7 +28,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 import org.apache.olingo.odata2.api.commons.HttpContentType;
-import org.apache.olingo.odata2.api.data.ListsDataSource;
+import org.apache.olingo.odata2.api.data.DataSource;
 import org.apache.olingo.odata2.api.edm.EdmEntitySet;
 import org.apache.olingo.odata2.api.edm.EdmException;
 import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
@@ -48,7 +48,7 @@ import org.apache.olingo.odata2.ref.model.Team;
  * Data for the reference scenario
  * 
  */
-public class ScenarioDataSource implements ListsDataSource {
+public class ScenarioDataSource implements DataSource {
 
   private static final String ENTITYSET_1_1 = "Employees";
   private static final String ENTITYSET_1_2 = "Teams";


[12/12] git commit: Renamed project

Posted by mi...@apache.org.
Renamed project


Project: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/commit/12ea18ae
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/tree/12ea18ae
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/diff/12ea18ae

Branch: refs/heads/PocEdmAnnotationsExtension
Commit: 12ea18aed44f33fb58b577887533bf841771bfea
Parents: 28b35ff
Author: Michael Bolz <mi...@apache.org>
Authored: Thu Dec 5 10:03:26 2013 +0100
Committer: Michael Bolz <mi...@apache.org>
Committed: Thu Dec 5 10:03:26 2013 +0100

----------------------------------------------------------------------
 .../annotation-processor-api/pom.xml            |   42 +
 .../olingo/odata2/api/data/DataSource.java      |  200 +++
 .../odata2/api/data/DataSourceProcessor.java    |   47 +
 .../olingo/odata2/api/data/ValueAccess.java     |   69 +
 .../annotation-processor-core/pom.xml           |   48 +
 .../annotation/data/AnnotationInMemoryDs.java   |  351 ++++
 .../annotation/data/AnnotationValueAccess.java  |  106 ++
 .../annotation/data/BeanPropertyAccess.java     |  186 ++
 .../odata2/core/annotation/data/DataStore.java  |  192 +++
 .../annotation/edm/AnnotationEdmProvider.java   |  773 +++++++++
 .../annotation/processor/ListsProcessor.java    | 1630 ++++++++++++++++++
 .../core/annotation/util/AnnotationHelper.java  |  726 ++++++++
 .../core/annotation/util/ClassHelper.java       |  105 ++
 .../data/AnnotationsInMemoryDsTest.java         |  190 ++
 .../edm/AnnotationEdmProviderTest.java          |  463 +++++
 .../odata2/core/annotation/model/Building.java  |   95 +
 .../odata2/core/annotation/model/City.java      |   62 +
 .../odata2/core/annotation/model/Employee.java  |  187 ++
 .../odata2/core/annotation/model/Location.java  |   61 +
 .../odata2/core/annotation/model/Manager.java   |   47 +
 .../annotation/model/ModelSharedConstants.java  |   25 +
 .../odata2/core/annotation/model/Photo.java     |  128 ++
 .../odata2/core/annotation/model/RefBase.java   |   55 +
 .../core/annotation/model/ResourceHelper.java   |   64 +
 .../odata2/core/annotation/model/Room.java      |   89 +
 .../odata2/core/annotation/model/Team.java      |   81 +
 .../annotation-processor-webref/pom.xml         |  120 ++
 .../odata2/ref/annotation/model/Building.java   |   97 ++
 .../odata2/ref/annotation/model/City.java       |   61 +
 .../odata2/ref/annotation/model/Employee.java   |  192 +++
 .../odata2/ref/annotation/model/Location.java   |   60 +
 .../odata2/ref/annotation/model/Manager.java    |   43 +
 .../annotation/model/ModelSharedConstants.java  |   25 +
 .../odata2/ref/annotation/model/Photo.java      |  128 ++
 .../odata2/ref/annotation/model/RefBase.java    |   78 +
 .../ref/annotation/model/ResourceHelper.java    |   93 +
 .../odata2/ref/annotation/model/Room.java       |   88 +
 .../odata2/ref/annotation/model/Team.java       |   73 +
 .../processor/AnnotationPocServiceFactory.java  |  202 +++
 .../src/main/resources/log4j.xml                |   39 +
 .../src/main/version/version.html               |   27 +
 .../src/main/webapp/WEB-INF/web.xml             |   48 +
 .../src/main/webapp/index.jsp                   |  116 ++
 odata2-annotation-processor/pom.xml             |   30 +
 .../edm-annotation-api/pom.xml                  |   42 -
 .../olingo/odata2/api/data/DataSource.java      |  200 ---
 .../odata2/api/data/DataSourceProcessor.java    |   47 -
 .../olingo/odata2/api/data/ValueAccess.java     |   69 -
 .../edm-annotation-core/pom.xml                 |   48 -
 .../annotation/data/AnnotationInMemoryDs.java   |  351 ----
 .../annotation/data/AnnotationValueAccess.java  |  106 --
 .../annotation/data/BeanPropertyAccess.java     |  186 --
 .../odata2/core/annotation/data/DataStore.java  |  192 ---
 .../annotation/edm/AnnotationEdmProvider.java   |  773 ---------
 .../annotation/processor/ListsProcessor.java    | 1630 ------------------
 .../core/annotation/util/AnnotationHelper.java  |  726 --------
 .../core/annotation/util/ClassHelper.java       |  105 --
 .../data/AnnotationsInMemoryDsTest.java         |  190 --
 .../edm/AnnotationEdmProviderTest.java          |  463 -----
 .../odata2/core/annotation/model/Building.java  |   95 -
 .../odata2/core/annotation/model/City.java      |   62 -
 .../odata2/core/annotation/model/Employee.java  |  187 --
 .../odata2/core/annotation/model/Location.java  |   61 -
 .../odata2/core/annotation/model/Manager.java   |   47 -
 .../annotation/model/ModelSharedConstants.java  |   25 -
 .../odata2/core/annotation/model/Photo.java     |  128 --
 .../odata2/core/annotation/model/RefBase.java   |   55 -
 .../core/annotation/model/ResourceHelper.java   |   64 -
 .../odata2/core/annotation/model/Room.java      |   89 -
 .../odata2/core/annotation/model/Team.java      |   81 -
 .../edm-annotation-webref/pom.xml               |  120 --
 .../odata2/ref/annotation/model/Building.java   |   97 --
 .../odata2/ref/annotation/model/City.java       |   61 -
 .../odata2/ref/annotation/model/Employee.java   |  192 ---
 .../odata2/ref/annotation/model/Location.java   |   60 -
 .../odata2/ref/annotation/model/Manager.java    |   43 -
 .../annotation/model/ModelSharedConstants.java  |   25 -
 .../odata2/ref/annotation/model/Photo.java      |  128 --
 .../odata2/ref/annotation/model/RefBase.java    |   78 -
 .../ref/annotation/model/ResourceHelper.java    |   93 -
 .../odata2/ref/annotation/model/Room.java       |   88 -
 .../odata2/ref/annotation/model/Team.java       |   73 -
 .../processor/AnnotationPocServiceFactory.java  |  202 ---
 .../src/main/resources/log4j.xml                |   39 -
 .../src/main/version/version.html               |   27 -
 .../src/main/webapp/WEB-INF/web.xml             |   48 -
 .../src/main/webapp/index.jsp                   |  116 --
 odata2-edm-annotation/pom.xml                   |   30 -
 odata2-lib/odata-ref/pom.xml                    |    2 +-
 pom.xml                                         |    2 +-
 90 files changed, 7544 insertions(+), 7544 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-api/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-api/pom.xml b/odata2-annotation-processor/annotation-processor-api/pom.xml
new file mode 100644
index 0000000..e42ec20
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-api/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<project
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+  xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+	
+  <parent>
+    <groupId>org.apache.olingo</groupId>
+    <artifactId>olingo-odata2-annotation-processor-incubating</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <artifactId>olingo-odata2-annotation-processor-api-incubating</artifactId>
+  <name>${project.artifactId}</name>
+        
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-api-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
new file mode 100644
index 0000000..694f199
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSource.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * 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.odata2.api.data;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
+import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
+
+/**
+ * <p>This interface is intended to make it easier to implement an OData
+ * service in cases where all data for each entity set can be provided as a {@link List} of objects from which all
+ * properties described in the
+ * Entity Data Model can be retrieved and set.</p>
+ * <p>By obeying these restrictions, data-source implementations get the
+ * following advantages:
+ * <ul>
+ * <li>All system query options can be handled centrally.</li>
+ * <li>Following navigation paths must only be done step by step.</li>
+ * </ul>
+ * </p>
+ * 
+ */
+public interface DataSource {
+
+  /**
+   * Retrieves the whole data list for the specified entity set.
+   * @param entitySet the requested {@link EdmEntitySet}
+   * @return the requested data list
+   */
+  List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+      ODataApplicationException;
+
+  /**
+   * Retrieves a single data object for the specified entity set and key.
+   * @param entitySet the requested {@link EdmEntitySet}
+   * @param keys the entity key as map of key names to key values
+   * @return the requested data object
+   */
+  Object readData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
+      ODataNotFoundException, EdmException, ODataApplicationException;
+
+  /**
+   * <p>Retrieves data for the specified function import and key.</p>
+   * <p>This method is called also for function imports that have defined in
+   * their metadata an other HTTP method than <code>GET</code>.</p>
+   * @param function the requested {@link EdmFunctionImport}
+   * @param parameters the parameters of the function import
+   * as map of parameter names to parameter values
+   * @param keys the key of the returned entity set, as map of key names to key values,
+   * if the return type of the function import is a collection of entities
+   * (optional)
+   * @return the requested data object, either a list or a single object;
+   * if the function import's return type is of type <code>Binary</code>,
+   * the returned object(s) must be of type {@link BinaryData}
+   */
+  Object readData(EdmFunctionImport function, Map<String, Object> parameters, Map<String, Object> keys)
+      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
+
+  /**
+   * <p>Retrieves related data for the specified source data, entity set, and key.</p>
+   * <p>If the underlying association of the EDM is specified to have target
+   * multiplicity '*' and no target key is given, this method returns a list of
+   * related data, otherwise it returns a single data object.</p>
+   * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
+   * @param sourceData the data object of the source entity
+   * @param targetEntitySet the requested target {@link EdmEntitySet}
+   * @param targetKeys the key of the target entity as map of key names to key values
+   * (optional)
+   * @return the requested releated data object, either a list or a single object
+   */
+  Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+      Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+      ODataApplicationException;
+
+  /**
+   * Retrieves the binary data and the MIME type for the media resource
+   * associated to the specified media-link entry.
+   * @param entitySet the {@link EdmEntitySet} of the media-link entry
+   * @param mediaLinkEntryData the data object of the media-link entry
+   * @return the binary data and the MIME type of the media resource
+   */
+  BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData) throws ODataNotImplementedException,
+      ODataNotFoundException, EdmException, ODataApplicationException;
+
+  /**
+   * <p>Creates and returns a new instance of the requested data-object type.</p>
+   * <p>This instance must not be part of the corresponding list and should
+   * have empty content, apart from the key and other mandatory properties.
+   * However, intermediate objects to access complex properties must not be
+   * <code>null</code>.</p>
+   * @param entitySet the {@link EdmEntitySet} the object must correspond to
+   * @return the new data object
+   */
+  Object newDataObject(EdmEntitySet entitySet) throws ODataNotImplementedException, EdmException,
+      ODataApplicationException;
+
+  /**
+   * Writes the binary data for the media resource associated to the
+   * specified media-link entry.
+   * @param entitySet the {@link EdmEntitySet} of the media-link entry
+   * @param mediaLinkEntryData the data object of the media-link entry
+   * @param binaryData the binary data of the media resource along with
+   * the MIME type of the binary data
+   */
+  void writeBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData, BinaryData binaryData)
+      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException;
+
+  /**
+   * Deletes a single data object identified by the specified entity set and key.
+   * @param entitySet the {@link EdmEntitySet} of the entity to be deleted
+   * @param keys the entity key as map of key names to key values
+   */
+  void deleteData(EdmEntitySet entitySet, Map<String, Object> keys) throws ODataNotImplementedException,
+      ODataNotFoundException, EdmException, ODataApplicationException;
+
+  /**
+   * <p>Inserts an instance into the entity list of the specified entity set.</p>
+   * <p>If {@link #newDataObject} has not set the key and other mandatory
+   * properties already, this method must set them before inserting the
+   * instance into the list.</p>
+   * @param entitySet the {@link EdmEntitySet} the object must correspond to
+   * @param data the data object of the new entity
+   */
+  void createData(EdmEntitySet entitySet, Object data) throws ODataNotImplementedException, EdmException,
+      ODataApplicationException;
+
+  /**
+   * Deletes the relation from the specified source data to a target entity
+   * specified by entity set and key.
+   * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
+   * @param sourceData the data object of the source entity
+   * @param targetEntitySet the {@link EdmEntitySet} of the target entity
+   * @param targetKeys the key of the target entity as map of key names to key values
+   * (optional)
+   */
+  void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+      Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+      ODataApplicationException;
+
+  /**
+   * Writes a relation from the specified source data to a target entity
+   * specified by entity set and key.
+   * @param sourceEntitySet the {@link EdmEntitySet} of the source entity
+   * @param sourceData the data object of the source entity
+   * @param targetEntitySet the {@link EdmEntitySet} of the relation target
+   * @param targetKeys the key of the target entity as map of key names to key values
+   */
+  void writeRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+      Map<String, Object> targetKeys) throws ODataNotImplementedException, ODataNotFoundException, EdmException,
+      ODataApplicationException;
+
+  /**
+   * Container to store binary data (as byte array) and the associated MIME type.
+   */
+  public class BinaryData {
+    private final byte[] data;
+    private final String mimeType;
+
+    public BinaryData(final byte[] data, final String mimeType) {
+      this.data = data;
+      this.mimeType = mimeType;
+    }
+
+    public byte[] getData() {
+      return data;
+    }
+
+    public String getMimeType() {
+      return mimeType;
+    }
+
+    @Override
+    public String toString() {
+      return "data=" + Arrays.toString(data) + ", mimeType=" + mimeType;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
new file mode 100644
index 0000000..2be5663
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/DataSourceProcessor.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.odata2.api.data;
+
+import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
+
+/**
+ * Abstract class for implementation of the centralized parts of OData processing,
+ * allowing to use the simplified {@link DataSource} and {@link ValueAccess} for the
+ * actual data handling.
+ * <br/>
+ * Extend this class and implement a DataSourceProcessor if the default implementation
+ * (<code>ListProcessor</code> found in <code>annotation-processor-core module</code>) has to be overwritten.
+ */
+public abstract class DataSourceProcessor extends ODataSingleProcessor {
+
+  protected final DataSource dataSource;
+  protected final ValueAccess valueAccess;
+  
+  /**
+   * Initialize a {@link DataSourceProcessor} in combination with given {@link DataSource} (providing data objects)
+   * and {@link ValueAccess} (accessing values of data objects).
+   * 
+   * @param dataSource used for accessing the data objects
+   * @param valueAccess for accessing the values provided by the data objects
+   */
+  public DataSourceProcessor(final DataSource dataSource, final ValueAccess valueAccess) {
+    this.dataSource = dataSource;
+    this.valueAccess = valueAccess;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java
new file mode 100644
index 0000000..685e1b6
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/api/data/ValueAccess.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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.odata2.api.data;
+
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.exception.ODataException;
+
+/**
+ * This interface is intended to access values in a Java object.
+ */
+public interface ValueAccess {
+
+  /**
+   * Retrieves the value of an EDM property for the given data object.
+   * @param data     the Java data object
+   * @param property the requested {@link EdmProperty}
+   * @return the requested property value
+   */
+  public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException;
+
+  /**
+   * Sets the value of an EDM property for the given data object.
+   * @param data     the Java data object
+   * @param property the {@link EdmProperty}
+   * @param value    the new value of the property
+   */
+  public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException;
+
+  /**
+   * Retrieves the Java type of an EDM property for the given data object.
+   * @param data     the Java data object
+   * @param property the requested {@link EdmProperty}
+   * @return the requested Java type
+   */
+  public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException;
+
+  /**
+   * Retrieves the value defined by a mapping object for the given data object.
+   * @param data     the Java data object
+   * @param mapping  the requested {@link EdmMapping}
+   * @return the requested value
+   */
+  public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException;
+
+  /**
+   * Sets the value defined by a mapping object for the given data object.
+   * @param data     the Java data object
+   * @param mapping  the {@link EdmMapping}
+   * @param value    the new value
+   */
+  public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/pom.xml b/odata2-annotation-processor/annotation-processor-core/pom.xml
new file mode 100644
index 0000000..4732522
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>olingo-odata2-annotation-processor-core-incubating</artifactId>
+  <packaging>jar</packaging>
+  <name>${project.artifactId}</name>
+
+  <parent>
+    <groupId>org.apache.olingo</groupId>
+    <artifactId>olingo-odata2-annotation-processor-incubating</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-annotation-processor-api-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-api-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-api-annotation-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-core-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+  
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
new file mode 100644
index 0000000..db03a4c
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
@@ -0,0 +1,351 @@
+/**
+ * *****************************************************************************
+ * 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.odata2.core.annotation.data;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.data.DataSource;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
+import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.util.ClassHelper;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.AnnotatedNavInfo;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper.ODataAnnotationException;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+public class AnnotationInMemoryDs implements DataSource {
+
+  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+  private final Map<String, DataStore<Object>> dataStores = new HashMap<String, DataStore<Object>>();
+  private final boolean persistInMemory;
+
+  public AnnotationInMemoryDs(String packageToScan) {
+    this(packageToScan, true);
+  }
+  
+  public AnnotationInMemoryDs(String packageToScan, boolean persistInMemory) {
+    this.persistInMemory = persistInMemory;
+    List<Class<?>> foundClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
+      @Override
+      public boolean isClassValid(Class<?> c) {
+        return null != c.getAnnotation(org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet.class);
+      }
+    });
+
+    init(foundClasses);
+  }
+
+  @SuppressWarnings("unchecked")
+  private void init(List<Class<?>> foundClasses) {
+    for (Class<?> clz : foundClasses) {
+
+      DataStore<Object> dhs = (DataStore<Object>) getDataStore(clz);
+      org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet entitySet =
+          clz.getAnnotation(org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet.class);
+      dataStores.put(entitySet.name(), dhs);
+    }
+  }
+
+  public <T> DataStore<T> getDataStore(Class<T> clazz) {
+    return DataStore.createInMemory(clazz, persistInMemory);
+  }
+
+  @Override
+  public List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException,
+      ODataNotFoundException, EdmException, ODataApplicationException {
+
+    DataStore<Object> holder = getDataStore(entitySet);
+    if (holder != null) {
+      return new ArrayList<Object>(holder.read());
+    }
+
+    throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+  }
+
+  @Override
+  public Object readData(EdmEntitySet entitySet, Map<String, Object> keys)
+      throws ODataNotFoundException, EdmException, ODataApplicationException {
+
+    DataStore<Object> store = getDataStore(entitySet);
+    if (store != null) {
+      Object keyInstance = store.createInstance();
+      ANNOTATION_HELPER.setKeyFields(keyInstance, keys);
+
+      Object result = store.read(keyInstance);
+      if (result != null) {
+        return result;
+      }
+    }
+
+    throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+  }
+
+  @Override
+  public Object readData(EdmFunctionImport function, Map<String, Object> parameters, Map<String, Object> keys)
+      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+  }
+
+  @Override
+  public Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+      Map<String, Object> targetKeys)
+      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+
+    DataStore<?> sourceStore = dataStores.get(sourceEntitySet.getName());
+    DataStore<?> targetStore = dataStores.get(targetEntitySet.getName());
+
+    AnnotatedNavInfo navInfo = ANNOTATION_HELPER.getCommonNavigationInfo(
+        sourceStore.getDataTypeClass(), targetStore.getDataTypeClass());
+    Field sourceField = navInfo.getFromField();
+    if (sourceField == null) {
+      throw new ODataRuntimeException("Missing source field for related data (sourceStore='" + sourceStore
+              + "', targetStore='" + targetStore + "').");
+    }
+
+    Object navigationInstance = getValue(sourceField, sourceData);
+    List<Object> resultData = new ArrayList<Object>();
+    for (Object targetInstance : targetStore.read()) {
+      if (navigationInstance instanceof Collection) {
+        for (Object object : (Collection<?>) navigationInstance) {
+          if (ANNOTATION_HELPER.keyMatch(targetInstance, object)) {
+            resultData.add(targetInstance);
+          }
+        }
+      } else if (ANNOTATION_HELPER.keyMatch(targetInstance, navigationInstance)) {
+        resultData.add(targetInstance);
+      }
+    }
+
+    if (navInfo.getToMultiplicity() == EdmMultiplicity.MANY) {
+      if (targetKeys.isEmpty()) {
+        return resultData;
+      } else {
+        for (Object result : resultData) {
+          if (ANNOTATION_HELPER.keyMatch(result, targetKeys)) {
+            return result;
+          }
+        }
+        return null;
+      }
+    } else {
+      if (resultData.isEmpty()) {
+        return null;
+      }
+      return resultData.get(0);
+    }
+  }
+
+  @Override
+  public BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData)
+      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+
+    Object data = ANNOTATION_HELPER.getValueForField(mediaLinkEntryData, EdmMediaResourceContent.class);
+    Object mimeType = ANNOTATION_HELPER.getValueForField(mediaLinkEntryData, EdmMediaResourceMimeType.class);
+
+    BinaryData db = new BinaryData((byte[]) data, String.valueOf(mimeType));
+    return db;
+  }
+
+  @Override
+  public Object newDataObject(EdmEntitySet entitySet)
+      throws ODataNotImplementedException, EdmException, ODataApplicationException {
+
+    DataStore<Object> dataStore = getDataStore(entitySet);
+    if (dataStore != null) {
+      return dataStore.createInstance();
+    }
+
+    throw new ODataRuntimeException("No DataStore found for entitySet with name: " + entitySet.getName());
+  }
+
+  @Override
+  public void writeBinaryData(EdmEntitySet entitySet, Object mediaEntityInstance, BinaryData binaryData)
+      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+
+    try {
+      ANNOTATION_HELPER.setValueForAnnotatedField(
+          mediaEntityInstance, EdmMediaResourceContent.class, binaryData.getData());
+      ANNOTATION_HELPER.setValueForAnnotatedField(
+          mediaEntityInstance, EdmMediaResourceMimeType.class, binaryData.getMimeType());
+    } catch (ODataAnnotationException e) {
+      throw new ODataRuntimeException("Invalid media resource annotation at entity set '" + entitySet.getName() 
+          + "' with message '" + e.getMessage() + "'.", e);
+    }
+  }
+
+  /**
+   * <p>Updates a single data object identified by the specified entity set and key fields of
+   * the data object.</p>
+   * @param entitySet the {@link EdmEntitySet} the object must correspond to
+   * @param data the data object of the new entity
+   * @return updated data object instance
+   * @throws org.apache.olingo.odata2.api.exception.ODataNotImplementedException
+   * @throws org.apache.olingo.odata2.api.edm.EdmException
+   * @throws org.apache.olingo.odata2.api.exception.ODataApplicationException
+   */
+  public Object updateData(EdmEntitySet entitySet, Object data)
+          throws ODataNotImplementedException, EdmException, ODataApplicationException {
+
+    DataStore<Object> dataStore = getDataStore(entitySet);
+    return dataStore.update(data);
+  }
+
+  @Override
+  public void deleteData(EdmEntitySet entitySet, Map<String, Object> keys)
+      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+    DataStore<Object> dataStore = getDataStore(entitySet);
+    Object keyInstance = dataStore.createInstance();
+    ANNOTATION_HELPER.setKeyFields(keyInstance, keys);
+    dataStore.delete(keyInstance);
+  }
+
+  @Override
+  public void createData(EdmEntitySet entitySet, Object data)
+      throws ODataNotImplementedException, EdmException, ODataApplicationException {
+
+    DataStore<Object> dataStore = getDataStore(entitySet);
+    dataStore.create(data);
+  }
+
+  @Override
+  public void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+      Map<String, Object> targetKeys)
+      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+  }
+
+  @Override
+  public void writeRelation(EdmEntitySet sourceEntitySet, Object sourceEntity, EdmEntitySet targetEntitySet,
+      Map<String, Object> targetEntityValues)
+      throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+    // get common data
+    DataStore<Object> sourceStore = dataStores.get(sourceEntitySet.getName());
+    DataStore<Object> targetStore = dataStores.get(targetEntitySet.getName());
+
+    AnnotatedNavInfo commonNavInfo = ANNOTATION_HELPER.getCommonNavigationInfo(
+        sourceStore.getDataTypeClass(), targetStore.getDataTypeClass());
+    
+    // get and validate source fields
+    Field sourceField = commonNavInfo.getFromField();
+    if (sourceField == null) {
+      throw new ODataRuntimeException("Missing source field for related data (sourceStore='" + sourceStore
+              + "', targetStore='" + targetStore + "').");
+    }
+    
+    // get related target entity
+    Object targetEntity = targetStore.createInstance();
+    ANNOTATION_HELPER.setKeyFields(targetEntity, targetEntityValues);
+    targetEntity = targetStore.read(targetEntity);
+    
+    // set at source
+    setValueAtNavigationField(sourceEntity, sourceField, targetEntity);
+    // set at target
+    Field targetField = commonNavInfo.getToField();
+    if(targetField != null) {
+      setValueAtNavigationField(targetEntity, targetField, sourceEntity);
+    }
+  }
+
+  /**
+   * Set (Multiplicity != *) or add (Multiplicity == *) <code>value</code> at <code>field</code>
+   * of <code>instance</code>. 
+   * 
+   * @param instance
+   * @param field
+   * @param value
+   * @throws EdmException
+   */
+  private void setValueAtNavigationField(Object instance, Field field, Object value) 
+      throws EdmException {
+    Class<?> fieldTypeClass = field.getType();
+    if (Collection.class.isAssignableFrom(fieldTypeClass)) {
+      @SuppressWarnings("unchecked")
+      Collection<Object> collection = (Collection<Object>) ANNOTATION_HELPER.getValueForField(
+          instance, field.getName(), EdmNavigationProperty.class);
+      if(collection == null) {
+        collection = new ArrayList<Object>();
+        setValue(instance, field, collection);
+      }
+      collection.add(value);
+    } else if(fieldTypeClass.isArray()) {
+      throw new ODataRuntimeException("Write relations for internal used arrays is not supported.");
+    } else {
+      setValue(instance, field, value);
+    }
+  }
+
+  /**
+   * Returns corresponding DataStore for EdmEntitySet or if no data store is registered an
+   * ODataRuntimeException is thrown.
+   * Never returns NULL.
+   * 
+   * @param entitySet for which the corresponding DataStore is returned
+   * @return a DataStore object 
+   * @throws EdmException 
+   * @throws  ODataRuntimeException if no DataStore is found
+   */
+  private DataStore<Object> getDataStore(EdmEntitySet entitySet) throws EdmException {
+    final String name = entitySet.getName();
+    DataStore<Object> dataStore = dataStores.get(name);
+    if (dataStore == null) {
+      throw new ODataRuntimeException("No DataStore found for entity set '" + entitySet + "'.");
+    }
+    return dataStore;
+  }
+
+  private Object getValue(Field field, Object instance) {
+    try {
+      boolean access = field.isAccessible();
+      field.setAccessible(true);
+      Object value = field.get(instance);
+      field.setAccessible(access);
+      return value;
+    } catch (IllegalArgumentException e) {
+      throw new ODataRuntimeException("Error for getting value of field '"
+          + field + "' at instance '" + instance + "'.", e);
+    } catch (IllegalAccessException e) {
+      throw new ODataRuntimeException("Error for getting value of field '"
+          + field + "' at instance '" + instance + "'.", e);
+    }
+  }
+
+  private void setValue(Object instance, Field field, Object value) {
+    try {
+      boolean access = field.isAccessible();
+      field.setAccessible(true);
+      field.set(instance, value);
+      field.setAccessible(access);
+    } catch (IllegalArgumentException e) {
+      throw new ODataRuntimeException("Error for setting value of field: '"
+          + field + "' at instance: '" + instance + "'.", e);
+    } catch (IllegalAccessException e) {
+      throw new ODataRuntimeException("Error for setting value of field: '"
+          + field + "' at instance: '" + instance + "'.", e);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
new file mode 100644
index 0000000..14183bf
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.data;
+
+import org.apache.olingo.odata2.api.data.ValueAccess;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+
+/**
+ *
+ */
+public class AnnotationValueAccess implements ValueAccess {
+  private final AnnotationHelper annotationHelper = new AnnotationHelper();
+
+  /**
+   * Retrieves the value of an EDM property for the given data object.
+   * @param data     the Java data object
+   * @param property the requested {@link EdmProperty}
+   * @return the requested property value
+   */
+  @Override
+  public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException {
+    if(data == null) {
+      return null;
+    } else if (annotationHelper.isEdmAnnotated(data)) {
+      return annotationHelper.getValueForProperty(data, property.getName());
+    }
+    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+  }
+
+  /**
+   * Sets the value of an EDM property for the given data object.
+   * @param data     the Java data object
+   * @param property the {@link EdmProperty}
+   * @param value    the new value of the property
+   */
+  @Override
+  public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException {
+    if (annotationHelper.isEdmAnnotated(data)) {
+      annotationHelper.setValueForProperty(data, property.getName(), value);
+    } else {
+      throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+    }
+  }
+
+  /**
+   * Retrieves the Java type of an EDM property for the given data object.
+   * @param data     the Java data object
+   * @param property the requested {@link EdmProperty}
+   * @return the requested Java type
+   */
+  public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException {
+    if (annotationHelper.isEdmAnnotated(data)) {
+      Class<?> fieldType = annotationHelper.getFieldTypeForProperty(data, property.getName());
+      if (fieldType == null) {
+        throw new ODataException("No field type found for property " + property);
+      }
+      return fieldType;
+    }
+    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+  }
+
+  /**
+   * Retrieves the value defined by a mapping object for the given data object.
+   * @param data     the Java data object
+   * @param mapping  the requested {@link EdmMapping}
+   * @return the requested value
+   */
+  public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException {
+    if (mapping != null && mapping.getMediaResourceMimeTypeKey() != null) {
+      return annotationHelper.getValueForProperty(data, mapping.getMediaResourceMimeTypeKey());
+    }
+    return null;
+  }
+
+  /**
+   * Sets the value defined by a mapping object for the given data object.
+   * @param data     the Java data object
+   * @param mapping  the {@link EdmMapping}
+   * @param value    the new value
+   */
+  public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException {
+    if (mapping != null && mapping.getMediaResourceMimeTypeKey() != null) {
+      annotationHelper.setValueForProperty(data, mapping.getMediaResourceMimeTypeKey(), value);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
new file mode 100644
index 0000000..be3baac
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.data;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import org.apache.olingo.odata2.api.data.ValueAccess;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.exception.ODataHttpException;
+import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
+
+/**
+ * Data access.
+ */
+public class BeanPropertyAccess implements ValueAccess {
+
+  @Override
+  public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException {
+    return getValue(data, getGetterMethodName(property));
+  }
+
+  @Override
+  public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException {
+    final String methodName = getSetterMethodName(getGetterMethodName(property));
+    if (methodName != null) {
+      setValue(data, methodName, value);
+    }
+  }
+
+  @Override
+  public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException {
+    return getType(data, getGetterMethodName(property));
+  }
+
+  @Override
+  public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException {
+    if (mapping != null && mapping.getMimeType() != null) {
+      return getValue(data, mapping.getMimeType());
+    }
+    return null;
+  }
+
+  @Override
+  public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException {
+    if (mapping != null && mapping.getMimeType() != null) {
+      setValue(data, getSetterMethodName(mapping.getMimeType()), value);
+    }
+  }
+
+  private String getGetterMethodName(final EdmProperty property) throws EdmException {
+    final String prefix = isBooleanProperty(property) ? "is" : "get";
+    final String defaultMethodName = prefix + property.getName();
+    return property.getMapping() == null || property.getMapping().getInternalName() == null ?
+        defaultMethodName : property.getMapping().getInternalName();
+  }
+
+  private boolean isBooleanProperty(final EdmProperty property) throws EdmException {
+    return property.isSimple() 
+        && property.getType() == EdmSimpleTypeKind.Boolean.getEdmSimpleTypeInstance();
+  }
+
+  private String getSetterMethodName(final String getterMethodName) {
+    return getterMethodName.contains(".") ?
+        null : getterMethodName.replaceFirst("^is", "set").replaceFirst("^get", "set");
+  }
+
+  private <T> Object getValue(final T data, final String methodName) throws ODataNotFoundException {
+    Object dataObject = data;
+
+    for (final String method : methodName.split("\\.", -1)) {
+      if (dataObject != null) {
+        try {
+          dataObject = dataObject.getClass().getMethod(method).invoke(dataObject);
+        } catch (SecurityException e) {
+          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+        } catch (NoSuchMethodException e) {
+          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+        } catch (IllegalArgumentException e) {
+          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+        } catch (IllegalAccessException e) {
+          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+        } catch (InvocationTargetException e) {
+          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+        }
+      }
+    }
+
+    return dataObject;
+  }
+
+  private <T, V> void setValue(final T data, final String methodName, final V value)
+      throws ODataNotFoundException {
+    try {
+      boolean found = false;
+      for (final Method method : Arrays.asList(data.getClass().getMethods())) {
+        if (method.getName().equals(methodName)) {
+          found = true;
+          final Class<?> type = method.getParameterTypes()[0];
+          if (value == null) {
+            if (type.equals(byte.class) || type.equals(short.class) || type.equals(int.class)
+                || type.equals(long.class) || type.equals(char.class)) {
+              method.invoke(data, 0);
+            } else if (type.equals(float.class) || type.equals(double.class)) {
+              method.invoke(data, 0.0);
+            } else if (type.equals(boolean.class)) {
+              method.invoke(data, false);
+            } else {
+              method.invoke(data, value);
+            }
+          } else {
+            method.invoke(data, value);
+          }
+          break;
+        }
+      }
+      if (!found) {
+        throw new ODataNotFoundException(null);
+      }
+    } catch (SecurityException e) {
+      throw new ODataNotFoundException(null, e);
+    } catch (IllegalArgumentException e) {
+      throw new ODataNotFoundException(null, e);
+    } catch (IllegalAccessException e) {
+      throw new ODataNotFoundException(null, e);
+    } catch (InvocationTargetException e) {
+      throw new ODataNotFoundException(null, e);
+    }
+  }
+
+  private <T> Class<?> getType(final T data, final String methodName) throws ODataNotFoundException {
+    if (data == null) {
+      throw new ODataNotFoundException(ODataHttpException.COMMON);
+    }
+
+    Class<?> type = data.getClass();
+    for (final String method : methodName.split("\\.", -1)) {
+      try {
+        type = type.getMethod(method).getReturnType();
+        if (type.isPrimitive()) {
+          if (type == boolean.class) {
+            type = Boolean.class;
+          } else if (type == byte.class) {
+            type = Byte.class;
+          } else if (type == short.class) {
+            type = Short.class;
+          } else if (type == int.class) {
+            type = Integer.class;
+          } else if (type == long.class) {
+            type = Long.class;
+          } else if (type == float.class) {
+            type = Float.class;
+          } else if (type == double.class) {
+            type = Double.class;
+          }
+        }
+      } catch (final SecurityException e) {
+        throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+      } catch (final NoSuchMethodException e) {
+        throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+      }
+    }
+    return type;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/12ea18ae/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
new file mode 100644
index 0000000..696ab9a
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
@@ -0,0 +1,192 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.data;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+/**
+ *
+ */
+public class DataStore<T> {
+
+  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+  private final List<T> dataStore;
+  private final Class<T> dataTypeClass;
+
+  private int idCounter = 1;
+
+  private static class InMemoryDataStore {
+    private static final Map<Class<?>, DataStore<?>> c2ds = new HashMap<Class<?>, DataStore<?>>();
+
+    @SuppressWarnings("unchecked")
+    static DataStore<?> getInstance(Class<?> clz, boolean createNewInstance) {
+      DataStore<?> ds = c2ds.get(clz);
+      if (createNewInstance || ds == null) {
+        ds = new DataStore<Object>((Class<Object>) clz);
+        c2ds.put(clz, ds);
+      }
+      return ds;
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public static <T> DataStore<T> createInMemory(Class<T> clazz) {
+    return (DataStore<T>) InMemoryDataStore.getInstance(clazz, true);
+  }
+
+  @SuppressWarnings("unchecked")
+  public static <T> DataStore<T> createInMemory(Class<T> clazz, boolean keepExisting) {
+    return (DataStore<T>) InMemoryDataStore.getInstance(clazz, !keepExisting);
+  }
+
+  private DataStore(List<T> wrapStore, Class<T> clz) {
+    dataStore = Collections.synchronizedList(wrapStore);
+    dataTypeClass = clz;
+  }
+
+  private DataStore(Class<T> clz) {
+    this(new ArrayList<T>(), clz);
+  }
+
+  public Class<T> getDataTypeClass() {
+    return dataTypeClass;
+  }
+
+  public String getEntityTypeName() {
+    return ANNOTATION_HELPER.extractEntityTypeName(dataTypeClass);
+  }
+
+  public T createInstance() {
+    try {
+      return dataTypeClass.newInstance();
+    } catch (InstantiationException e) {
+      throw new ODataRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
+    } catch (IllegalAccessException e) {
+      throw new ODataRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
+    }
+  }
+
+  public T read(T obj) {
+    List<Object> objKeys = getKeys(obj);
+    for (T stored : dataStore) {
+      if (objKeys.equals(getKeys(stored))) {
+        return stored;
+      }
+    }
+    return null;
+  }
+
+  public Collection<T> read() {
+    return Collections.unmodifiableCollection(dataStore);
+  }
+
+  public T create(T object) throws DataStoreException {
+    synchronized (dataStore) {
+      if (read(object) != null || getKeys(object).contains(null)) {
+        createKeys(object);
+        return this.create(object);
+      }
+      dataStore.add(object);
+    }
+    return object;
+  }
+
+  public T update(T object) {
+    synchronized (dataStore) {
+      T stored = read(object);
+      dataStore.remove(stored);
+      dataStore.add(object);
+    }
+    return object;
+  }
+
+  public T delete(T object) {
+    synchronized (dataStore) {
+      T stored = read(object);
+      if (stored != null) {
+        dataStore.remove(stored);
+      }
+      return stored;
+    }
+  }
+
+  private List<Object> getKeys(T object) {
+    Map<String, Object> keys = ANNOTATION_HELPER.getValueForAnnotatedFields(object, EdmKey.class);
+
+    // XXX: list should be in a defined order -> better to create an 'Key' object which is comparable 
+    List<Object> keyList = new ArrayList<Object>(keys.values());
+    return keyList;
+  }
+
+  private T createKeys(T object) throws DataStoreException {
+    List<Field> fields = ANNOTATION_HELPER.getAnnotatedFields(object, EdmKey.class);
+    if (fields.isEmpty()) {
+      throw new DataStoreException("No EdmKey annotated fields found for class " + object.getClass());
+    }
+    Map<String, Object> fieldName2KeyValue = new HashMap<String, Object>();
+
+    for (Field field : fields) {
+      Object key = createKey(field);
+      fieldName2KeyValue.put(ANNOTATION_HELPER.getCanonicalName(field), key);
+    }
+
+    ANNOTATION_HELPER.setValuesToAnnotatedFields(object, EdmKey.class, fieldName2KeyValue);
+
+    return object;
+  }
+
+  private Object createKey(Field field) {
+    Class<?> type = field.getType();
+
+    if (type == String.class) {
+      return String.valueOf(idCounter++);
+    } else if (type == Integer.class || type == int.class) {
+      return Integer.valueOf(idCounter++);
+    } else if (type == Long.class || type == long.class) {
+      return Long.valueOf(idCounter++);
+    }
+
+    throw new UnsupportedOperationException("Automated key generation for type '" + type
+        + "' is not supported (caused on field '" + field + "').");
+  }
+
+  public static class DataStoreException extends ODataApplicationException {
+    private static final long serialVersionUID = 42L;
+
+    public DataStoreException(String message) {
+      this(message, null);
+    }
+
+    public DataStoreException(String message, Throwable cause) {
+      super(message, Locale.ENGLISH, cause);
+    }
+  }
+}