You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by tb...@apache.org on 2014/01/02 13:47:32 UTC

[45/47] git commit: [OLINGO-83] Renamed test packages

[OLINGO-83] Renamed test packages


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/80dc018d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/tree/80dc018d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/diff/80dc018d

Branch: refs/heads/ODataServlet
Commit: 80dc018d1e447dafc0e1918fab71d8d29e3aac93
Parents: 80379ec
Author: Michael Bolz <mi...@apache.org>
Authored: Fri Dec 20 16:10:24 2013 +0100
Committer: Tamara Boehm <ta...@sap.com>
Committed: Thu Jan 2 13:36:47 2014 +0100

----------------------------------------------------------------------
 .../core/AnnotationServiceFactoryImpl.java      |  12 +-
 .../core/AnnotationServiceFactoryImplTest.java  |  74 +++
 .../datasource/AnnotationsInMemoryDsTest.java   | 628 +++++++++++++++++++
 .../core/edm/AnnotationEdmProviderTest.java     | 463 ++++++++++++++
 .../processor/core/model/Building.java          |  99 +++
 .../annotation/processor/core/model/City.java   |  61 ++
 .../processor/core/model/Employee.java          | 187 ++++++
 .../processor/core/model/Location.java          |  60 ++
 .../processor/core/model/Manager.java           |  47 ++
 .../core/model/ModelSharedConstants.java        |  25 +
 .../annotation/processor/core/model/Photo.java  | 128 ++++
 .../processor/core/model/RefBase.java           |  55 ++
 .../processor/core/model/ResourceHelper.java    |  66 ++
 .../annotation/processor/core/model/Room.java   |  93 +++
 .../annotation/processor/core/model/Team.java   |  81 +++
 .../data/AnnotationsInMemoryDsTest.java         | 628 -------------------
 .../edm/AnnotationEdmProviderTest.java          | 462 --------------
 .../odata2/core/annotation/model/Building.java  |  99 ---
 .../odata2/core/annotation/model/City.java      |  61 --
 .../odata2/core/annotation/model/Employee.java  | 187 ------
 .../odata2/core/annotation/model/Location.java  |  60 --
 .../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   |  66 --
 .../odata2/core/annotation/model/Room.java      |  93 ---
 .../odata2/core/annotation/model/Team.java      |  81 ---
 28 files changed, 2068 insertions(+), 2003 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/80dc018d/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/AnnotationServiceFactoryImpl.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/AnnotationServiceFactoryImpl.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/AnnotationServiceFactoryImpl.java
