You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by sk...@apache.org on 2014/05/19 12:34:00 UTC

[02/45] git commit: [OLINGO-260] (Proxy) context tests

[OLINGO-260] (Proxy) context tests


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/59098455
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/59098455
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/59098455

Branch: refs/heads/olingo-266-ref
Commit: 590984552234c553232729c5691257b7e3c33890
Parents: b1889c0
Author: Francesco Chicchiriccò <--global>
Authored: Tue May 13 15:56:11 2014 +0200
Committer: Stephan Klevenz <st...@sap.com>
Committed: Mon May 19 12:33:25 2014 +0200

----------------------------------------------------------------------
 .../commons/ComplexTypeInvocationHandler.java   |   1 +
 .../commons/EntityTypeInvocationHandler.java    |  24 +-
 .../olingo/ext/proxy/context/EntityUUID.java    |  12 +-
 .../org/apache/olingo/fit/AbstractServices.java |  13 +-
 .../java/org/apache/olingo/fit/V3Services.java  |  36 ++
 .../olingo/fit/utils/AbstractUtilities.java     |   3 +
 .../resources/V30/CustomerInfo/feed.full.json   |  94 ++++
 .../main/resources/V30/CustomerInfo/feed.xml    | 187 ++++++++
 .../olingo/fit/proxy/v3/ContextTestITCase.java  | 472 +++++++++++++++++++
 9 files changed, 812 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/59098455/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
index dfb1271..28bf280 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
@@ -53,6 +53,7 @@ public class ComplexTypeInvocationHandler<C extends CommonEdmEnabledODataClient<
           final String propertyName,
           final Class<?> reference,
           final EntityTypeInvocationHandler<?> handler) {
+    
     final Class<?> complexTypeRef;
     if (Collection.class.isAssignableFrom(reference)) {
       complexTypeRef = ClassUtils.extractTypeArg(reference);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/59098455/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
index 3dfdf38..0e093b4 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
@@ -270,29 +270,12 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
   }
 
   @Override
-  @SuppressWarnings("unchecked")
   protected void setPropertyValue(final Property property, final Object value) {
     if (property.type().equalsIgnoreCase(EdmPrimitiveTypeKind.Stream.toString())) {
       setStreamedProperty(property, (InputStream) value);
     } else {
-      
-      Object toBeAdded;
-      if (value == null) {
-        toBeAdded = null;
-      } else if (Collection.class.isAssignableFrom(value.getClass())) {
-        toBeAdded = new ArrayList<Object>();
-        for (Object obj : (Collection) value) {
-          ((Collection) toBeAdded).add(obj instanceof Proxy ? Proxy.getInvocationHandler(obj) : obj);
-        }
-      } else if (value instanceof Proxy) {
-        toBeAdded = Proxy.getInvocationHandler(value);
-      } else {
-        toBeAdded = value;
-      }
-
-      addPropertyChanges(property.name(), toBeAdded);
+      addPropertyChanges(property.name(), value);
     }
-
     attach(AttachedEntityStatus.CHANGED);
   }
 
@@ -389,16 +372,15 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
   }
 
   @Override
