You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by il...@apache.org on 2014/05/17 16:06:39 UTC

[4/5] [OLINGO-260] contained tests

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
index 18c2ce2..6e70a0e 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
@@ -73,8 +73,6 @@ class EntitySetInvocationHandler<
    */
   private static final Logger LOG = LoggerFactory.getLogger(EntitySetInvocationHandler.class);
 
-  private final String entitySetName;
-
   private final boolean isSingleton;
 
   private final Class<T> typeRef;
@@ -85,20 +83,38 @@ class EntitySetInvocationHandler<
 
   @SuppressWarnings({"rawtypes", "unchecked"})
   static EntitySetInvocationHandler getInstance(
-          final Class<?> ref, final EntityContainerInvocationHandler containerHandler) {
+          final Class<?> ref, final EntityContainerInvocationHandler containerHandler, final String entitySetName) {
+
+    final CommonURIBuilder<?> uriBuilder = containerHandler.getClient().
+            getURIBuilder(containerHandler.getFactory().getServiceRoot());
 
-    return new EntitySetInvocationHandler(ref, containerHandler, (ref.getAnnotation(EntitySet.class)).name());
+    final StringBuilder entitySetSegment = new StringBuilder();
+    if (!containerHandler.isDefaultEntityContainer()) {
+      entitySetSegment.append(containerHandler.getEntityContainerName()).append('.');
+    }
+    entitySetSegment.append(entitySetName);
+
+    uriBuilder.appendEntitySetSegment(entitySetSegment.toString());
+
+    return new EntitySetInvocationHandler(ref, containerHandler, entitySetName, uriBuilder.build());
+  }
+
+  @SuppressWarnings({"rawtypes", "unchecked"})
+  static EntitySetInvocationHandler getInstance(
+          final Class<?> ref, final EntityContainerInvocationHandler containerHandler, final URI uri) {
+
+    return new EntitySetInvocationHandler(ref, containerHandler, (ref.getAnnotation(EntitySet.class)).name(), uri);
   }
 
   @SuppressWarnings("unchecked")
   protected EntitySetInvocationHandler(
           final Class<?> ref,
           final EntityContainerInvocationHandler containerHandler,
-          final String entitySetName) {
+          final String entitySetName,
+          final URI uri) {
 
     super(containerHandler.getClient(), containerHandler);
 
-    this.entitySetName = entitySetName;
     this.isSingleton = AbstractSingleton.class.isAssignableFrom(ref);
 
     final Type[] entitySetParams = ((ParameterizedType) ref.getGenericInterfaces()[0]).getActualTypeArguments();
@@ -106,16 +122,7 @@ class EntitySetInvocationHandler<
     this.typeRef = (Class<T>) entitySetParams[0];
     this.collTypeRef = (Class<EC>) entitySetParams[2];
 
-    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(containerHandler.getFactory().getServiceRoot());
-
-    final StringBuilder entitySetSegment = new StringBuilder();
-    if (!containerHandler.isDefaultEntityContainer()) {
-      entitySetSegment.append(containerHandler.getEntityContainerName()).append('.');
-    }
-    entitySetSegment.append(entitySetName);
-
-    uriBuilder.appendEntitySetSegment(entitySetSegment.toString());
-    this.uri = uriBuilder.build();
+    this.uri = uri;
   }
 
   protected Class<T> getTypeRef() {
@@ -126,11 +133,7 @@ class EntitySetInvocationHandler<
     return collTypeRef;
   }
 