index 9c673a3..7947d6b 100644
--- a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/AnnotationServiceFactoryImpl.java
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/AnnotationServiceFactoryImpl.java
@@ -29,20 +29,10 @@ import org.apache.olingo.odata2.api.exception.ODataException;
 import org.apache.olingo.odata2.api.rt.RuntimeDelegate;
 
 /**
- * ODataServiceFactory implementation based on ListProcessor
+ * AnnotationServiceFactoryInstance (ODataServiceFactory) implementation based on ListProcessor
  * in combination with Annotation-Support-Classes for EdmProvider, DataSource and ValueAccess.
  */
 public class AnnotationServiceFactoryImpl implements AnnotationServiceFactoryInstance {
-
-  /**
-   * Create an instance which further can create an {@link ODataService}.
-   * 
-   * @return instance which further can create an {@link ODataService}.
-   */
-  public AnnotationServiceFactoryInstance createInstance() {
-    return new AnnotationServiceFactoryImpl();
-  }
-
   /**
    * {@inheritDoc}
    */

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/80dc018d/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/AnnotationServiceFactoryImplTest.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/AnnotationServiceFactoryImplTest.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/AnnotationServiceFactoryImplTest.java
new file mode 100644
index 0000000..4feaac7
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/AnnotationServiceFactoryImplTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.annotation.processor.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import junit.framework.Assert;
+
+import org.apache.olingo.odata2.annotation.processor.core.model.Building;
+import org.apache.olingo.odata2.annotation.processor.core.model.Employee;
+import org.apache.olingo.odata2.annotation.processor.core.model.Manager;
+import org.apache.olingo.odata2.annotation.processor.core.model.Photo;
+import org.apache.olingo.odata2.annotation.processor.core.model.RefBase;
+import org.apache.olingo.odata2.annotation.processor.core.model.Room;
+import org.apache.olingo.odata2.annotation.processor.core.model.Team;
+import org.apache.olingo.odata2.api.ODataService;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class AnnotationServiceFactoryImplTest {
+
+  @Test
+  public void createFromPackage() throws ODataException {
+    AnnotationServiceFactoryImpl factory = new AnnotationServiceFactoryImpl();
+    ODataService service = factory.createAnnotationService(Building.class.getPackage().getName());
+    
+    Assert.assertNotNull(service);
+  }
+  
+  @Test
+  public void createFromAnnotatedClasses() throws ODataException {
+    AnnotationServiceFactoryImpl factory = new AnnotationServiceFactoryImpl();
+    final Collection<Class<?>> annotatedClasses = new ArrayList<Class<?>>();
+    annotatedClasses.add(RefBase.class);
+    annotatedClasses.add(Building.class);
+    annotatedClasses.add(Employee.class);
+    annotatedClasses.add(Manager.class);
+    annotatedClasses.add(Photo.class);
+    annotatedClasses.add(Room.class);
+    annotatedClasses.add(Team.class);
+    ODataService service = factory.createAnnotationService(annotatedClasses);
+    
+    Assert.assertNotNull(service);
+  }
+
+  @Test(expected=ODataException.class)
+  public void createFromClasses() throws ODataException {
+    AnnotationServiceFactoryImpl factory = new AnnotationServiceFactoryImpl();
+    
+    final Collection<Class<?>> notAnnotatedClasses = new ArrayList<Class<?>>();
+    notAnnotatedClasses.add(String.class);
+    notAnnotatedClasses.add(Long.class);
+    ODataService service = factory.createAnnotationService(notAnnotatedClasses);
+    
+    Assert.assertNotNull(service);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/80dc018d/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationsInMemoryDsTest.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationsInMemoryDsTest.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationsInMemoryDsTest.java
new file mode 100644
index 0000000..b9ebcb3
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationsInMemoryDsTest.java
@@ -0,0 +1,628 @@
+/*
+ * 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.annotation.processor.core.datasource;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+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.model.Building;
+import org.apache.olingo.odata2.annotation.processor.core.model.ModelSharedConstants;
+import org.apache.olingo.odata2.annotation.processor.core.model.Photo;
+import org.apache.olingo.odata2.annotation.processor.core.model.Room;
+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.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.exception.ODataRuntimeException;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ *
+ */
+public class AnnotationsInMemoryDsTest {
+
+  private final AnnotationInMemoryDs datasource;
+  private final AnnotationEdmProvider edmProvider;
+  private static final String DEFAULT_CONTAINER = ModelSharedConstants.CONTAINER_1;
+
+  public AnnotationsInMemoryDsTest() throws ODataException {
+    datasource = new AnnotationInMemoryDs(Building.class.getPackage().getName(), false);
+    edmProvider = new AnnotationEdmProvider(Building.class.getPackage().getName());
+  }
+
+  @Test
+  @Ignore
+  public void multiThreadedSyncOnBuildingsTest() throws Exception {
+    final EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
+    CountDownLatch latch;
+
+    List<Thread> threads = new ArrayList<Thread>();
+    int max = 500;
+
+    latch = new CountDownLatch(max);
+    for (int i = 0; i < max; i++) {
+      threads.add(createBuildingThread(latch, datasource, edmEntitySet, String.valueOf("10")));
+    }
+
+    for (Thread thread : threads) {
+      thread.start();
+    }
+
+    latch.await(60, TimeUnit.SECONDS);
+
+    DataStore<Building> ds = datasource.getDataStore(Building.class);
+    Collection<Building> buildings = ds.read();
+    Assert.assertEquals(max, buildings.size());
+  }
+
+  @org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet
+  @org.apache.olingo.odata2.api.annotation.edm.EdmEntityType
+  private static class SimpleEntity {
+    @EdmKey
+    @EdmProperty
+    public Integer id;
+    @EdmProperty
+    public String name;
+  }
+
+  @Test
+  @Ignore
+  public void multiThreadedSyncCreateReadTest() throws Exception {
+    Collection<Class<?>> ac = new ArrayList<Class<?>>();
+    ac.add(SimpleEntity.class);
+    final AnnotationInMemoryDs localDs = new AnnotationInMemoryDs(SimpleEntity.class.getPackage().getName(), true);
+    final AnnotationEdmProvider localProvider = new AnnotationEdmProvider(ac);
+    final EdmEntitySet edmEntitySet = createMockedEdmEntitySet(localProvider, "SimpleEntitySet");
+    final CountDownLatch latch;
+
+    List<Thread> threads = new ArrayList<Thread>();
+    int max = 500;
+    latch = new CountDownLatch(max);
+    for (int i = 0; i < max; i++) {
+      Runnable run = new Runnable() {
+        @Override
+        public void run() {
+          SimpleEntity se = new SimpleEntity();
+          se.id = Integer.valueOf(String.valueOf(System.currentTimeMillis()).substring(8));
+          se.name = "Name: " + System.currentTimeMillis();
+          try {
+            localDs.createData(edmEntitySet, se);
+          } catch (Exception ex) {
+            throw new RuntimeException(ex);
+          }finally{
+            latch.countDown();
+          }
+        }
+      };
+
+      threads.add(new Thread(run));
+    }
+
+    for (Thread thread : threads) {
+      thread.start();
+    }
+
+    latch.await(60, TimeUnit.SECONDS);
+
+    DataStore<SimpleEntity> ds = localDs.getDataStore(SimpleEntity.class);
+    Collection<SimpleEntity> buildings = ds.read();
+    Assert.assertEquals(max, buildings.size());
+  }
+
+  private Thread createBuildingThread(final CountDownLatch latch, final DataSource datasource,
+      final EdmEntitySet edmEntitySet, final String id) {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        Building building = new Building();
+        building.setName("Common Building - " + System.currentTimeMillis());
+        building.setId(id);
+        try {
+          datasource.createData(edmEntitySet, building);
+        } catch (Exception ex) {
+          ex.printStackTrace();
+          throw new RuntimeException(ex);
+        } finally {
+          latch.countDown();
+        }
+      }
+    };
+
+    return new Thread(run);
+  }
+  
+  @Test
+  public void readBinaryData() throws Exception {
+    EdmEntitySet entitySet = createMockedEdmEntitySet("Photos");
+
+    DataStore<Photo> photoDataStore = datasource.getDataStore(Photo.class);
+    Photo photo = new Photo();
+    photo.setName("SomePic");
+    photo.setType("PNG");
+    byte[] image = "binary".getBytes(Charset.defaultCharset());
+    photo.setImage(image);
+    photo.setImageType("image/png");
+    photoDataStore.create(photo);
+
+    Map<String, Object> keys = new HashMap<String, Object>();
+    keys.put("Name", "SomePic");
+    keys.put("ImageFormat", "PNG");
+    Photo toReadPhoto = (Photo) datasource.readData(entitySet, keys);
+    
+    // execute
+    BinaryData readBinaryData = datasource.readBinaryData(entitySet, toReadPhoto);
+
+    // validate
+    Assert.assertEquals("binary", new String(readBinaryData.getData(), Charset.defaultCharset()));
+    Assert.assertArrayEquals(image, readBinaryData.getData());
+    Assert.assertEquals("image/png", readBinaryData.getMimeType());
+  }
+
+  @Test
+  public void readBinaryDataDirect() throws Exception {
+    EdmEntitySet entitySet = createMockedEdmEntitySet("Photos");
+
+    DataStore<Photo> photoDataStore = datasource.getDataStore(Photo.class);
+    Photo photo = new Photo();
+    photo.setName("SomePic");
+    photo.setType("PNG");
+    byte[] image = "binary".getBytes(Charset.defaultCharset());
+    photo.setImage(image);
+    photo.setImageType("image/png");
+    photoDataStore.create(photo);
+    
+    Photo toReadPhoto = new Photo();
+    toReadPhoto.setName("SomePic");
+    toReadPhoto.setType("PNG");
+    toReadPhoto.setImage(null);
+    toReadPhoto.setImageType(null);
+
+    BinaryData readBinaryData = datasource.readBinaryData(entitySet, toReadPhoto);
+    
+    Assert.assertEquals("binary", new String(readBinaryData.getData(), Charset.defaultCharset()));
+    Assert.assertArrayEquals(image, readBinaryData.getData());
+    Assert.assertEquals("image/png", readBinaryData.getMimeType());
+  }
+
+  
+  @Test
+  public void writeBinaryData() throws Exception {
+    EdmEntitySet entitySet = createMockedEdmEntitySet("Photos");
+
+    DataStore<Photo> photoDataStore = datasource.getDataStore(Photo.class);
+
+    Photo toWritePhoto = new Photo();
+    toWritePhoto.setName("SomePic");
+    toWritePhoto.setType("PNG");
+    photoDataStore.create(toWritePhoto);
+    byte[] image = "binary".getBytes(Charset.defaultCharset());
+    String mimeType = "image/png";
+    BinaryData writeBinaryData = new BinaryData(image, mimeType);
+    // execute
+    datasource.writeBinaryData(entitySet, toWritePhoto, writeBinaryData);
+
+    // validate
+    Photo photoKey = new Photo();
+    photoKey.setName("SomePic");
+    photoKey.setType("PNG");
+    Photo storedPhoto = photoDataStore.read(photoKey);
+    Assert.assertEquals("binary", new String(storedPhoto.getImage(), Charset.defaultCharset()));
+    Assert.assertArrayEquals(image, storedPhoto.getImage());
+    Assert.assertEquals("image/png", storedPhoto.getImageType());
+  }
+
+  @Test(expected=ODataNotFoundException.class)
+  public void writeBinaryDataNotFound() throws Exception {
+    EdmEntitySet entitySet = createMockedEdmEntitySet("Photos");
+
+    Photo toWritePhoto = new Photo();
+    toWritePhoto.setName("SomePic");
+    toWritePhoto.setType("PNG");
+    byte[] image = "binary".getBytes(Charset.defaultCharset());
+    String mimeType = "image/png";
+    BinaryData writeBinaryData = new BinaryData(image, mimeType);
+    // execute
+    datasource.writeBinaryData(entitySet, toWritePhoto, writeBinaryData);
+  }
+
+  
+  @Test
+  public void newDataObject() throws Exception {
+    EdmEntitySet roomsEntitySet = createMockedEdmEntitySet("Rooms");
+    Room room = (Room) datasource.newDataObject(roomsEntitySet);
+    
+    Assert.assertNotNull(room);
+  }
+
+  @Test
+  public void readEntity() throws Exception {
+    EdmEntitySet buildingsEntitySet = createMockedEdmEntitySet("Buildings");
+    EdmEntitySet roomsEntitySet = createMockedEdmEntitySet("Rooms");
+
+    Building building = new Building();
+    building.setName("Common Building");
+
+    final int roomsCount = 3;
+    List<Room> rooms = new ArrayList<Room>();
+    for (int i = 0; i < roomsCount; i++) {
+      Room room = new Room(i, "Room " + i);
+      room.setBuilding(building);
+      datasource.createData(roomsEntitySet, room);
+      rooms.add(room);
+    }
+
+    building.getRooms().addAll(rooms);
+    datasource.createData(buildingsEntitySet, building);
+
+    Map<String, Object> keys = new HashMap<String, Object>();
+    keys.put("Id", "1");
+
+    // execute
+    Object relatedData = datasource.readData(buildingsEntitySet, keys);
+
+    // validate
+    Building readBuilding = (Building) relatedData;
+    Assert.assertEquals("Common Building", readBuilding.getName());
+    Assert.assertEquals("1", readBuilding.getId());
+    
+    Collection<Room> relatedRooms = readBuilding.getRooms();
+    Assert.assertEquals(roomsCount, relatedRooms.size());
+    for (Room room : relatedRooms) {
+      Assert.assertNotNull(room.getId());
+      Assert.assertTrue(room.getName().matches("Room \\d*"));
+      Assert.assertEquals("Common Building", room.getBuilding().getName());
+    }
+  }
+
+  @Test
+  public void readEntities() throws Exception {
+    EdmEntitySet roomsEntitySet = createMockedEdmEntitySet("Rooms");
+
+    Building building = new Building();
+    building.setName("Common Building");
+
+    final int roomsCount = 11;
+    List<Room> rooms = new ArrayList<Room>();
+    for (int i = 0; i < roomsCount; i++) {
+      Room room = new Room(i, "Room " + i);
+      room.setBuilding(building);
+      datasource.createData(roomsEntitySet, room);
+      rooms.add(room);
+    }
+
+    // execute
+    Object relatedData = datasource.readData(roomsEntitySet);
+
+    // validate
+    @SuppressWarnings("unchecked")
+    Collection<Room> relatedRooms = (Collection<Room>) relatedData;
+    Assert.assertEquals(roomsCount, relatedRooms.size());
+    for (Room room : relatedRooms) {
+      Assert.assertNotNull(room.getId());
+      Assert.assertTrue(room.getName().matches("Room \\d*"));
+      Assert.assertEquals("Common Building", room.getBuilding().getName());
+    }
+  }
+
+  
+  @Test
+  @SuppressWarnings("unchecked")
+  public void readRelatedEntities() throws Exception {
+    EdmEntitySet buildingsEntitySet = createMockedEdmEntitySet("Buildings");
+    EdmEntitySet roomsEntitySet = createMockedEdmEntitySet("Rooms");
+
+    Building building = new Building();
+    building.setName("Common Building");
+
+    final int roomsCount = 10;
+    List<Room> rooms = new ArrayList<Room>();
+    for (int i = 0; i < roomsCount; i++) {
+      Room room = new Room(i, "Room " + i);
+      room.setBuilding(building);
+      datasource.createData(roomsEntitySet, room);
+      rooms.add(room);
+    }
+
+    building.getRooms().addAll(rooms);
+    datasource.createData(buildingsEntitySet, building);
+
+    Map<String, Object> keys = new HashMap<String, Object>();
+    keys.put("Id", "1");
+
+    Building read = (Building) datasource.readData(buildingsEntitySet, keys);
+    Assert.assertEquals("Common Building", read.getName());
+    Assert.assertEquals("1", read.getId());
+
+    // execute
+    Object relatedData = datasource.readRelatedData(
+        buildingsEntitySet, building, roomsEntitySet, Collections.EMPTY_MAP);
+
+    // validate
+    Assert.assertTrue("Result is no collection.", relatedData instanceof Collection);
+    Collection<Room> relatedRooms = (Collection<Room>) relatedData;
+    Assert.assertEquals(roomsCount, relatedRooms.size());
+    for (Room room : relatedRooms) {
+      Assert.assertNotNull(room.getId());
+      Assert.assertTrue(room.getName().matches("Room \\d*"));
+      Assert.assertEquals("Common Building", room.getBuilding().getName());
+    }
+  }
+
+  @Test
+  public void readRelatedTargetEntity() throws Exception {
+    EdmEntitySet buildingsEntitySet = createMockedEdmEntitySet("Buildings");
+    EdmEntitySet roomsEntitySet = createMockedEdmEntitySet("Rooms");
+
+    Building building = new Building();
+    building.setName("Common Building");
+
+    final int roomsCount = 10;
+    List<Room> rooms = new ArrayList<Room>();
+    for (int i = 0; i < roomsCount; i++) {
+      Room room = new Room(i, "Room " + i);
+      room.setBuilding(building);
+      datasource.createData(roomsEntitySet, room);
+      rooms.add(room);
+    }
+
+    building.getRooms().addAll(rooms);
+    datasource.createData(buildingsEntitySet, building);
+
+    Map<String, Object> keys = new HashMap<String, Object>();
+    keys.put("Id", "1");
+
+    Building read = (Building) datasource.readData(buildingsEntitySet, keys);
+    Assert.assertEquals("Common Building", read.getName());
+    Assert.assertEquals("1", read.getId());
+
+    // execute
+    Map<String, Object> targetKeys = new HashMap<String, Object>();
+    targetKeys.put("Id", 3);
+    Object relatedData = datasource.readRelatedData(
+        buildingsEntitySet, building, roomsEntitySet, targetKeys);
+
+    // validate
+    Assert.assertTrue("Result is no Room.", relatedData instanceof Room);
+    Room relatedRoom = (Room) relatedData;
+    Assert.assertEquals("3", relatedRoom.getId());
+    Assert.assertEquals("Room 3", relatedRoom.getName());
+    Assert.assertEquals("Common Building", relatedRoom.getBuilding().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
+  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());
+  }
+  
+  
+  @Test
+  public void deleteSimpleEntity() throws Exception {
+    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Buildings");
+    DataStore<Building> datastore = datasource.getDataStore(Building.class);
+
+    Building building = new Building();
+    building.setName("Common Building");
+    datastore.create(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());
+
+    //
+    datasource.deleteData(edmEntitySet, keys);
+    
+    // validate
+    try {
+      Building readAfterDelete = (Building) datasource.readData(edmEntitySet, keys);
+      Assert.fail("Expected " + ODataNotFoundException.class + "was not thrown for '" + readAfterDelete + "'.");
+    } catch (ODataNotFoundException e) { }
+  }
+
+  @Test(expected=ODataRuntimeException.class)
+  public void unknownEntitySetForEntity() throws Exception {
+    String entitySetName = "Unknown";
+    FullQualifiedName entityType = new FullQualifiedName(DEFAULT_CONTAINER, entitySetName);
+
+    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());
+      
+    Map<String, Object> keys = new HashMap<String, Object>();
+    keys.put("Id", "1");
+    //
+    datasource.readData(edmEntitySet, keys);
+  }
+
+  @Test(expected=ODataRuntimeException.class)
+  public void unknownEntitySetForEntities() throws Exception {
+    String entitySetName = "Unknown";
+    FullQualifiedName entityType = new FullQualifiedName(DEFAULT_CONTAINER, entitySetName);
+
+    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());
+      
+    //
+    datasource.readData(edmEntitySet);
+  }
+
+
+  private EdmEntitySet createMockedEdmEntitySet(final String entitySetName) throws ODataException {
+    return createMockedEdmEntitySet(edmProvider, entitySetName);
+  }
+
+  private EdmEntitySet createMockedEdmEntitySet(AnnotationEdmProvider edmProvider, final 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/80dc018d/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/edm/AnnotationEdmProviderTest.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/edm/AnnotationEdmProviderTest.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/edm/AnnotationEdmProviderTest.java
new file mode 100644
index 0000000..7c35fca
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/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.annotation.processor.core.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.annotation.processor.core.model.Building;
+import org.apache.olingo.odata2.annotation.processor.core.model.City;
+import org.apache.olingo.odata2.annotation.processor.core.model.Employee;
+import org.apache.olingo.odata2.annotation.processor.core.model.Location;
+import org.apache.olingo.odata2.annotation.processor.core.model.Manager;
+import org.apache.olingo.odata2.annotation.processor.core.model.ModelSharedConstants;
+import org.apache.olingo.odata2.annotation.processor.core.model.Photo;
+import org.apache.olingo.odata2.annotation.processor.core.model.RefBase;
+import org.apache.olingo.odata2.annotation.processor.core.model.Room;
+import org.apache.olingo.odata2.annotation.processor.core.model.Team;
+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.junit.Test;
+
+/**
+ *
+ */
+public class AnnotationEdmProviderTest {
+
+  private static final String TEST_MODEL_PACKAGE = "org.apache.olingo.odata2.annotation.processor.core.model";
+
+  @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(TEST_MODEL_PACKAGE);
+
+    // 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(final String name) {
+    return new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, name);
+  }
+
+  private void validateAssociation(final 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(final Association association,
+      final String fromRole, final EdmMultiplicity fromMulti, final FullQualifiedName fromType,
+      final String toRole, final EdmMultiplicity toMulti, final 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(final AssociationEnd associationEnd,
+      final String role, final EdmMultiplicity multiplicity, final 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(final NavigationProperty navigationProperty, final String name,
+      final String relationship, final String fromRole, final 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(final NavigationProperty navigationProperty,
+      final String relationship, final String fromRole, final String toRole) {
+    validateNavProperty(navigationProperty, null, relationship, fromRole, toRole);
+  }
+
+  private boolean containsProperty(final List<Property> properties, final String propertyName) {
+    return getProperty(properties, propertyName) != null;
+  }
+
+  private Property getProperty(final List<Property> properties, final String name) {
+    for (Property property : properties) {
+      if (name.equals(property.getName())) {
+        return property;
+      }
+    }
+    return null;
+  }
+
+  private PropertyRef getPropertyRef(final List<PropertyRef> properties, final 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/80dc018d/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Building.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Building.java
new file mode 100644
index 0000000..bc9f54b
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Building.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * 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.core.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 setId(String id) {
+    this.id = 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/80dc018d/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/City.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/City.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/City.java
new file mode 100644
index 0000000..2e630ba
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/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.core.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/80dc018d/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Employee.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Employee.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Employee.java
new file mode 100644
index 0000000..136a2e1
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/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.annotation.processor.core.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/80dc018d/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Location.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Location.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Location.java
new file mode 100644
index 0000000..99f56c9
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/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.core.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/80dc018d/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Manager.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Manager.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Manager.java
new file mode 100644
index 0000000..cd894f0
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/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.annotation.processor.core.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/80dc018d/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/ModelSharedConstants.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/ModelSharedConstants.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/ModelSharedConstants.java
new file mode 100644
index 0000000..bd4d3d4
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/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.core.model;
+
+public interface ModelSharedConstants {
+
+  String NAMESPACE_1 = "RefScenario";
+  String CONTAINER_1 = "DefaultContainer";
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/80dc018d/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Photo.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Photo.java
new file mode 100644
index 0000000..83be665
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/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.core.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) {
+    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/80dc018d/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/RefBase.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/RefBase.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/RefBase.java
new file mode 100644
index 0000000..e998efc
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/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.annotation.processor.core.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(final int id, final String name) {
+    this.name = name;
+    this.id = id;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public String getId() {
+    return Integer.toString(id);
+  }
+
+  public void setName(final String name) {
+    this.name = name;
+  }
+
+  public void setId(final int id) {
+    this.id = id;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/80dc018d/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/ResourceHelper.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/ResourceHelper.java
new file mode 100644
index 0000000..f9e9d88
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/ResourceHelper.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * 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.core.model;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+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(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/80dc018d/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Room.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Room.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Room.java
new file mode 100644
index 0000000..57e42db
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/model/Room.java
@@ -0,0 +1,93 @@
+/*
+ * 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.annotation.processor.core.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() {
+    this(0, null);
+  }
+  
+  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 + "}";
+  }
+}