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/20 14:19:59 UTC

[2/8] [OLINGO-83] Refactoring of 'annotation-processor-*' modules

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/3bd59050/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
deleted file mode 100644
index f2157a0..0000000
--- a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/AnnotationHelper.java
+++ /dev/null
@@ -1,777 +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(final Object firstInstance, final 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(final Object instance, final Map<String, Object> keyName2Value) {
-    Map<String, Object> instanceKeyFields = getValueForAnnotatedFields(instance, EdmKey.class);
-    return keyValuesMatch(instanceKeyFields, keyName2Value);
-  }
-
-  private boolean keyValuesMatch(final Map<String, Object> firstKeyValues, final 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(final Object firstKey, final Object secondKey) {
-    if (firstKey == null) {
-      if (secondKey == null) {
-        return true;
-      } else {
-        return secondKey.equals(firstKey);
-      }
-    } else {
-      return firstKey.equals(secondKey);
-    }
-  }
-
-  public String extractEntitTypeName(final EdmNavigationProperty enp, final Class<?> fallbackClass) {
-    Class<?> entityTypeClass = enp.toType();
-    return extractEntityTypeName(entityTypeClass == Object.class ? fallbackClass : entityTypeClass);
-  }
-
-  public String extractEntitTypeName(final EdmNavigationProperty enp, final 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(final Class<?> annotatedClass) {
-    return extractTypeName(annotatedClass, EdmEntityType.class);
-  }
-
-  /**
-   * Returns <code>NULL</code> if given class is not annotated.
-   * If annotated the entity set name is returned and if
-   * no name is set a default name is generated based on the simple class name.
-   * 
-   * @param annotatedClass
-   * @return
-   */
-  public String extractEntitySetName(final Class<?> annotatedClass) {
-    if (annotatedClass == Object.class) {
-      return null;
-    }
-    EdmEntitySet entitySet = annotatedClass.getAnnotation(EdmEntitySet.class);
-    if (entitySet == null) {
-      return null;
-    }
-
-    String name = entitySet.name();
-    if (name.isEmpty()) {
-      return getCanonicalName(annotatedClass) + "Set";
-    }
-    return name;
-  }
-
-  public FullQualifiedName extractEntityTypeFqn(final EdmEntityType type, final Class<?> annotatedClass) {
-    if (type.namespace().isEmpty()) {
-      return new FullQualifiedName(generateNamespace(annotatedClass), extractEntityTypeName(annotatedClass));
-    }
-    return new FullQualifiedName(type.namespace(), extractEntityTypeName(annotatedClass));
-  }
-
-  public FullQualifiedName extractEntityTypeFqn(final Class<?> annotatedClass) {
-    EdmEntityType type = annotatedClass.getAnnotation(EdmEntityType.class);
-    if (type == null) {
-      return null;
-    }
-    return extractEntityTypeFqn(type, annotatedClass);
-  }
-
-  public FullQualifiedName extractComplexTypeFqn(final Class<?> annotatedClass) {
-    EdmComplexType type = annotatedClass.getAnnotation(EdmComplexType.class);
-    if (type == null) {
-      return null;
-    }
-    return extractComplexTypeFqn(type, annotatedClass);
-  }
-
-  public FullQualifiedName extractComplexTypeFqn(final EdmComplexType type, final Class<?> annotatedClass) {
-    if (type.namespace().isEmpty()) {
-      return new FullQualifiedName(generateNamespace(annotatedClass), extractComplexTypeName(annotatedClass));
-    }
-    return new FullQualifiedName(type.namespace(), extractComplexTypeName(annotatedClass));
-  }
-
-  public String extractComplexTypeName(final Class<?> annotatedClass) {
-    return extractTypeName(annotatedClass, EdmComplexType.class);
-  }
-
-  public String generateNamespace(final 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(final Class<?> annotatedClass, final 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(final 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(final Field field) {
-    String propertyName = getPropertyNameFromAnnotation(field);
-    if (propertyName.isEmpty()) {
-      propertyName = getCanonicalName(field);
-    }
-    return propertyName;
-  }
-
-  public String extractFromRoleName(final EdmNavigationProperty enp, final Field field) {
-    return getCanonicalRole(field.getDeclaringClass());
-  }
-
-  public String extractToRoleName(final EdmNavigationProperty enp, final 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(final Class<?> fallbackClass) {
-    String toRole = extractEntityTypeName(fallbackClass);
-    return "r_" + toRole;
-  }
-
-  public String extractRelationshipName(final EdmNavigationProperty enp, final 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(final EdmNavigationProperty enp, final 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(final T instance, final 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 = 42L;
-
-    public ODataAnnotationException(final String message) {
-      super(message);
-    }
-
-    public ODataAnnotationException(final String message, final Exception cause) {
-      super(message, cause);
-    }
-  }
-
-  public class AnnotatedNavInfo {
-    private final Field fromField;
-    private final Field toField;
-    private final EdmNavigationProperty fromNavigation;
-    private final EdmNavigationProperty toNavigation;
-
-    public AnnotatedNavInfo(final Field fromField, final Field toField, final EdmNavigationProperty fromNavigation,
-        final 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(final Class<?> sourceClass, final 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(final Object instance, final 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(final Object instance, final 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(final Object instance, final String propertyName, final Object propertyValue) {
-    if (instance != null) {
-      Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
-      if (field != null) {
-        setFieldValue(instance, field, propertyValue);
-      }
-    }
-  }
-
-  private Field getFieldForPropertyName(final Object instance, final String propertyName,
-      final Class<?> resultClass, final 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(final Object instance, final String fieldName,
-      final Class<? extends Annotation> annotation) {
-    if (instance == null) {
-      return null;
-    }
-    return getValueForField(instance, fieldName, instance.getClass(), annotation, true);
-  }
-
-  public Object getValueForField(final Object instance, final Class<? extends Annotation> annotation) {
-    if (instance == null) {
-      return null;
-    }
-    return getValueForField(instance, instance.getClass(), annotation, true);
-  }
-
-  private Object getValueForField(final Object instance, final Class<?> resultClass,
-      final Class<? extends Annotation> annotation, final boolean inherited) {
-    return getValueForField(instance, null, resultClass, annotation, inherited);
-  }
-
-  public Map<String, Object> getValueForAnnotatedFields(final Object instance,
-      final Class<? extends Annotation> annotation) {
-    return getValueForAnnotatedFields(instance, instance.getClass(), annotation, true);
-  }
-
-  private Map<String, Object> getValueForAnnotatedFields(final Object instance, final Class<?> resultClass,
-      final Class<? extends Annotation> annotation, final 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(final Object instance, final Class<? extends Annotation> annotation,
-      final 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(final Object instance,
-      final Class<? extends Annotation> annotation, final 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(final Object instance, final Class<? extends Annotation> annotation) {
-    if (instance == null) {
-      return null;
-    }
-    return getAnnotatedFields(instance.getClass(), annotation, true);
-  }
-
-  public List<Field> getAnnotatedFields(final Class<?> fieldClass, final Class<? extends Annotation> annotation) {
-    return getAnnotatedFields(fieldClass, annotation, true);
-  }
-
-  /**
-   * 
-   * @param instance
-   * @param resultClass
-   * @param annotation
-   * @param inherited
-   * @return
-   */
-  private List<Field> getAnnotatedFields(final Class<?> resultClass,
-      final Class<? extends Annotation> annotation, final 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(final Object instance, final String fieldName, final Class<?> resultClass,
-      final Class<? extends Annotation> annotation, final 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(final Object instance, final 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(final Object instance, final Field field, final 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(final Field field, final 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(final Object object) {
-    if (object == null) {
-      return false;
-    }
-    return isEdmAnnotated(object.getClass());
-  }
-
-  public boolean isEdmTypeAnnotated(final Class<?> clazz) {
-    boolean isComplexEntity = clazz.getAnnotation(EdmComplexType.class) != null;
-    boolean isEntity = clazz.getAnnotation(EdmEntityType.class) != null;
-    return isComplexEntity || isEntity;
-  }
-
-  public boolean isEdmAnnotated(final 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(final Field field) {
-    return firstCharToUpperCase(field.getName());
-  }
-
-  public String getCanonicalName(final Class<?> clazz) {
-    return firstCharToUpperCase(clazz.getSimpleName());
-  }
-
-  private String firstCharToUpperCase(final String content) {
-    if (content == null || content.isEmpty()) {
-      return content;
-    }
-    return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1);
-  }
-
-  public EdmSimpleTypeKind mapTypeKind(final 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(final 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(final String message) {
-      super(message);
-    }
-  }
-
-  public String getCanonicalNamespace(final Class<?> aClass) {
-    return generateNamespace(aClass);
-  }
-
-  public String extractContainerName(final 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/3bd59050/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
deleted file mode 100644
index cca35ab..0000000
--- a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/core/annotation/util/ClassHelper.java
+++ /dev/null
@@ -1,140 +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.lang.reflect.Field;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-/**
- *
- */
-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(final File dir, final 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(final File pathname) {
-      return pathname.isDirectory();
-    }
-  };
-
-  public static final List<Class<?>> loadClasses(final String packageToScan, final ClassValidator cv) {
-    return loadClasses(packageToScan, CLASSFILE_FILTER, cv);
-  }
-
-  public static final List<Class<?>> loadClasses(final String packageToScan, final FilenameFilter ff,
-      final 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;
-  }
-
-  public static Object getFieldValue(final Object instance, final Field field) {
-    try {
-      synchronized (field) {
-        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);
-    }
-  }
-
-  public static void setFieldValue(final Object instance, final Field field, final Object value) {
-    try {
-      synchronized (field) {
-        boolean access = field.isAccessible();
-        field.setAccessible(true);
-        field.set(instance, value);
-        field.setAccessible(access);
-      }
-    } catch (IllegalArgumentException ex) { // should never happen
-      throw new ODataRuntimeException(ex);
-    } catch (IllegalAccessException ex) { // should never happen
-      throw new ODataRuntimeException(ex);
-    }
-  }
-
-  private static File[] listSubFolder(final 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/3bd59050/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
index 3e2fbd4..5059327 100644
--- 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
@@ -25,22 +25,24 @@ import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.olingo.odata2.annotation.processor.core.datasource.AnnotationInMemoryDs;
+import org.apache.olingo.odata2.annotation.processor.core.datasource.DataSource;
+import org.apache.olingo.odata2.annotation.processor.core.datasource.DataStore;
+import org.apache.olingo.odata2.annotation.processor.core.datasource.DataSource.BinaryData;
+import org.apache.olingo.odata2.annotation.processor.core.edm.AnnotationEdmProvider;
+import org.apache.olingo.odata2.annotation.processor.core.util.AnnotationHelper;
 import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
 import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
-import org.apache.olingo.odata2.api.data.DataSource;
-import org.apache.olingo.odata2.api.data.DataSource.BinaryData;
 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.api.exception.ODataNotFoundException;
-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.model.Room;
-import org.apache.olingo.odata2.core.annotation.util.AnnotationHelper;
 import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
 import org.junit.Assert;
 import org.junit.Ignore;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/3bd59050/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
index b6863c6..2f9a1e7 100644
--- 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
@@ -27,6 +27,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 
+import org.apache.olingo.odata2.annotation.processor.core.edm.AnnotationEdmProvider;
 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;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/3bd59050/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/AnnotationRefServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/AnnotationRefServiceFactory.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/AnnotationRefServiceFactory.java
new file mode 100644
index 0000000..ccaca81
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/AnnotationRefServiceFactory.java
@@ -0,0 +1,215 @@
+/**
+ * *****************************************************************************
+ * 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.annotation.processor.ref;
+
+import java.util.Calendar;
+
+import org.apache.olingo.odata2.annotation.processor.api.AnnotationServiceFactory;
+import org.apache.olingo.odata2.annotation.processor.core.datasource.DataStore;
+import org.apache.olingo.odata2.annotation.processor.core.datasource.DataStore.DataStoreException;
+import org.apache.olingo.odata2.annotation.processor.ref.model.Building;
+import org.apache.olingo.odata2.annotation.processor.ref.model.Employee;
+import org.apache.olingo.odata2.annotation.processor.ref.model.Location;
+import org.apache.olingo.odata2.annotation.processor.ref.model.Manager;
+import org.apache.olingo.odata2.annotation.processor.ref.model.Photo;
+import org.apache.olingo.odata2.annotation.processor.ref.model.ResourceHelper;
+import org.apache.olingo.odata2.annotation.processor.ref.model.Room;
+import org.apache.olingo.odata2.annotation.processor.ref.model.Team;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ODataServiceFactory implemantion based on ListProcessor
+ * in combination with Annotation-Support-Classes for EdmProvider, DataSource and ValueAccess.
+ */
+public class AnnotationRefServiceFactory extends ODataServiceFactory {
+
+  /**
+   * Instance holder for all annotation relevant instances which should be used as singleton
+   * instances within the ODataApplication (ODataService)
+   */
+  private static class AnnotationInstances {
+    final static String MODEL_PACKAGE = "org.apache.olingo.odata2.annotation.processor.ref.model";
+
+    final static ODataService ANNOTATION_ODATA_SERVICE;
+    
+    static {
+      try {
+        ANNOTATION_ODATA_SERVICE = AnnotationServiceFactory.createAnnotationService(MODEL_PACKAGE);
+        initializeSampleData();
+      } catch (ODataApplicationException ex) {
+        throw new RuntimeException("Exception during sample data generation.", ex);
+      } catch (ODataException ex) {
+        throw new RuntimeException("Exception during data source initialization generation.", ex);
+      }
+    }
+  }
+
+  @Override
+  public ODataService createService(final ODataContext context) throws ODataException {
+    // Edm via Annotations and ListProcessor via AnnotationDS with AnnotationsValueAccess
+    return AnnotationInstances.ANNOTATION_ODATA_SERVICE;
+  }
+
+  @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
+   */
+
+  /**
+   * Callback class to enable debugging.
+   */
+  private final class ScenarioDebugCallback implements ODataDebugCallback {
+
+    @Override
+    public boolean isDebugEnabled() {
+      return true;
+    }
+  }
+
+  /**
+   * Callback class for error handling.
+   */
+  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 static <T> DataStore<T> getDataStore(Class<T> clz) throws DataStoreException {
+    return DataStore.createInMemory(clz, true);
+  }
+  
+  private static void initializeSampleData() throws ODataApplicationException {
+    DataStore<Team> teamDs = 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 = 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 = 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 = 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 = 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 static Employee createEmployee(final String name,
+      final Location location, final int age, final Calendar date,
+      final byte[] image, final String imageType, final String imageUrl,
+      final Manager manager, final Team team, final 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 static Team createTeam(final String teamName, final boolean isScrumTeam) {
+    Team team = new Team();
+    team.setName(teamName);
+    team.setScrumTeam(isScrumTeam);
+    return team;
+  }
+
+  private static Building createBuilding(final String buildingName) {
+    Building b = new Building();
+    b.setName(buildingName);
+    return b;
+  }
+
+  private static Photo createPhoto(final String name, final 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 static Room createRoom(final String name, final int seats, final int version, final 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/3bd59050/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Building.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Building.java
new file mode 100644
index 0000000..125c936
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/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.annotation.processor.ref.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(final 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/3bd59050/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/City.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/City.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/City.java
new file mode 100644
index 0000000..7a72178
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/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.annotation.processor.ref.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/3bd59050/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Employee.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Employee.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Employee.java
new file mode 100644
index 0000000..98d57ca
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/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.annotation.processor.ref.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/3bd59050/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Location.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Location.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Location.java
new file mode 100644
index 0000000..b131f7e
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/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.annotation.processor.ref.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/3bd59050/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Manager.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Manager.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Manager.java
new file mode 100644
index 0000000..136c476
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/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.annotation.processor.ref.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/3bd59050/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/ModelSharedConstants.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/ModelSharedConstants.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/ModelSharedConstants.java
new file mode 100644
index 0000000..05cb2db
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/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.annotation.processor.ref.model;
+
+public interface ModelSharedConstants {
+
+  String NAMESPACE_1 = "RefScenario";
+  String CONTAINER_1 = "Container1";
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/3bd59050/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Photo.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Photo.java
new file mode 100644
index 0000000..d0285ec
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/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.annotation.processor.ref.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) {
+    mimeType = imageType;
+  }
+
+  @Override
+  public int hashCode() {
+    int hash = 5;
+    hash = 83 * hash + (name != null ? name.hashCode() : 0);
+    hash = 83 * hash + (type != null ? type.hashCode() : 0);
+    return hash;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    final Photo other = (Photo) obj;
+    if ((name == null) ? (other.name != null) : !name.equals(other.name)) {
+      return false;
+    }
+    if ((type == null) ? (other.type != null) : !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/3bd59050/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/RefBase.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/RefBase.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/RefBase.java
new file mode 100644
index 0000000..d0d3edc
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/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.annotation.processor.ref.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(final String name) {
+    this.name = name;
+  }
+
+  public void setId(final int id) {
+    this.id = String.valueOf(id);
+  }
+
+  @Override
+  public int hashCode() {
+    if (id == null) {
+      return -1;
+    }
+    return id.hashCode();
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    final RefBase other = (RefBase) obj;
+    if ((name == null) ? (other.name != null) : !name.equals(other.name)) {
+      return false;
+    }
+    if ((id == null) ? (other.id != null) : !id.equals(other.id)) {
+      return false;
+    }
+    return true;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/3bd59050/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/ResourceHelper.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/ResourceHelper.java
new file mode 100644
index 0000000..7d64bc4
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/ResourceHelper.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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.annotation.processor.ref.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(final String resource) {
+    return load(resource, new byte[0]);
+  }
+
+  public static byte[] load(final String resource, final 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(final 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/3bd59050/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Room.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Room.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Room.java
new file mode 100644
index 0000000..78e7a2c
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/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.annotation.processor.ref.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/3bd59050/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Team.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Team.java b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/Team.java
new file mode 100644
index 0000000..7f48f66
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-webref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/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.annotation.processor.ref.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(final Employee e) {
+    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