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/10/10 14:00:44 UTC

[1/3] Initial EdmAnnotation contribution

Updated Branches:
  refs/heads/PocEdmAnnotationsExtension [created] ae7c1f52d


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumerTest.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumerTest.java
new file mode 100644
index 0000000..c588b30
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumerTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.olingo.odata2.core.annotation.processor.json;
+
+import org.apache.olingo.odata2.core.annotation.processor.json.JsonConsumer;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class JsonConsumerTest {
+
+  public static final String SIMPLE_TEAM = "{\"d\":{"
+          + "\"__metadata\":{\"id\":\"https://localhost/Test.svc/Teams('1')\","
+          + "\"uri\":\"https://localhost/Test.svc/Teams('1')\","
+          + "\"type\":\"Test.Team\""
+          + "},"
+          + "\"Id\":\"1\","
+          + "\"Name\":\"Team 1\","
+          + "\"isScrumTeam\":false}}";
+
+  public static final String SIMPLER_TEAM = "{"
+          + "\"d\":{"
+          + "\"Id\":\"1\",\"Name\":\"Team 1\",\"isScrumTeam\":false"
+          + "}}";
+
+  @Test
+  public void simplerRead() throws Exception {
+    InputStream content = encapsulate(SIMPLER_TEAM);
+    JsonConsumer jc = new JsonConsumer(content);
+    Map<String, String> name2Values = jc.read();
+
+//    System.out.println("" + name2Values);
+    Assert.assertEquals(3, name2Values.size());
+
+    Assert.assertEquals("1", name2Values.get("Id"));
+    Assert.assertEquals("Team 1", name2Values.get("Name"));
+    Assert.assertEquals("false", name2Values.get("isScrumTeam"));
+  }
+
+  @Test
+  public void simpleRead() throws Exception {
+    InputStream content = encapsulate(SIMPLE_TEAM);
+    JsonConsumer jc = new JsonConsumer(content);
+    Map<String, String> name2Values = jc.read();
+
+//    System.out.println("" + name2Values);
+    Assert.assertEquals(6, name2Values.size());
+
+    Assert.assertEquals("1", name2Values.get("Id"));
+    Assert.assertEquals("Team 1", name2Values.get("Name"));
+    Assert.assertEquals("false", name2Values.get("isScrumTeam"));
+    
+    Assert.assertEquals("https://localhost/Test.svc/Teams('1')", name2Values.get("md_id"));
+    Assert.assertEquals("https://localhost/Test.svc/Teams('1')", name2Values.get("md_uri"));
+    Assert.assertEquals("Test.Team", name2Values.get("md_type"));
+  }
+
+  public static InputStream encapsulate(final String content) {
+    try {
+      return new ByteArrayInputStream(content.getBytes("UTF-8"));
+    } catch (UnsupportedEncodingException e) {
+      // we know that UTF-8 is supported
+      throw new RuntimeException("UTF-8 MUST be supported.", e);
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/pom.xml b/odata2-edm-annotation/edm-annotation-webref/pom.xml
new file mode 100644
index 0000000..89ae0b4
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/pom.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file 
+distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under 
+the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may 
+obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to 
+in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 
+ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under 
+the License. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>olingo-odata2-edm-annotation-webref-incubating</artifactId>
+  <packaging>war</packaging>
+  <name>${project.artifactId}</name>
+
+  <parent>
+    <groupId>org.apache.olingo</groupId>
+    <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <build>
+    <finalName>${project.artifactId}</finalName>
+    <resources>
+      <resource>
+        <directory>src/main/version</directory>
+        <filtering>true</filtering>
+        <targetPath>../${project.build.finalName}/gen</targetPath>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+      </resource>
+      <resource>
+        <directory>target/maven-shared-archive-resources</directory>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <groupId>com.sap.research</groupId>
+        <artifactId>nwcloud-maven-plugin</artifactId>
+        <version>1.0.0.RELEASE</version>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+
+  </build>
+
+  <dependencies>
+    <dependency>
+      <!-- required because of auto detection of web facet 2.5 -->
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>2.5</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+      <version>${cxf.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-api-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-core-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-edm-annotation-api-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-edm-annotation-core-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <version>1.7.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.glassfish.jersey.containers</groupId>
+      <artifactId>jersey-container-servlet</artifactId>
+      <version>2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.glassfish.jersey.core</groupId>
+      <artifactId>jersey-client</artifactId>
+      <version>2.0</version>
+    </dependency>
+  </dependencies>
+
+  <profiles>
+    <profile>
+      <id>dev</id>
+
+      <build>
+        <defaultGoal>cargo:run</defaultGoal>
+
+        <plugins>
+          <plugin>
+            <groupId>org.codehaus.cargo</groupId>
+            <artifactId>cargo-maven2-plugin</artifactId>
+            <version>1.4.2</version>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
new file mode 100644
index 0000000..4035b24
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/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.ref.annotation.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+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.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.NavigationEnd;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+
+/**
+ *  
+ */
+@EdmEntityType(name="Building", namespace=ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name="Buildings", container="Container1")
+public class Building {
+  @EdmKey
+  @EdmProperty(type = EdmSimpleTypeKind.String)
+  private int id;
+  @EdmProperty
+  private String name;
+  private byte[] image;
+  @EdmNavigationProperty(name="nb_rooms", relationship="BuildingRooms",
+          to = @NavigationEnd(role = "r_Room", type="Room", multiplicity = EdmMultiplicity.MANY))
+  private List<Room> rooms = new ArrayList<Room>();
+
+  public Building() { }
+
+  public Building(final int id, final String name) {
+    this.id = id;
+    setName(name);
+  }
+
+  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 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/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
new file mode 100644
index 0000000..40e030f
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/City.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.ref.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexEntity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+/**
+ *  
+ */
+@EdmComplexEntity(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/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/DataContainer.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/DataContainer.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/DataContainer.java
new file mode 100644
index 0000000..d9974e1
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/DataContainer.java
@@ -0,0 +1,290 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.ref.annotation.model;
+
+import org.apache.olingo.odata2.ref.annotation.model.Building;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.TimeZone;
+
+/**
+ * Container and initialization code for the data objects of the reference scenario.
+ * 
+ */
+public class DataContainer {
+
+  private static final String IMAGE_JPEG = "image/jpeg";
+
+  private List<Employee> employees = new ArrayList<Employee>();
+  private List<Team> teams = new ArrayList<Team>();
+  private List<Room> rooms = new ArrayList<Room>();
+  private List<Manager> managers = new ArrayList<Manager>();
+  private List<Building> buildings = new ArrayList<Building>();
+  private List<Photo> photos = new ArrayList<Photo>();
+  private int employeeId = 0;
+  private int teamId = 0;
+  private int roomId = 0;
+  private int buildingId = 0;
+  private int photoId = 0;
+
+  public void init() {
+    // ------------- Teams ---------------
+    Team team1 = createTeam();
+    team1.setScrumTeam(false);
+    teams.add(team1);
+
+    Team team2 = createTeam();
+    team2.setScrumTeam(true);
+    teams.add(team2);
+
+    Team team3 = createTeam();
+    team3.setScrumTeam(false);
+    teams.add(team3);
+
+    // ------------- Buildings ---------------
+    Building building1 = createBuilding();
+    buildings.add(building1);
+
+    Building building2 = createBuilding();
+    buildings.add(building2);
+
+    Building building3 = createBuilding();
+    buildings.add(building3);
+
+    // ------------- Rooms ---------------
+    Room room1 = createRoom();
+    room1.setSeats(1);
+    room1.setBuilding(building1);
+    building1.getRooms().add(room1);
+    room1.setVersion(1);
+    rooms.add(room1);
+
+    Room room2 = createRoom();
+    room2.setSeats(5);
+    room2.setBuilding(building2);
+    building2.getRooms().add(room2);
+    room2.setVersion(2);
+    rooms.add(room2);
+
+    Room room3 = createRoom();
+    room3.setSeats(2);
+    room3.setBuilding(building2);
+    building2.getRooms().add(room3);
+    room3.setVersion(3);
+    rooms.add(room3);
+
+    for (int i = 4; i <= 103; i++) {
+      Room roomN = createRoom();
+      roomN.setSeats(4 + (i - 3) % 5);
+      roomN.setBuilding(building3);
+      building3.getRooms().add(roomN);
+      roomN.setVersion(1);
+      rooms.add(roomN);
+    }
+
+    // ------------- Employees and Managers ------------
+    Manager emp1 = createManager();
+    emp1.setEmployeeName("Walter Winter");
+    emp1.setAge(52);
+    emp1.setTeam(team1);
+    team1.getEmployees().add(emp1);
+    emp1.setRoom(room1);
+    room1.getEmployees().add(emp1);
+    emp1.setManager(emp1);
+    emp1.getEmployees().add(emp1);
+    emp1.setLocation(new Location("Germany", "69124", "Heidelberg"));
+    emp1.setEntryDate(generateDate(1999, 1, 1));
+    emp1.setImageUri("Employees('1')/$value");
+    emp1.setImage("/male_1_WinterW.jpg");
+    emp1.setImageType(IMAGE_JPEG);
+    employees.add(emp1);
+    managers.add(emp1);
+
+    Employee emp2 = createEmployee();
+    emp2.setEmployeeName("Frederic Fall");
+    emp2.setAge(32);
+    emp2.setTeam(team1);
+    team1.getEmployees().add(emp2);
+    emp2.setRoom(room2);
+    room2.getEmployees().add(emp2);
+    emp2.setManager(emp1);
+    emp1.getEmployees().add(emp2);
+    emp2.setLocation(new Location("Germany", "69190", "Walldorf"));
+    emp2.setEntryDate(generateDate(2003, 7, 1));
+    emp2.setImageUri("Employees('2')/$value");
+    emp2.setImage("/male_2_FallF.jpg");
+    emp2.setImageType(IMAGE_JPEG);
+    employees.add(emp2);
+
+    Manager emp3 = createManager();
+    emp3.setEmployeeName("Jonathan Smith");
+    emp3.setAge(56);
+    emp3.setTeam(team1);
+    team1.getEmployees().add(emp3);
+    emp3.setRoom(room2);
+    room2.getEmployees().add(emp3);
+    emp3.setManager(emp1);
+    emp1.getEmployees().add(emp3);
+    emp3.setLocation(emp2.getLocation());
+    emp3.setEntryDate(null);
+    emp3.setImageUri("Employees('3')/$value");
+    emp3.setImage("/male_3_SmithJo.jpg");
+    emp3.setImageType(IMAGE_JPEG);
+    employees.add(emp3);
+    managers.add(emp3);
+
+    Employee emp4 = createEmployee();
+    emp4.setEmployeeName("Peter Burke");
+    emp4.setAge(39);
+    emp4.setTeam(team2);
+    team2.getEmployees().add(emp4);
+    emp4.setRoom(room2);
+    room2.getEmployees().add(emp4);
+    emp4.setManager(emp3);
+    emp3.getEmployees().add(emp4);
+    emp4.setLocation(emp2.getLocation());
+    emp4.setEntryDate(generateDate(2004, 9, 12));
+    emp4.setImageUri("Employees('4')/$value");
+    emp4.setImage("/male_4_BurkeP.jpg");
+    emp4.setImageType(IMAGE_JPEG);
+    employees.add(emp4);
+
+    Employee emp5 = createEmployee();
+    emp5.setEmployeeName("John Field");
+    emp5.setAge(42);
+    emp5.setTeam(team2);
+    team2.getEmployees().add(emp5);
+    emp5.setRoom(room3);
+    room3.getEmployees().add(emp5);
+    emp5.setManager(emp3);
+    emp3.getEmployees().add(emp5);
+    emp5.setLocation(emp2.getLocation());
+    emp5.setEntryDate(generateDate(2001, 2, 1));
+    emp5.setImageUri("Employees('5')/$value");
+    emp5.setImage("/male_5_FieldJ.jpg");
+    emp5.setImageType(IMAGE_JPEG);
+    employees.add(emp5);
+
+    Employee emp6 = createEmployee();
+    emp6.setEmployeeName("Susan Bay");
+    emp6.setAge(29);
+    emp6.setTeam(team3);
+    team3.getEmployees().add(emp6);
+    emp6.setRoom(room2);
+    room2.getEmployees().add(emp6);
+    emp6.setManager(emp1);
+    emp1.getEmployees().add(emp6);
+    emp6.setLocation(emp2.getLocation());
+    emp6.setEntryDate(generateDate(2010, 12, 1));
+    emp6.setImageUri("Employees('6')/$value");
+    emp6.setImage("/female_6_BaySu.jpg");
+    emp6.setImageType(IMAGE_JPEG);
+    employees.add(emp6);
+
+    // ------------- Photos ---------------
+    Photo photo1 = createPhoto("image/png");
+    photo1.setContent("Образ");
+    photos.add(photo1);
+
+    Photo photo2 = createPhoto("image/bmp");
+    photos.add(photo2);
+
+    Photo photo3 = createPhoto(IMAGE_JPEG);
+    photos.add(photo3);
+
+    Photo photo4 = createPhoto("foo");
+    photo4.setContent("Продукт");
+    photos.add(photo4);
+  }
+
+  private Calendar generateDate(final int year, final int month, final int day) {
+    Calendar date = Calendar.getInstance();
+
+    date.clear();
+    date.setTimeZone(TimeZone.getTimeZone("GMT"));
+    date.set(year, month - 1, day); // month is zero-based!
+    return date;
+  }
+
+  public Employee createEmployee() {
+    return new Employee(++employeeId, "Employee " + employeeId);
+  }
+
+  public Team createTeam() {
+    return new Team(++teamId, "Team " + teamId);
+  }
+
+  public Room createRoom() {
+    return new Room(++roomId, "Room " + roomId);
+  }
+
+  public Manager createManager() {
+    return new Manager(++employeeId, "Employee " + employeeId);
+  }
+
+  public Building createBuilding() {
+    return new Building(++buildingId, "Building " + buildingId);
+  }
+
+  public Photo createPhoto(final String type) {
+    return new Photo(++photoId, "Photo " + photoId, type);
+  }
+
+  public List<Employee> getEmployees() {
+    return employees;
+  }
+
+  public List<Team> getTeams() {
+    return teams;
+  }
+
+  public List<Room> getRooms() {
+    return rooms;
+  }
+
+  public List<Manager> getManagers() {
+    return managers;
+  }
+
+  public List<Building> getBuildings() {
+    return buildings;
+  }
+
+  public List<Photo> getPhotos() {
+    return photos;
+  }
+
+  public void reset() {
+    employees.clear();
+    teams.clear();
+    rooms.clear();
+    managers.clear();
+    buildings.clear();
+    photos.clear();
+
+    employeeId = 0;
+    teamId = 0;
+    roomId = 0;
+    buildingId = 0;
+    photoId = 0;
+
+    init();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
new file mode 100644
index 0000000..0ef9e3b
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.ref.annotation.model;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+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.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.NavigationEnd;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+
+/**
+ *  
+ */
+@EdmEntityType(name="Employee", namespace=ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name="Employees", container=ModelSharedConstants.CONTAINER_1)
+public class Employee {
+  private static int counter = 1;
+  @EdmProperty(name="EmployeeId", type = EdmSimpleTypeKind.Int32)
+  @EdmKey
+  private int employeeId;
+  @EdmProperty(name="EmployeeName")
+  private String employeeName;
+  @EdmProperty
+  private int age;
+  @EdmNavigationProperty(name="ne_Manager", relationship="ManagerEmployees",
+          from = @NavigationEnd(role="r_Employees", multiplicity = EdmMultiplicity.MANY))//,
+//          to = @NavigationEnd(type = "Manager"))
+  private Manager manager;
+  private Team team;
+  private Room room;
+  private String imageType;
+  private byte[] image;
+  private String imageUrl;
+  private Calendar entryDate;
+  @EdmComplexProperty(name="Location")
+  private Location location;
+
+  public Employee(final int employeeId, final String name) {
+    this.employeeId = employeeId;
+    setEmployeeName(name);
+  }
+
+  public String getId() {
+    return Integer.toString(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() {
+    return employeeId;
+  }
+
+  @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/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
new file mode 100644
index 0000000..f63e8a4
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Location.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.ref.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexEntity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+/**
+ *  
+ */
+@EdmComplexEntity(name = "c_Location", namespace = ModelSharedConstants.NAMESPACE_1)
+public class Location {
+  @EdmProperty
+  private String country;
+  @EdmComplexProperty
+  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/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
new file mode 100644
index 0000000..521c43d
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Manager.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.ref.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.NavigationEnd;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Manager", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Managers", container = ModelSharedConstants.CONTAINER_1)
+public class Manager extends Employee {
+
+  @EdmNavigationProperty(name = "nm_Employees", relationship = "ManagerEmployees",
+          to = @NavigationEnd(role = "r_Employees", type = "Employee"))
+  private List<Employee> employees = new ArrayList<Employee>();
+
+  public Manager(final int 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/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelException.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelException.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelException.java
new file mode 100644
index 0000000..3b6d033
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelException.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.ref.annotation.model;
+
+/**
+ *  
+ */
+public class ModelException extends RuntimeException {
+
+  private static final long serialVersionUID = 1L;
+
+  public ModelException(final Exception e) {
+    super(e);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
new file mode 100644
index 0000000..ab17fbb
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ModelSharedConstants.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.ref.annotation.model;
+
+public interface ModelSharedConstants {
+
+  String NAMESPACE_1 = "RefScenario";
+  String CONTAINER_1 = "Container1";
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
new file mode 100644
index 0000000..92d1ac6
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.ref.annotation.model;
+
+import java.util.Arrays;
+
+/**
+ *  
+ */
+public class Photo {
+  private static final String RESOURCE = "/male_1_WinterW.jpg";
+  private static byte[] defaultImage = ResourceHelper.loadAsByte(RESOURCE);
+
+  private final int id;
+  private String name;
+  private String type = "image/jpeg";
+  private String imageUrl = "http://localhost" + RESOURCE;
+  private byte[] image = defaultImage;
+  private String imageType = type;
+  private byte[] binaryData;
+  private String content;
+
+  public Photo(final int id, final String name, final String type) {
+    this.id = id;
+    setName(name);
+    setType(type);
+  }
+
+  public int getId() {
+    return id;
+  }
+
+  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 imageType;
+  }
+
+  public void setImageType(final String imageType) {
+    this.imageType = imageType;
+  }
+
+  public byte[] getBinaryData() {
+    if (binaryData == null) {
+      return null;
+    } else {
+      return binaryData.clone();
+    }
+  }
+
+  public void setBinaryData(final byte[] binaryData) {
+    this.binaryData = binaryData;
+  }
+
+  public void setContent(final String content) {
+    this.content = content;
+  }
+
+  public String getContent() {
+    return content;
+  }
+
+  @Override
+  public int hashCode() {
+    return id;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+        || obj != null && getClass() == obj.getClass() && id == ((Photo) obj).id;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"Id\":" + id + ","
+        + "\"Name\":\"" + name + "\","
+        + "\"Type\":\"" + type + "\","
+        + "\"ImageUrl\":\"" + imageUrl + "\","
+        + "\"Image\":\"" + Arrays.toString(image) + "\","
+        + "\"ImageType\":\"" + imageType + "\","
+        + "\"Content:\"" + content + "\","
+        + "\"BinaryData\":\"" + Arrays.toString(binaryData) + "\"}";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
new file mode 100644
index 0000000..82d9812
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.ref.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+
+/**
+ *
+ */
+@EdmEntityType(name="Base", namespace=ModelSharedConstants.NAMESPACE_1)
+public abstract class RefBase {
+  @EdmProperty(name="Name")
+  protected String name;
+  @EdmProperty(name="Id", type = EdmSimpleTypeKind.String)
+  @EdmKey
+  protected int id;
+
+  public RefBase(int id, String name) {
+    this.name = name;
+    this.id = id;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public String getId() {
+    return Integer.toString(id);
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public void setId(int id) {
+    this.id = id;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
new file mode 100644
index 0000000..adc5f11
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ResourceHelper.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.ref.annotation.model;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author d046871
+ */
+class ResourceHelper {
+
+  public static byte[] loadAsByte(String resource) {
+    return load(resource, new byte[0]);
+  }
+
+  public static byte[] load(String resource, byte[] defaultResult) {
+    InputStream instream = null;
+    try {
+      instream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
+      if (instream == null) {
+        return defaultResult;
+      }
+      ByteArrayOutputStream stream = new ByteArrayOutputStream();
+      int b = 0;
+      while ((b = instream.read()) != -1) {
+        stream.write(b);
+      }
+
+      return stream.toByteArray();
+    } catch (IOException e) {
+      throw new ModelException(e);
+    } finally {
+      if(instream != null) {
+        try {
+          instream.close();
+        } catch (IOException ex) { }
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
new file mode 100644
index 0000000..2feb5cd
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.ref.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+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.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.NavigationEnd;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Room", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Rooms", container = ModelSharedConstants.CONTAINER_1)
+public class Room extends RefBase {
+
+  @EdmProperty
+  private Integer seats;
+  @EdmProperty
+  private Integer version;
+  @EdmNavigationProperty(name="nr_Building", relationship="BuildingRooms",
+          from = @NavigationEnd(role="r_Room", multiplicity = EdmMultiplicity.MANY))
+  private Building building;
+  @EdmNavigationProperty(name="nr_Employees", relationship="RoomEmployees", 
+          from = @NavigationEnd(role = "r_Room", type = "Room", multiplicity = EdmMultiplicity.ONE),
+          to = @NavigationEnd(role = "r_Employees", type = "Employee", multiplicity = EdmMultiplicity.MANY))
+  private List<Employee> employees = new ArrayList<Employee>();
+
+  public Room(final int id, final String name) {
+    super(id, name);
+  }
+
+  public void setSeats(final int seats) {
+    this.seats = seats;
+  }
+
+  public int getSeats() {
+    return seats;
+  }
+
+  public void setVersion(final int version) {
+    this.version = version;
+  }
+
+  public int getVersion() {
+    return version;
+  }
+
+  public void setBuilding(final Building building) {
+    this.building = building;
+  }
+
+  public Building getBuilding() {
+    return building;
+  }
+
+  public List<Employee> getEmployees() {
+    return employees;
+  }
+
+  @Override
+  public int hashCode() {
+    return id;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+            || obj != null && getClass() == obj.getClass() && id == ((Room) obj).id;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Seats\":" + seats + ",\"Version\":" + version + "}";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
new file mode 100644
index 0000000..b805b77
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.ref.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+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.NavigationEnd;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+
+/**
+*  
+*/
+@EdmEntityType(name="Team", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name="Teams", container = ModelSharedConstants.CONTAINER_1)
+public class Team extends RefBase {
+  @EdmProperty(type = EdmSimpleTypeKind.Boolean)
+  private Boolean isScrumTeam;
+  @EdmNavigationProperty(name = "ne_Teams", relationship="TeamEmployees", 
+          from = @NavigationEnd(role = "r_Team",  type = "Team"),
+          to = @NavigationEnd(role = "r_Employees", type = "Employee", multiplicity = EdmMultiplicity.MANY))
+  private List<Employee> employees = new ArrayList<Employee>();
+
+  public Team() {
+    super(-1, null);
+  }
+  
+  public Team(final int id, final String name) {
+    super(id, name);
+  }
+
+  public Boolean isScrumTeam() {
+    return isScrumTeam;
+  }
+
+  public void setScrumTeam(final Boolean isScrumTeam) {
+    this.isScrumTeam = isScrumTeam;
+  }
+  
+  public void addEmployee(Employee e) {
+    this.employees.add(e);
+  }
+
+  public List<Employee> getEmployees() {
+    return employees;
+  }
+
+  @Override
+  public int hashCode() {
+    return id;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+        || obj != null && getClass() == obj.getClass() && id == ((Team) obj).id;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"IsScrumTeam\":" + isScrumTeam + "}";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ds/BuildingDs.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ds/BuildingDs.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ds/BuildingDs.java
new file mode 100644
index 0000000..282bb4f
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ds/BuildingDs.java
@@ -0,0 +1,67 @@
+/*
+ * 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.ref.annotation.model.ds;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityCreate;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDataSource;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDelete;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityRead;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntitySetRead;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityUpdate;
+import org.apache.olingo.odata2.ref.annotation.model.Building;
+
+/**
+ *
+ */
+@EntityDataSource(name="BuildingDataSource", entityType = Building.class)
+public class BuildingDs {
+  
+  private static int idCounter = 1;
+  private final static Map<Integer, Building> id2Building = new HashMap<Integer, Building>();
+
+  @EntityRead
+  public Building read(String id) {
+    return id2Building.get(Integer.valueOf(id));
+  }
+  
+  @EntitySetRead
+  public Collection<Building> read() {
+    return id2Building.values();
+  }
+    
+  @EntityCreate
+  @EntityUpdate
+  public Building createOrUpdate(Building building) {
+    Building b = id2Building.get(Integer.valueOf(building.getId()));
+    if(b != null) {
+      b.setName(building.getName());
+    } else {      
+      final int id = idCounter++;
+      b = new Building(id, building.getName());
+      id2Building.put(Integer.valueOf(id), b);
+    }
+    return b;    
+  }
+  
+  @EntityDelete
+  public Building delete(String id) {
+    return id2Building.remove(Integer.valueOf(id));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ds/TeamDs.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ds/TeamDs.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ds/TeamDs.java
new file mode 100644
index 0000000..9426c7b
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/ds/TeamDs.java
@@ -0,0 +1,66 @@
+/*
+ * 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.ref.annotation.model.ds;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityRead;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDataSource;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityCreate;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntitySetRead;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityUpdate;
+import org.apache.olingo.odata2.ref.annotation.model.Team;
+
+/**
+ *
+ */
+@EntityDataSource(name="TeamDataSource", entityType = Team.class)
+public class TeamDs {
+  
+  private static int idCounter = 1;
+  private static final Map<Integer, Team> id2Team = new HashMap<Integer, Team>();
+
+  @EntityRead
+  public Team readTeam(String id) {
+    return id2Team.get(Integer.valueOf(id));
+  }
+  
+  @EntitySetRead
+  public Collection<Team> readAllTeams() {
+    return id2Team.values();
+  }
+  
+  @EntityCreate
+  public Team writeTeam(Team team) {
+    final int id = idCounter++;
+    team.setId(id);
+    id2Team.put(Integer.valueOf(id), team);
+
+    return team;
+  }
+  
+  @EntityUpdate
+  public Team update(Team team) {
+    Team t = id2Team.get(Integer.valueOf(team.getId()));
+    if(t != null) {
+      t.setName(team.getName());
+      t.setScrumTeam(team.isScrumTeam());
+    }
+    return team;    
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/ScenarioErrorCallback.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/ScenarioErrorCallback.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/ScenarioErrorCallback.java
new file mode 100644
index 0000000..45a4f81
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/ScenarioErrorCallback.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.ref.annotation.processor;
+
+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.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;
+
+/**
+ * Callback for handling errors by logging internal server errors additionally.
+ * 
+ */
+public class ScenarioErrorCallback implements ODataErrorCallback {
+
+  private static 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);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/ScenarioServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/ScenarioServiceFactory.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/ScenarioServiceFactory.java
new file mode 100644
index 0000000..7ff3ee4
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/ScenarioServiceFactory.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.ref.annotation.processor;
+
+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.exception.ODataException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.core.annotation.edm.AnnotationEdmProvider;
+import org.apache.olingo.odata2.core.annotation.processor.AnnotationProcessor;
+import org.apache.olingo.odata2.ref.annotation.model.Building;
+import org.apache.olingo.odata2.ref.annotation.model.Team;
+import org.apache.olingo.odata2.ref.annotation.model.ds.BuildingDs;
+import org.apache.olingo.odata2.ref.annotation.model.ds.TeamDs;
+
+/**
+ *
+ */
+public class ScenarioServiceFactory extends ODataServiceFactory {
+
+  private static boolean isInitialized = false;
+  
+  @Override
+  public ODataService createService(final ODataContext context) throws ODataException {
+    if(!isInitialized) {
+      initializeSampleData();
+      isInitialized = true;
+    }
+
+    return createODataSingleProcessorService(
+            new AnnotationEdmProvider("org.apache.olingo.odata2.ref.annotation.model"),
+            new AnnotationProcessor(context, "org.apache.olingo.odata2.ref.annotation.model"));
+  }
+
+  @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));
+  }
+
+
+  private final class ScenarioDebugCallback implements ODataDebugCallback {
+
+    @Override
+    public boolean isDebugEnabled() {
+      return true;
+    }
+  }
+  
+  
+  private void initializeSampleData() {
+    TeamDs teamDs = new TeamDs();
+    teamDs.writeTeam(createTeam("Team Alpha", true));
+    teamDs.writeTeam(createTeam("Team Beta", false));
+    teamDs.writeTeam(createTeam("Team Gamma", false));
+    teamDs.writeTeam(createTeam("Team Omega", true));
+    teamDs.writeTeam(createTeam("Team Zeta", true));
+    
+    BuildingDs buildingsDs = new BuildingDs();
+    buildingsDs.createOrUpdate(createBuilding("Red Building"));
+    buildingsDs.createOrUpdate(createBuilding("Green Building"));
+    buildingsDs.createOrUpdate(createBuilding("Blue Building"));
+  }
+
+  private Team createTeam(String teamName, boolean isScrumTeam) {
+    Team team = new Team();
+    team.setName(teamName);
+    team.setScrumTeam(isScrumTeam);
+    return team;
+  }
+
+  private Building createBuilding(String buildingName) {
+    Building b = new Building();
+    b.setName(buildingName);
+    return b;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/resources/log4j.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/resources/log4j.xml b/odata2-edm-annotation/edm-annotation-webref/src/main/resources/log4j.xml
new file mode 100644
index 0000000..90a4706
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/resources/log4j.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+         or more contributor license agreements.  See the NOTICE file
+         distributed with this work for additional information
+         regarding copyright ownership.  The ASF licenses this file
+         to you under the Apache License, Version 2.0 (the
+         "License"); you may not use this file except in compliance
+         with the License.  You may obtain a copy of the License at
+  
+           http://www.apache.org/licenses/LICENSE-2.0
+  
+         Unless required by applicable law or agreed to in writing,
+         software distributed under the License is distributed on an
+         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+         KIND, either express or implied.  See the License for the
+         specific language governing permissions and limitations
+         under the License.
+-->
+<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+    <appender name="console" class="org.apache.log4j.ConsoleAppender">
+        <param name="Target" value="System.out" />
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%-5p %c{1} - %m%n" />
+        </layout>
+    </appender>
+
+    <logger name="org.apache.olingo.odata2.ref" additivity="false">
+        <level value="trace" />
+        <appender-ref ref="console" />
+    </logger>
+    
+    <root>
+        <priority value="error" />
+        <appender-ref ref="console" />
+    </root>
+</log4j:configuration>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/version/version.html
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/version/version.html b/odata2-edm-annotation/edm-annotation-webref/src/main/version/version.html
new file mode 100644
index 0000000..6d76d0b
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/version/version.html
@@ -0,0 +1,27 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<table border="1">
+<tr><td>name</td><td>${name}</td></tr>
+<tr><td>version</td><td>${version}</td></tr>
+<tr><td>timestamp</td><td>${timestamp}</td></tr>
+<tr><td>project.build.finalName</td><td>${project.build.finalName}</td></tr>
+</table>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/META-INF/context.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/META-INF/context.xml b/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/META-INF/context.xml
new file mode 100644
index 0000000..1b76b24
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/META-INF/context.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Context antiJARLocking="true" path="/olingo.odata2.edm.annotation.refweb"/>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/WEB-INF/web.xml b/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..1795259
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+         or more contributor license agreements.  See the NOTICE file
+         distributed with this work for additional information
+         regarding copyright ownership.  The ASF licenses this file
+         to you under the Apache License, Version 2.0 (the
+         "License"); you may not use this file except in compliance
+         with the License.  You may obtain a copy of the License at
+  
+           http://www.apache.org/licenses/LICENSE-2.0
+  
+         Unless required by applicable law or agreed to in writing,
+         software distributed under the License is distributed on an
+         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+         KIND, either express or implied.  See the License for the
+         specific language governing permissions and limitations
+         under the License.
+-->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+	id="WebApp_ID" version="2.5">
+	<display-name>org.apache.olingo.odata2.ref.annotations.web</display-name>
+	<welcome-file-list>
+		<welcome-file>index.jsp</welcome-file>
+	</welcome-file-list>
+	
+	<servlet>
+		<servlet-name>ReferenceScenarioServlet</servlet-name>
+		<servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
+		<init-param>
+			<param-name>javax.ws.rs.Application</param-name>
+			<param-value>org.apache.olingo.odata2.core.rest.app.ODataApplication</param-value>
+		</init-param>
+		<init-param>
+			<param-name>org.apache.olingo.odata2.service.factory</param-name>
+			<param-value>org.apache.olingo.odata2.ref.annotation.processor.ScenarioServiceFactory</param-value>
+		</init-param>
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+
+	<servlet-mapping>
+		<servlet-name>ReferenceScenarioServlet</servlet-name>
+		<url-pattern>/ReferenceScenario.svc/*</url-pattern>
+	</servlet-mapping>
+
+</web-app>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp b/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp
new file mode 100644
index 0000000..3ffc551
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp
@@ -0,0 +1,111 @@
+<%@ page language="java" contentType="text/html; UTF-8" pageEncoding="UTF-8"%>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+         or more contributor license agreements.  See the NOTICE file
+         distributed with this work for additional information
+         regarding copyright ownership.  The ASF licenses this file
+         to you under the Apache License, Version 2.0 (the
+         "License"); you may not use this file except in compliance
+         with the License.  You may obtain a copy of the License at
+  
+           http://www.apache.org/licenses/LICENSE-2.0
+  
+         Unless required by applicable law or agreed to in writing,
+         software distributed under the License is distributed on an
+         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+         KIND, either express or implied.  See the License for the
+         specific language governing permissions and limitations
+         under the License.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<title>Apache Olingo - OData2 Library</title>
+<style type="text/css">
+body { font-family: Arial, sans-serif; font-size: 13px; line-height: 18px;
+       color: blue; background-color: #ffffff; }
+a { color: blue; text-decoration: none; }
+a:focus { outline: thin dotted #4076cb; outline-offset: -1px; }
+a:hover, a:active { outline: 0; }
+a:hover { color: #404a7e; text-decoration: underline; }
+h1, h2, h3, h4, h5, h6 { margin: 9px 0; font-family: inherit; font-weight: bold;
+                         line-height: 1; color: blue; }
+h1 { font-size: 36px; line-height: 40px; }
+h2 { font-size: 30px; line-height: 40px; }
+h3 { font-size: 24px; line-height: 40px; }
+h4 { font-size: 18px; line-height: 20px; }
+h5 { font-size: 14px; line-height: 20px; }
+h6 { font-size: 12px; line-height: 20px; }
+.logo { float: right; }
+ul { padding: 0; margin: 0 0 9px 25px; }
+ul ul { margin-bottom: 0; }
+li { line-height: 18px; }
+hr { margin: 18px 0;
+     border: 0; border-top: 1px solid #cccccc; border-bottom: 1px solid #ffffff; }
+table { border-collapse: collapse; border-spacing: 10px; }
+th, td { border: 1px solid; padding: 20px; }
+.code { font-family: "Courier New", monospace; font-size: 13px; line-height: 18px; }
+</style>
+</head>
+<body>
+	<h1>Apache Olingo - OData2 Library</h1>
+	<hr />
+	<h2>Reference Scenario</h2>
+	<table>
+		<tr>
+			<td valign="top">
+				<h3>Service Document and Metadata</h3>
+				<ul>
+					<li><a href="ReferenceScenario.svc?_wadl" target="_blank">wadl</a></li>
+					<li><a href="ReferenceScenario.svc/" target="_blank">service
+							document</a></li>
+					<li><a href="ReferenceScenario.svc/$metadata" target="_blank">metadata</a></li>
+				</ul>
+				<h3>EntitySets</h3>
+				<ul>
+					<li><a href="ReferenceScenario.svc/Employees" target="_blank">Employees</a></li>
+					<li><a href="ReferenceScenario.svc/Managers" target="_blank">Managers</a></li>
+					<li><a href="ReferenceScenario.svc/Buildings" target="_blank">Buildings</a></li>
+					<li><a href="ReferenceScenario.svc/Rooms" target="_blank">Rooms</a></li>
+					<li><a href="ReferenceScenario.svc/Container2.Photos"
+						target="_blank">Container2.Photos</a></li>
+				</ul>
+				<h3>Entities</h3>
+				<ul>
+					<li><a href="ReferenceScenario.svc/Employees('1')"
+						target="_blank">Employees('1')</a></li>
+					<li><a href="ReferenceScenario.svc/Managers('1')"
+						target="_blank">Managers('1')</a></li>
+					<li><a href="ReferenceScenario.svc/Buildings('1')"
+						target="_blank">Buildings('1')</a></li>
+					<li><a href="ReferenceScenario.svc/Rooms('1')" target="_blank">Rooms('1')</a></li>
+ 					<li><a href="ReferenceScenario.svc/Container2.Photos(Id=4,Type='foo')"
+                           target="_blank">Container2.Photos(Id=4,Type='foo')</a></li>
+				</ul>
+			</td>
+			<td valign="top">
+				&nbsp;
+			</td>
+			<td valign="bottom">
+				<div class="code">
+					<%
+					  String version = "gen/version.html";
+					%>
+					<%
+					  try {
+					%>
+					<jsp:include page='<%=version%>' />
+					<%
+					  } catch (Exception e) {
+					%>
+					<p>IDE Build</p>
+					<%
+					  }
+					%>
+				</div>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/pom.xml b/odata2-edm-annotation/pom.xml
new file mode 100644
index 0000000..436576f
--- /dev/null
+++ b/odata2-edm-annotation/pom.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file 
+    distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under 
+    the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may 
+    obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to 
+    in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 
+    ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under 
+    the License. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.olingo</groupId>
+    <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
+    <packaging>pom</packaging>
+    <name>${project.artifactId}</name>
+
+    <parent>
+        <groupId>org.apache.olingo</groupId>
+        <artifactId>olingo-odata2-parent-incubating</artifactId>
+        <version>1.1.0-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <modules>
+        <module>edm-annotation-api</module>
+        <module>edm-annotation-core</module>
+        <module>edm-annotation-webref</module>
+    </modules>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 0bf73f2..3a35a67 100644
--- a/pom.xml
+++ b/pom.xml
@@ -75,6 +75,7 @@
     <modules>
         <module>odata2-lib</module>
         <module>odata2-processor-jpa</module>
+        <module>odata2-edm-annotation</module>
         <module>odata2-dist</module>
     </modules>
 


[3/3] git commit: Initial EdmAnnotation contribution

Posted by mi...@apache.org.
Initial EdmAnnotation contribution


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

Branch: refs/heads/PocEdmAnnotationsExtension
Commit: ae7c1f52d812cd70354a9933e3b3cb3d61aa3186
Parents: 7ef5a9b
Author: Michael Bolz <mi...@sap.com>
Authored: Wed Oct 9 21:37:03 2013 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Thu Oct 10 13:49:47 2013 +0200

----------------------------------------------------------------------
 .gitignore                                      |   1 +
 .../edm-annotation-api/pom.xml                  |  42 ++
 .../api/annotation/edm/EdmComplexEntity.java    |  31 +
 .../api/annotation/edm/EdmComplexProperty.java  |  32 +
 .../odata2/api/annotation/edm/EdmEntitySet.java |  31 +
 .../api/annotation/edm/EdmEntityType.java       |  31 +
 .../odata2/api/annotation/edm/EdmKey.java       |  29 +
 .../annotation/edm/EdmNavigationProperty.java   |  36 +
 .../odata2/api/annotation/edm/EdmProperty.java  |  33 +
 .../odata2/api/annotation/edm/Facets.java       |  36 +
 .../api/annotation/edm/NavigationEnd.java       |  34 +
 .../api/annotation/edm/ds/EntityCreate.java     |  29 +
 .../api/annotation/edm/ds/EntityDataSource.java |  32 +
 .../api/annotation/edm/ds/EntityDelete.java     |  29 +
 .../api/annotation/edm/ds/EntityRead.java       |  29 +
 .../api/annotation/edm/ds/EntitySetRead.java    |  29 +
 .../api/annotation/edm/ds/EntityUpdate.java     |  29 +
 .../edm-annotation-core/pom.xml                 |  41 ++
 .../annotation/edm/AnnotationEdmProvider.java   | 737 +++++++++++++++++++
 .../core/annotation/edm/AnnotationHelper.java   |  62 ++
 .../odata2/core/annotation/edm/ClassHelper.java | 104 +++
 .../processor/AnnotationProcessor.java          | 439 +++++++++++
 .../processor/json/EdmAnnotationSerializer.java | 215 ++++++
 .../annotation/processor/json/JsonConsumer.java | 136 ++++
 .../annotation/processor/json/JsonWriter.java   | 256 +++++++
 .../src/main/resources/log4j.xml                |  39 +
 .../edm/AnnotationEdmProviderTest.java          | 318 ++++++++
 .../odata2/core/annotation/model/Building.java  | 100 +++
 .../odata2/core/annotation/model/City.java      |  61 ++
 .../odata2/core/annotation/model/Employee.java  | 181 +++++
 .../odata2/core/annotation/model/Location.java  |  61 ++
 .../odata2/core/annotation/model/Manager.java   |  46 ++
 .../annotation/model/ModelSharedConstants.java  |  25 +
 .../odata2/core/annotation/model/Photo.java     | 130 ++++
 .../odata2/core/annotation/model/RefBase.java   |  55 ++
 .../odata2/core/annotation/model/Room.java      |  93 +++
 .../odata2/core/annotation/model/Team.java      |  83 +++
 .../processor/json/JsonConsumerTest.java        |  85 +++
 .../edm-annotation-webref/pom.xml               | 125 ++++
 .../odata2/ref/annotation/model/Building.java   |  99 +++
 .../odata2/ref/annotation/model/City.java       |  61 ++
 .../ref/annotation/model/DataContainer.java     | 290 ++++++++
 .../odata2/ref/annotation/model/Employee.java   | 189 +++++
 .../odata2/ref/annotation/model/Location.java   |  61 ++
 .../odata2/ref/annotation/model/Manager.java    |  46 ++
 .../ref/annotation/model/ModelException.java    |  32 +
 .../annotation/model/ModelSharedConstants.java  |  25 +
 .../odata2/ref/annotation/model/Photo.java      | 131 ++++
 .../odata2/ref/annotation/model/RefBase.java    |  57 ++
 .../ref/annotation/model/ResourceHelper.java    |  61 ++
 .../odata2/ref/annotation/model/Room.java       |  97 +++
 .../odata2/ref/annotation/model/Team.java       |  83 +++
 .../ref/annotation/model/ds/BuildingDs.java     |  67 ++
 .../odata2/ref/annotation/model/ds/TeamDs.java  |  66 ++
 .../processor/ScenarioErrorCallback.java        |  47 ++
 .../processor/ScenarioServiceFactory.java       |  97 +++
 .../src/main/resources/log4j.xml                |  39 +
 .../src/main/version/version.html               |  27 +
 .../src/main/webapp/META-INF/context.xml        |   2 +
 .../src/main/webapp/WEB-INF/web.xml             |  48 ++
 .../src/main/webapp/index.jsp                   | 111 +++
 odata2-edm-annotation/pom.xml                   |  30 +
 pom.xml                                         |   1 +
 63 files changed, 5672 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 9c201f5..3f1a76b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ bin
 *.bak
 classes
 .DS_Store
+nb-configuration.xml

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/pom.xml b/odata2-edm-annotation/edm-annotation-api/pom.xml
new file mode 100644
index 0000000..5d697f2
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+         or more contributor license agreements.  See the NOTICE file
+         distributed with this work for additional information
+         regarding copyright ownership.  The ASF licenses this file
+         to you under the Apache License, Version 2.0 (the
+         "License"); you may not use this file except in compliance
+         with the License.  You may obtain a copy of the License at
+  
+           http://www.apache.org/licenses/LICENSE-2.0
+  
+         Unless required by applicable law or agreed to in writing,
+         software distributed under the License is distributed on an
+         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+         KIND, either express or implied.  See the License for the
+         specific language governing permissions and limitations
+         under the License.
+-->
+<project
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+  xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+	
+  <parent>
+    <groupId>org.apache.olingo</groupId>
+    <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <artifactId>olingo-odata2-edm-annotation-api-incubating</artifactId>
+  <name>${project.artifactId}</name>
+        
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-api-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexEntity.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexEntity.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexEntity.java
new file mode 100644
index 0000000..adec2d7
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexEntity.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface EdmComplexEntity {
+  String name() default "";
+  String namespace();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexProperty.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexProperty.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexProperty.java
new file mode 100644
index 0000000..3af0227
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexProperty.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface EdmComplexProperty {
+  String name() default "";
+  String namespace() default "";
+  String facet() default "";
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntitySet.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntitySet.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntitySet.java
new file mode 100644
index 0000000..b62d986
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntitySet.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface EdmEntitySet {
+  String name();
+  String container();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntityType.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntityType.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntityType.java
new file mode 100644
index 0000000..67a363d
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntityType.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface EdmEntityType {
+  String name() default "";
+  String namespace();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmKey.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmKey.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmKey.java
new file mode 100644
index 0000000..48db91f
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmKey.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface EdmKey {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmNavigationProperty.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmNavigationProperty.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmNavigationProperty.java
new file mode 100644
index 0000000..cf898df
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmNavigationProperty.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface EdmNavigationProperty {
+  String name();
+  String relationship();
+  
+  //
+  NavigationEnd from() default @NavigationEnd;
+  NavigationEnd to() default @NavigationEnd;
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmProperty.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmProperty.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmProperty.java
new file mode 100644
index 0000000..68c411b
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmProperty.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface EdmProperty {
+  EdmSimpleTypeKind type() default EdmSimpleTypeKind.Null;
+  String name() default "";
+  String facet() default "";
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/Facets.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/Facets.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/Facets.java
new file mode 100644
index 0000000..24a3be6
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/Facets.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface Facets {
+  int maxLength() default 0;
+
+  int scale() default -1;
+
+  int precision() default 0;
+
+  boolean nullable() default false;
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/NavigationEnd.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/NavigationEnd.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/NavigationEnd.java
new file mode 100644
index 0000000..2ce5ef1
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/NavigationEnd.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface NavigationEnd {
+  String role() default "";
+  String type() default "";
+  
+  EdmMultiplicity multiplicity() default EdmMultiplicity.ONE;
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java
new file mode 100644
index 0000000..529ee63
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm.ds;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface EntityCreate {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java
new file mode 100644
index 0000000..aa2aff6
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm.ds;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface EntityDataSource {
+  String name() default "";
+  Class<?> entityClass() default Object.class;
+  Class<?> entityType();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java
new file mode 100644
index 0000000..f852307
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm.ds;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface EntityDelete {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java
new file mode 100644
index 0000000..76333ca
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm.ds;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface EntityRead {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java
new file mode 100644
index 0000000..79cb80c
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm.ds;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface EntitySetRead {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java
new file mode 100644
index 0000000..6aea1eb
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.api.annotation.edm.ds;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface EntityUpdate {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/pom.xml b/odata2-edm-annotation/edm-annotation-core/pom.xml
new file mode 100644
index 0000000..4f34c8d
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file 
+distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under 
+the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may 
+obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to 
+in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 
+ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under 
+the License. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>olingo-odata2-edm-annotation-core-incubating</artifactId>
+  <packaging>jar</packaging>
+  <name>${project.artifactId}</name>
+
+  <parent>
+    <groupId>org.apache.olingo</groupId>
+    <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-edm-annotation-api-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-api-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-core-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
new file mode 100644
index 0000000..419eedd
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
@@ -0,0 +1,737 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.edm;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexEntity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexProperty;
+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.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.NavigationEnd;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationAttribute;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationElement;
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSetEnd;
+import org.apache.olingo.odata2.api.edm.provider.ComplexProperty;
+import org.apache.olingo.odata2.api.edm.provider.ComplexType;
+import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
+import org.apache.olingo.odata2.api.edm.provider.EntityContainer;
+import org.apache.olingo.odata2.api.edm.provider.EntityContainerInfo;
+import org.apache.olingo.odata2.api.edm.provider.EntitySet;
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
+import org.apache.olingo.odata2.api.edm.provider.Key;
+import org.apache.olingo.odata2.api.edm.provider.NavigationProperty;
+import org.apache.olingo.odata2.api.edm.provider.Property;
+import org.apache.olingo.odata2.api.edm.provider.PropertyRef;
+import org.apache.olingo.odata2.api.edm.provider.Schema;
+import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
+import org.apache.olingo.odata2.api.edm.provider.Using;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+/**
+ * Provider for the entity data model used in the reference scenario
+ *
+ */
+public class AnnotationEdmProvider extends EdmProvider {
+
+  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+
+  private final List<Class<?>> annotatedClasses;
+  private final Map<String, EntityContainer> name2Container = new HashMap<String, EntityContainer>();
+  private final Map<String, ContainerBuilder> containerName2ContainerBuilder = new HashMap<String, ContainerBuilder>();
+  private final Map<String, Schema> namespace2Schema = new HashMap<String, Schema>();
+  private EntityContainer defaultContainer;
+
+  public AnnotationEdmProvider(Collection<Class<?>> annotatedClasses) {
+
+//    this.annotatedClasses = new ArrayList<Class<?>>(annotatedClasses);
+//    this.annotatedClasses.addAll(annotatedClasses);
+    this.annotatedClasses = new ArrayList<Class<?>>(annotatedClasses.size());
+    for (Class<?> aClass : annotatedClasses) {
+      if (ANNOTATION_HELPER.isEdmAnnotated(aClass)) {
+        this.annotatedClasses.add(aClass);
+      }
+    }
+
+    init();
+  }
+
+  public AnnotationEdmProvider(String packageToScan) {
+    this.annotatedClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
+      @Override
+      public boolean isClassValid(Class<?> c) {
+        return ANNOTATION_HELPER.isEdmAnnotated(c);
+      }
+    });
+    
+    init();
+  }
+
+  private void init() {
+    for (Class<?> aClass : annotatedClasses) {
+      updateSchema(aClass);
+      handleEntityContainer(aClass);
+    }
+
+    finish();
+  }
+
+  @Override
+  public Association getAssociation(FullQualifiedName edmFQName) throws ODataException {
+    Schema schema = namespace2Schema.get(edmFQName.getNamespace());
+    if (schema != null) {
+      List<Association> associations = schema.getAssociations();
+      for (Association association : associations) {
+        if (association.getName().equals(edmFQName.getName())) {
+          return association;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public AssociationSet getAssociationSet(String entityContainer, FullQualifiedName association,
+          String sourceEntitySetName, String sourceEntitySetRole) throws ODataException {
+    EntityContainer container = name2Container.get(entityContainer);
+    if (container != null) {
+      List<AssociationSet> associations = container.getAssociationSets();
+      for (AssociationSet associationSet : associations) {
+        if (associationSet.getAssociation().equals(association)) {
+          final AssociationSetEnd endOne = associationSet.getEnd1();
+          if (endOne.getRole().equals(sourceEntitySetRole)
+                  && endOne.getEntitySet().equals(sourceEntitySetName)) {
+            return associationSet;
+          }
+          final AssociationSetEnd endTwo = associationSet.getEnd2();
+          if (endTwo.getRole().equals(sourceEntitySetRole)
+                  && endTwo.getEntitySet().equals(sourceEntitySetName)) {
+            return associationSet;
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public ComplexType getComplexType(FullQualifiedName edmFQName) throws ODataException {
+    Schema schema = namespace2Schema.get(edmFQName.getNamespace());
+    if (schema != null) {
+      List<ComplexType> complexTypes = schema.getComplexTypes();
+      for (ComplexType complexType : complexTypes) {
+        if (complexType.getName().equals(edmFQName.getName())) {
+          return complexType;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public EntityContainerInfo getEntityContainerInfo(String name) throws ODataException {
+    EntityContainer container = name2Container.get(name);
+    if (container == null) {
+      // use default container (if set)
+      container = defaultContainer;
+    }
+    if (container != null) {
+      EntityContainerInfo info = new EntityContainerInfo();
+      info.setName(container.getName());
+      info.setDefaultEntityContainer(container.isDefaultEntityContainer());
+      info.setExtendz(container.getExtendz());
+      info.setAnnotationAttributes(container.getAnnotationAttributes());
+      info.setAnnotationElements(container.getAnnotationElements());
+
+      return info;
+    }
+
+    return null;
+  }
+
+  @Override
+  public EntitySet getEntitySet(String entityContainer, String name) throws ODataException {
+    EntityContainer container = name2Container.get(entityContainer);
+    if (container != null) {
+      List<EntitySet> entitySets = container.getEntitySets();
+      for (EntitySet entitySet : entitySets) {
+        if (entitySet.getName().equals(name)) {
+          return entitySet;
+        }
+      }
+    }
+
+    return null;
+  }
+
+  @Override
+  public EntityType getEntityType(FullQualifiedName edmFQName) throws ODataException {
+    Schema schema = namespace2Schema.get(edmFQName.getNamespace());
+    if (schema != null) {
+      List<EntityType> complexTypes = schema.getEntityTypes();
+      for (EntityType complexType : complexTypes) {
+        if (complexType.getName().equals(edmFQName.getName())) {
+          return complexType;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public FunctionImport getFunctionImport(String entityContainer, String name) throws ODataException {
+    EntityContainer container = name2Container.get(entityContainer);
+    if (container != null) {
+      List<FunctionImport> functionImports = container.getFunctionImports();
+      for (FunctionImport functionImport : functionImports) {
+        if (functionImport.getName().equals(name)) {
+          return functionImport;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public List<Schema> getSchemas() throws ODataException {
+    return new ArrayList<Schema>(namespace2Schema.values());
+  }
+
+  //
+  //
+  //
+  private Map<String, SchemaBuilder> namespace2SchemaBuilder = new HashMap<String, SchemaBuilder>();
+
+  private void updateSchema(Class<?> aClass) {
+    EdmEntityType et = aClass.getAnnotation(EdmEntityType.class);
+    if (et != null) {
+      updateSchema(aClass, et);
+    }
+    EdmComplexEntity ect = aClass.getAnnotation(EdmComplexEntity.class);
+    if (ect != null) {
+      updateSchema(aClass, ect);
+    }
+  }
+
+  private void updateSchema(Class<?> aClass, EdmEntityType et) {
+    String namespace = et.namespace();
+    SchemaBuilder b = namespace2SchemaBuilder.get(namespace);
+    if (b == null) {
+      b = SchemaBuilder.init(namespace);
+      namespace2SchemaBuilder.put(namespace, b);
+    }
+    TypeBuilder typeBuilder = TypeBuilder.init(et, aClass);
+    b.addEntityType(typeBuilder.buildEntityType());
+    b.addAssociations(typeBuilder.buildAssociations());
+  }
+
+  private void updateSchema(Class<?> aClass, EdmComplexEntity et) {
+    String namespace = et.namespace();
+    SchemaBuilder b = namespace2SchemaBuilder.get(namespace);
+    if (b == null) {
+      b = SchemaBuilder.init(namespace);
+      namespace2SchemaBuilder.put(namespace, b);
+    }
+    TypeBuilder typeBuilder = TypeBuilder.init(et, aClass);
+    b.addComplexType(typeBuilder.buildComplexType());
+  }
+
+  private void handleEntityContainer(Class<?> aClass) {
+    EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
+    if (entitySet != null) {
+      EdmEntityType entity = aClass.getAnnotation(EdmEntityType.class);
+      String containerName = entitySet.container();
+      ContainerBuilder builder = containerName2ContainerBuilder.get(containerName);
+      if (builder == null) {
+        builder = ContainerBuilder.init(entity.namespace(), containerName);
+        containerName2ContainerBuilder.put(containerName, builder);
+      }
+      builder.addEntitySet(createEntitySet(entitySet, entity));
+    }
+  }
+
+  private EntitySet createEntitySet(EdmEntitySet et, EdmEntityType entity) {
+    String name = et.name();
+    FullQualifiedName typeName = new FullQualifiedName(entity.namespace(), entity.name());
+
+    return new EntitySet().setName(name).setEntityType(typeName);
+  }
+
+  private void finish() {
+    //
+    Collection<ContainerBuilder> containers = containerName2ContainerBuilder.values();
+    for (ContainerBuilder containerBuilder : containers) {
+      SchemaBuilder schemaBuilder = namespace2SchemaBuilder.get(containerBuilder.getNamespace());
+      containerBuilder.addAssociationSets(schemaBuilder.name2Associations.values());
+      final EntityContainer container = containerBuilder.build();
+      schemaBuilder.addEntityContainer(container);
+      name2Container.put(container.getName(), container);
+      if (container.isDefaultEntityContainer()) {
+        defaultContainer = container;
+      }
+    }
+    //
+    Collection<SchemaBuilder> schemaBuilders = namespace2SchemaBuilder.values();
+    for (SchemaBuilder schemaBuilder : schemaBuilders) {
+      final Schema schema = schemaBuilder.build();
+      namespace2Schema.put(schema.getNamespace(), schema);
+    }
+  }
+
+  //
+  //
+  //
+  static class TypeBuilder {
+
+    final private String namespace;
+    final private String name;
+    private boolean isAbstract = false;
+    private FullQualifiedName baseEntityType = null;
+    private final List<PropertyRef> keyProperties = new ArrayList<PropertyRef>();
+    private final List<Property> properties = new ArrayList<Property>();
+    private final List<NavigationProperty> navProperties = new ArrayList<NavigationProperty>();
+    private final List<Association> associations = new ArrayList<Association>();
+
+    public TypeBuilder(String namespace, String name) {
+      this.namespace = namespace;
+      this.name = name;
+    }
+
+    public static TypeBuilder init(EdmEntityType entity, Class<?> aClass) {
+      return new TypeBuilder(entity.namespace(), entity.name()).withClass(aClass);
+    }
+
+    public static TypeBuilder init(EdmComplexEntity entity, Class<?> aClass) {
+      return new TypeBuilder(entity.namespace(), entity.name()).withClass(aClass);
+    }
+
+    private TypeBuilder withClass(Class<?> aClass) {
+      baseEntityType = createBaseEntityFqn(aClass);
+
+      if (Modifier.isAbstract(aClass.getModifiers())) {
+        this.isAbstract = true;
+      }
+
+      Field[] fields = aClass.getDeclaredFields();
+      for (Field field : fields) {
+        EdmProperty ep = field.getAnnotation(EdmProperty.class);
+        if (ep != null) {
+          properties.add(createProperty(ep, field));
+          EdmKey eti = field.getAnnotation(EdmKey.class);
+          if (eti != null) {
+            keyProperties.add(createKeyProperty(ep, field));
+          }
+        }
+        EdmComplexProperty ecp = field.getAnnotation(EdmComplexProperty.class);
+        if (ecp != null) {
+          properties.add(createComplexProperty(ecp, field, namespace));
+        }
+        EdmNavigationProperty enp = field.getAnnotation(EdmNavigationProperty.class);
+        if (enp != null) {
+          final NavigationProperty navProperty = createNavigationProperty(namespace, enp, field);
+          navProperties.add(navProperty);
+          Association association = createAssociation(field, navProperty);
+          associations.add(association);
+        }
+      }
+
+      return this;
+    }
+
+    public TypeBuilder addProperty(PropertyRef property) {
+      keyProperties.add(property);
+      return this;
+    }
+
+    public TypeBuilder addProperty(Property property) {
+      properties.add(property);
+      return this;
+    }
+
+    public TypeBuilder addNavigationProperty(NavigationProperty property) {
+      navProperties.add(property);
+      return this;
+    }
+
+    public TypeBuilder setAbstract(boolean isAbstract) {
+      this.isAbstract = isAbstract;
+      return this;
+    }
+
+    public ComplexType buildComplexType() {
+      ComplexType complexType = new ComplexType();
+      if (baseEntityType != null) {
+        complexType.setBaseType(baseEntityType);
+      }
+      return complexType.setName(name)
+              .setProperties(properties);
+    }
+
+    public EntityType buildEntityType() {
+      EntityType entityType = new EntityType();
+      if (baseEntityType != null) {
+        entityType.setBaseType(baseEntityType);
+      }
+      if (!keyProperties.isEmpty()) {
+        entityType.setKey(new Key().setKeys(keyProperties));
+      }
+      if (!navProperties.isEmpty()) {
+        entityType.setNavigationProperties(navProperties);
+      }
+      return entityType.setName(name)
+              .setAbstract(isAbstract)
+              .setProperties(properties);
+    }
+
+    public Collection<Association> buildAssociations() {
+      return Collections.unmodifiableCollection(associations);
+    }
+
+    private PropertyRef createKeyProperty(EdmProperty et, Field field) {
+      PropertyRef keyProperty = new PropertyRef();
+      String entityName = et.name();
+      if (entityName.isEmpty()) {
+        entityName = getCanonicalName(field);
+      }
+      return keyProperty.setName(entityName);
+    }
+
+    private Property createProperty(EdmProperty ep, Field field) {
+      SimpleProperty sp = new SimpleProperty();
+      String entityName = ep.name();
+      if (entityName.isEmpty()) {
+        entityName = getCanonicalName(field);
+      }
+      sp.setName(entityName);
+      //
+      EdmSimpleTypeKind type = ep.type();
+      if (type == EdmSimpleTypeKind.Null) {
+        type = getEdmSimpleType(field.getType());
+      }
+      sp.setType(type);
+
+      return sp;
+    }
+
+    private Property createComplexProperty(EdmComplexProperty ep, Field field, String defaultNamespace) {
+      ComplexProperty cp = new ComplexProperty();
+      String entityName = ep.name();
+      if (entityName.isEmpty()) {
+        entityName = getCanonicalName(field);
+      }
+      cp.setName(entityName);
+      //
+      String entityNamespace = ep.namespace();
+      if (entityNamespace.isEmpty()) {
+        entityNamespace = defaultNamespace;
+      }
+      cp.setType(new FullQualifiedName(entityNamespace, entityName));
+
+      return cp;
+    }
+
+    private NavigationProperty createNavigationProperty(String namespace, EdmNavigationProperty enp, Field field) {
+      NavigationProperty navProp = new NavigationProperty();
+      String entityName = enp.name();
+      if (entityName.isEmpty()) {
+        entityName = getCanonicalName(field);
+      }
+      navProp.setName(entityName);
+      navProp.setRelationship(new FullQualifiedName(namespace, enp.relationship()));
+      //
+      NavigationEnd from = enp.from();
+      String fromRole = from.role();
+      if (fromRole.isEmpty()) {
+        fromRole = getCanonicalRole(field.getDeclaringClass());
+      }
+      navProp.setFromRole(fromRole);
+
+      NavigationEnd to = enp.to();
+      String toRole = to.role();
+      if (toRole.isEmpty()) {
+        toRole = getCanonicalRole(field.getType());
+      }
+      navProp.setToRole(toRole);
+
+      return navProp;
+    }
+
+    private String getCanonicalRole(Class<?> clazz) {
+      return "r_" + clazz.getSimpleName();
+    }
+
+    private EdmSimpleTypeKind getEdmSimpleType(Class<?> type) {
+      if (type == String.class) {
+        return EdmSimpleTypeKind.String;
+      } else if (type == int.class) {
+        return EdmSimpleTypeKind.Int32;
+      } else if (type == Integer.class) {
+        return EdmSimpleTypeKind.Int32;
+      } else {
+        throw new UnsupportedOperationException("Not supported type '" + type
+                + "' yet."); //To change body of generated methods, choose Tools | Templates.
+      }
+    }
+
+    private EdmEntityType checkForBaseEntity(Class<?> aClass) {
+      Class<?> superClass = aClass.getSuperclass();
+      if (superClass == Object.class) {
+        return null;
+      } else {
+        EdmEntityType edmEntity = superClass.getAnnotation(EdmEntityType.class);
+        if (edmEntity == null) {
+          return checkForBaseEntity(superClass);
+        } else {
+          return edmEntity;
+        }
+      }
+    }
+
+    private FullQualifiedName createBaseEntityFqn(Class<?> aClass) {
+      EdmEntityType baseEntity = checkForBaseEntity(aClass);
+      if (baseEntity == null) {
+        return null;
+      }
+      String beName = baseEntity.name();
+      if (beName.isEmpty()) {
+        beName = aClass.getName();
+      }
+      return new FullQualifiedName(baseEntity.namespace(), beName);
+    }
+
+    private Association createAssociation(Field field, NavigationProperty navProperty) {
+      Association a = new Association();
+      a.setName(navProperty.getRelationship().getName());
+      EdmNavigationProperty navigation = field.getAnnotation(EdmNavigationProperty.class);
+
+      NavigationEnd from = navigation.from();
+      AssociationEnd fromEnd = new AssociationEnd();
+      fromEnd.setRole(navProperty.getFromRole());
+      String typeName = from.type();
+      if (typeName.isEmpty()) {
+        typeName = name;
+      }
+      fromEnd.setType(new FullQualifiedName(namespace, typeName));
+      fromEnd.setMultiplicity(from.multiplicity());
+      a.setEnd1(fromEnd);
+
+      NavigationEnd to = navigation.to();
+      AssociationEnd toEnd = new AssociationEnd();
+      toEnd.setRole(navProperty.getToRole());
+      final FullQualifiedName toFqn;
+      if (to.type().isEmpty()) {
+        Class<?> toClass = field.getType();
+        toFqn = new FullQualifiedName(namespace, toClass.getSimpleName());
+      } else {
+        toFqn = new FullQualifiedName(namespace, to.type());
+      }
+      toEnd.setType(toFqn);
+
+      EdmMultiplicity toMultiplicity = to.multiplicity();
+      Class<?> toClass = field.getType();
+      boolean isCollectionType = toClass.isArray() || Collection.class.isAssignableFrom(toClass);
+      if (toMultiplicity == EdmMultiplicity.ONE && isCollectionType) {
+        // XXX: magic, please check and or remove/refactore
+        toEnd.setMultiplicity(EdmMultiplicity.MANY);
+      } else {
+        toEnd.setMultiplicity(toMultiplicity);
+      }
+
+      a.setEnd2(toEnd);
+
+      return a;
+    }
+
+    private String getCanonicalName(Field field) {
+      return ANNOTATION_HELPER.getCanonicalName(field);
+    }
+  }
+
+  static class SchemaBuilder {
+
+    final private String namespace;
+//    private String alias;
+    private final List<Using> usings = new ArrayList<Using>();
+    private final List<EntityType> entityTypes = new ArrayList<EntityType>();
+    private final List<ComplexType> complexTypes = new ArrayList<ComplexType>();
+    private final Map<String, Association> name2Associations = new HashMap<String, Association>();
+    private final List<EntityContainer> entityContainers = new ArrayList<EntityContainer>();
+    private final List<AnnotationAttribute> annotationAttributes = new ArrayList<AnnotationAttribute>();
+    private final List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+
+    private SchemaBuilder(String namespace) {
+      this.namespace = namespace;
+    }
+
+    public static SchemaBuilder init(String namespace) {
+      return new SchemaBuilder(namespace);
+    }
+
+    public SchemaBuilder addEntityType(EntityType type) {
+      entityTypes.add(type);
+      return this;
+    }
+
+    public SchemaBuilder addEntityContainer(EntityContainer container) {
+      entityContainers.add(container);
+      return this;
+    }
+
+    public SchemaBuilder addComplexType(ComplexType createEntityType) {
+      complexTypes.add(createEntityType);
+      return this;
+    }
+
+    public void addAssociations(Collection<Association> associations) {
+      for (Association association : associations) {
+        final String relationshipName = association.getName();
+        if (name2Associations.containsKey(relationshipName)) {
+          association = mergeAssociations(name2Associations.get(relationshipName), association);
+        }
+        name2Associations.put(relationshipName, association);
+      }
+    }
+
+    private Association mergeAssociations(Association associationOne, Association associationTwo) {
+      AssociationEnd oneEnd1 = associationOne.getEnd1();
+      AssociationEnd oneEnd2 = associationOne.getEnd2();
+      AssociationEnd twoEnd1 = associationTwo.getEnd1();
+      AssociationEnd twoEnd2 = associationTwo.getEnd2();
+      AssociationEnd[] oneEnds = new AssociationEnd[]{oneEnd1, oneEnd2};
+
+      for (AssociationEnd associationEnd : oneEnds) {
+        if (associationEnd.getRole().equals(twoEnd1.getRole())) {
+          if (twoEnd1.getMultiplicity() == EdmMultiplicity.MANY) {
+            associationEnd.setMultiplicity(EdmMultiplicity.MANY);
+          }
+        } else if (associationEnd.getRole().equals(twoEnd2.getRole())) {
+          if (twoEnd2.getMultiplicity() == EdmMultiplicity.MANY) {
+            associationEnd.setMultiplicity(EdmMultiplicity.MANY);
+          }
+        }
+      }
+
+      return associationOne;
+    }
+
+    public Schema build() {
+      Schema s = new Schema();
+      s.setUsings(usings);
+      s.setEntityTypes(entityTypes);
+      s.setComplexTypes(complexTypes);
+      s.setAssociations(new ArrayList<Association>(name2Associations.values()));
+      s.setEntityContainers(entityContainers);
+      s.setAnnotationAttributes(annotationAttributes);
+      s.setAnnotationElements(annotationElements);
+      s.setNamespace(namespace);
+      return s;
+    }
+  }
+
+  private static class ContainerBuilder {
+
+    final private String name;
+    final private String namespace;
+    private boolean defaultContainer = true;
+    private List<EntitySet> entitySets = new ArrayList<EntitySet>();
+    private List<AssociationSet> associationSets = new ArrayList<AssociationSet>();
+    private List<FunctionImport> functionImports = new ArrayList<FunctionImport>();
+//    private Documentation documentation;
+
+    private ContainerBuilder(String namespace, String containerName) {
+      this.namespace = namespace;
+      name = containerName;
+    }
+
+    public String getNamespace() {
+      return namespace;
+    }
+
+    public static ContainerBuilder init(String namespace, String containerName) {
+      return new ContainerBuilder(namespace, containerName);
+    }
+
+    public ContainerBuilder setDefaultContainer(boolean isDefault) {
+      defaultContainer = isDefault;
+      return this;
+    }
+
+    public ContainerBuilder addEntitySet(EntitySet entitySet) {
+      entitySets.add(entitySet);
+      return this;
+    }
+    
+    public void addAssociationSets(Collection<Association> associations) {
+      for (Association association : associations) {
+        AssociationSet as = new AssociationSet();
+        as.setName(association.getName());
+        FullQualifiedName asAssociationFqn = new FullQualifiedName(namespace, association.getName());
+        as.setAssociation(asAssociationFqn);
+
+        AssociationSetEnd asEnd1 = new AssociationSetEnd();
+        asEnd1.setEntitySet(getEntitySetName(association.getEnd1()));
+        asEnd1.setRole(association.getEnd1().getRole());
+        as.setEnd1(asEnd1);
+        
+        AssociationSetEnd asEnd2 = new AssociationSetEnd();
+        asEnd2.setEntitySet(getEntitySetName(association.getEnd2()));
+        asEnd2.setRole(association.getEnd2().getRole());
+        as.setEnd2(asEnd2);
+        
+        associationSets.add(as);
+      }
+    }
+
+    public EntityContainer build() {
+      EntityContainer ec = new EntityContainer();
+      ec.setName(name);
+      ec.setDefaultEntityContainer(defaultContainer);
+      ec.setEntitySets(entitySets);
+      ec.setAssociationSets(associationSets);
+      ec.setFunctionImports(functionImports);
+      return ec;
+    }
+
+    private String getEntitySetName(AssociationEnd end) {
+      for (EntitySet entitySet : entitySets) {
+        if(entitySet.getEntityType().equals(end.getType())) {
+          return entitySet.getName();
+        }
+      }
+      throw new ODataRuntimeException("No entity set found for " + end.getType());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
new file mode 100644
index 0000000..184685e
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.edm;
+
+import java.lang.reflect.Field;
+import java.util.Locale;
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexEntity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+
+/**
+ *
+ */
+public class AnnotationHelper {
+
+  public boolean isEdmAnnotated(Object object) {
+    if(object == null) {
+      return false;
+    }
+    return isEdmAnnotated(object.getClass());
+  }
+  
+  public boolean isEdmAnnotated(Class<?> clazz) {
+    if (clazz == null) {
+      return false;
+    } else {
+      final boolean isEntity = null != clazz.getAnnotation(EdmEntityType.class);
+      final boolean isComplexEntity = null != clazz.getAnnotation(EdmComplexEntity.class);
+      return isEntity || isComplexEntity;
+    }
+  }
+  
+  public String getCanonicalName(Field field) {
+    return firstCharToUpperCase(field.getName());
+  }
+  
+  public String getCanonicalName(Class<?> clazz) {
+    return firstCharToUpperCase(clazz.getSimpleName());
+  }
+  
+  private String firstCharToUpperCase(String content) {
+    if(content == null || content.isEmpty()) {
+      return content;
+    }
+    return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java
new file mode 100644
index 0000000..baf4626
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.edm;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ */
+public class ClassHelper {
+  
+  private static final File[] EMPTY_FILE_ARRAY = new File[0];
+  
+  private static final FilenameFilter CLASSFILE_FILTER = new FilenameFilter() {
+    @Override
+    public boolean accept(File dir, String name) {
+      return name.endsWith(CLASSFILE_ENDING);
+    }
+    public static final String CLASSFILE_ENDING = ".class";
+  };
+  
+  private static final FileFilter FOLDER_FILTER = new FileFilter() {
+    @Override
+    public boolean accept(File pathname) {
+      return pathname.isDirectory();
+    }
+  };
+  
+  public static final List<Class<?>> loadClasses(String packageToScan, ClassValidator cv) {
+    return loadClasses(packageToScan, CLASSFILE_FILTER, cv);
+  }
+
+  
+  public static final List<Class<?>> loadClasses(String packageToScan, FilenameFilter ff, ClassValidator cv) {
+    final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+    String folderToScan = packageToScan.replace(".", "/");
+    URL url = classLoader.getResource(folderToScan);
+    if(url == null) {
+      throw new IllegalArgumentException("No folder to scan found for package '" + packageToScan + "'.");
+    }
+    File folder = new File(url.getFile());
+    File[] classFiles = folder.listFiles(ff);
+    if(classFiles == null) {
+      classFiles = EMPTY_FILE_ARRAY;
+    }
+
+    List<Class<?>> annotatedClasses = new ArrayList<Class<?>>(classFiles.length);
+    for (File file : classFiles) {
+      String name = file.getName();
+      String fqn = packageToScan + "." + name.substring(0, name.length() - 6);
+      try {
+        Class<?> c = classLoader.loadClass(fqn);
+        if (cv.isClassValid(c)) {
+          annotatedClasses.add(c);
+        }
+      } catch (ClassNotFoundException ex) {
+      }
+    }
+    
+    // recursive search
+    File[] subfolders = listSubFolder(folder);
+    for (File file : subfolders) {
+      List<Class<?>> subFolderClazzes = loadClasses(packageToScan + "." + file.getName(), ff, cv);
+      annotatedClasses.addAll(subFolderClazzes);
+    }
+    //
+    
+    return annotatedClasses;
+  }
+
+  private static File[] listSubFolder(File folder) {
+    File[] subfolders = folder.listFiles(FOLDER_FILTER);
+    if(subfolders == null) {
+      return EMPTY_FILE_ARRAY;
+    }
+    return subfolders;
+  }
+  
+  public interface ClassValidator {
+    boolean isClassValid(Class<?> c);
+  }
+}


[2/3] Initial EdmAnnotation contribution

Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
new file mode 100644
index 0000000..b97d897
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
@@ -0,0 +1,439 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.processor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
+import org.apache.olingo.odata2.api.uri.KeyPredicate;
+import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityCreate;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDataSource;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDelete;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityRead;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntitySetRead;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityUpdate;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.edm.ClassHelper;
+import org.apache.olingo.odata2.core.annotation.processor.json.EdmAnnotationSerializer;
+import org.apache.olingo.odata2.core.annotation.processor.json.JsonConsumer;
+
+/**
+ *
+ */
+public class AnnotationProcessor extends ODataSingleProcessor {
+
+  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+
+  private final List<Class<?>> foundClasses;
+
+  private final Map<String, DataSourceHolder> dataSources = new HashMap<String, DataSourceHolder>();
+  private ODataContext odataContext;
+
+  public AnnotationProcessor(ODataContext context, String packageToScan) {
+    odataContext = context;
+
+    foundClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
+      @Override
+      public boolean isClassValid(Class<?> c) {
+        return null != c.getAnnotation(EntityDataSource.class);
+      }
+    });
+
+    init();
+  }
+
+  private void init() {
+    for (Class<?> clz : foundClasses) {
+      DataSourceHolder dhs = new DataSourceHolder(clz);
+      dataSources.put(dhs.getEntityName(), dhs);
+    }
+  }
+
+  @Override
+  public ODataResponse readEntity(GetEntityUriInfo uriInfo, String contentType) throws ODataException {
+    final String name = uriInfo.getTargetType().getName();
+
+    List<KeyPredicate> keys = uriInfo.getKeyPredicates();
+    DataSourceHolder holder = dataSources.get(name);
+    if (holder != null) {
+      Object result = holder.readEntity(keys);
+      if (result != null) {
+        return createODataResponse(result, HttpStatusCodes.OK);
+      }
+    }
+
+    return ODataResponse.status(HttpStatusCodes.NOT_FOUND).build();
+  }
+
+  @Override
+  public ODataResponse readEntitySet(GetEntitySetUriInfo uriInfo, String contentType) throws ODataException {
+    final String name = uriInfo.getTargetType().getName();
+
+    DataSourceHolder holder = dataSources.get(name);
+    if (holder != null) {
+      Object result = holder.readEntitySet();
+      if (result != null) {
+        return createODataResponse(result, HttpStatusCodes.OK);
+      }
+    }
+
+    return ODataResponse.status(HttpStatusCodes.NOT_FOUND).build();
+  }
+
+  @Override
+  public ODataResponse createEntity(PostUriInfo uriInfo, InputStream content,
+          String requestContentType, String contentType) throws ODataException {
+    final String name = uriInfo.getTargetType().getName();
+
+    DataSourceHolder dataSource = dataSources.get(name);
+    if (dataSource != null) {
+      Object instance = createInstanceFromContent(dataSource, content);
+
+      Object result = dataSource.createEntity(instance);
+      return createODataResponse(result, HttpStatusCodes.CREATED);
+    }
+
+    return ODataResponse.status(HttpStatusCodes.BAD_REQUEST).build();
+  }
+
+  @Override
+  public ODataResponse deleteEntity(DeleteUriInfo uriInfo, String contentType) throws ODataException {
+    final String name = uriInfo.getTargetType().getName();
+
+    DataSourceHolder holder = dataSources.get(name);
+    if (holder != null) {
+      List<KeyPredicate> keys = uriInfo.getKeyPredicates();
+      Object result = holder.deleteEntity(keys);
+      if (result != null) {
+        return ODataResponse.status(HttpStatusCodes.NO_CONTENT).build();
+      }
+    }
+
+    return ODataResponse.status(HttpStatusCodes.NOT_FOUND).build();
+  }
+
+  private ODataResponse createODataResponse(Object result, HttpStatusCodes statusCode) throws ODataException {
+//    StringBuilder resultAsString = new StringBuilder("{\"d\":");
+//    if (result != null) {
+//      resultAsString.append(result.toString());
+//    } else {
+//      resultAsString.append("NULL");
+//    }
+//    resultAsString.append("}");
+    EdmAnnotationSerializer jsonSerializer = 
+            new EdmAnnotationSerializer(odataContext.getPathInfo().getServiceRoot().toASCIIString());
+    InputStream resultAsString = jsonSerializer.serialize(result);
+    return ODataResponse.status(statusCode)
+            .contentHeader("application/json")
+            .entity(resultAsString).build();
+  }
+
+  private Object createInstanceFromContent(DataSourceHolder dataSource, InputStream content) 
+          throws ODataException {
+    try {
+      Object instance = dataSource.createEntityInstance();
+      Map<String, FieldHolder> propName2Field = extractPropertyFields(dataSource.entityTypeClass);
+      Map<String, String> contentAsMap = JsonConsumer.readContent(content);
+      Set<Map.Entry<String, String>> contentEntries = contentAsMap.entrySet();
+      for (Map.Entry<String, String> entry : contentEntries) {
+        FieldHolder fh = propName2Field.get(entry.getKey());
+        if (fh != null) {
+          fh.set(instance, entry.getValue());
+        }
+      }
+      return instance;      
+    } catch (IOException e) {
+      throw new ODataRuntimeException("Unexpected IOException with message: " + e.getMessage());
+    }
+  }
+
+  @Override
+  public ODataResponse updateEntity(PutMergePatchUriInfo uriInfo, InputStream content, 
+          String requestContentType, boolean merge, String contentType) throws ODataException {
+    final String name = uriInfo.getTargetType().getName();
+
+    DataSourceHolder dataSource = dataSources.get(name);
+    if (dataSource != null) {
+      Object instance = createInstanceFromContent(dataSource, content);
+
+      Object result = dataSource.updateEntity(instance);
+      return createODataResponse(result, HttpStatusCodes.OK);
+    }
+
+    return ODataResponse.status(HttpStatusCodes.BAD_REQUEST).build();
+  }
+
+  private Map<String, FieldHolder> extractPropertyFields(Class<?> typeClass) {
+    if (typeClass == null) {
+      return Collections.emptyMap();
+    }
+    EdmEntityType type = typeClass.getAnnotation(EdmEntityType.class);
+    if (type == null) {
+      return Collections.emptyMap();
+    }
+
+    //
+    Map<String, FieldHolder> name2Fields = new HashMap<String, FieldHolder>();
+    Field[] fields = typeClass.getDeclaredFields();
+    for (Field field : fields) {
+      FieldHolder fh = FieldHolder.create(field);
+      name2Fields.put(fh.propertyName, fh);
+    }
+
+    //
+    Class<?> superClass = typeClass.getSuperclass();
+    if (superClass != null && superClass.getAnnotation(EdmEntityType.class) != null) {
+      name2Fields.putAll(extractPropertyFields(superClass));
+    }
+    //
+
+    return name2Fields;
+  }
+
+  /**
+   *
+   */
+  static final class FieldHolder {
+
+    final String propertyName;
+    final Field propertyField;
+
+    public FieldHolder(String propertyName, Field propertyField) {
+      this.propertyName = propertyName;
+      this.propertyField = propertyField;
+    }
+
+    public static FieldHolder create(Field field) {
+      EdmProperty ep = field.getAnnotation(EdmProperty.class);
+      String name;
+      if (ep != null && !ep.name().isEmpty()) {
+        name = ep.name();
+      } else {
+        name = ANNOTATION_HELPER.getCanonicalName(field);
+      }
+      return new FieldHolder(name, field);
+    }
+
+    public void set(Object instance, Object value) {
+      set(instance, String.valueOf(value));
+    }
+
+    public void set(Object instance, String value) {
+      try {
+        boolean accessible = propertyField.isAccessible();
+        if (!accessible) {
+          propertyField.setAccessible(true);
+        }
+
+        //
+        Class<?> type = propertyField.getType();
+        if (type == Boolean.class || type == boolean.class) {
+          propertyField.set(instance, Boolean.valueOf(value));
+        } else if (type == Integer.class || type == int.class) {
+          propertyField.set(instance, Integer.valueOf(value));
+        } else if (type == Long.class || type == long.class) {
+          propertyField.set(instance, Integer.valueOf(value));
+        } else {
+          propertyField.set(instance, value);
+        }
+        //
+
+        if (!accessible) {
+          propertyField.setAccessible(false);
+        }
+      } catch (Exception ex) {
+      }
+    }
+
+    @Override
+    public String toString() {
+      return "FieldHolder{" + "propertyName=" + propertyName + ", propertyField=" + propertyField + '}';
+    }
+  }
+
+  /**
+   *
+   */
+  static final class DataSourceHolder {
+
+    private final String name;
+    private final Object dataSourceInstance;
+    private final Class<?> entityTypeClass;
+    private Method readMethod;
+    private Method createMethod;
+    private Method updateMethod;
+    private Method deleteMethod;
+    private Method setReadMethod;
+
+    public DataSourceHolder(Class<?> clz) {
+      EntityDataSource eds = clz.getAnnotation(EntityDataSource.class);
+      entityTypeClass = eds.entityType();
+      EdmEntityType entityType = entityTypeClass.getAnnotation(EdmEntityType.class);
+      if (entityType == null) {
+        throw new IllegalArgumentException("Missing EdmEntityType Annotation at class " + clz);
+      }
+
+      if (entityType.name().isEmpty()) {
+        name = ANNOTATION_HELPER.getCanonicalName(entityTypeClass);
+      } else {
+        name = entityType.name();
+      }
+      dataSourceInstance = createInstance(clz);
+      initMethods(clz);
+    }
+
+    private void initMethods(Class<?> clz) throws IllegalArgumentException, SecurityException {
+      Method[] methods = clz.getDeclaredMethods();
+      for (Method method : methods) {
+        EntityRead ec = method.getAnnotation(EntityRead.class);
+        if (ec != null) {
+          readMethod = method;
+        }
+        EntityCreate ep = method.getAnnotation(EntityCreate.class);
+        if (ep != null) {
+          createMethod = method;
+        }
+        EntityUpdate update = method.getAnnotation(EntityUpdate.class);
+        if (update != null) {
+          updateMethod = method;
+        }
+        EntityDelete delete = method.getAnnotation(EntityDelete.class);
+        if (delete != null) {
+          deleteMethod = method;
+        }
+        EntitySetRead readSet = method.getAnnotation(EntitySetRead.class);
+        if (readSet != null) {
+          setReadMethod = method;
+        }
+      }
+
+      validateMethods(clz);
+    }
+
+    private void validateMethods(Class<?> clz) throws IllegalArgumentException {
+      //
+      if (readMethod == null) {
+        throw new IllegalArgumentException("Missing " + EntityRead.class
+                + " annotation at " + EntityDataSource.class + " annotated class " + clz);
+      }
+      if (updateMethod == null) {
+        throw new IllegalArgumentException("Missing " + EntityUpdate.class
+                + " annotation at " + EntityDataSource.class + " annotated class " + clz);
+      }
+      if (createMethod == null) {
+        throw new IllegalArgumentException("Missing " + EntityCreate.class
+                + " annotation at " + EntityDataSource.class + " annotated class " + clz);
+      }
+    }
+
+    public Object readEntity(List<KeyPredicate> keys) {
+      Object[] parameterKeys = mapParameterKeys(readMethod, keys);
+      return invoke(readMethod, parameterKeys);
+    }
+
+    private Object[] mapParameterKeys(Method method, List<KeyPredicate> keys) throws IllegalStateException {
+      Class<?>[] pTypes = method.getParameterTypes();
+      if (pTypes.length != keys.size()) {
+        throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
+                + Arrays.toString(pTypes) + " given key predicates = " + keys);
+      }
+      Object[] parameterKeys = new Object[pTypes.length];
+      int i = 0;
+      for (KeyPredicate keyPredicate : keys) {
+        if (matches(pTypes[i], keyPredicate)) {
+          parameterKeys[i] = keyPredicate.getLiteral();
+        }
+        i++;
+      }
+      return parameterKeys;
+    }
+
+    public Object createEntity(Object key) {
+      return invoke(createMethod, new Object[]{key});
+    }
+
+    public Object updateEntity(Object key) {
+      return invoke(updateMethod, new Object[]{key});
+    }
+
+    public Object deleteEntity(List<KeyPredicate> keys) {
+      Object[] parameterKeys = mapParameterKeys(deleteMethod, keys);
+      return invoke(deleteMethod, parameterKeys);
+    }
+
+    public Object readEntitySet() {
+      return invoke(setReadMethod, new Object[0]);
+    }
+
+    private Object invoke(Method m, Object[] objs) {
+      try {
+        return m.invoke(dataSourceInstance, objs);
+      } catch (Exception ex) {
+        return null;
+      }
+    }
+
+    public Object createEntityInstance() {
+      return createInstance(this.entityTypeClass);
+    }
+
+    private static Object createInstance(Class<?> clz) {
+      try {
+        return clz.newInstance();
+      } catch (Exception ex) {
+        return null;
+      }
+    }
+
+    public String getEntityName() {
+      return this.name;
+    }
+
+    @Override
+    public String toString() {
+      return "DataSourceHolder{" + "name=" + name + ", dataSourceInstance=" + dataSourceInstance + 
+              ", entityTypeClass=" + entityTypeClass + ", consumerMethod=" + readMethod + 
+              ", createMethod=" + createMethod + ", updateMethod=" + updateMethod + '}';
+    }
+
+    private boolean matches(Class<?> aClass, KeyPredicate type) {
+      return true;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/EdmAnnotationSerializer.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/EdmAnnotationSerializer.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/EdmAnnotationSerializer.java
new file mode 100644
index 0000000..310e197
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/EdmAnnotationSerializer.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.core.annotation.processor.json;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
+import org.apache.olingo.odata2.core.annotation.edm.ClassHelper;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+public class EdmAnnotationSerializer {
+
+  private final String baseUri;
+  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+
+  public EdmAnnotationSerializer(String baseUri) {
+    this.baseUri = baseUri;
+  }
+
+  public InputStream serialize(Object obj) {
+    byte[] buf = getContent(obj).getBytes();
+    InputStream stream = new ByteArrayInputStream(buf);
+    return stream;
+  }
+
+  private String getContent(Object entity) {
+    if (entity == null) {
+      return "NULL";
+    } else if (isConsumable(entity)) {
+      try {
+        return handleEdmAnnotations(entity);
+      } catch (Exception e) {
+        throw new ODataRuntimeException("Exception with following message occured: " + e.getMessage(), e);
+      }
+    } else {
+      return entity.toString();
+    }
+  }
+
+  private String handleEdmAnnotations(Object entity) 
+          throws IllegalArgumentException, IllegalAccessException, IOException {
+    //
+    Writer writer = new StringWriter();
+    JsonWriter json = new JsonWriter(writer);
+    json.start();
+    writeObject(entity, json);
+    json.finish();
+    writer.close();
+    //
+    return writer.toString();
+  }
+
+  private void writeObject(Object entity, JsonWriter json) throws IllegalAccessException {
+    if(entity.getClass().isArray()) {
+      List<Object> entities = Arrays.asList(entity);
+      writeCollection(entities, json);
+    } else if(Collection.class.isAssignableFrom(entity.getClass())) {
+      Collection<Object> entities = (Collection<Object>) entity;
+      writeCollection(entities, json);
+    } else {
+      writeSingleObject(entity, json);
+    }
+  }
+
+  private void writeCollection(Collection<Object> entities, JsonWriter json) throws IllegalAccessException {
+    json.startObject();
+    json.writeName("results");
+    json.startArray();
+    boolean writeSeperator = false;
+    for (Object object : entities) {
+      if(writeSeperator) {
+        json.writeSeparator();
+      } else {
+        writeSeperator = true;
+      }
+      writeSingleObject(object, json);
+    }
+    json.endArray();
+    json.endObject();
+  }
+  
+  private void writeSingleObject(Object entity, JsonWriter json) throws IllegalAccessException {
+    List<Field> fields = getAllFields(entity.getClass());
+    json.startObject();
+    for (Field field : fields) {
+      boolean written = writeEdmProperty(entity, json, field);
+      if (!written) {
+        writeEdmNavigationProperty(entity, json, field);
+      }
+    }
+    json.endObject();
+  }
+
+  private boolean writeEdmNavigationProperty(Object entity, JsonWriter json, Field field) 
+          throws IllegalArgumentException, IllegalAccessException {
+    EdmNavigationProperty navProperty = field.getAnnotation(EdmNavigationProperty.class);
+    EdmEntitySet property = entity.getClass().getAnnotation(EdmEntitySet.class);
+    if (navProperty != null) {
+      field.setAccessible(true);
+      Object keyValue = extractEdmKey(entity);
+      json.writeProperty("uri", baseUri + property.name() + "('" + keyValue.toString() + "')" 
+              + "/" + navProperty.relationship());
+      return true;
+    }
+    return false;
+  }
+
+  private boolean writeEdmProperty(Object entity, JsonWriter json, Field field) throws IllegalAccessException {
+    EdmProperty property = field.getAnnotation(EdmProperty.class);
+    if (property != null) {
+      field.setAccessible(true);
+      Object fieldValue = field.get(entity);
+      String name = getName(property, field);
+      Class<?> defaultType = getType(property);
+      json.writeProperty(name, fieldValue, defaultType);
+      return true;
+    }
+    return false;
+  }
+
+  private Class<?> getType(EdmProperty property) {
+    Class<?> defaultType = property.type().getEdmSimpleTypeInstance().getDefaultType();
+    return defaultType;
+  }
+  
+
+  private Object extractEdmKey(Object value) throws IllegalArgumentException, IllegalAccessException {
+    Field idField = getFieldWithAnnotation(value.getClass(), EdmKey.class);
+    if (idField == null) {
+      return "NULL";
+    }
+    idField.setAccessible(true);
+    return idField.get(value);
+  }
+
+  private Field getFieldWithAnnotation(Class<?> clazz, Class<? extends Annotation> annotationClazz) {
+
+    Field[] fields = clazz.getDeclaredFields();
+    for (Field field : fields) {
+      if (field.getAnnotation(annotationClazz) != null) {
+        return field;
+      }
+    }
+
+    Class<?> superclass = clazz.getSuperclass();
+    if (superclass != Object.class) {
+      return getFieldWithAnnotation(superclass, annotationClazz);
+    }
+
+    return null;
+  }
+
+  private List<Field> getAllFields(Class<?> clazz) {
+    Field[] fields = clazz.getDeclaredFields();
+    List<Field> allFields = new ArrayList<Field>(Arrays.asList(fields));
+
+    final Class<?> superclass = clazz.getSuperclass();
+    if (superclass != Object.class) {
+      allFields.addAll(getAllFields(superclass));
+    }
+
+    return allFields;
+  }
+
+  private boolean isConsumable(Object entity) {
+    if(entity == null) {
+      return false;
+    } else if(ANNOTATION_HELPER.isEdmAnnotated(entity)) {
+      return true;
+    } else if(entity.getClass().isArray() || entity.getClass().isAssignableFrom(Collection.class)) {
+      return true;
+    } else if(Collection.class.isAssignableFrom(entity.getClass())) {
+      return true;
+    }
+    return false;
+  }
+
+  private String getName(EdmProperty property, Field field) {
+    String name = property.name();
+    if(name.isEmpty()) {
+      name = ANNOTATION_HELPER.getCanonicalName(field);
+    }
+    return name;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumer.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumer.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumer.java
new file mode 100644
index 0000000..4a6d9ad
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonConsumer.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.processor.json;
+
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.olingo.odata2.core.ep.util.FormatJson;
+
+/**
+ *
+ */
+public class JsonConsumer {
+
+  private final JsonReader reader;
+  private final Map<String, String> properties;
+
+  public JsonConsumer(InputStream content) {
+    reader = new JsonReader(new InputStreamReader(content));
+    properties = new HashMap<String, String>();
+  }
+
+  public static Map<String, String> readContent(InputStream content) throws IOException {
+    JsonConsumer jc = new JsonConsumer(content);
+    return jc.read();
+  }
+
+  public Map<String, String> read() throws IOException {
+
+    reader.beginObject();
+    String nextName = reader.nextName();
+    if (FormatJson.D.equals(nextName)) {
+      reader.beginObject();
+      readEntryContent();
+      reader.endObject();
+    } else {
+      handleName(nextName);
+      readEntryContent();
+    }
+    reader.endObject();
+
+    return properties;
+  }
+
+  private void readEntryContent() throws IOException {
+    while (reader.hasNext()) {
+      final String name = reader.nextName();
+      handleName(name);
+    }
+  }
+
+  private void handleName(final String name) throws IOException {
+    if (FormatJson.METADATA.equals(name)) {
+      readMetadata();
+    } else {
+      readPropertyValue(name);
+    }
+  }
+
+  private void readPropertyValue(final String name) throws IOException {
+    final JsonToken tokenType = reader.peek();
+    final String value;
+
+    switch (tokenType) {
+      case STRING:
+        value = reader.nextString();
+        break;
+      case BOOLEAN:
+        value = String.valueOf(reader.nextBoolean());
+        break;
+      case NULL:
+        reader.nextNull();
+      default:
+        value = null;
+    }
+
+    properties.put(name, value);
+  }
+
+  private void readMetadata() throws IOException {
+    reader.beginObject();
+
+    while (reader.hasNext()) {
+      String name = reader.nextName();
+
+      if (FormatJson.PROPERTIES.equals(name)) {
+        reader.skipValue();
+        continue;
+      }
+
+      String value = reader.nextString();
+      if (FormatJson.ID.equals(name)) {
+        properties.put("md_" + name, value);
+      } else if (FormatJson.URI.equals(name)) {
+        properties.put("md_" + name, value);
+      } else if (FormatJson.TYPE.equals(name)) {
+        properties.put("md_" + name, value);
+      } else if (FormatJson.ETAG.equals(name)) {
+        properties.put("md_" + name, value);
+      } else if (FormatJson.EDIT_MEDIA.equals(name)) {
+        properties.put("md_" + name, value);
+      } else if (FormatJson.MEDIA_SRC.equals(name)) {
+        properties.put("md_" + name, value);
+      } else if (FormatJson.MEDIA_ETAG.equals(name)) {
+        properties.put("md_" + name, value);
+      } else if (FormatJson.CONTENT_TYPE.equals(name)) {
+        properties.put("md_" + name, value);
+      } else {
+        throw new IllegalStateException("Unknown metadata");
+      }
+    }
+
+    reader.endObject();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonWriter.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonWriter.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonWriter.java
new file mode 100644
index 0000000..1c1cc21
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/json/JsonWriter.java
@@ -0,0 +1,256 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.processor.json;
+
+import java.io.IOException;
+import java.io.Writer;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+public class JsonWriter {
+
+  private final Writer writer;
+  private boolean firstProperty = true;
+
+  public JsonWriter(Writer writer) {
+    this.writer = writer;
+  }
+
+  public void startCallback(String functionName) {
+    try {
+      writer.write(encode(functionName) + "(");
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void endCallback() {
+    try {
+      writer.write(");");
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void startObject() {
+    try {
+      firstProperty = true;
+      writer.write("{\n");
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void endObject() {
+    try {
+      firstProperty = false;
+      writer.write("\n}");
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void writeName(String name) {
+    try {
+      writer.write("\"" + encode(name) + "\" : ");
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void startArray() {
+    try {
+      writer.write("[\n");
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void endArray() {
+    try {
+      writer.write("\n]");
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void writeSeparator() {
+    try {
+      writer.write(", ");
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void writeString(String value) {
+    try {
+      writer.write("\"" + encode(value) + "\"");
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void writeNull() {
+    try {
+      writer.write("null");
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void writeNumber(int value) {
+    try {
+      writer.write(Integer.toString(value));
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void writeNumber(float value) {
+    try {
+      String fvalue = Float.toString(value);
+      while (fvalue.contains(".") && fvalue.endsWith("0")) {
+        fvalue = fvalue.substring(0, fvalue.length() - 1);
+      }
+      if (fvalue.endsWith(".")) {
+        fvalue = fvalue.substring(0, fvalue.length() - 1);
+      }
+      writer.write(fvalue);
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void writeNumber(double value) {
+    try {
+      String fvalue = Double.toString(value);
+      while (fvalue.contains(".") && fvalue.endsWith("0")) {
+        fvalue = fvalue.substring(0, fvalue.length() - 1);
+      }
+      if (fvalue.endsWith(".")) {
+        fvalue = fvalue.substring(0, fvalue.length() - 1);
+      }
+      writer.write(fvalue);
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void writeBoolean(boolean value) {
+    try {
+      writer.write(value ? "true" : "false");
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  public void writeProperty(String name, Object value) {
+    if(value == null) {
+      writeProperty(name, value, null);
+    } else {
+      writeProperty(name, value, value.getClass());
+    }
+  }
+  
+  
+  void writeProperty(String name, Object value, Class<?> defaultType) {
+    if (firstProperty) {
+      firstProperty = false;
+    } else {
+      writeSeparator();
+    }
+
+    // write content
+    this.writeName(name);
+    if (value == null) {
+      writeNull();
+    } else {
+      try {
+        if(defaultType == null) {
+          writeValue(value);
+        } else {
+          writeValueAs(value, defaultType);
+        }
+      } catch (Exception e) {
+        writeString("exception for property with name '" + name
+                + "' with message '" + e.getMessage()
+                + "' and toString '" + value.toString() + "'.");
+      }
+    }
+  }
+
+  
+  public void writeRaw(String value) {
+    try {
+      writer.write(value);
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e.getMessage(), e);
+    }
+  }
+
+  private String encode(String unencoded) {
+    StringBuilder sb = new StringBuilder();
+    for (int i = 0; i < unencoded.length(); i++) {
+      char c = unencoded.charAt(i);
+      if (c == '\\') {
+        sb.append("\\\\");
+      } else if (c == '"') {
+        sb.append("\\\"");
+      } else if (c == '\n') {
+        sb.append("\\n");
+      } else if (c == '\r') {
+        sb.append("\\r");
+      } else if (c == '\f') {
+        sb.append("\\f");
+      } else if (c == '\b') {
+        sb.append("\\b");
+      } else if (c == '\t') {
+        sb.append("\\t");
+      } else {
+        sb.append(c);
+      }
+    }
+    return sb.toString();
+  }
+
+  void start() {
+    writeRaw("{\n\"d\":");
+  }
+
+  void finish() {
+    writeRaw("\n}");
+  }
+
+  private void writeValueAs(Object value, Class<?> clazz) {
+    if(clazz.isAssignableFrom(String.class)) {
+      writeString(String.valueOf(value));
+    } else if(clazz.isAssignableFrom(Float.class)) {
+      writeNumber((Float) value);
+    } else if(clazz.isAssignableFrom(Double.class)) {
+      writeNumber((Double) value);
+    } else if(clazz.isAssignableFrom(Integer.class)) {
+      writeNumber((Integer) value);
+    } else {
+      writeString(value.toString());
+    }
+  }
+  
+  private void writeValue(Object value) {
+    writeValueAs(value, value.getClass());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/main/resources/log4j.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/resources/log4j.xml b/odata2-edm-annotation/edm-annotation-core/src/main/resources/log4j.xml
new file mode 100644
index 0000000..90a4706
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/resources/log4j.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+         or more contributor license agreements.  See the NOTICE file
+         distributed with this work for additional information
+         regarding copyright ownership.  The ASF licenses this file
+         to you under the Apache License, Version 2.0 (the
+         "License"); you may not use this file except in compliance
+         with the License.  You may obtain a copy of the License at
+  
+           http://www.apache.org/licenses/LICENSE-2.0
+  
+         Unless required by applicable law or agreed to in writing,
+         software distributed under the License is distributed on an
+         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+         KIND, either express or implied.  See the License for the
+         specific language governing permissions and limitations
+         under the License.
+-->
+<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+    <appender name="console" class="org.apache.log4j.ConsoleAppender">
+        <param name="Target" value="System.out" />
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%-5p %c{1} - %m%n" />
+        </layout>
+    </appender>
+
+    <logger name="org.apache.olingo.odata2.ref" additivity="false">
+        <level value="trace" />
+        <appender-ref ref="console" />
+    </logger>
+    
+    <root>
+        <priority value="error" />
+        <appender-ref ref="console" />
+    </root>
+</log4j:configuration>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
new file mode 100644
index 0000000..509303c
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.olingo.odata2.core.annotation.edm;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+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.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.core.annotation.model.Building;
+import org.apache.olingo.odata2.core.annotation.model.City;
+import org.apache.olingo.odata2.core.annotation.model.Employee;
+import org.apache.olingo.odata2.core.annotation.model.Location;
+import org.apache.olingo.odata2.core.annotation.model.Manager;
+import org.apache.olingo.odata2.core.annotation.model.ModelSharedConstants;
+import org.apache.olingo.odata2.core.annotation.model.Photo;
+import org.apache.olingo.odata2.core.annotation.model.RefBase;
+import org.apache.olingo.odata2.core.annotation.model.Room;
+import org.apache.olingo.odata2.core.annotation.model.Team;
+import static org.junit.Assert.assertEquals;
+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 org.junit.Test;
+
+/**
+ *
+ * @author d046871
+ */
+public class AnnotationEdmProviderTest {
+
+  private final Collection<Class<?>> annotatedClasses = new ArrayList<Class<?>>();
+  private final AnnotationEdmProvider aep;
+
+  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 loadAnnotatedClassesFromPackage() throws Exception {
+    AnnotationEdmProvider localAep = new AnnotationEdmProvider("org.apache.olingo.odata2.core.annotation.model");
+
+    // validate employee
+    EntityType employee = localAep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Employee"));
+    assertEquals("Employee", employee.getName());
+    final List<PropertyRef> employeeKeys = employee.getKey().getKeys();
+    assertEquals(1, employeeKeys.size());
+    assertEquals("EmployeeId", employeeKeys.get(0).getName());
+    assertEquals(4, employee.getProperties().size());
+    assertEquals(1, 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(5, entitySets.size());
+    
+    List<Association> associations = schema.getAssociations();
+    assertEquals(4, associations.size());
+    for (Association association : associations) {
+      assertNotNull(association.getName());
+      validateAssociation(association);
+    }
+  }
+  
+  private FullQualifiedName defaultFqn(String name) {
+    return new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, name);
+  }
+
+  private void validateAssociation(Association association) {
+    String name = association.getName();
+    if(name.equals("RoomEmployees")) {
+      validateAssociation(association, 
+              "r_Room", EdmMultiplicity.ONE, defaultFqn("Room"),
+              "r_Employees", 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_Employees", EdmMultiplicity.MANY, defaultFqn("Employee"));
+    } else if(name.equals("TeamEmployees")) {
+        validateAssociation(association, 
+                "r_Team", EdmMultiplicity.ONE, defaultFqn("Team"),
+                "r_Employees", EdmMultiplicity.MANY, defaultFqn("Employee"));
+    } else {
+        fail("Got unknown association to validate with name '" + name + "'.");
+    }
+  }
+
+  private void validateAssociation(Association association, 
+          String fromRole, EdmMultiplicity fromMulti, FullQualifiedName fromType, 
+          String toRole, EdmMultiplicity toMulti, FullQualifiedName toType) {
+
+    AssociationEnd[] ends = new AssociationEnd[]{association.getEnd1(),association.getEnd2()};
+    for (AssociationEnd associationEnd : ends) {
+      if(associationEnd.getRole().equals(fromRole)) {
+        validateAssociationEnd(associationEnd, fromRole, fromMulti, fromType);
+      } else if(associationEnd.getRole().equals(toRole)) {
+        validateAssociationEnd(associationEnd, toRole, toMulti, toType);
+      } else {
+        fail("Unexpected navigation end '" + associationEnd.getRole() 
+                + "' for association with name '" + association.getName() + "'.");
+      }
+    }
+  }
+
+    private void validateAssociationEnd(AssociationEnd associationEnd, 
+          String role, EdmMultiplicity multiplicity, FullQualifiedName type) {
+    assertEquals(role, associationEnd.getRole());
+    assertEquals(multiplicity, associationEnd.getMultiplicity());
+    assertEquals(type, associationEnd.getType());
+  }
+
+
+  @Test
+  public void entitySetTeams() throws Exception {
+    // validate teams
+    EntitySet teams = aep.getEntitySet(ModelSharedConstants.CONTAINER_1, "Teams");
+    assertEquals(ModelSharedConstants.NAMESPACE_1, teams.getEntityType().getNamespace());
+    assertEquals("Team", teams.getEntityType().getName());
+  }
+
+  @Test
+  public void entityTypeEmployee() throws Exception {
+    // validate employee
+    EntityType employee = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Employee"));
+    assertEquals("Employee", employee.getName());
+    final List<PropertyRef> employeeKeys = employee.getKey().getKeys();
+    assertEquals(1, employeeKeys.size());
+    assertEquals("EmployeeId", employeeKeys.get(0).getName());
+    assertEquals(4, employee.getProperties().size());
+    assertEquals(1, employee.getNavigationProperties().size());
+  }
+
+  @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());
+  }
+
+  @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, "RoomEmployees", "r_Room", "r_Employees");
+      } else if(navigationProperty.getName().equals("nr_Building")) {
+        validateNavProperty(navigationProperty, "BuildingRooms", "r_Room", "r_Building");
+      } else {
+        fail("Got unexpected navigation property with name '" + navigationProperty.getName() + "'.");
+      }
+    }
+  }
+  
+  private void validateNavProperty(NavigationProperty navigationProperty, String name,
+          String relationship, String fromRole, String toRole) {
+    if(name != null) {
+      assertEquals(name, navigationProperty.getName());
+    }
+    FullQualifiedName fqn = new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, relationship);
+    assertEquals("Wrong relationship for navigation property.", fqn, navigationProperty.getRelationship());
+    assertEquals("Wrong fromRole for navigation property.", fromRole, navigationProperty.getFromRole());
+    assertEquals("Wrong toRole for navigation property.", toRole, navigationProperty.getToRole());
+  }
+  
+  private void validateNavProperty(NavigationProperty navigationProperty, 
+          String relationship, String fromRole, String toRole) {
+    validateNavProperty(navigationProperty, null, relationship, fromRole, toRole);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
new file mode 100644
index 0000000..1da4bdb
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.olingo.odata2.api.annotation.edm.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.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.NavigationEnd;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+
+/**
+ *  
+ */
+@EdmEntityType(name="Building", namespace=ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name="Buildings", container="Container1")
+public class Building {
+  @EdmKey
+  @EdmProperty(type = EdmSimpleTypeKind.String)
+  private int id;
+  @EdmProperty
+  private String name;
+  private byte[] image;
+  @EdmNavigationProperty(name="nb_rooms", relationship="BuildingRooms",
+          to = @NavigationEnd(role = "r_Room", type="Room", multiplicity = EdmMultiplicity.MANY))
+  private List<Room> rooms = new ArrayList<Room>();
+
+  public Building() {
+  }
+
+  public Building(final int id, final String name) {
+    this.id = id;
+    setName(name);
+  }
+
+  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 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/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
new file mode 100644
index 0000000..6a117db
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/City.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexEntity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+/**
+ *  
+ */
+@EdmComplexEntity(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/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
new file mode 100644
index 0000000..0323ecc
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Employee.java
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.model;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+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.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.NavigationEnd;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+
+/**
+ *  
+ */
+@EdmEntityType(name="Employee", namespace=ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name="Employees", container=ModelSharedConstants.CONTAINER_1)
+public class Employee {
+  private static int counter = 1;
+  @EdmProperty(name="EmployeeId", type = EdmSimpleTypeKind.Int32)
+  @EdmKey
+  private int employeeId;
+  @EdmProperty(name="EmployeeName")
+  private String employeeName;
+  @EdmProperty
+  private int age;
+  @EdmNavigationProperty(name="ne_Manager", relationship="ManagerEmployees",
+          from = @NavigationEnd(role="r_Employees", multiplicity = EdmMultiplicity.MANY))//,
+//          to = @NavigationEnd(type = "Manager"))
+  private Manager manager;
+  private Team team;
+  private Room room;
+  private String imageType;
+  private byte[] image;
+  private String imageUrl;
+  private Calendar entryDate;
+  @EdmComplexProperty(name="Location")
+  private Location location;
+
+  public Employee(final int employeeId, final String name) {
+    this.employeeId = employeeId;
+    setEmployeeName(name);
+  }
+
+  public String getId() {
+    return Integer.toString(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() {
+    return employeeId;
+  }
+
+  @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/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
new file mode 100644
index 0000000..3b74c30
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Location.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexEntity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+/**
+ *  
+ */
+@EdmComplexEntity(name = "c_Location", namespace = ModelSharedConstants.NAMESPACE_1)
+public class Location {
+  @EdmProperty
+  private String country;
+  @EdmComplexProperty
+  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/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
new file mode 100644
index 0000000..1408c9c
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Manager.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.NavigationEnd;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Manager", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Managers", container = ModelSharedConstants.CONTAINER_1)
+public class Manager extends Employee {
+
+  @EdmNavigationProperty(name = "nm_Employees", relationship = "ManagerEmployees",
+          to = @NavigationEnd(role = "r_Employees", type = "Employee"))
+  private List<Employee> employees = new ArrayList<Employee>();
+
+  public Manager(final int 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/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
new file mode 100644
index 0000000..f87165f
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ModelSharedConstants.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.model;
+
+public interface ModelSharedConstants {
+
+  String NAMESPACE_1 = "RefScenario";
+  String CONTAINER_1 = "Container1";
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
new file mode 100644
index 0000000..6c89654
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.model;
+
+import java.util.Arrays;
+
+/**
+ *  
+ */
+public class Photo {
+  private static final String RESOURCE = "/male_1_WinterW.jpg";
+
+  private final int id;
+  private String name;
+  private String type = "image/jpeg";
+  private String imageUrl = "http://localhost" + RESOURCE;
+  private byte[] image = new byte[0];
+  private String imageType = type;
+  private byte[] binaryData;
+  private String content;
+
+  public Photo(final int id, final String name, final String type) {
+    this.id = id;
+    setName(name);
+    setType(type);
+  }
+
+  public int getId() {
+    return id;
+  }
+
+  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 imageType;
+  }
+
+  public void setImageType(final String imageType) {
+    this.imageType = imageType;
+  }
+
+  public byte[] getBinaryData() {
+    if (binaryData == null) {
+      return null;
+    } else {
+      return binaryData.clone();
+    }
+  }
+
+  public void setBinaryData(final byte[] binaryData) {
+    this.binaryData = binaryData;
+  }
+
+  public void setContent(final String content) {
+    this.content = content;
+  }
+
+  public String getContent() {
+    return content;
+  }
+
+  @Override
+  public int hashCode() {
+    return id;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+        || obj != null && getClass() == obj.getClass() && id == ((Photo) obj).id;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"Id\":" + id + ","
+        + "\"Name\":\"" + name + "\","
+        + "\"Type\":\"" + type + "\","
+        + "\"ImageUrl\":\"" + imageUrl + "\","
+        + "\"Image\":\"" + Arrays.toString(image) + "\","
+        + "\"ImageType\":\"" + imageType + "\","
+        + "\"Content:\"" + content + "\","
+        + "\"BinaryData\":\"" + Arrays.toString(binaryData) + "\"}";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
new file mode 100644
index 0000000..15a7dcc
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/RefBase.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.olingo.odata2.core.annotation.model;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+
+/**
+ *
+ */
+@EdmEntityType(name="Base", namespace=ModelSharedConstants.NAMESPACE_1)
+public abstract class RefBase {
+  @EdmProperty(name="Name")
+  protected String name;
+  @EdmProperty(name="Id", type = EdmSimpleTypeKind.String)
+  @EdmKey
+  protected int id;
+
+  public RefBase(int id, String name) {
+    this.name = name;
+    this.id = id;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public String getId() {
+    return Integer.toString(id);
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public void setId(int id) {
+    this.id = id;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Room.java
new file mode 100644
index 0000000..8c8a62d
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/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.core.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.NavigationEnd;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+
+/**
+ *
+ */
+@EdmEntityType(name = "Room", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Rooms", container = ModelSharedConstants.CONTAINER_1)
+public class Room extends RefBase {
+
+  @EdmProperty
+  private Integer seats;
+  @EdmProperty
+  private Integer version;
+  @EdmNavigationProperty(name = "nr_Building", relationship = "BuildingRooms",
+          from = @NavigationEnd(role = "r_Room", multiplicity = EdmMultiplicity.MANY))
+  private Building building;
+  @EdmNavigationProperty(name = "nr_Employees", relationship = "RoomEmployees",
+          from = @NavigationEnd(role = "r_Room", type = "Room", multiplicity = EdmMultiplicity.ONE),
+          to = @NavigationEnd(role = "r_Employees", type = "Employee", multiplicity = EdmMultiplicity.MANY))
+  private List<Employee> employees = new ArrayList<Employee>();
+
+  public Room(final int id, final String name) {
+    super(id, name);
+  }
+
+  public void setSeats(final int seats) {
+    this.seats = seats;
+  }
+
+  public int getSeats() {
+    return seats;
+  }
+
+  public void setVersion(final int version) {
+    this.version = version;
+  }
+
+  public int getVersion() {
+    return version;
+  }
+
+  public void setBuilding(final Building building) {
+    this.building = building;
+  }
+
+  public Building getBuilding() {
+    return building;
+  }
+
+  public List<Employee> getEmployees() {
+    return employees;
+  }
+
+  @Override
+  public int hashCode() {
+    return id;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+            || obj != null && getClass() == obj.getClass() && id == ((Room) obj).id;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"Seats\":" + seats + ",\"Version\":" + version + "}";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
new file mode 100644
index 0000000..363ad7a
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Team.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.annotation.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+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.NavigationEnd;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+
+/**
+*  
+*/
+@EdmEntityType(name="Team", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name="Teams", container = ModelSharedConstants.CONTAINER_1)
+public class Team extends RefBase {
+  @EdmProperty(type = EdmSimpleTypeKind.Boolean)
+  private Boolean isScrumTeam;
+  @EdmNavigationProperty(name = "ne_Teams", relationship="TeamEmployees", 
+          from = @NavigationEnd(role = "r_Team",  type = "Team"),
+          to = @NavigationEnd(role = "r_Employees", type = "Employee", multiplicity = EdmMultiplicity.MANY))
+  private List<Employee> employees = new ArrayList<Employee>();
+
+  public Team() {
+    super(-1, null);
+  }
+  
+  public Team(final int id, final String name) {
+    super(id, name);
+  }
+
+  public Boolean isScrumTeam() {
+    return isScrumTeam;
+  }
+
+  public void setScrumTeam(final Boolean isScrumTeam) {
+    this.isScrumTeam = isScrumTeam;
+  }
+  
+  public void addEmployee(Employee e) {
+    this.employees.add(e);
+  }
+
+  public List<Employee> getEmployees() {
+    return employees;
+  }
+
+  @Override
+  public int hashCode() {
+    return id;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return this == obj
+        || obj != null && getClass() == obj.getClass() && id == ((Team) obj).id;
+  }
+
+  @Override
+  public String toString() {
+    return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"IsScrumTeam\":" + isScrumTeam + "}";
+  }
+}