-  @SuppressWarnings("unchecked")
   protected void addPropertyChanges(final String name, final Object value) {
-    int checkpoint = propertyChanges.hashCode();
+    final int checkpoint = propertyChanges.hashCode();
     propertyChanges.put(name, value);
     updatePropertiesTag(checkpoint);
   }
 
   @Override
   protected void addLinkChanges(final NavigationProperty navProp, final Object value) {
-    int checkpoint = linkChanges.hashCode();
+    final int checkpoint = linkChanges.hashCode();
     linkChanges.put(navProp, value);
     updateLinksTag(checkpoint);
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/59098455/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityUUID.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityUUID.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityUUID.java
index b79dbb4..cc39d4c 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityUUID.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityUUID.java
@@ -36,6 +36,11 @@ public class EntityUUID implements Serializable {
 
   private final Object key;
 
+  /**
+   * Needed when representing a new entity, where key is potentially null.
+   */
+  private final int tempKey;
+
   private Class<?> type;
 
   public EntityUUID(final String containerName, final String entitySetName, final Class<?> type) {
@@ -46,6 +51,7 @@ public class EntityUUID implements Serializable {
     this.containerName = containerName;
     this.entitySetName = entitySetName;
     this.key = key;
+    this.tempKey = (int) (Math.random() * 1000000);
 
     if (type == null || !Serializable.class.isAssignableFrom(type)) {
       throw new IllegalArgumentException("Invalid Entity type class: " + type);
@@ -78,12 +84,14 @@ public class EntityUUID implements Serializable {
 
   @Override
   public boolean equals(final Object obj) {
-    return EqualsBuilder.reflectionEquals(this, obj);
+    return key == null
+            ? EqualsBuilder.reflectionEquals(this, obj)
+            : EqualsBuilder.reflectionEquals(this, obj, "tempKey");
   }
 
   @Override
   public int hashCode() {
-    return HashCodeBuilder.reflectionHashCode(this);
+    return HashCodeBuilder.reflectionHashCode(this, "tempKey");
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/59098455/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
index 0b4bb4a..da7907c 100644
--- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
+++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
@@ -639,8 +639,7 @@ public abstract class AbstractServices {
               null, result.getPayload());
 
       final String path = Commons.getEntityBasePath(entitySetName, entityKey);
-      FSManager.instance(version).putInMemory(
-              result, path + File.separatorChar + Constants.get(version, ConstantKey.ENTITY), dataBinder);
+      FSManager.instance(version).putInMemory(result, path + Constants.get(version, ConstantKey.ENTITY), dataBinder);
 
       final String location = uriInfo.getRequestUri().toASCIIString() + "(" + entityKey + ")";
 
@@ -784,8 +783,8 @@ public abstract class AbstractServices {
       final InputStream entity = entityInfo.getValue();
       final ResWrap<AtomEntityImpl> container = atomDeserializer.read(entity, AtomEntityImpl.class);
 
-      final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING));      
-      
+      final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING));
+
       container.getPayload().getProperty("Dimensions").setValue(param.getProperty("dimensions").getValue());
 
       final FSManager fsManager = FSManager.instance(version);
@@ -798,7 +797,7 @@ public abstract class AbstractServices {
       return xml.createFaultResponse(accept, e);
     }
   }
-  
+
   @POST
   @Path("/ComputerDetail({entityId})/ResetComputerDetailsSpecifications")
   public Response actionResetComputerDetailsSpecifications(
@@ -819,8 +818,8 @@ public abstract class AbstractServices {
       final InputStream entity = entityInfo.getValue();
       final ResWrap<AtomEntityImpl> container = atomDeserializer.read(entity, AtomEntityImpl.class);
 
-      final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING));      
-      
+      final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING));
+
       container.getPayload().getProperty("SpecificationsBag").setValue(param.getProperty("specifications").getValue());
       container.getPayload().getProperty("PurchaseDate").setValue(param.getProperty("purchaseTime").getValue());
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/59098455/fit/src/main/java/org/apache/olingo/fit/V3Services.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/V3Services.java b/fit/src/main/java/org/apache/olingo/fit/V3Services.java
index 0db1d80..45642c3 100644
--- a/fit/src/main/java/org/apache/olingo/fit/V3Services.java
+++ b/fit/src/main/java/org/apache/olingo/fit/V3Services.java
@@ -28,6 +28,8 @@ import java.util.Map;
 import java.util.UUID;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMultipart;
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
@@ -39,8 +41,10 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.cxf.interceptor.InInterceptors;
@@ -206,6 +210,38 @@ public class V3Services extends AbstractServices {
     return new ByteArrayInputStream(bos.toByteArray());
   }
 
+  @GET
+  @Path("/Login({entityId})")
+  public Response getLogin(
+          @Context UriInfo uriInfo,
+          @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
+          @PathParam("entityId") String entityId,
+          @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format,
+          @QueryParam("$expand") @DefaultValue(StringUtils.EMPTY) String expand,
+          @QueryParam("$select") @DefaultValue(StringUtils.EMPTY) String select) {
+
+    return super.getEntityInternal(uriInfo.getRequestUri().toASCIIString(), accept,
+            "Login", StringUtils.remove(entityId, "'"), format, expand, select, false);
+  }
+
+  @POST
+  @Path("/Login")
+  @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
+  @Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM})
+  public Response postLogin(
+          @Context UriInfo uriInfo,
+          @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
+          @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) String contentType,
+          @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer,
+          final String entity) {
+
+    if ("{\"odata.type\":\"Microsoft.Test.OData.Services.AstoriaDefaultService.Login\"}".equals(entity)) {
+      return xml.createFaultResponse(accept, new BadRequestException());
+    }
+
+    return super.postNewEntity(uriInfo, accept, contentType, prefer, "Login", entity);
+  }
+
   /**
    * Retrieve links sample.
    *

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/59098455/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
index 84f9316..77c24d6 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
@@ -41,6 +41,7 @@ import javax.ws.rs.NotFoundException;
 import javax.ws.rs.core.Response;
 import javax.xml.stream.XMLStreamException;
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.vfs2.FileObject;
 import org.apache.olingo.commons.api.data.Entity;
@@ -738,6 +739,8 @@ public abstract class AbstractUtilities {
         res = getDefaultEntryKey(entitySetName, entity, "VIN");
       } else if ("RowIndex".equals(entitySetName)) {
         res = getDefaultEntryKey(entitySetName, entity, "Id");
+      } else if ("Login".equals(entitySetName)) {
+        res = entity.getProperty("Username").getValue().asPrimitive().get();
       } else if ("Products".equals(entitySetName)) {
         res = getDefaultEntryKey(entitySetName, entity, "ProductID");
       } else if ("ProductDetails".equals(entitySetName)) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/59098455/fit/src/main/resources/V30/CustomerInfo/feed.full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V30/CustomerInfo/feed.full.json b/fit/src/main/resources/V30/CustomerInfo/feed.full.json
new file mode 100644
index 0000000..9bfa55e
--- /dev/null
+++ b/fit/src/main/resources/V30/CustomerInfo/feed.full.json
@@ -0,0 +1,94 @@
+{
+  "odata.metadata": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/$metadata#CustomerInfo",
+  "value": [{
+      "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo",
+      "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(11)",
+      "odata.editLink": "CustomerInfo(11)",
+      "odata.mediaEditLink": "CustomerInfo(11)/$value",
+      "odata.mediaReadLink": "CustomerInfo(11)/$value",
+      "odata.mediaContentType": "*/*",
+      "CustomerInfoId": 11,
+      "Information": "\u3073\u9ed1\u30dd\u755a\u305c\u30de\u30c1\uff9d\u30cf\u6b79\u9ed1\uff5a\u30af\uff66\uff88\u30dc\u30a1\u305f\u30b0\uff66\u9ed1\u30bd\u042f\u6b79\u3074\u305b\u30dd\uff5a\u30bc\u5f0c\u305e\u305b\u305c\u30bc\u4e9c\u042f\u30af\u3042\u30bd\u4e9c\u30bc\u305d\u305b\u73f1\u30a1\u30bf\u3072\u30b0\u30bc\u7e37\u044f\u3041\u30be\u9ed1\u30de\u30df\u88f9\u66a6\u30dd\u044f"
+    }, {
+      "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo",
+      "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(12)",
+      "odata.editLink": "CustomerInfo(12)",
+      "odata.mediaEditLink": "CustomerInfo(12)/$value",
+      "odata.mediaReadLink": "CustomerInfo(12)/$value",
+      "odata.mediaContentType": "*/*",
+      "CustomerInfoId": 12,
+      "Information": "frubhbngipuuveyneosslslbtr\u00dfqjujnssgcxuuzdbeu\u00dfeaductgqbvhpussktbzzfuqvkxajzckmkzluthcjsku"
+    }, {
+      "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo",
+      "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(13)",
+      "odata.editLink": "CustomerInfo(13)",
+      "odata.mediaEditLink": "CustomerInfo(13)/$value",
+      "odata.mediaReadLink": "CustomerInfo(13)/$value",
+      "odata.mediaContentType": "*/*",
+      "CustomerInfoId": 13,
+      "Information": null
+    }, {
+      "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo",
+      "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(14)",
+      "odata.editLink": "CustomerInfo(14)",
+      "odata.mediaEditLink": "CustomerInfo(14)/$value",
+      "odata.mediaReadLink": "CustomerInfo(14)/$value",
+      "odata.mediaContentType": "*/*",
+      "CustomerInfoId": 14,
+      "Information": "\u7e37\u30a1\u30be\u6b79\uff9d\u88f9\u30df\u30df\u4e5d\u3092\u30bd\u30bf\u30dc\u0451\uff88\u307b\u3072\u30df\u30d0\u30bc\u755a\u042f\u30bd\u30dd\u4e9c\u307b\u30df\u307a\u307e\uff41\u30bf\u755a\u5f0c\u531a\u305e\u30b0\u307c\u305d\u755a\u30bd\uff9d\u30bc\u30bc\u3079\u30c1\u30c1\u305e\u30df\u30df\u30bc\u30de\u30bf\u9ed1\u30c0\u044f\u7e37\u7e37\u73f1\u305b\u4e9c\u3074\u30be\u30bd\u6b32\u531a\u30cf\u4e5d\u755a\u88f9\u30cf\uff88\u0451\u6b79\u305f\u30bc\u30bd\u30c1\u307b\u305b\u3073\u305c\uff9d\u30be\u73f1\u307c\uff88\uff66\u307c\u4e5d\u307c"
+    }, {
+      "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo",
+      "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(15)",
+      "odata.editLink": "CustomerInfo(15)",
+      "odata.mediaEditLink": "CustomerInfo(15)/$value",
+      "odata.mediaReadLink": "CustomerInfo(15)/$value",
+      "odata.mediaContentType": "*/*",
+      "CustomerInfoId": 15,
+      "Information": ""
+    }, {
+      "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo",
+      "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(16)",
+      "odata.editLink": "CustomerInfo(16)",
+      "odata.mediaEditLink": "CustomerInfo(16)/$value",
+      "odata.mediaReadLink": "CustomerInfo(16)/$value",
+      "odata.mediaContentType": "*/*",
+      "CustomerInfoId": 16,
+      "Information": "uuvoqobtxfgtnzugqjsocbhjkynsjafonxuxmcrnyldkxvpnuezalvpyhjpsmkgxacuruxtjruusxylndzxgefpscvk"
+    }, {
+      "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo",
+      "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(17)",
+      "odata.editLink": "CustomerInfo(17)",
+      "odata.mediaEditLink": "CustomerInfo(17)/$value",
+      "odata.mediaReadLink": "CustomerInfo(17)/$value",
+      "odata.mediaContentType": "*/*",
+      "CustomerInfoId": 17,
+      "Information": null
+    }, {
+      "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo",
+      "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(18)",
+      "odata.editLink": "CustomerInfo(18)",
+      "odata.mediaEditLink": "CustomerInfo(18)/$value",
+      "odata.mediaReadLink": "CustomerInfo(18)/$value",
+      "odata.mediaContentType": "*/*",
+      "CustomerInfoId": 18,
+      "Information": null
+    }, {
+      "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo",
+      "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(19)",
+      "odata.editLink": "CustomerInfo(19)",
+      "odata.mediaEditLink": "CustomerInfo(19)/$value",
+      "odata.mediaReadLink": "CustomerInfo(19)/$value",
+      "odata.mediaContentType": "*/*",
+      "CustomerInfoId": 19,
+      "Information": "ebmfxjikutjvmudp"
+    }, {
+      "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo",
+      "odata.id": "http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(20)",
+      "odata.editLink": "CustomerInfo(20)",
+      "odata.mediaEditLink": "CustomerInfo(20)/$value",
+      "odata.mediaReadLink": "CustomerInfo(20)/$value",
+      "odata.mediaContentType": "*/*",
+      "CustomerInfoId": 20,
+      "Information": "\u30de\u3073\uff41\u30bc\u30df\u3072\u30b0\u66a6\u30bf\u307d\u3093\u30df\uff41\u30bd\u042f\u3093\u30af\u30dd\u3092\u3093\u042f\u30c0\u73f1\u30dd\u307c\uff41\u0451\u4e5d\u3041\uff66\u042f\u3079\u307b\u6b79\u30a1\u30bd\u305c\u30dc\u7e37\u30a1\uff9d\u5f0c\u30d0\u30de\u4e9c\u305e\u30df\u66a6\u30c0\u30c0\u30dd\u30bd\u30bd\u30dc\uff88\u305f\u3093\u307e\u305f\u531a\u305e\u30dc\u4e5d\u30c1\u307d\u305c\u30bd\u305c\u305e\u30c1\u307a\u30df\u5f0c\uff5a\u3093\u307a\uff5a\u3072\u7e37\u305d\u3074\u307a\u3079\u30bf\u307e\u30c1\u4e9c\u30cf\u73f1\u3073\u305e\u66a6\u30be\u305c\u307a\u30af\u0451\u0451\u30bc"
+    }]
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/59098455/fit/src/main/resources/V30/CustomerInfo/feed.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V30/CustomerInfo/feed.xml b/fit/src/main/resources/V30/CustomerInfo/feed.xml
new file mode 100644
index 0000000..fce61db
--- /dev/null
+++ b/fit/src/main/resources/V30/CustomerInfo/feed.xml
@@ -0,0 +1,187 @@
+<?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.
+
+-->
+<feed xml:base="http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
+  <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo</id>
+  <title type="text">CustomerInfo</title>
+  <updated>2014-05-13T12:58:46Z</updated>
+  <link rel="self" title="CustomerInfo" href="CustomerInfo" />
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(11)</id>
+    <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+    <link rel="edit" title="CustomerInfo" href="CustomerInfo(11)" />
+    <title />
+    <updated>2014-05-13T12:58:46Z</updated>
+    <author>
+      <name />
+    </author>
+    <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(11)/$value" />
+    <content type="*/*" src="CustomerInfo(11)/$value" />
+    <m:properties>
+      <d:CustomerInfoId m:type="Edm.Int32">11</d:CustomerInfoId>
+      <d:Information>び黑ポ畚ぜマチンハ歹黑zクヲネボァたグヲ黑ソЯ歹ぴせポzゼ弌ぞせぜゼ亜Яクあソ亜ゼそせ珱ァタひグゼ縷яぁゾ黑マミ裹暦ポя</d:Information>
+    </m:properties>
+  </entry>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(12)</id>
+    <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+    <link rel="edit" title="CustomerInfo" href="CustomerInfo(12)" />
+    <title />
+    <updated>2014-05-13T12:58:46Z</updated>
+    <author>
+      <name />
+    </author>
+    <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(12)/$value" />
+    <content type="*/*" src="CustomerInfo(12)/$value" />
+    <m:properties>
+      <d:CustomerInfoId m:type="Edm.Int32">12</d:CustomerInfoId>
+      <d:Information>frubhbngipuuveyneosslslbtrßqjujnssgcxuuzdbeußeaductgqbvhpussktbzzfuqvkxajzckmkzluthcjsku</d:Information>
+    </m:properties>
+  </entry>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(13)</id>
+    <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+    <link rel="edit" title="CustomerInfo" href="CustomerInfo(13)" />
+    <title />
+    <updated>2014-05-13T12:58:46Z</updated>
+    <author>
+      <name />
+    </author>
+    <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(13)/$value" />
+    <content type="*/*" src="CustomerInfo(13)/$value" />
+    <m:properties>
+      <d:CustomerInfoId m:type="Edm.Int32">13</d:CustomerInfoId>
+      <d:Information m:null="true" />
+    </m:properties>
+  </entry>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(14)</id>
+    <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+    <link rel="edit" title="CustomerInfo" href="CustomerInfo(14)" />
+    <title />
+    <updated>2014-05-13T12:58:46Z</updated>
+    <author>
+      <name />
+    </author>
+    <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(14)/$value" />
+    <content type="*/*" src="CustomerInfo(14)/$value" />
+    <m:properties>
+      <d:CustomerInfoId m:type="Edm.Int32">14</d:CustomerInfoId>
+      <d:Information>縷ァゾ歹ン裹ミミ九をソタボёネほひミバゼ畚Яソポ亜ほミぺまaタ畚弌匚ぞグぼそ畚ソンゼゼべチチぞミミゼマタ黑ダя縷縷珱せ亜ぴゾソ欲匚ハ九畚裹ハネё歹たゼソチほせびぜンゾ珱ぼネヲぼ九ぼ</d:Information>
+    </m:properties>
+  </entry>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(15)</id>
+    <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+    <link rel="edit" title="CustomerInfo" href="CustomerInfo(15)" />
+    <title />
+    <updated>2014-05-13T12:58:46Z</updated>
+    <author>
+      <name />
+    </author>
+    <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(15)/$value" />
+    <content type="*/*" src="CustomerInfo(15)/$value" />
+    <m:properties>
+      <d:CustomerInfoId m:type="Edm.Int32">15</d:CustomerInfoId>
+      <d:Information></d:Information>
+    </m:properties>
+  </entry>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(16)</id>
+    <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+    <link rel="edit" title="CustomerInfo" href="CustomerInfo(16)" />
+    <title />
+    <updated>2014-05-13T12:58:46Z</updated>
+    <author>
+      <name />
+    </author>
+    <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(16)/$value" />
+    <content type="*/*" src="CustomerInfo(16)/$value" />
+    <m:properties>
+      <d:CustomerInfoId m:type="Edm.Int32">16</d:CustomerInfoId>
+      <d:Information>uuvoqobtxfgtnzugqjsocbhjkynsjafonxuxmcrnyldkxvpnuezalvpyhjpsmkgxacuruxtjruusxylndzxgefpscvk</d:Information>
+    </m:properties>
+  </entry>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(17)</id>
+    <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+    <link rel="edit" title="CustomerInfo" href="CustomerInfo(17)" />
+    <title />
+    <updated>2014-05-13T12:58:46Z</updated>
+    <author>
+      <name />
+    </author>
+    <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(17)/$value" />
+    <content type="*/*" src="CustomerInfo(17)/$value" />
+    <m:properties>
+      <d:CustomerInfoId m:type="Edm.Int32">17</d:CustomerInfoId>
+      <d:Information m:null="true" />
+    </m:properties>
+  </entry>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(18)</id>
+    <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+    <link rel="edit" title="CustomerInfo" href="CustomerInfo(18)" />
+    <title />
+    <updated>2014-05-13T12:58:46Z</updated>
+    <author>
+      <name />
+    </author>
+    <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(18)/$value" />
+    <content type="*/*" src="CustomerInfo(18)/$value" />
+    <m:properties>
+      <d:CustomerInfoId m:type="Edm.Int32">18</d:CustomerInfoId>
+      <d:Information m:null="true" />
+    </m:properties>
+  </entry>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(19)</id>
+    <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+    <link rel="edit" title="CustomerInfo" href="CustomerInfo(19)" />
+    <title />
+    <updated>2014-05-13T12:58:46Z</updated>
+    <author>
+      <name />
+    </author>
+    <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(19)/$value" />
+    <content type="*/*" src="CustomerInfo(19)/$value" />
+    <m:properties>
+      <d:CustomerInfoId m:type="Edm.Int32">19</d:CustomerInfoId>
+      <d:Information>ebmfxjikutjvmudp</d:Information>
+    </m:properties>
+  </entry>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/stub/StaticService/V30/Static.svc/CustomerInfo(20)</id>
+    <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+    <link rel="edit" title="CustomerInfo" href="CustomerInfo(20)" />
+    <title />
+    <updated>2014-05-13T12:58:46Z</updated>
+    <author>
+      <name />
+    </author>
+    <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(20)/$value" />
+    <content type="*/*" src="CustomerInfo(20)/$value" />
+    <m:properties>
+      <d:CustomerInfoId m:type="Edm.Int32">20</d:CustomerInfoId>
+      <d:Information>マびaゼミひグ暦タぽんミaソЯんクポをんЯダ珱ポぼaё九ぁヲЯべほ歹ァソぜボ縷ァン弌バマ亜ぞミ暦ダダポソソボネたんまた匚ぞボ九チぽぜソぜぞチぺミ弌zんぺzひ縷そぴぺべタまチ亜ハ珱びぞ暦ゾぜぺクёёゼ</d:Information>
+    </m:properties>
+  </entry>
+</feed>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/59098455/fit/src/test/java/org/apache/olingo/fit/proxy/v3/ContextTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/ContextTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/ContextTestITCase.java
new file mode 100644
index 0000000..c7e2948
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/ContextTestITCase.java
@@ -0,0 +1,472 @@
+/*
+ * 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.fit.proxy.v3;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.olingo.ext.proxy.api.annotations.NavigationProperty;
+import org.apache.olingo.ext.proxy.commons.EntityTypeInvocationHandler;
+import org.apache.olingo.ext.proxy.context.AttachedEntityStatus;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.
+        ContactDetails;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.
+        Customer;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.
+        CustomerInfo;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.
+        Login;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.
+        Order;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.
+        OrderCollection;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.
+        Phone;
+import org.junit.Test;
+
+/**
+ * This is the unit test class to check entity retrieve operations.
+ */
+public class ContextTestITCase extends AbstractTestITCase {
+
+  @Test
+  public void attachDetachNewEntity() {
+    final Customer customer1 = container.getCustomer().newCustomer();
+    final Customer customer2 = container.getCustomer().newCustomer();
+
+    final EntityTypeInvocationHandler source1 =
+            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer1);
+    final EntityTypeInvocationHandler source2 =
+            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer2);
+
+    assertTrue(entityContext.isAttached(source1));
+    assertTrue(entityContext.isAttached(source2));
+
+    entityContext.detach(source1);
+    assertFalse(entityContext.isAttached(source1));
+    assertTrue(entityContext.isAttached(source2));
+
+    entityContext.detach(source2);
+    assertFalse(entityContext.isAttached(source1));
+    assertFalse(entityContext.isAttached(source2));
+  }
+
+  @Test
+  public void attachDetachExistingEntity() {
+    final Customer customer1 = container.getCustomer().get(-10);
+    final Customer customer2 = container.getCustomer().get(-9);
+    final Customer customer3 = container.getCustomer().get(-10);
+
+    final EntityTypeInvocationHandler source1 =
+            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer1);
+    final EntityTypeInvocationHandler source2 =
+            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer2);
+    final EntityTypeInvocationHandler source3 =
+            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer3);
+
+    assertFalse(entityContext.isAttached(source1));
+    assertFalse(entityContext.isAttached(source2));
+    assertFalse(entityContext.isAttached(source3));
+
+    entityContext.attach(source1);
+    assertTrue(entityContext.isAttached(source1));
+    assertFalse(entityContext.isAttached(source2));
+    assertTrue(entityContext.isAttached(source3));
+
+    entityContext.attach(source2);
+    assertTrue(entityContext.isAttached(source1));
+    assertTrue(entityContext.isAttached(source2));
+    assertTrue(entityContext.isAttached(source3));
+
+    try {
+      entityContext.attach(source3);
+      fail();
+    } catch (IllegalStateException ignore) {
+      // ignore
+    }
+
+    entityContext.detach(source1);
+    assertFalse(entityContext.isAttached(source1));
+    assertTrue(entityContext.isAttached(source2));
+    assertFalse(entityContext.isAttached(source3));
+
+    entityContext.detach(source2);
+    assertFalse(entityContext.isAttached(source1));
+    assertFalse(entityContext.isAttached(source2));
+    assertFalse(entityContext.isAttached(source3));
+  }
+
+  @Test
+  public void linkTargetExisting() {
+    final Customer customer = container.getCustomer().newCustomer();
+    final CustomerInfo customerInfo = container.getCustomerInfo().get(11);
+
+    customer.setInfo(customerInfo);
+
+    assertNotNull(customer.getInfo());
+
+    final EntityTypeInvocationHandler source =
+            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer);
+    final EntityTypeInvocationHandler target =
+            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo);
+
+    assertTrue(entityContext.isAttached(source));
+    assertEquals(AttachedEntityStatus.NEW, entityContext.getStatus(source));
+    assertTrue(entityContext.isAttached(target));
+    assertEquals(AttachedEntityStatus.LINKED, entityContext.getStatus(target));
+
+    checkUnidirectional("Info", source, "Customer", target, false);
+
+    entityContext.detachAll();
+
+    assertFalse(entityContext.isAttached(source));
+    assertFalse(entityContext.isAttached(target));
+  }
+
+  @Test
+  public void linkSourceExisting() {
+    final Customer customer = container.getCustomer().get(-10);;
+    final CustomerInfo customerInfo = container.getCustomerInfo().newCustomerInfo();
+
+    customer.setInfo(customerInfo);
+
+    assertNotNull(customer.getInfo());
+
+    final EntityTypeInvocationHandler source =
+            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer);
+    final EntityTypeInvocationHandler target =
+            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo);
+
+    assertTrue(entityContext.isAttached(source));
+    assertEquals(AttachedEntityStatus.CHANGED, entityContext.getStatus(source));
+    assertTrue(entityContext.isAttached(target));
+    assertEquals(AttachedEntityStatus.NEW, entityContext.getStatus(target));
+
+    checkUnidirectional("Info", source, "Customer", target, false);
+
+    entityContext.detachAll();
+
+    assertFalse(entityContext.isAttached(source));
+    assertFalse(entityContext.isAttached(target));
+  }
+
+  @Test
+  public void linkBothExisting() {
+    final Customer customer = container.getCustomer().get(-10);
+    final CustomerInfo customerInfo = container.getCustomerInfo().get(12);
+
+    customer.setInfo(customerInfo);
+
+    assertNotNull(customer.getInfo());
+
+    final EntityTypeInvocationHandler source =
+            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer);
+    final EntityTypeInvocationHandler target =
+            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo);
+
+    assertTrue(entityContext.isAttached(source));
+    assertEquals(AttachedEntityStatus.CHANGED, entityContext.getStatus(source));
+    assertTrue(entityContext.isAttached(target));
+    assertEquals(AttachedEntityStatus.LINKED, entityContext.getStatus(target));
+
+    checkUnidirectional("Info", source, "Customer", target, false);
+
+    entityContext.detachAll();
+
+    assertFalse(entityContext.isAttached(source));
+    assertFalse(entityContext.isAttached(target));
+  }
+
+  @Test
+  public void linkEntitySet() {
+    final Customer customer = container.getCustomer().newCustomer();
+
+    final OrderCollection toBeLinked = container.getOrder().newOrderCollection();
+    toBeLinked.add(container.getOrder().newOrder());
+    toBeLinked.add(container.getOrder().newOrder());
+    toBeLinked.add(container.getOrder().newOrder());
+
+    customer.setOrders(toBeLinked);
+    assertNotNull(customer.getOrders());
+    assertEquals(3, customer.getOrders().size());
+
+    final EntityTypeInvocationHandler<?> source =
+            (EntityTypeInvocationHandler<?>) Proxy.getInvocationHandler(customer);
+
+    assertTrue(entityContext.isAttached(source));
+    assertEquals(AttachedEntityStatus.NEW, entityContext.getStatus(source));
+    assertEquals(3, ((Collection) (source.getLinkChanges().entrySet().iterator().next().getValue())).size());
+
+    for (Order order : toBeLinked) {
+      final EntityTypeInvocationHandler<?> target =
+              (EntityTypeInvocationHandler<?>) Proxy.getInvocationHandler(order);
+
+      assertTrue(entityContext.isAttached(target));
+      assertEquals(AttachedEntityStatus.NEW, entityContext.getStatus(target));
+      checkUnidirectional("Orders", source, "Customer", target, true);
+    }
+
+    entityContext.detachAll();
+
+    assertFalse(entityContext.isAttached(source));
+
+    for (Order order : toBeLinked) {
+      assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(order)));
+    }
+  }
+
+  @Test
+  public void addProperty() {
+    final Customer customer = container.getCustomer().newCustomer();
+    customer.setCustomerId(100);
+
+    final ContactDetails cd = customer.factory().newPrimaryContactInfo();
+    customer.setPrimaryContactInfo(cd);
+
+    cd.setAlternativeNames(Arrays.asList("alternative1", "alternative2"));
+
+    final ContactDetails bcd = customer.factory().newBackupContactInfo();
+    customer.setBackupContactInfo(Collections.<ContactDetails>singletonList(bcd));
+
+    bcd.setAlternativeNames(Arrays.asList("alternative3", "alternative4"));
+
+    assertEquals(Integer.valueOf(100), customer.getCustomerId());
+    assertNotNull(customer.getPrimaryContactInfo().getAlternativeNames());
+    assertEquals(2, customer.getPrimaryContactInfo().getAlternativeNames().size());
+    assertTrue(customer.getPrimaryContactInfo().getAlternativeNames().contains("alternative1"));
+    assertEquals(2, customer.getBackupContactInfo().iterator().next().getAlternativeNames().size());
+    assertTrue(customer.getBackupContactInfo().iterator().next().getAlternativeNames().contains("alternative4"));
+
+    final EntityTypeInvocationHandler source = (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer);
+
+    assertTrue(entityContext.isAttached(source));
+    assertEquals(AttachedEntityStatus.NEW, entityContext.getStatus(source));
+
+    entityContext.detachAll();
+
+    assertFalse(entityContext.isAttached(source));
+  }
+
+  @Test
+  public void readEntityInTheContext() {
+    CustomerInfo customerInfo = container.getCustomerInfo().get(16);
+    customerInfo.setInformation("some other info ...");
+
+    assertEquals("some other info ...", customerInfo.getInformation());
+
+    customerInfo = container.getCustomerInfo().get(16);
+    assertEquals("some other info ...", customerInfo.getInformation());
+
+    entityContext.detachAll();
+    customerInfo = container.getCustomerInfo().get(16);
+    assertNotEquals("some other info ...", customerInfo.getInformation());
+  }
+
+  @Test
+  public void readAllWithEntityInTheContext() {
+    CustomerInfo customerInfo = container.getCustomerInfo().get(16);
+    customerInfo.setInformation("some other info ...");
+
+    assertEquals("some other info ...", customerInfo.getInformation());
+
+    boolean found = false;
+    for (CustomerInfo info : container.getCustomerInfo().getAll()) {
+      if (info.getCustomerInfoId() == 16) {
+        assertEquals("some other info ...", customerInfo.getInformation());
+        found = true;
+      }
+    }
+    assertTrue(found);
+
+    entityContext.detachAll();
+
+    found = false;
+    for (CustomerInfo info : container.getCustomerInfo().getAll()) {
+      if (info.getCustomerInfoId() == 16) {
+        assertNotEquals("some other info ...", info.getInformation());
+        found = true;
+      }
+    }
+    assertTrue(found);
+  }
+
+  @Test
+  public void checkContextInCaseOfErrors() {
+    final Login login = container.getLogin().newLogin();
+
+    final EntityTypeInvocationHandler handler = (EntityTypeInvocationHandler) Proxy.getInvocationHandler(login);
+
+    assertTrue(entityContext.isAttached(handler));
+
+    try {
+      container.flush();
+      fail();
+    } catch (Exception e) {
+      // ignore
+    }
+
+    assertTrue(entityContext.isAttached(handler));
+
+    login.setCustomerId(-10);
+    login.setUsername("customer");
+
+    container.flush();
+    assertFalse(entityContext.isAttached(handler));
+    assertNotNull(container.getLogin().get("customer"));
+
+    container.getLogin().delete(login.getUsername());
+    assertTrue(entityContext.isAttached(handler));
+
+    container.flush();
+    assertFalse(entityContext.isAttached(handler));
+    assertNull(container.getLogin().get("customer"));
+  }
+
+  @Test
+  public void flushTest() {
+    Customer customer = container.getCustomer().newCustomer();
+    customer.setCustomerId(300);
+    customer.setName("samplename");
+
+    final List<Integer> keys = new ArrayList<Integer>();
+    keys.add(-200);
+    keys.add(-201);
+    keys.add(-202);
+
+    final OrderCollection toBeLinked = container.getOrder().newOrderCollection();
+    for (Integer key : keys) {
+      final Order order = container.getOrder().newOrder();
+      order.setOrderId(key);
+      order.setCustomerId(300);
+      order.setCustomer(customer);
+      toBeLinked.add(order);
+    }
+
+    customer.setOrders(toBeLinked);
+
+    final CustomerInfo customerInfo = container.getCustomerInfo().get(16);
+    customerInfo.setInformation("some new info ...");
+    customer.setInfo(customerInfo);
+
+    final ContactDetails cd = customer.factory().newPrimaryContactInfo();
+    cd.setAlternativeNames(Arrays.asList("alternative1", "alternative2"));
+    cd.setEmailBag(Collections.<String>singleton("myemail@mydomain.org"));
+    cd.setMobilePhoneBag(Collections.<Phone>emptySet());
+
+    final ContactDetails bcd = customer.factory().newBackupContactInfo();
+    bcd.setAlternativeNames(Arrays.asList("alternative3", "alternative4"));
+    bcd.setEmailBag(Collections.<String>emptySet());
+    bcd.setMobilePhoneBag(Collections.<Phone>emptySet());
+
+    customer.setPrimaryContactInfo(cd);
+    customer.setBackupContactInfo(Collections.<ContactDetails>singletonList(bcd));
+
+    assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo)));
+    assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer)));
+    for (Order linked : toBeLinked) {
+      assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(linked)));
+    }
+
+    container.flush();
+
+    assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo)));
+    assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer)));
+    for (Order linked : toBeLinked) {
+      assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(linked)));
+    }
+
+    assertEquals("some new info ...", container.getCustomerInfo().get(16).getInformation());
+
+    container.getOrder().delete(toBeLinked);
+    container.getCustomer().delete(customer.getCustomerId());
+
+    assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer)));
+    for (Order linked : toBeLinked) {
+      assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(linked)));
+    }
+
+    container.flush();
+
+    assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer)));
+    for (Order linked : toBeLinked) {
+      assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(linked)));
+    }
+  }
+
+  private void checkUnlink(
+          final String sourceName,
+          final EntityTypeInvocationHandler<?> source) {
+
+    boolean found = false;
+    for (Map.Entry<NavigationProperty, Object> property : source.getLinkChanges().entrySet()) {
+      if (property.getKey().name().equals(sourceName)) {
+        found = true;
+      }
+    }
+    assertFalse(found);
+  }
+
+  private void checkLink(
+          final String sourceName,
+          final EntityTypeInvocationHandler<?> source,
+          final EntityTypeInvocationHandler<?> target,
+          final boolean isCollection) {
+
+    boolean found = false;
+    for (Map.Entry<NavigationProperty, Object> property : source.getLinkChanges().entrySet()) {
+      if (property.getKey().name().equals(sourceName)) {
+        if (isCollection) {
+          found = false;
+          for (Object proxy : (Collection) property.getValue()) {
+            if (target.equals((EntityTypeInvocationHandler) Proxy.getInvocationHandler(proxy))) {
+              found = true;
+            }
+          }
+        } else {
+          found = target.equals(
+                  (EntityTypeInvocationHandler) Proxy.getInvocationHandler(property.getValue()));
+        }
+      }
+    }
+    assertTrue(found);
+  }
+
+  private void checkUnidirectional(
+          final String sourceName,
+          final EntityTypeInvocationHandler<?> source,
+          final String targetName,
+          final EntityTypeInvocationHandler<?> target,
+          final boolean isCollection) {
+
+    checkLink(sourceName, source, target, isCollection);
+    checkUnlink(targetName, target);
+  }
+}