-  protected String getEntitySetName() {
-    return entitySetName;
-  }
-
-  protected URI getURI() {
+  protected URI getEntitySetURI() {
     return uri;
   }
 
@@ -155,8 +158,8 @@ class EntitySetInvocationHandler<
     final CommonODataEntity entity = client.getObjectFactory().newEntity(
             new FullQualifiedName(containerHandler.getSchemaName(), ClassUtils.getEntityTypeName(reference)));
 
-    final EntityTypeInvocationHandler handler =
-            EntityTypeInvocationHandler.getInstance(entity, entitySetName, reference, containerHandler);
+    final EntityInvocationHandler handler =
+            EntityInvocationHandler.getInstance(null, entity, uri, reference, containerHandler);
     EntityContainerFactory.getContext().entityContext().attachNew(handler);
 
     return (NE) Proxy.newProxyInstance(
@@ -188,7 +191,7 @@ class EntitySetInvocationHandler<
     try {
       result = get(key) != null;
     } catch (Exception e) {
-      LOG.error("Could not check existence of {}({})", this.entitySetName, key, e);
+      LOG.error("Could not check existence of {}({})", this.uri, key, e);
     }
 
     return result;
@@ -230,10 +233,10 @@ class EntitySetInvocationHandler<
       throw new IllegalArgumentException("Null key");
     }
 
-    final EntityUUID uuid = new EntityUUID(containerHandler.getEntityContainerName(), entitySetName, typeRef, key);
+    final EntityUUID uuid = new EntityUUID(containerHandler.getEntityContainerName(), uri, typeRef, key);
     LOG.debug("Ask for '{}({})'", typeRef.getSimpleName(), key);
 
-    EntityTypeInvocationHandler handler = EntityContainerFactory.getContext().entityContext().getEntity(uuid);
+    EntityInvocationHandler handler = EntityContainerFactory.getContext().entityContext().getEntity(uuid);
 
     if (handler == null) {
       // not yet attached: search against the service
@@ -261,7 +264,7 @@ class EntitySetInvocationHandler<
           throw new IllegalArgumentException("Invalid " + typeRef.getSimpleName() + "(" + key + ")");
         }
 
-        handler = EntityTypeInvocationHandler.getInstance(entity, this, typeRef);
+        handler = EntityInvocationHandler.getInstance(uriBuilder.build(), entity, this, typeRef);
         handler.setETag(etag);
       } catch (Exception e) {
         LOG.info("Entity '" + uuid + "' not found", e);
@@ -301,9 +304,10 @@ class EntitySetInvocationHandler<
     final List<S> items = new ArrayList<S>(entities.size());
 
     for (CommonODataEntity entity : entities) {
-      final EntityTypeInvocationHandler handler = EntityTypeInvocationHandler.getInstance(entity, this, typeRef);
+      final EntityInvocationHandler handler =
+              EntityInvocationHandler.getInstance(entity.getEditLink(), entity, this, typeRef);
 
-      final EntityTypeInvocationHandler handlerInTheContext =
+      final EntityInvocationHandler handlerInTheContext =
               EntityContainerFactory.getContext().entityContext().getEntity(handler.getUUID());
 
       items.add((S) Proxy.newProxyInstance(
@@ -396,16 +400,16 @@ class EntitySetInvocationHandler<
   public void delete(final KEY key) throws IllegalArgumentException {
     final EntityContext entityContext = EntityContainerFactory.getContext().entityContext();
 
-    EntityTypeInvocationHandler entity = entityContext.getEntity(new EntityUUID(
+    EntityInvocationHandler entity = entityContext.getEntity(new EntityUUID(
             containerHandler.getEntityContainerName(),
-            entitySetName,
+            uri,
             typeRef,
             key));
 
     if (entity == null) {
       // search for entity
       final T searched = get(key);
-      entity = (EntityTypeInvocationHandler) Proxy.getInvocationHandler(searched);
+      entity = (EntityInvocationHandler) Proxy.getInvocationHandler(searched);
       entityContext.attach(entity, AttachedEntityStatus.DELETED);
     } else {
       entityContext.setStatus(entity, AttachedEntityStatus.DELETED);
@@ -417,7 +421,7 @@ class EntitySetInvocationHandler<
     final EntityContext entityContext = EntityContainerFactory.getContext().entityContext();
 
     for (T en : entities) {
-      final EntityTypeInvocationHandler entity = (EntityTypeInvocationHandler) Proxy.getInvocationHandler(en);
+      final EntityInvocationHandler entity = (EntityInvocationHandler) Proxy.getInvocationHandler(en);
       if (entityContext.isAttached(entity)) {
         entityContext.setStatus(entity, AttachedEntityStatus.DELETED);
       } else {
@@ -426,7 +430,7 @@ class EntitySetInvocationHandler<
     }
   }
 
-  private boolean isDeleted(final EntityTypeInvocationHandler handler) {
+  private boolean isDeleted(final EntityInvocationHandler handler) {
     return EntityContainerFactory.getContext().entityContext().getStatus(handler) == AttachedEntityStatus.DELETED;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/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
deleted file mode 100644
index 57b73d0..0000000
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.olingo.ext.proxy.commons;
-
-import java.io.InputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.lang.reflect.Type;
-import java.net.URI;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.client.api.communication.request.retrieve.ODataMediaRequest;
-import org.apache.olingo.client.core.uri.URIUtils;
-import org.apache.olingo.commons.api.domain.CommonODataEntity;
-import org.apache.olingo.commons.api.domain.CommonODataProperty;
-import org.apache.olingo.commons.api.domain.ODataLinked;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
-import org.apache.olingo.commons.api.format.ODataMediaFormat;
-import org.apache.olingo.ext.proxy.api.annotations.EntityType;
-import org.apache.olingo.ext.proxy.api.annotations.NavigationProperty;
-import org.apache.olingo.ext.proxy.api.annotations.Property;
-import org.apache.olingo.ext.proxy.context.AttachedEntityStatus;
-import org.apache.olingo.ext.proxy.context.EntityUUID;
-import org.apache.olingo.ext.proxy.utils.CoreUtils;
-
-public class EntityTypeInvocationHandler extends AbstractTypeInvocationHandler {
-
-  private static final long serialVersionUID = 2629912294765040037L;
-
-  protected Map<String, Object> propertyChanges = new HashMap<String, Object>();
-
-  protected Map<NavigationProperty, Object> linkChanges = new HashMap<NavigationProperty, Object>();
-
-  protected int propertiesTag = 0;
-
-  protected int linksTag = 0;
-
-  private Map<String, InputStream> streamedPropertyChanges = new HashMap<String, InputStream>();
-
-  private InputStream stream;
-
-  private EntityUUID uuid;
-
-  static EntityTypeInvocationHandler getInstance(
-          final CommonODataEntity entity,
-          final EntitySetInvocationHandler<?, ?, ?> entitySet,
-          final Class<?> typeRef) {
-
-    return getInstance(
-            entity,
-            entitySet.getEntitySetName(),
-            typeRef,
-            entitySet.containerHandler);
-  }
-
-  static EntityTypeInvocationHandler getInstance(
-          final CommonODataEntity entity,
-          final String entitySetName,
-          final Class<?> typeRef,
-          final EntityContainerInvocationHandler containerHandler) {
-
-    return new EntityTypeInvocationHandler(entity, entitySetName, typeRef, containerHandler);
-  }
-
-  private EntityTypeInvocationHandler(
-          final CommonODataEntity entity,
-          final String entitySetName,
-          final Class<?> typeRef,
-          final EntityContainerInvocationHandler containerHandler) {
-
-    super(containerHandler.getClient(), typeRef, (ODataLinked) entity, containerHandler);
-
-    this.internal = entity;
-    getEntity().setMediaEntity(typeRef.getAnnotation(EntityType.class).hasStream());
-
-    this.uuid = new EntityUUID(
-            containerHandler.getEntityContainerName(),
-            entitySetName,
-            typeRef,
-            CoreUtils.getKey(client, typeRef, entity));
-  }
-
-  public void setEntity(final CommonODataEntity entity) {
-    this.internal = entity;
-    getEntity().setMediaEntity(typeRef.getAnnotation(EntityType.class).hasStream());
-
-    this.uuid = new EntityUUID(
-            getUUID().getContainerName(),
-            getUUID().getEntitySetName(),
-            getUUID().getType(),
-            CoreUtils.getKey(client, typeRef, entity));
-
-    this.propertyChanges.clear();
-    this.linkChanges.clear();
-    this.streamedPropertyChanges.clear();
-    this.propertiesTag = 0;
-    this.linksTag = 0;
-  }
-
-  public EntityUUID getUUID() {
-    return uuid;
-  }
-
-  public String getEntityContainerName() {
-    return uuid.getContainerName();
-  }
-
-  public String getEntitySetName() {
-    return uuid.getEntitySetName();
-  }
-
-  public final CommonODataEntity getEntity() {
-    return (CommonODataEntity) internal;
-  }
-
-  /**
-   * Gets the current ETag defined into the wrapped entity.
-   *
-   * @return
-   */
-  public String getETag() {
-    return getEntity().getETag();
-  }
-
-  /**
-   * Overrides ETag value defined into the wrapped entity.
-   *
-   * @param eTag ETag.
-   */
-  public void setETag(final String eTag) {
-    getEntity().setETag(eTag);
-  }
-
-  public Map<String, Object> getPropertyChanges() {
-    return propertyChanges;
-  }
-
-  public Map<NavigationProperty, Object> getLinkChanges() {
-    return linkChanges;
-  }
-
-  private void updatePropertiesTag(final int checkpoint) {
-    if (checkpoint == propertiesTag) {
-      propertiesTag = propertyChanges.hashCode();
-    }
-  }
-
-  private void updateLinksTag(final int checkpoint) {
-    if (checkpoint == linksTag) {
-      linksTag = linkChanges.hashCode();
-    }
-  }
-
-  @Override
-  protected Object getPropertyValue(final String name, final Type type) {
-    try {
-      final CommonODataProperty property = getEntity().getProperty(name);
-
-      Object res;
-      if (propertyChanges.containsKey(name)) {
-        res = propertyChanges.get(name);
-      } else {
-        res = CoreUtils.getValueFromProperty(client, property, type, this);
-
-        if (res != null) {
-          addPropertyChanges(name, res);
-        }
-      }
-
-      return res;
-    } catch (Exception e) {
-      throw new IllegalArgumentException("Error getting value for property '" + name + "'", e);
-    }
-  }
-
-  @Override
-  public Collection<String> getAdditionalPropertyNames() {
-    final Set<String> res = new HashSet<String>(propertyChanges.keySet());
-    final Set<String> propertyNames = new HashSet<String>();
-    for (Method method : typeRef.getMethods()) {
-      final Annotation ann = method.getAnnotation(Property.class);
-      if (ann != null) {
-        final String property = ((Property) ann).name();
-        propertyNames.add(property);
-
-        // maybe someone could add a normal attribute to the additional set
-        res.remove(property);
-      }
-    }
-
-    for (CommonODataProperty property : getEntity().getProperties()) {
-      if (!propertyNames.contains(property.getName())) {
-        res.add(property.getName());
-      }
-    }
-
-    return res;
-  }
-
-  @Override
-  @SuppressWarnings("unchecked")
-  protected void setPropertyValue(final Property property, final Object value) {
-    if (property.type().equalsIgnoreCase(EdmPrimitiveTypeKind.Stream.toString())) {
-      setStreamedProperty(property, (InputStream) value);
-    } else {
-      addPropertyChanges(property.name(), value);
-
-      if (value != null) {
-        final Collection<?> coll;
-        if (Collection.class.isAssignableFrom(value.getClass())) {
-          coll = Collection.class.cast(value);
-        } else {
-          coll = Collections.singleton(value);
-        }
-
-        for (Object item : coll) {
-          if (item instanceof Proxy) {
-            final InvocationHandler handler = Proxy.getInvocationHandler(item);
-            if ((handler instanceof ComplexTypeInvocationHandler)
-                    && ((ComplexTypeInvocationHandler) handler).getEntityHandler() == null) {
-              ((ComplexTypeInvocationHandler) handler).setEntityHandler(this);
-            }
-          }
-        }
-      }
-    }
-
-    attach(AttachedEntityStatus.CHANGED);
-  }
-
-  @Override
-  public boolean isChanged() {
-    return this.linkChanges.hashCode() != this.linksTag
-            || this.propertyChanges.hashCode() != this.propertiesTag
-            || this.stream != null
-            || !this.streamedPropertyChanges.isEmpty();
-  }
-
-  public void setStream(final InputStream stream) {
-    if (typeRef.getAnnotation(EntityType.class).hasStream()) {
-      IOUtils.closeQuietly(this.stream);
-      this.stream = stream;
-      attach(AttachedEntityStatus.CHANGED);
-    }
-  }
-
-  public InputStream getStreamChanges() {
-    return this.stream;
-  }
-
-  public Map<String, InputStream> getStreamedPropertyChanges() {
-    return streamedPropertyChanges;
-  }
-
-  public InputStream getStream() {
-
-    final URI contentSource = getEntity().getMediaContentSource();
-
-    if (this.stream == null
-            && typeRef.getAnnotation(EntityType.class).hasStream()
-            && contentSource != null) {
-
-      final String contentType =
-              StringUtils.isBlank(getEntity().getMediaContentType()) ? "*/*" : getEntity().getMediaContentType();
-
-      final ODataMediaRequest retrieveReq = client.getRetrieveRequestFactory().getMediaRequest(contentSource);
-      retrieveReq.setFormat(ODataMediaFormat.fromFormat(contentType));
-
-      this.stream = retrieveReq.execute().getBody();
-    }
-
-    return this.stream;
-  }
-
-  public Object getStreamedProperty(final Property property) {
-
-    InputStream res = streamedPropertyChanges.get(property.name());
-
-    try {
-      if (res == null) {
-        final URI link = URIUtils.getURI(
-                containerHandler.getFactory().getServiceRoot(),
-                CoreUtils.getMediaEditLink(property.name(), getEntity()).toASCIIString());
-
-        final ODataMediaRequest req = client.getRetrieveRequestFactory().getMediaRequest(link);
-        res = req.execute().getBody();
-
-      }
-    } catch (Exception e) {
-      res = null;
-    }
-
-    return res;
-
-  }
-
-  private void setStreamedProperty(final Property property, final InputStream input) {
-    final Object obj = propertyChanges.get(property.name());
-    if (obj instanceof InputStream) {
-      IOUtils.closeQuietly((InputStream) obj);
-    }
-
-    streamedPropertyChanges.put(property.name(), input);
-  }
-
-  @Override
-  protected Object getNavigationPropertyValue(final NavigationProperty property, final Method getter) {
-    final Object navPropValue;
-
-    if (linkChanges.containsKey(property)) {
-      navPropValue = linkChanges.get(property);
-    } else {
-      navPropValue = retriveNavigationProperty(property, getter);
-    }
-
-    if (navPropValue != null) {
-      addLinkChanges(property, navPropValue);
-    }
-
-    return navPropValue;
-  }
-
-  @Override
-  protected void addPropertyChanges(final String name, final Object value) {
-    final int checkpoint = propertyChanges.hashCode();
-    propertyChanges.put(name, value);
-    updatePropertiesTag(checkpoint);
-  }
-
-  @Override
-  protected void addLinkChanges(final NavigationProperty navProp, final Object value) {
-    final int checkpoint = linkChanges.hashCode();
-    linkChanges.put(navProp, value);
-    updateLinksTag(checkpoint);
-  }
-
-  @Override
-  public String toString() {
-    return uuid.toString();
-  }
-
-  @Override
-  public int hashCode() {
-    return uuid.hashCode();
-  }
-
-  @Override
-  public boolean equals(final Object obj) {
-    return obj instanceof EntityTypeInvocationHandler
-            && ((EntityTypeInvocationHandler) obj).getUUID().equals(uuid);
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
index cdc0bfb..69e1f9b 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
@@ -55,7 +55,7 @@ class OperationInvocationHandler extends AbstractInvocationHandler implements Op
     return new OperationInvocationHandler(containerHandler);
   }
 
-  static OperationInvocationHandler getInstance(final EntityTypeInvocationHandler entityHandler) {
+  static OperationInvocationHandler getInstance(final EntityInvocationHandler entityHandler) {
     return new OperationInvocationHandler(entityHandler);
   }
 
@@ -74,7 +74,7 @@ class OperationInvocationHandler extends AbstractInvocationHandler implements Op
     this.serviceRoot = containerHandler.getFactory().getServiceRoot();
   }
 
-  private OperationInvocationHandler(final EntityTypeInvocationHandler entityHandler) {
+  private OperationInvocationHandler(final EntityInvocationHandler entityHandler) {
     super(entityHandler.getClient(), entityHandler.containerHandler);
 
     this.target = entityHandler;
@@ -128,7 +128,7 @@ class OperationInvocationHandler extends AbstractInvocationHandler implements Op
         final Map.Entry<URI, EdmOperation> edmOperation;
         if (target instanceof EntityContainerInvocationHandler) {
           edmOperation = getUnboundOperation(operation, parameterNames);
-        } else if (target instanceof EntityTypeInvocationHandler) {
+        } else if (target instanceof EntityInvocationHandler) {
           edmOperation = getBoundOperation(operation, parameterNames);
         } else if (target instanceof EntityCollectionInvocationHandler) {
           edmOperation = getCollectionBoundOperation(operation, parameterNames);
@@ -161,7 +161,7 @@ class OperationInvocationHandler extends AbstractInvocationHandler implements Op
   }
 
   private Map.Entry<URI, EdmOperation> getBoundOperation(final Operation operation, final List<String> parameterNames) {
-    final CommonODataEntity entity = ((EntityTypeInvocationHandler) target).getEntity();
+    final CommonODataEntity entity = ((EntityInvocationHandler) target).getEntity();
 
     ODataOperation boundOp = entity.getOperation(operation.name());
     if (boundOp == null) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/SingletonInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/SingletonInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/SingletonInvocationHandler.java
index 4ec75eb..57b1b39 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/SingletonInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/SingletonInvocationHandler.java
@@ -22,7 +22,6 @@ import java.io.Serializable;
 import java.lang.reflect.Method;
 import org.apache.olingo.ext.proxy.api.AbstractEntityCollection;
 import org.apache.olingo.ext.proxy.api.AbstractSingleton;
-import org.apache.olingo.ext.proxy.api.annotations.Singleton;
 
 public class SingletonInvocationHandler<
         T extends Serializable, KEY extends Serializable, EC extends AbstractEntityCollection<T>>
@@ -33,18 +32,19 @@ public class SingletonInvocationHandler<
 
   @SuppressWarnings({"rawtypes", "unchecked"})
   static SingletonInvocationHandler getInstance(
-          final Class<?> ref, final EntityContainerInvocationHandler containerHandler) {
+          final Class<?> ref, final EntityContainerInvocationHandler containerHandler, final String singletonName) {
 
-    return new SingletonInvocationHandler(ref, containerHandler);
+    return new SingletonInvocationHandler(ref, containerHandler, singletonName);
   }
 
   private final EntitySetInvocationHandler<?, ?, ?> entitySetHandler;
 
   @SuppressWarnings({"rawtypes", "unchecked"})
-  private SingletonInvocationHandler(final Class<?> ref, final EntityContainerInvocationHandler containerHandler) {
+  private SingletonInvocationHandler(
+          final Class<?> ref, final EntityContainerInvocationHandler containerHandler, final String singletonName) {
+
     super(containerHandler.getClient(), containerHandler);
-    this.entitySetHandler =
-            new EntitySetInvocationHandler(ref, containerHandler, (ref.getAnnotation(Singleton.class)).name());
+    this.entitySetHandler = EntitySetInvocationHandler.getInstance(ref, containerHandler, singletonName);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/AttachedEntity.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/AttachedEntity.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/AttachedEntity.java
index 96cad42..8126bcc 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/AttachedEntity.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/AttachedEntity.java
@@ -18,20 +18,20 @@
  */
 package org.apache.olingo.ext.proxy.context;
 
-import org.apache.olingo.ext.proxy.commons.EntityTypeInvocationHandler;
+import org.apache.olingo.ext.proxy.commons.EntityInvocationHandler;
 
 public class AttachedEntity {
 
-  private final EntityTypeInvocationHandler entity;
+  private final EntityInvocationHandler entity;
 
   private final AttachedEntityStatus status;
 
-  public AttachedEntity(final EntityTypeInvocationHandler entity, final AttachedEntityStatus status) {
+  public AttachedEntity(final EntityInvocationHandler entity, final AttachedEntityStatus status) {
     this.entity = entity;
     this.status = status;
   }
 
-  public EntityTypeInvocationHandler getEntity() {
+  public EntityInvocationHandler getEntity() {
     return entity;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java
index ab2c9a8..2b42cd1 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java
@@ -24,7 +24,7 @@ import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import org.apache.olingo.ext.proxy.commons.EntityTypeInvocationHandler;
+import org.apache.olingo.ext.proxy.commons.EntityInvocationHandler;
 
 /**
  * Entity context.
@@ -36,16 +36,16 @@ public class EntityContext implements Iterable<AttachedEntity> {
    * <br/>
    * This map have to be used to search for entities by key.
    */
-  private final Map<EntityUUID, EntityTypeInvocationHandler> searchableEntities =
-          new HashMap<EntityUUID, EntityTypeInvocationHandler>();
+  private final Map<EntityUUID, EntityInvocationHandler> searchableEntities =
+          new HashMap<EntityUUID, EntityInvocationHandler>();
 
   /**
    * All attached entities (new entities included).
    * <br/>
    * Attachment order will be maintained.
    */
-  private final Map<EntityTypeInvocationHandler, AttachedEntityStatus> allAttachedEntities =
-          new LinkedHashMap<EntityTypeInvocationHandler, AttachedEntityStatus>();
+  private final Map<EntityInvocationHandler, AttachedEntityStatus> allAttachedEntities =
+          new LinkedHashMap<EntityInvocationHandler, AttachedEntityStatus>();
 
   /**
    * Attaches an entity with status <tt>NEW</tt>.
@@ -55,7 +55,7 @@ public class EntityContext implements Iterable<AttachedEntity> {
    * @see AttachedEntityStatus
    * @param entity entity to be attached.
    */
-  public void attachNew(final EntityTypeInvocationHandler entity) {
+  public void attachNew(final EntityInvocationHandler entity) {
     if (allAttachedEntities.containsKey(entity)) {
       throw new IllegalStateException("An entity with the same key has already been attached");
     }
@@ -70,7 +70,7 @@ public class EntityContext implements Iterable<AttachedEntity> {
    * @see AttachedEntityStatus
    * @param entity entity to be attached.
    */
-  public void attach(final EntityTypeInvocationHandler entity) {
+  public void attach(final EntityInvocationHandler entity) {
     attach(entity, AttachedEntityStatus.ATTACHED);
   }
 
@@ -83,7 +83,7 @@ public class EntityContext implements Iterable<AttachedEntity> {
    * @param entity entity to be attached.
    * @param status status.
    */
-  public void attach(final EntityTypeInvocationHandler entity, final AttachedEntityStatus status) {
+  public void attach(final EntityInvocationHandler entity, final AttachedEntityStatus status) {
     if (isAttached(entity)) {
       throw new IllegalStateException("An entity with the same profile has already been attached");
     }
@@ -100,7 +100,7 @@ public class EntityContext implements Iterable<AttachedEntity> {
    *
    * @param entity entity to be detached.
    */
-  public void detach(final EntityTypeInvocationHandler entity) {
+  public void detach(final EntityInvocationHandler entity) {
     if (searchableEntities.containsKey(entity.getUUID())) {
       searchableEntities.remove(entity.getUUID());
     }
@@ -123,7 +123,7 @@ public class EntityContext implements Iterable<AttachedEntity> {
    * @param uuid entity key.
    * @return retrieved entity.
    */
-  public EntityTypeInvocationHandler getEntity(final EntityUUID uuid) {
+  public EntityInvocationHandler getEntity(final EntityUUID uuid) {
     return searchableEntities.get(uuid);
   }
 
@@ -133,7 +133,7 @@ public class EntityContext implements Iterable<AttachedEntity> {
    * @param entity entity to be retrieved.
    * @return attached entity status.
    */
-  public AttachedEntityStatus getStatus(final EntityTypeInvocationHandler entity) {
+  public AttachedEntityStatus getStatus(final EntityInvocationHandler entity) {
     if (!isAttached(entity)) {
       throw new IllegalStateException("Entity is not in the context");
     }
@@ -147,7 +147,7 @@ public class EntityContext implements Iterable<AttachedEntity> {
    * @param entity attached entity to be modified.
    * @param status new status.
    */
-  public void setStatus(final EntityTypeInvocationHandler entity, final AttachedEntityStatus status) {
+  public void setStatus(final EntityInvocationHandler entity, final AttachedEntityStatus status) {
     if (!isAttached(entity)) {
       throw new IllegalStateException("Entity is not in the context");
     }
@@ -177,7 +177,7 @@ public class EntityContext implements Iterable<AttachedEntity> {
    * @param entity entity.
    * @return <tt>true</tt> if is attached; <tt>false</tt> otherwise.
    */
-  public boolean isAttached(final EntityTypeInvocationHandler entity) {
+  public boolean isAttached(final EntityInvocationHandler entity) {
     return allAttachedEntities.containsKey(entity)
             || (entity.getUUID().getKey() != null && searchableEntities.containsKey(entity.getUUID()));
   }
@@ -190,7 +190,7 @@ public class EntityContext implements Iterable<AttachedEntity> {
   @Override
   public Iterator<AttachedEntity> iterator() {
     final List<AttachedEntity> res = new ArrayList<AttachedEntity>();
-    for (Map.Entry<EntityTypeInvocationHandler, AttachedEntityStatus> attachedEntity : allAttachedEntities.
+    for (Map.Entry<EntityInvocationHandler, AttachedEntityStatus> attachedEntity : allAttachedEntities.
             entrySet()) {
       res.add(new AttachedEntity(attachedEntity.getKey(), attachedEntity.getValue()));
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityLinkDesc.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityLinkDesc.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityLinkDesc.java
index 791f471..3c8dadd 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityLinkDesc.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityLinkDesc.java
@@ -26,7 +26,7 @@ import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 import org.apache.olingo.commons.api.domain.ODataLinkType;
-import org.apache.olingo.ext.proxy.commons.EntityTypeInvocationHandler;
+import org.apache.olingo.ext.proxy.commons.EntityInvocationHandler;
 
 public class EntityLinkDesc implements Serializable {
 
@@ -34,16 +34,16 @@ public class EntityLinkDesc implements Serializable {
 
   private final String sourceName;
 
-  private final EntityTypeInvocationHandler source;
+  private final EntityInvocationHandler source;
 
-  private final Collection<EntityTypeInvocationHandler> targets;
+  private final Collection<EntityInvocationHandler> targets;
 
   private final ODataLinkType type;
 
   public EntityLinkDesc(
           final String sourceName,
-          final EntityTypeInvocationHandler source,
-          final Collection<EntityTypeInvocationHandler> target,
+          final EntityInvocationHandler source,
+          final Collection<EntityInvocationHandler> target,
           final ODataLinkType type) {
     this.sourceName = sourceName;
     this.source = source;
@@ -53,12 +53,12 @@ public class EntityLinkDesc implements Serializable {
 
   public EntityLinkDesc(
           final String sourceName,
-          final EntityTypeInvocationHandler source,
-          final EntityTypeInvocationHandler target,
+          final EntityInvocationHandler source,
+          final EntityInvocationHandler target,
           final ODataLinkType type) {
     this.sourceName = sourceName;
     this.source = source;
-    this.targets = Collections.<EntityTypeInvocationHandler>singleton(target);
+    this.targets = Collections.<EntityInvocationHandler>singleton(target);
     this.type = type;
   }
 
@@ -66,11 +66,11 @@ public class EntityLinkDesc implements Serializable {
     return sourceName;
   }
 
-  public EntityTypeInvocationHandler getSource() {
+  public EntityInvocationHandler getSource() {
     return source;
   }
 
-  public Collection<EntityTypeInvocationHandler> getTargets() {
+  public Collection<EntityInvocationHandler> getTargets() {
     return targets;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/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 cc39d4c..edfc227 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
@@ -19,6 +19,7 @@
 package org.apache.olingo.ext.proxy.context;
 
 import java.io.Serializable;
+import java.net.URI;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.builder.EqualsBuilder;
@@ -32,7 +33,7 @@ public class EntityUUID implements Serializable {
 
   private final String containerName;
 
-  private final String entitySetName;
+  private final URI entitySetURI;
 
   private final Object key;
 
@@ -43,13 +44,13 @@ public class EntityUUID implements Serializable {
 
   private Class<?> type;
 
-  public EntityUUID(final String containerName, final String entitySetName, final Class<?> type) {
-    this(containerName, entitySetName, type, null);
+  public EntityUUID(final String containerName, final URI entitySetURI, final Class<?> type) {
+    this(containerName, entitySetURI, type, null);
   }
 
-  public EntityUUID(final String containerName, final String entitySetName, final Class<?> type, final Object key) {
+  public EntityUUID(final String containerName, final URI entitySetURI, final Class<?> type, final Object key) {
     this.containerName = containerName;
-    this.entitySetName = entitySetName;
+    this.entitySetURI = entitySetURI;
     this.key = key;
     this.tempKey = (int) (Math.random() * 1000000);
 
@@ -70,8 +71,8 @@ public class EntityUUID implements Serializable {
     return containerName;
   }
 
-  public String getEntitySetName() {
-    return entitySetName;
+  public URI getEntitySetURI() {
+    return entitySetURI;
   }
 
   public Object getKey() {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
index cda964e..38dd4cc 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
@@ -60,9 +60,9 @@ import org.apache.olingo.ext.proxy.api.annotations.EnumType;
 import org.apache.olingo.ext.proxy.api.annotations.Key;
 import org.apache.olingo.ext.proxy.api.annotations.Namespace;
 import org.apache.olingo.ext.proxy.api.annotations.Property;
-import org.apache.olingo.ext.proxy.commons.AbstractTypeInvocationHandler;
-import org.apache.olingo.ext.proxy.commons.ComplexTypeInvocationHandler;
-import org.apache.olingo.ext.proxy.commons.EntityTypeInvocationHandler;
+import org.apache.olingo.ext.proxy.commons.AbstractStructuredInvocationHandler;
+import org.apache.olingo.ext.proxy.commons.ComplexInvocationHandler;
+import org.apache.olingo.ext.proxy.commons.EntityInvocationHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -112,10 +112,10 @@ public final class CoreUtils {
       } else {
         objHandler = obj;
       }
-      if (objHandler instanceof ComplexTypeInvocationHandler) {
-        value = ((ComplexTypeInvocationHandler) objHandler).getComplex();
+      if (objHandler instanceof ComplexInvocationHandler) {
+        value = ((ComplexInvocationHandler) objHandler).getComplex();
 
-        final Class<?> typeRef = ((ComplexTypeInvocationHandler) objHandler).getTypeRef();
+        final Class<?> typeRef = ((ComplexInvocationHandler) objHandler).getTypeRef();
         for (Method method : typeRef.getMethods()) {
           final Property propAnn = method.getAnnotation(Property.class);
           if (propAnn != null) {
@@ -385,8 +385,8 @@ public final class CoreUtils {
       final Class<?> typeRef;
       if (bean instanceof Proxy) {
         final InvocationHandler handler = Proxy.getInvocationHandler(bean);
-        if (handler instanceof AbstractTypeInvocationHandler) {
-          typeRef = ((ComplexTypeInvocationHandler) handler).getTypeRef();
+        if (handler instanceof AbstractStructuredInvocationHandler) {
+          typeRef = ((ComplexInvocationHandler) handler).getTypeRef();
         } else {
           throw new IllegalStateException("Invalid bean " + bean);
         }
@@ -425,7 +425,7 @@ public final class CoreUtils {
               final Object complex = Proxy.newProxyInstance(
                       Thread.currentThread().getContextClassLoader(),
                       new Class<?>[] {getter.getReturnType()},
-                      ComplexTypeInvocationHandler.getInstance(
+                      ComplexInvocationHandler.getInstance(
                               client, property.getName(), getter.getReturnType(), null));
 
               populate(client, complex, Property.class, property.getValue().asComplex().iterator());
@@ -450,7 +450,7 @@ public final class CoreUtils {
                   final Object collItem = Proxy.newProxyInstance(
                           Thread.currentThread().getContextClassLoader(),
                           new Class<?>[] {collItemClass},
-                          ComplexTypeInvocationHandler.getInstance(
+                          ComplexInvocationHandler.getInstance(
                                   client, property.getName(), collItemClass, null));
 
                   populate(client, collItem, Property.class, value.asComplex().iterator());
@@ -471,7 +471,7 @@ public final class CoreUtils {
           final CommonEdmEnabledODataClient<?> client,
           final CommonODataProperty property,
           final Type typeRef,
-          final EntityTypeInvocationHandler entityHandler)
+          final EntityInvocationHandler entityHandler)
           throws InstantiationException, IllegalAccessException {
 
     Class<?> internalRef;
@@ -495,7 +495,7 @@ public final class CoreUtils {
       res = Proxy.newProxyInstance(
               Thread.currentThread().getContextClassLoader(),
               new Class<?>[] {internalRef},
-              ComplexTypeInvocationHandler.getInstance(
+              ComplexInvocationHandler.getInstance(
                       client, property.getValue().asComplex(), internalRef, entityHandler));
     } else if (property.hasCollectionValue()) {
       final ArrayList<Object> collection = new ArrayList<Object>();
@@ -510,7 +510,7 @@ public final class CoreUtils {
           final Object collItem = Proxy.newProxyInstance(
                   Thread.currentThread().getContextClassLoader(),
                   new Class<?>[] {internalRef},
-                  ComplexTypeInvocationHandler.getInstance(
+                  ComplexInvocationHandler.getInstance(
                           client, value.asComplex(), internalRef, entityHandler));
 
           collection.add(collItem);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractPOJOGenMojo.java
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractPOJOGenMojo.java b/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractPOJOGenMojo.java
index 420d4c2..f8ab5f2 100644
--- a/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractPOJOGenMojo.java
+++ b/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractPOJOGenMojo.java
@@ -44,6 +44,7 @@ import org.apache.olingo.commons.api.edm.EdmEntityContainer;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
 import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.edm.EdmEnumType;
+import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
 import org.apache.olingo.commons.api.edm.EdmSchema;
 import org.apache.olingo.commons.api.edm.EdmSingleton;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
@@ -267,6 +268,20 @@ public abstract class AbstractPOJOGenMojo extends AbstractMojo {
           objs.clear();
           objs.put("complexType", complex);
           parseObj(typesBaseDir, typesPkg, "complexType", className + ".java", objs);
+
+          for (String navPropName : complex.getNavigationPropertyNames()) {
+            final EdmNavigationProperty navProp = complex.getNavigationProperty(navPropName);
+            if ((complex.getBaseType() == null
+                    || edm.getEntityType(complex.getBaseType().getFullQualifiedName()).
+                    getNavigationProperty(navPropName) == null)
+                    && navProp.containsTarget()) {
+              
+              objs.clear();
+              objs.put("navProp", navProp);
+              parseObj(base, pkg, "containedEntitySet",
+                      utility.capitalize(navProp.getName()) + ".java", objs);
+            }
+          }
         }
 
         for (EdmEntityType entity : schema.getEntityTypes()) {
@@ -304,6 +319,20 @@ public abstract class AbstractPOJOGenMojo extends AbstractMojo {
                   utility.capitalize(entity.getName()) + ".java", objs);
           parseObj(typesBaseDir, typesPkg, "entityCollection",
                   utility.capitalize(entity.getName()) + "Collection.java", objs);
+
+          for (String navPropName : entity.getNavigationPropertyNames()) {
+            final EdmNavigationProperty navProp = entity.getNavigationProperty(navPropName);
+            if ((entity.getBaseType() == null
+                    || edm.getEntityType(entity.getBaseType().getFullQualifiedName()).
+                    getNavigationProperty(navPropName) == null)
+                    && navProp.containsTarget()) {
+
+              objs.clear();
+              objs.put("navProp", navProp);
+              parseObj(base, pkg, "containedEntitySet",
+                      utility.capitalize(navProp.getName()) + ".java", objs);
+            }
+          }
         }
 
         // write container and top entity sets into the base package

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java b/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java
index 32bfc6b..ebbeb53 100644
--- a/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java
+++ b/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java
@@ -69,7 +69,7 @@ public abstract class AbstractUtility {
 
   protected final String namespace;
 
-  private final Edm metadata;
+  private final Edm edm;
 
   private final EdmSchema schema;
 
@@ -79,35 +79,43 @@ public abstract class AbstractUtility {
     this.basePackage = basePackage;
     this.schemaName = schema.getAlias();
     this.namespace = schema.getNamespace();
-    this.metadata = metadata;
+    this.edm = metadata;
     this.schema = schema;
 
     collectEntityTypes();
   }
 
   public EdmTypeInfo getEdmTypeInfo(final EdmType type) {
-    return new EdmTypeInfo.Builder().setEdm(metadata).
+    return new EdmTypeInfo.Builder().setEdm(edm).
             setTypeExpression(type.getFullQualifiedName().toString()).build();
   }
 
   public EdmTypeInfo getEdmTypeInfo(final String expression) {
-    return new EdmTypeInfo.Builder().setEdm(metadata).setTypeExpression(expression).build();
+    return new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(expression).build();
   }
 
   public EdmTypeInfo getEdmType(final EdmSingleton singleton) {
     return getEdmTypeInfo(singleton.getEntityType().getFullQualifiedName().toString());
   }
 
+  public EdmTypeInfo getEdmType(final EdmNavigationProperty navProp) {
+    return getEdmTypeInfo(navProp.getType().getFullQualifiedName().toString());
+  }
+
   public boolean isComplex(final FullQualifiedName fqn) {
-    return metadata.getComplexType(fqn) != null;
+    return edm.getComplexType(fqn) != null;
   }
 
   public Map<String, String> getEntityKeyType(final EdmSingleton singleton) {
     return getEntityKeyType(singleton.getEntityType());
   }
 
+  public Map<String, String> getEntityKeyType(final EdmNavigationProperty navProp) {
+    return getEntityKeyType(navProp.getType());
+  }
+
   protected Edm getMetadata() {
-    return metadata;
+    return edm;
   }
 
   protected EdmSchema getSchema() {
@@ -120,8 +128,9 @@ public abstract class AbstractUtility {
 
   public NavPropertyBindingDetails getNavigationBindingDetails(
           final EdmStructuredType sourceEntityType, final EdmNavigationProperty property) {
+
     if (property.containsTarget()) {
-      return new NavPropertyContainsTarget(metadata, property.getType());
+      return new NavPropertyContainsTarget(edm, property.getType());
     }
 
     try {
@@ -138,7 +147,7 @@ public abstract class AbstractUtility {
     }
 
     try {
-      return new NavPropertyBindingDetails(metadata, type);
+      return new NavPropertyBindingDetails(edm, type);
     } catch (IllegalStateException ignore) {
       return getNavigationBindings(type.getBaseType());
     }
@@ -152,14 +161,20 @@ public abstract class AbstractUtility {
     }
 
     try {
-      return new NavPropertyBindingDetails(metadata, sourceEntityType, property);
+      return new NavPropertyBindingDetails(edm, sourceEntityType, property);
     } catch (IllegalStateException ignore) {
       return getNavigationBindingDetails(sourceEntityType.getBaseType(), property);
     }
   }
 
+  public String getContainedEntitySet(final EdmNavigationProperty navProp) {
+    return new StringBuilder().append(basePackage).append('.').
+            append(navProp.getType().getFullQualifiedName().getNamespace().toLowerCase()). // namespace
+            append('.').append(capitalize(navProp.getName())).toString();
+  }
+
   public EdmFunction getFunctionByName(final FullQualifiedName name) {
-    final EdmSchema targetSchema = metadata.getSchema(name.getNamespace());
+    final EdmSchema targetSchema = edm.getSchema(name.getNamespace());
 
     if (targetSchema != null) {
       for (EdmFunction function : targetSchema.getFunctions()) {
@@ -173,7 +188,7 @@ public abstract class AbstractUtility {
   }
 
   public EdmAction getActionByName(final FullQualifiedName name) {
-    final EdmSchema targetSchema = metadata.getSchema(name.getNamespace());
+    final EdmSchema targetSchema = edm.getSchema(name.getNamespace());
 
     if (targetSchema != null) {
       for (EdmAction action : targetSchema.getActions()) {
@@ -305,7 +320,7 @@ public abstract class AbstractUtility {
       if (edmType.isEntityType()) {
         res.append("Collection");
       } else {
-        res.append(">");
+        res.append('>');
       }
     }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/NavPropertyContainsTarget.java
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/NavPropertyContainsTarget.java b/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/NavPropertyContainsTarget.java
index 54ce6fe..8e3d2c5 100644
--- a/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/NavPropertyContainsTarget.java
+++ b/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/NavPropertyContainsTarget.java
@@ -23,12 +23,12 @@ import org.apache.olingo.commons.api.edm.EdmEntityType;
 
 public class NavPropertyContainsTarget extends NavPropertyBindingDetails {
 
-    public NavPropertyContainsTarget(final Edm edm, final EdmEntityType type) {
-        super();
-        this.edm = edm;
-        this.entitySet = null;
-        this.container = null;
-        this.type = type;
-        schema = edm.getSchema(type.getNamespace());
-    }
+  public NavPropertyContainsTarget(final Edm edm, final EdmEntityType type) {
+    super();
+    this.edm = edm;
+    this.entitySet = null;
+    this.container = null;
+    this.type = type;
+    schema = edm.getSchema(type.getNamespace());
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/pojogen-maven-plugin/src/main/resources/containedEntitySet.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/containedEntitySet.vm b/ext/pojogen-maven-plugin/src/main/resources/containedEntitySet.vm
new file mode 100644
index 0000000..6433d47
--- /dev/null
+++ b/ext/pojogen-maven-plugin/src/main/resources/containedEntitySet.vm
@@ -0,0 +1,65 @@
+#*
+ * 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 ${package};
+
+import org.apache.olingo.ext.proxy.api.AbstractEntitySet;
+import org.apache.olingo.ext.proxy.api.annotations.EntitySet;
+import org.apache.olingo.ext.proxy.api.annotations.CompoundKey;
+import org.apache.olingo.ext.proxy.api.annotations.CompoundKeyElement;
+#foreach($ns in $namespaces)
+import ${basePackage}.${ns}.*;
+import ${basePackage}.${ns}.types.*;
+#end
+
+import org.apache.olingo.commons.api.edm.geo.Geospatial;
+import org.apache.olingo.commons.api.edm.geo.GeospatialCollection;
+import org.apache.olingo.commons.api.edm.geo.LineString;
+import org.apache.olingo.commons.api.edm.geo.MultiLineString;
+import org.apache.olingo.commons.api.edm.geo.MultiPoint;
+import org.apache.olingo.commons.api.edm.geo.MultiPolygon;
+import org.apache.olingo.commons.api.edm.geo.Point;
+import org.apache.olingo.commons.api.edm.geo.Polygon;
+import java.math.BigDecimal;
+import java.net.URI;
+import java.util.UUID;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Calendar;
+import javax.xml.datatype.Duration;
+
+#set( $keys = $utility.getEntityKeyType($navProp) )
+#if( $keys.size() > 1 )
+  #set( $type = $utility.getEdmType($navProp).EntityType.Name + "Key" )
+#elseif( $keys.size() == 1 )
+  #set( $type = $keys.values().iterator().next() )
+#else
+  #set( $type = "" )
+#end
+
+@EntitySet(name = "$navProp.Name", contained = true)
+public interface $utility.capitalize($navProp.Name) 
+  extends AbstractEntitySet<$utility.getJavaType($navProp.Type), $type, $utility.getJavaType($navProp.Type)Collection> {
+
+#foreach( $dos in $utility.getDescendantsOrSelf($utility.getEdmType($navProp)) )
+    #set( $djt = $utility.getJavaType($dos) )
+    #set( $sIdx = $djt.lastIndexOf('.') + 1 )
+    $djt new$djt.substring($sIdx)();
+    ${djt}Collection new$djt.substring($sIdx)Collection();
+#end
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/pojogen-maven-plugin/src/main/resources/container.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/container.vm b/ext/pojogen-maven-plugin/src/main/resources/container.vm
index 18d383d..362018d 100644
--- a/ext/pojogen-maven-plugin/src/main/resources/container.vm
+++ b/ext/pojogen-maven-plugin/src/main/resources/container.vm
@@ -56,7 +56,6 @@ public interface $utility.capitalize($container.Name) extends Container {
 
 #foreach($entitySet in $container.EntitySets)
     $utility.capitalize($entitySet.Name) get$utility.capitalize($entitySet.Name)();
-
 #end
 
 #parse( "${odataVersion}/container.vm" )

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/pojogen-maven-plugin/src/main/resources/entitySet.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/entitySet.vm b/ext/pojogen-maven-plugin/src/main/resources/entitySet.vm
index e98ed97..8ba5ce6 100644
--- a/ext/pojogen-maven-plugin/src/main/resources/entitySet.vm
+++ b/ext/pojogen-maven-plugin/src/main/resources/entitySet.vm
@@ -52,7 +52,7 @@ import javax.xml.datatype.Duration;
   #set( $type = "" )
 #end
 
-#parse( "${odataVersion}/entitySet.vm" )
+@EntitySet(name = "$entitySet.Name")
 public interface $utility.capitalize($entitySet.Name) 
   extends AbstractEntitySet<$utility.getJavaType($entitySet.EntityType), $type, $utility.getJavaType($entitySet.EntityType)Collection> {
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/pojogen-maven-plugin/src/main/resources/entityType.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/entityType.vm b/ext/pojogen-maven-plugin/src/main/resources/entityType.vm
index 1114445..aeebe7b 100644
--- a/ext/pojogen-maven-plugin/src/main/resources/entityType.vm
+++ b/ext/pojogen-maven-plugin/src/main/resources/entityType.vm
@@ -95,7 +95,7 @@ public interface $utility.capitalize($entityType.Name)
                 fcKeepInContent = #if($fcprops.containsKey("fcKeepInContent"))$fcprops.get("fcKeepInContent")#{else}false#end)
     $utility.getJavaType($property.Type, $property.Collection) get$utility.capitalize($property.Name)();
 
-    void set$utility.capitalize($property.Name)(final $utility.getJavaType($property.Type, $property.Collection) _$utility.uncapitalize($property.Name));    
+    void set$utility.capitalize($property.Name)($utility.getJavaType($property.Type, $property.Collection) _$utility.uncapitalize($property.Name));    
     #if($utility.isComplex($property.Type.FullQualifiedName))#*
       *##set( $adding = $complexProps.add($property) )
     #end
@@ -104,18 +104,24 @@ public interface $utility.capitalize($entityType.Name)
     
 #foreach($propertyName in $entityType.NavigationPropertyNames)
     #set($property = $entityType.getNavigationProperty($propertyName))
-    #set( $type = $utility.getNavigationType($property) )
-    #set( $binding = $utility.getNavigationBindingDetails($entityType, $property) )
+    #set($type = $utility.getNavigationType($property))
+    #set($binding = $utility.getNavigationBindingDetails($entityType, $property))
 
     @NavigationProperty(name = "$property.Name", 
                 type = "$type", 
                 targetSchema = "$binding.Schema.Namespace", 
                 targetContainer = "#if($binding.Container)$binding.Container.Name#end", 
-                targetEntitySet = "#if($binding.EntitySet)$binding.EntitySet.Name#end")
-    $utility.getJavaType($type, $property.Collection) get$utility.capitalize($property.Name)();
+                targetEntitySet = "#if($binding.EntitySet)$binding.EntitySet.Name#end",
+                containsTarget = $property.containsTarget())
+    #if($property.containsTarget() && $property.Collection)#*
+      *#$utility.getContainedEntitySet($property) get$utility.capitalize($property.Name)();
 
-    void set$utility.capitalize($property.Name)(final $utility.getJavaType($type, $property.Collection) _$utility.uncapitalize($property.Name));
+    void set$utility.capitalize($property.Name)($utility.getContainedEntitySet($property) _$utility.uncapitalize($property.Name));
+    #else#*
+      *#$utility.getJavaType($type, $property.Collection) get$utility.capitalize($property.Name)();
 
+    void set$utility.capitalize($property.Name)($utility.getJavaType($type, $property.Collection) _$utility.uncapitalize($property.Name));
+    #end
 #end
 
 #if($entityType.hasStream())

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/pojogen-maven-plugin/src/main/resources/entityTypeKey.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/entityTypeKey.vm b/ext/pojogen-maven-plugin/src/main/resources/entityTypeKey.vm
index 143ae5e..423b0e1 100644
--- a/ext/pojogen-maven-plugin/src/main/resources/entityTypeKey.vm
+++ b/ext/pojogen-maven-plugin/src/main/resources/entityTypeKey.vm
@@ -60,7 +60,7 @@ public class $keyRef extends AbstractEntityKey {
         return _$utility.uncapitalize($entry.getKey());
     }
 
-    public void set$utility.capitalize($entry.getKey())(final $entry.getValue() _$utility.uncapitalize($entry.getKey())) {
+    public void set$utility.capitalize($entry.getKey())($entry.getValue() _$utility.uncapitalize($entry.getKey())) {
         this._$utility.uncapitalize($entry.getKey()) = _$utility.uncapitalize($entry.getKey());
     }#*
     *##set ( $count = $count + 1 )

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm b/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm
index 4f0f86b..2c3c7ff 100644
--- a/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm
+++ b/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm
@@ -28,7 +28,7 @@ public interface $utility.capitalize($complexType.Name)
     @Property(name = "$property.Name", type = "$property.Type.FullQualifiedName.toString()", nullable = $property.Nullable)
     $utility.getJavaType($property.Type, $property.Collection) get$utility.capitalize($property.Name)();
 
-    void set$utility.capitalize($property.Name)(final $utility.getJavaType($property.Type, $property.Collection) _$utility.uncapitalize($property.Name));
+    void set$utility.capitalize($property.Name)($utility.getJavaType($property.Type, $property.Collection) _$utility.uncapitalize($property.Name));
 
     #if($utility.isComplex($property.Type.FullQualifiedName))#*
       *##set( $adding = $complexProps.add($property) )

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/pojogen-maven-plugin/src/main/resources/v30/entitySet.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/v30/entitySet.vm b/ext/pojogen-maven-plugin/src/main/resources/v30/entitySet.vm
deleted file mode 100644
index 86f2bad..0000000
--- a/ext/pojogen-maven-plugin/src/main/resources/v30/entitySet.vm
+++ /dev/null
@@ -1,19 +0,0 @@
-#*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *#
-@EntitySet(name = "$entitySet.Name")

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm b/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm
index e3d2a55..b76717f 100644
--- a/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm
+++ b/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm
@@ -41,7 +41,7 @@ public interface $utility.capitalize($complexType.Name)
                 srid = "#if($property.getSRID())$property.getSRID()#end")
     $utility.getJavaType($property.Type, $property.Collection) get$utility.capitalize($property.Name)();
 
-    void set$utility.capitalize($property.Name)(final $utility.getJavaType($property.Type, $property.Collection) _$utility.uncapitalize($property.Name));
+    void set$utility.capitalize($property.Name)($utility.getJavaType($property.Type, $property.Collection) _$utility.uncapitalize($property.Name));
 
     #if($utility.isComplex($property.Type.FullQualifiedName))#*
       *##set( $adding = $complexProps.add($property) )
@@ -61,7 +61,7 @@ public interface $utility.capitalize($complexType.Name)
                 targetEntitySet = "#if($binding.EntitySet)$binding.EntitySet.Name#end")
     $utility.getJavaType($type, $property.Collection) get$utility.capitalize($property.Name)();
 
-    void set$utility.capitalize($property.Name)(final $utility.getJavaType($type, $property.Collection) _$utility.uncapitalize($property.Name));
+    void set$utility.capitalize($property.Name)($utility.getJavaType($type, $property.Collection) _$utility.uncapitalize($property.Name));
 
 #end
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/ext/pojogen-maven-plugin/src/main/resources/v40/entitySet.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/v40/entitySet.vm b/ext/pojogen-maven-plugin/src/main/resources/v40/entitySet.vm
deleted file mode 100644
index cf60af0..0000000
--- a/ext/pojogen-maven-plugin/src/main/resources/v40/entitySet.vm
+++ /dev/null
@@ -1,19 +0,0 @@
-#*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *#
-@EntitySet(name = "$entitySet.Name", includeInServiceDocument = $entitySet.IncludeInServiceDocument)

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101902).full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101902).full.json b/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101902).full.json
new file mode 100644
index 0000000..ba7e1d8
--- /dev/null
+++ b/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101902).full.json
@@ -0,0 +1,16 @@
+{
+  "@odata.context": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/$metadata#Accounts(101)/MyPaymentInstruments/$entity",
+  "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument",
+  "@odata.id": "Accounts(101)/MyPaymentInstruments(101902)",
+  "@odata.editLink": "Accounts(101)/MyPaymentInstruments(101902)",
+  "PaymentInstrumentID": 101902,
+  "FriendlyName": "101 first PI",
+  "CreatedDate@odata.type": "#DateTimeOffset",
+  "CreatedDate": "2014-04-09T00:00:00Z",
+  "TheStoredPI@odata.associationLink": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Accounts(101)/MyPaymentInstruments(101902)/TheStoredPI/$ref",
+  "TheStoredPI@odata.navigationLink": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Accounts(101)/MyPaymentInstruments(101902)/TheStoredPI",
+  "BillingStatements@odata.associationLink": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Accounts(101)/MyPaymentInstruments(101902)/BillingStatements/$ref",
+  "BillingStatements@odata.navigationLink": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Accounts(101)/MyPaymentInstruments(101902)/BillingStatements",
+  "BackupStoredPI@odata.associationLink": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Accounts(101)/MyPaymentInstruments(101902)/BackupStoredPI/$ref",
+  "BackupStoredPI@odata.navigationLink": "http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Accounts(101)/MyPaymentInstruments(101902)/BackupStoredPI"
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101902).xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101902).xml b/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101902).xml
new file mode 100644
index 0000000..78397c9
--- /dev/null
+++ b/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101902).xml
@@ -0,0 +1,40 @@
+<?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.
+
+-->
+<entry xml:base="http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/$metadata#Accounts(101)/MyPaymentInstruments/$entity">
+  <category term="#Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument" scheme="http://docs.oasis-open.org/odata/ns/scheme"/>
+  <link rel="http://docs.oasis-open.org/odata/ns/related/TheStoredPI" type="application/atom+xml;type=entry" title="TheStoredPI" href="http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Accounts(101)/MyPaymentInstruments(101902)/TheStoredPI"/>
+  <link rel="http://docs.oasis-open.org/odata/ns/related/BillingStatements" type="application/atom+xml;type=feed" title="BillingStatements" href="http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Accounts(101)/MyPaymentInstruments(101902)/BillingStatements"/>
+  <link rel="http://docs.oasis-open.org/odata/ns/related/BackupStoredPI" type="application/atom+xml;type=entry" title="BackupStoredPI" href="http://localhost:${cargo.servlet.port}/stub/StaticService/V40/Static.svc/Accounts(101)/MyPaymentInstruments(101902)/BackupStoredPI"/>
+  <id/>
+  <title/>
+  <updated>2014-04-14T12:47:37Z</updated>
+  <author>
+    <name/>
+  </author>
+  <content type="application/xml">
+    <m:properties>
+      <d:PaymentInstrumentID m:type="Int32">101902</d:PaymentInstrumentID>
+      <d:FriendlyName>101 first PI</d:FriendlyName>
+      <d:CreatedDate m:type="DateTimeOffset">2014-04-09T00:00:00Z</d:CreatedDate>
+    </m:properties>
+  </content>
+</entry>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/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
index b1b2e75..df6ef13 100644
--- 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
@@ -34,7 +34,7 @@ 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.commons.EntityInvocationHandler;
 import org.apache.olingo.ext.proxy.context.AttachedEntityStatus;
 import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.
         ContactDetails;
@@ -62,10 +62,10 @@ public class ContextTestITCase extends AbstractTestITCase {
     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);
+    final EntityInvocationHandler source1 =
+            (EntityInvocationHandler) Proxy.getInvocationHandler(customer1);
+    final EntityInvocationHandler source2 =
+            (EntityInvocationHandler) Proxy.getInvocationHandler(customer2);
 
     assertTrue(entityContext.isAttached(source1));
     assertTrue(entityContext.isAttached(source2));
@@ -85,12 +85,12 @@ public class ContextTestITCase extends AbstractTestITCase {
     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);
+    final EntityInvocationHandler source1 =
+            (EntityInvocationHandler) Proxy.getInvocationHandler(customer1);
+    final EntityInvocationHandler source2 =
+            (EntityInvocationHandler) Proxy.getInvocationHandler(customer2);
+    final EntityInvocationHandler source3 =
+            (EntityInvocationHandler) Proxy.getInvocationHandler(customer3);
 
     assertFalse(entityContext.isAttached(source1));
     assertFalse(entityContext.isAttached(source2));
@@ -133,10 +133,10 @@ public class ContextTestITCase extends AbstractTestITCase {
 
     assertNotNull(customer.getInfo());
 
-    final EntityTypeInvocationHandler source =
-            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer);
-    final EntityTypeInvocationHandler target =
-            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo);
+    final EntityInvocationHandler source =
+            (EntityInvocationHandler) Proxy.getInvocationHandler(customer);
+    final EntityInvocationHandler target =
+            (EntityInvocationHandler) Proxy.getInvocationHandler(customerInfo);
 
     assertTrue(entityContext.isAttached(source));
     assertEquals(AttachedEntityStatus.NEW, entityContext.getStatus(source));
@@ -160,10 +160,10 @@ public class ContextTestITCase extends AbstractTestITCase {
 
     assertNotNull(customer.getInfo());
 
-    final EntityTypeInvocationHandler source =
-            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer);
-    final EntityTypeInvocationHandler target =
-            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo);
+    final EntityInvocationHandler source =
+            (EntityInvocationHandler) Proxy.getInvocationHandler(customer);
+    final EntityInvocationHandler target =
+            (EntityInvocationHandler) Proxy.getInvocationHandler(customerInfo);
 
     assertTrue(entityContext.isAttached(source));
     assertEquals(AttachedEntityStatus.CHANGED, entityContext.getStatus(source));
@@ -187,10 +187,10 @@ public class ContextTestITCase extends AbstractTestITCase {
 
     assertNotNull(customer.getInfo());
 
-    final EntityTypeInvocationHandler source =
-            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer);
-    final EntityTypeInvocationHandler target =
-            (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo);
+    final EntityInvocationHandler source =
+            (EntityInvocationHandler) Proxy.getInvocationHandler(customer);
+    final EntityInvocationHandler target =
+            (EntityInvocationHandler) Proxy.getInvocationHandler(customerInfo);
 
     assertTrue(entityContext.isAttached(source));
     assertEquals(AttachedEntityStatus.CHANGED, entityContext.getStatus(source));
@@ -218,14 +218,14 @@ public class ContextTestITCase extends AbstractTestITCase {
     assertNotNull(customer.getOrders());
     assertEquals(3, customer.getOrders().size());
 
-    final EntityTypeInvocationHandler source = (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer);
+    final EntityInvocationHandler source = (EntityInvocationHandler) 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);
+      final EntityInvocationHandler target = (EntityInvocationHandler) Proxy.getInvocationHandler(order);
 
       assertTrue(entityContext.isAttached(target));
       assertEquals(AttachedEntityStatus.NEW, entityContext.getStatus(target));
@@ -237,7 +237,7 @@ public class ContextTestITCase extends AbstractTestITCase {
     assertFalse(entityContext.isAttached(source));
 
     for (Order order : toBeLinked) {
-      assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(order)));
+      assertFalse(entityContext.isAttached((EntityInvocationHandler) Proxy.getInvocationHandler(order)));
     }
   }
 
@@ -263,7 +263,7 @@ public class ContextTestITCase extends AbstractTestITCase {
     assertEquals(2, customer.getBackupContactInfo().iterator().next().getAlternativeNames().size());
     assertTrue(customer.getBackupContactInfo().iterator().next().getAlternativeNames().contains("alternative4"));
 
-    final EntityTypeInvocationHandler source = (EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer);
+    final EntityInvocationHandler source = (EntityInvocationHandler) Proxy.getInvocationHandler(customer);
 
     assertTrue(entityContext.isAttached(source));
     assertEquals(AttachedEntityStatus.NEW, entityContext.getStatus(source));
@@ -320,7 +320,7 @@ public class ContextTestITCase extends AbstractTestITCase {
   public void checkContextInCaseOfErrors() {
     final Login login = container.getLogin().newLogin();
 
-    final EntityTypeInvocationHandler handler = (EntityTypeInvocationHandler) Proxy.getInvocationHandler(login);
+    final EntityInvocationHandler handler = (EntityInvocationHandler) Proxy.getInvocationHandler(login);
 
     assertTrue(entityContext.isAttached(handler));
 
@@ -387,18 +387,18 @@ public class ContextTestITCase extends AbstractTestITCase {
     customer.setPrimaryContactInfo(cd);
     customer.setBackupContactInfo(Collections.<ContactDetails>singletonList(bcd));
 
-    assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo)));
-    assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer)));
+    assertTrue(entityContext.isAttached((EntityInvocationHandler) Proxy.getInvocationHandler(customerInfo)));
+    assertTrue(entityContext.isAttached((EntityInvocationHandler) Proxy.getInvocationHandler(customer)));
     for (Order linked : toBeLinked) {
-      assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(linked)));
+      assertTrue(entityContext.isAttached((EntityInvocationHandler) Proxy.getInvocationHandler(linked)));
     }
 
     container.flush();
 
-    assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customerInfo)));
-    assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer)));
+    assertFalse(entityContext.isAttached((EntityInvocationHandler) Proxy.getInvocationHandler(customerInfo)));
+    assertFalse(entityContext.isAttached((EntityInvocationHandler) Proxy.getInvocationHandler(customer)));
     for (Order linked : toBeLinked) {
-      assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(linked)));
+      assertFalse(entityContext.isAttached((EntityInvocationHandler) Proxy.getInvocationHandler(linked)));
     }
 
     assertEquals("some new info ...", container.getCustomerInfo().get(16).getInformation());
@@ -406,22 +406,22 @@ public class ContextTestITCase extends AbstractTestITCase {
     container.getOrder().delete(toBeLinked);
     container.getCustomer().delete(customer.getCustomerId());
 
-    assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer)));
+    assertTrue(entityContext.isAttached((EntityInvocationHandler) Proxy.getInvocationHandler(customer)));
     for (Order linked : toBeLinked) {
-      assertTrue(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(linked)));
+      assertTrue(entityContext.isAttached((EntityInvocationHandler) Proxy.getInvocationHandler(linked)));
     }
 
     container.flush();
 
-    assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(customer)));
+    assertFalse(entityContext.isAttached((EntityInvocationHandler) Proxy.getInvocationHandler(customer)));
     for (Order linked : toBeLinked) {
-      assertFalse(entityContext.isAttached((EntityTypeInvocationHandler) Proxy.getInvocationHandler(linked)));
+      assertFalse(entityContext.isAttached((EntityInvocationHandler) Proxy.getInvocationHandler(linked)));
     }
   }
 
   private void checkUnlink(
           final String sourceName,
-          final EntityTypeInvocationHandler source) {
+          final EntityInvocationHandler source) {
 
     boolean found = false;
     for (Map.Entry<NavigationProperty, Object> property : source.getLinkChanges().entrySet()) {
@@ -434,8 +434,8 @@ public class ContextTestITCase extends AbstractTestITCase {
 
   private void checkLink(
           final String sourceName,
-          final EntityTypeInvocationHandler source,
-          final EntityTypeInvocationHandler target,
+          final EntityInvocationHandler source,
+          final EntityInvocationHandler target,
           final boolean isCollection) {
 
     boolean found = false;
@@ -444,13 +444,13 @@ public class ContextTestITCase extends AbstractTestITCase {
         if (isCollection) {
           found = false;
           for (Object proxy : (Collection) property.getValue()) {
-            if (target.equals((EntityTypeInvocationHandler) Proxy.getInvocationHandler(proxy))) {
+            if (target.equals((EntityInvocationHandler) Proxy.getInvocationHandler(proxy))) {
               found = true;
             }
           }
         } else {
           found = target.equals(
-                  (EntityTypeInvocationHandler) Proxy.getInvocationHandler(property.getValue()));
+                  (EntityInvocationHandler) Proxy.getInvocationHandler(property.getValue()));
         }
       }
     }
@@ -459,9 +459,9 @@ public class ContextTestITCase extends AbstractTestITCase {
 
   private void checkUnidirectional(
           final String sourceName,
-          final EntityTypeInvocationHandler source,
+          final EntityInvocationHandler source,
           final String targetName,
-          final EntityTypeInvocationHandler target,
+          final EntityInvocationHandler target,
           final boolean isCollection) {
 
     checkLink(sourceName, source, target, isCollection);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityRetrieveTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityRetrieveTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityRetrieveTestITCase.java
index 7ec8cdf..0ea8ad5 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityRetrieveTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityRetrieveTestITCase.java
@@ -32,7 +32,7 @@ import org.apache.olingo.commons.api.edm.geo.Geospatial;
 import org.apache.olingo.commons.api.edm.geo.Geospatial.Type;
 import org.apache.olingo.commons.api.edm.geo.MultiLineString;
 import org.apache.olingo.commons.api.edm.geo.Point;
-import org.apache.olingo.ext.proxy.commons.EntityTypeInvocationHandler;
+import org.apache.olingo.ext.proxy.commons.EntityInvocationHandler;
 import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
         DefaultContainer;
 import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
@@ -212,7 +212,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
   public void checkForETag() {
     Product product = getContainer().getProduct().get(-10);
     assertTrue(StringUtils.isNotBlank(
-            ((EntityTypeInvocationHandler) Proxy.getInvocationHandler(product)).getETag()));
+            ((EntityInvocationHandler) Proxy.getInvocationHandler(product)).getETag()));
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ca66d671/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityUpdateTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityUpdateTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityUpdateTestITCase.java
index 82660eb..9450d29 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityUpdateTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityUpdateTestITCase.java
@@ -24,7 +24,7 @@ import static org.junit.Assert.assertNotNull;
 
 import java.lang.reflect.Proxy;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.ext.proxy.commons.EntityTypeInvocationHandler;
+import org.apache.olingo.ext.proxy.commons.EntityInvocationHandler;
 import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
         types.ConcurrencyInfo;
 import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
@@ -113,7 +113,7 @@ public class EntityUpdateTestITCase extends AbstractTestITCase {
     @Test
     public void concurrentModification() {
         Product product = container.getProduct().get(-10);
-        final String etag = ((EntityTypeInvocationHandler) Proxy.getInvocationHandler(product)).getETag();
+        final String etag = ((EntityInvocationHandler) Proxy.getInvocationHandler(product)).getETag();
         assertTrue(StringUtils.isNotBlank(etag));
 
         final String baseConcurrency = String.valueOf(System.currentTimeMillis());