You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2014/03/24 10:38:52 UTC

[1/8] [OLINGO-205, OLINGO-200] provided atom v4 deserialization for entity type/set + entity set request

Repository: incubator-olingo-odata4
Updated Branches:
  refs/heads/olingo200 a55ed62ac -> f0edb5081


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmStructuredType.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmStructuredType.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmStructuredType.java
index d48fda4..a807052 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmStructuredType.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmStructuredType.java
@@ -34,96 +34,99 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
 
 public abstract class AbstractEdmStructuredType extends EdmTypeImpl implements EdmStructuredType {
 
-  protected EdmStructuredType baseType;
+    protected EdmStructuredType baseType;
 
-  private List<String> propertyNames;
+    private List<String> propertyNames;
 
-  private List<String> navigationPropertyNames;
+    private List<String> navigationPropertyNames;
 
-  public AbstractEdmStructuredType(final Edm edm, final FullQualifiedName fqn, final EdmTypeKind kind,
-          final FullQualifiedName baseTypeName) {
+    public AbstractEdmStructuredType(
+            final Edm edm,
+            final FullQualifiedName fqn,
+            final EdmTypeKind kind,
+            final FullQualifiedName baseTypeName) {
 
-    super(edm, fqn, kind);
-  }
+        super(edm, fqn, kind);
+    }
 
-  protected abstract EdmStructuredType buildBaseType(FullQualifiedName baseTypeName);
+    protected abstract EdmStructuredType buildBaseType(FullQualifiedName baseTypeName);
 
-  protected abstract Map<String, EdmProperty> getProperties();
+    protected abstract Map<String, EdmProperty> getProperties();
 
-  protected abstract Map<String, EdmNavigationProperty> getNavigationProperties();
+    protected abstract Map<String, EdmNavigationProperty> getNavigationProperties();
 
-  @Override
-  public List<String> getPropertyNames() {
-    if (propertyNames == null) {
-      propertyNames = new ArrayList<String>();
-      if (baseType != null) {
-        propertyNames.addAll(baseType.getPropertyNames());
-      }
-      propertyNames.addAll(getProperties().keySet());
-    }
-    return propertyNames;
-  }
-
-  @Override
-  public List<String> getNavigationPropertyNames() {
-    if (navigationPropertyNames == null) {
-      navigationPropertyNames = new ArrayList<String>();
-      if (baseType != null) {
-        navigationPropertyNames.addAll(baseType.getNavigationPropertyNames());
-      }
-      navigationPropertyNames.addAll(getNavigationProperties().keySet());
-    }
-    return navigationPropertyNames;
-  }
-
-  @Override
-  public EdmElement getProperty(final String name) {
-    EdmElement property = getStructuralProperty(name);
-    if (property == null) {
-      property = getNavigationProperty(name);
-    }
-    return property;
-  }
-
-  @Override
-  public EdmProperty getStructuralProperty(final String name) {
-    EdmProperty property = null;
-    if (baseType != null) {
-      property = baseType.getStructuralProperty(name);
-    }
-    if (property == null) {
-      property = getProperties().get(name);
+    @Override
+    public List<String> getPropertyNames() {
+        if (propertyNames == null) {
+            propertyNames = new ArrayList<String>();
+            if (baseType != null) {
+                propertyNames.addAll(baseType.getPropertyNames());
+            }
+            propertyNames.addAll(getProperties().keySet());
+        }
+        return propertyNames;
     }
-    return property;
-  }
-
-  @Override
-  public EdmNavigationProperty getNavigationProperty(final String name) {
-    EdmNavigationProperty property = null;
-    if (baseType != null) {
-      property = baseType.getNavigationProperty(name);
+
+    @Override
+    public List<String> getNavigationPropertyNames() {
+        if (navigationPropertyNames == null) {
+            navigationPropertyNames = new ArrayList<String>();
+            if (baseType != null) {
+                navigationPropertyNames.addAll(baseType.getNavigationPropertyNames());
+            }
+            navigationPropertyNames.addAll(getNavigationProperties().keySet());
+        }
+        return navigationPropertyNames;
     }
-    if (property == null) {
-      property = getNavigationProperties().get(name);
+
+    @Override
+    public EdmElement getProperty(final String name) {
+        EdmElement property = getStructuralProperty(name);
+        if (property == null) {
+            property = getNavigationProperty(name);
+        }
+        return property;
     }
-    return property;
-  }
-
-  @Override
-  public boolean compatibleTo(final EdmType targetType) {
-    EdmStructuredType sourceType = this;
-    if (targetType == null) {
-      throw new EdmException("Target type must not be null");
+
+    @Override
+    public EdmProperty getStructuralProperty(final String name) {
+        EdmProperty property = null;
+        if (baseType != null) {
+            property = baseType.getStructuralProperty(name);
+        }
+        if (property == null) {
+            property = getProperties().get(name);
+        }
+        return property;
     }
-    while (!sourceType.getName().equals(targetType.getName()) 
-           || !sourceType.getNamespace().equals(targetType.getNamespace())) {
-      
-      sourceType = sourceType.getBaseType();
-      if (sourceType == null) {
-        return false;
-      }
+
+    @Override
+    public EdmNavigationProperty getNavigationProperty(final String name) {
+        EdmNavigationProperty property = null;
+        if (baseType != null) {
+            property = baseType.getNavigationProperty(name);
+        }
+        if (property == null) {
+            property = getNavigationProperties().get(name);
+        }
+        return property;
     }
 
-    return true;
-  }
+    @Override
+    public boolean compatibleTo(final EdmType targetType) {
+        EdmStructuredType sourceType = this;
+        if (targetType == null) {
+            throw new EdmException("Target type must not be null");
+        }
+        while (!sourceType.getName().equals(targetType.getName())
+                || !sourceType.getNamespace().equals(targetType.getNamespace())) {
+
+            sourceType = sourceType.getBaseType();
+            if (sourceType == null) {
+                return false;
+            }
+        }
+
+        return true;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNamedImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNamedImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNamedImpl.java
index 8f82d56..0f0bd5d 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNamedImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNamedImpl.java
@@ -23,18 +23,17 @@ import org.apache.olingo.commons.api.edm.EdmNamed;
 
 public abstract class EdmNamedImpl implements EdmNamed {
 
-  protected final Edm edm;
+    protected final Edm edm;
 
-  private final String name;
+    private final String name;
 
-  public EdmNamedImpl(final Edm edm, final String name) {
-    this.edm = edm;
-    this.name = name;
-  }
-
-  @Override
-  public String getName() {
-    return name;
-  }
+    public EdmNamedImpl(final Edm edm, final String name) {
+        this.edm = edm;
+        this.name = name;
+    }
 
+    @Override
+    public String getName() {
+        return name;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeImpl.java
index 7fc2808..ed20afa 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeImpl.java
@@ -25,24 +25,23 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
 
 public class EdmTypeImpl extends EdmNamedImpl implements EdmType {
 
-  protected final FullQualifiedName fqn;
+    protected final FullQualifiedName fqn;
 
-  protected final EdmTypeKind kind;
+    protected final EdmTypeKind kind;
 
-  public EdmTypeImpl(final Edm edm, final FullQualifiedName fqn, final EdmTypeKind kind) {
-    super(edm, fqn.getName());
-    this.fqn = fqn;
-    this.kind = kind;
-  }
+    public EdmTypeImpl(final Edm edm, final FullQualifiedName fqn, final EdmTypeKind kind) {
+        super(edm, fqn.getName());
+        this.fqn = fqn;
+        this.kind = kind;
+    }
 
-  @Override
-  public String getNamespace() {
-    return fqn.getNamespace();
-  }
-
-  @Override
-  public EdmTypeKind getKind() {
-    return kind;
-  }
+    @Override
+    public String getNamespace() {
+        return fqn.getNamespace();
+    }
 
+    @Override
+    public EdmTypeKind getKind() {
+        return kind;
+    }
 }


[5/8] git commit: [OLINGO-205, OLINGO-200] provided atom v4 deserialization for entity type/set + entity set request

Posted by fm...@apache.org.
[OLINGO-205, OLINGO-200] provided atom v4 deserialization for entity type/set + entity set request


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

Branch: refs/heads/olingo200
Commit: 9aefb95905edee86a6747c26afa40d6f57451008
Parents: 4780fc5
Author: fmartelli <fa...@gmail.com>
Authored: Mon Mar 24 09:50:23 2014 +0100
Committer: fmartelli <fa...@gmail.com>
Committed: Mon Mar 24 09:50:23 2014 +0100

----------------------------------------------------------------------
 .../org/apache/olingo/fit/AbstractServices.java |   28 +-
 .../olingo/fit/utils/AbstractJSONUtilities.java |  503 +++++++
 .../olingo/fit/utils/AbstractUtilities.java     |    3 +-
 .../olingo/fit/utils/AbstractXMLUtilities.java  | 1302 ++++++++++++++++
 .../org/apache/olingo/fit/utils/Accept.java     |   50 +-
 .../org/apache/olingo/fit/utils/Commons.java    |    6 +-
 .../apache/olingo/fit/utils/JSONUtilities.java  |  503 -------
 .../apache/olingo/fit/utils/XMLUtilities.java   | 1388 ------------------
 .../olingo/fit/utils/v3/JSONUtilities.java      |   28 +
 .../olingo/fit/utils/v3/XMLUtilities.java       |  191 +++
 .../olingo/fit/utils/v4/JSONUtilities.java      |   28 +
 .../olingo/fit/utils/v4/XMLUtilities.java       |  142 ++
 fit/src/main/resources/v4/People/feed.full.json |  332 +++++
 fit/src/main/resources/v4/People/feed.xml       |  218 +++
 fit/src/main/resources/v4/metadata.xml          |  743 +++++-----
 .../request/ODataBasicRequest.java              |    3 +-
 .../request/retrieve/ODataRetrieveRequest.java  |    3 +-
 .../olingo/client/api/domain/ODataLinkType.java |    8 +-
 .../apache/olingo/client/api/format/Format.java |   26 +
 .../olingo/client/api/format/ODataFormat.java   |    8 +-
 .../client/api/format/ODataMediaFormat.java     |    8 +-
 .../client/api/format/ODataPubFormat.java       |   47 +-
 .../client/api/format/ODataValueFormat.java     |    8 +-
 .../request/AbstractODataBasicRequest.java      |  144 +-
 .../communication/request/ODataRequestImpl.java |   12 +-
 .../request/invoke/ODataInvokeRequestImpl.java  |    4 +-
 .../retrieve/AbstractODataRetrieveRequest.java  |    3 +-
 .../request/retrieve/ODataRawRequestImpl.java   |    2 +-
 .../AbstractODataStreamedEntityRequest.java     |    4 +-
 .../core/data/AbstractJsonDeserializer.java     |    5 +-
 .../client/core/data/AtomDeserializer.java      |    2 -
 .../core/data/AtomPropertyDeserializer.java     |   16 +-
 .../core/data/JSONGeoValueDeserializer.java     |   11 +-
 .../client/core/edm/EdmActionImportImpl.java    |    1 -
 .../client/core/edm/EdmOperationImpl.java       |    8 +-
 .../olingo/client/core/edm/EdmTypeInfo.java     |   26 +-
 .../core/op/impl/AbstractODataBinder.java       |    8 +-
 .../core/op/impl/AbstractODataDeserializer.java |    1 -
 .../core/it/v3/EntityRetrieveTestITCase.java    |    2 +-
 .../client/core/it/v3/EntitySetTestITCase.java  |    2 +-
 .../core/it/v3/QueryOptionsTestITCase.java      |    3 +-
 .../client/core/it/v4/AbstractTestITCase.java   |    4 +-
 .../client/core/it/v4/EntitySetTestITCase.java  |  152 ++
 .../org/apache/olingo/commons/api/edm/Edm.java  |  161 +-
 .../olingo/commons/api/edm/EdmActionImport.java |    2 +-
 .../api/edm/constants/ODataServiceVersion.java  |    7 +-
 .../core/edm/AbstractEdmComplexType.java        |   39 +-
 .../core/edm/AbstractEdmEntityContainer.java    |  176 +--
 .../commons/core/edm/AbstractEdmOperation.java  |  131 +-
 .../core/edm/AbstractEdmOperationImport.java    |   65 +-
 .../core/edm/AbstractEdmStructuredType.java     |  159 +-
 .../olingo/commons/core/edm/EdmNamedImpl.java   |   21 +-
 .../olingo/commons/core/edm/EdmTypeImpl.java    |   31 +-
 53 files changed, 3917 insertions(+), 2861 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/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 12032c5..025e4fe 100644
--- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
+++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
@@ -19,8 +19,8 @@
 package org.apache.olingo.fit;
 
 import org.apache.olingo.fit.utils.Accept;
-import org.apache.olingo.fit.utils.XMLUtilities;
-import org.apache.olingo.fit.utils.JSONUtilities;
+import org.apache.olingo.fit.utils.AbstractXMLUtilities;
+import org.apache.olingo.fit.utils.AbstractJSONUtilities;
 import org.apache.olingo.fit.utils.ODataVersion;
 import org.apache.olingo.fit.utils.FSManager;
 
@@ -70,13 +70,18 @@ public abstract class AbstractServices {
   private static Set<ODataVersion> initialized = EnumSet.noneOf(ODataVersion.class);
 
   protected abstract ODataVersion getVersion();
-  protected final XMLUtilities xml;
+  protected final AbstractXMLUtilities xml;
 
-  protected final JSONUtilities json;
+  protected final AbstractJSONUtilities json;
 
   public AbstractServices() throws Exception {
-    this.xml = new XMLUtilities(getVersion());
-    this.json = new JSONUtilities(getVersion());
+    if (ODataVersion.v3 == getVersion()) {
+      this.xml = new org.apache.olingo.fit.utils.v3.XMLUtilities();
+      this.json = new org.apache.olingo.fit.utils.v3.JSONUtilities();
+    } else {
+      this.xml = new org.apache.olingo.fit.utils.v4.XMLUtilities();
+      this.json = new org.apache.olingo.fit.utils.v4.JSONUtilities();
+    }
 
     if (!initialized.contains(getVersion())) {
       xml.retrieveLinkInfoFromMetadata();
@@ -135,7 +140,7 @@ public abstract class AbstractServices {
       return xml.
               createResponse(FSManager.instance(getVersion()).readFile(filename, Accept.XML), null, Accept.XML);
     } catch (Exception e) {
-      return xml.createFaultResponse(Accept.XML.toString(), e);
+      return xml.createFaultResponse(Accept.XML.toString(getVersion()), e);
     }
   }
 
@@ -547,7 +552,7 @@ public abstract class AbstractServices {
 
       return xml.createResponse(null, null, null, Response.Status.NO_CONTENT);
     } catch (Exception e) {
-      return xml.createFaultResponse(Accept.XML.toString(), e);
+      return xml.createFaultResponse(Accept.XML.toString(getVersion()), e);
     }
   }
 
@@ -749,7 +754,7 @@ public abstract class AbstractServices {
 
     } catch (Exception e) {
       LOG.error("Error retrieving entity", e);
-      return xml.createFaultResponse(Accept.JSON.toString(), e);
+      return xml.createFaultResponse(Accept.JSON.toString(getVersion()), e);
     }
   }
 
@@ -775,7 +780,7 @@ public abstract class AbstractServices {
           @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format,
           final String changes) {
     if (xml.isMediaContent(entitySetName + "/" + path)) {
-      return replaceMediaProperty(prefer, entitySetName, entityId, path, format, changes);
+      return replaceMediaProperty(prefer, entitySetName, entityId, path, changes);
     } else {
       return replaceProperty(accept, prefer, entitySetName, entityId, path, format, changes, false);
     }
@@ -786,7 +791,6 @@ public abstract class AbstractServices {
           final String entitySetName,
           final String entityId,
           final String path,
-          final String format,
           final String value) {
     try {
       final AbstractUtilities utils = getUtilities(null);
@@ -809,7 +813,7 @@ public abstract class AbstractServices {
 
     } catch (Exception e) {
       LOG.error("Error retrieving entity", e);
-      return xml.createFaultResponse(Accept.JSON.toString(), e);
+      return xml.createFaultResponse(Accept.JSON.toString(getVersion()), e);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java
new file mode 100644
index 0000000..c62d341
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java
@@ -0,0 +1,503 @@
+/*
+ * 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.utils;
+
+import static org.apache.olingo.fit.utils.Constants.*;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.NotFoundException;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+
+public abstract class AbstractJSONUtilities extends AbstractUtilities {
+
+  public AbstractJSONUtilities(final ODataVersion version) throws Exception {
+    super(version);
+  }
+
+  @Override
+  protected Accept getDefaultFormat() {
+    return Accept.JSON_FULLMETA;
+  }
+
+  @Override
+  protected InputStream addLinks(
+          final String entitySetName, final String entitykey, final InputStream is, final Set<String> links)
+          throws Exception {
+    final ObjectMapper mapper = new ObjectMapper();
+    final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
+    IOUtils.closeQuietly(is);
+
+    for (String link : links) {
+      srcNode.set(link + JSON_NAVIGATION_SUFFIX,
+              new TextNode(Commons.getLinksURI(version, entitySetName, entitykey, link)));
+    }
+
+    return IOUtils.toInputStream(srcNode.toString());
+  }
+
+  @Override
+  protected Set<String> retrieveAllLinkNames(InputStream is) throws Exception {
+    final ObjectMapper mapper = new ObjectMapper();
+    final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
+    IOUtils.closeQuietly(is);
+
+    final Set<String> links = new HashSet<String>();
+
+    final Iterator<String> fieldIter = srcNode.fieldNames();
+
+    while (fieldIter.hasNext()) {
+      final String field = fieldIter.next();
+
+      if (field.endsWith(JSON_NAVIGATION_BIND_SUFFIX)
+              || field.endsWith(JSON_NAVIGATION_SUFFIX)
+              || field.endsWith(JSON_MEDIA_SUFFIX)
+              || field.endsWith(JSON_EDITLINK_NAME)) {
+        if (field.indexOf('@') > 0) {
+          links.add(field.substring(0, field.indexOf('@')));
+        } else {
+          links.add(field);
+        }
+      }
+    }
+
+    return links;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected NavigationLinks retrieveNavigationInfo(
+          final String entitySetName, final InputStream is)
+          throws Exception {
+    final ObjectMapper mapper = new ObjectMapper();
+    final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
+    IOUtils.closeQuietly(is);
+
+    final NavigationLinks links = new NavigationLinks();
+
+    final Iterator<Map.Entry<String, JsonNode>> fieldIter = srcNode.fields();
+
+    while (fieldIter.hasNext()) {
+      final Map.Entry<String, JsonNode> field = fieldIter.next();
+      if (field.getKey().endsWith(JSON_NAVIGATION_BIND_SUFFIX)) {
+        final String title = field.getKey().substring(0, field.getKey().indexOf('@'));
+        final List<String> hrefs = new ArrayList<String>();
+        if (field.getValue().isArray()) {
+          for (JsonNode href : ((ArrayNode) field.getValue())) {
+            final String uri = href.asText();
+            hrefs.add(uri.substring(uri.lastIndexOf('/') + 1));
+          }
+        } else {
+          final String uri = field.getValue().asText();
+          hrefs.add(uri.substring(uri.lastIndexOf('/') + 1));
+        }
+
+        links.addLinks(title, hrefs);
+      } else if (Commons.linkInfo.get(version).exists(entitySetName, field.getKey())) {
+        links.addInlines(field.getKey(), IOUtils.toInputStream(field.getValue().toString()));
+      }
+    }
+
+    return links;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected InputStream normalizeLinks(
+          final String entitySetName, final String entityKey, final InputStream is, final NavigationLinks links)
+          throws Exception {
+    final ObjectMapper mapper = new ObjectMapper();
+    final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
+
+    if (links != null) {
+      for (String linkTitle : links.getLinkNames()) {
+        // normalize link
+        srcNode.remove(linkTitle + JSON_NAVIGATION_BIND_SUFFIX);
+        srcNode.set(
+                linkTitle + JSON_NAVIGATION_SUFFIX,
+                new TextNode(String.format("%s(%s)/%s", entitySetName, entityKey, linkTitle)));
+      }
+
+      for (String linkTitle : links.getInlineNames()) {
+        // normalize link if exist; declare a new one if missing
+        srcNode.remove(linkTitle + JSON_NAVIGATION_BIND_SUFFIX);
+        srcNode.set(
+                linkTitle + JSON_NAVIGATION_SUFFIX,
+                new TextNode(String.format("%s(%s)/%s", entitySetName, entityKey, linkTitle)));
+
+        // remove inline
+        srcNode.remove(linkTitle);
+
+        // remove from links
+        links.removeLink(linkTitle);
+      }
+    }
+
+    srcNode.set(
+            JSON_EDITLINK_NAME,
+            new TextNode(Constants.DEFAULT_SERVICE_URL + entitySetName + "(" + entityKey + ")"));
+
+    return IOUtils.toInputStream(srcNode.toString());
+  }
+
+  @Override
+  public InputStream getPropertyValue(final InputStream src, final List<String> path)
+          throws Exception {
+    final ObjectMapper mapper = new ObjectMapper();
+    final JsonNode srcNode = mapper.readTree(src);
+    JsonNode node = getProperty(srcNode, path);
+    return IOUtils.toInputStream(node.asText());
+  }
+
+  @Override
+  public InputStream getProperty(
+          final String entitySetName, final String entityId, final List<String> path, final String edmType)
+          throws Exception {
+
+    final InputStream src =
+            fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) + ENTITY, Accept.JSON_FULLMETA);
+
+    final ObjectMapper mapper = new ObjectMapper();
+    final JsonNode srcNode = mapper.readTree(src);
+
+    final ObjectNode propertyNode = new ObjectNode(JsonNodeFactory.instance);
+
+    if (StringUtils.isNotBlank(edmType)) {
+      propertyNode.put(JSON_ODATAMETADATA_NAME, ODATA_METADATA_PREFIX + edmType);
+    }
+
+    JsonNode jsonNode = getProperty(srcNode, path);
+
+    if (jsonNode.isArray()) {
+      propertyNode.put("value", (ArrayNode) jsonNode);
+    } else if (jsonNode.isObject()) {
+      propertyNode.putAll((ObjectNode) jsonNode);
+    } else {
+      propertyNode.put("value", jsonNode.asText());
+    }
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    mapper.writeValue(bos, propertyNode);
+
+    final InputStream res = new ByteArrayInputStream(bos.toByteArray());
+    IOUtils.closeQuietly(bos);
+
+    return res;
+  }
+
+  private JsonNode getProperty(final JsonNode node, final List<String> path)
+          throws NotFoundException {
+
+    JsonNode propertyNode = node;
+    for (int i = 0; i < path.size(); i++) {
+      propertyNode = propertyNode.get(path.get(i));
+      if (propertyNode == null) {
+        throw new NotFoundException();
+      }
+    }
+
+    return propertyNode;
+  }
+
+  public InputStream addJsonInlinecount(
+          final InputStream src, final int count, final Accept accept)
+          throws Exception {
+    final ObjectMapper mapper = new ObjectMapper();
+    final JsonNode srcNode = mapper.readTree(src);
+
+    ((ObjectNode) srcNode).put(ODATA_COUNT_NAME, count);
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    mapper.writeValue(bos, srcNode);
+
+    final InputStream res = new ByteArrayInputStream(bos.toByteArray());
+    IOUtils.closeQuietly(bos);
+
+    return res;
+  }
+
+  public InputStream wrapJsonEntities(final InputStream entities) throws Exception {
+    final ObjectMapper mapper = new ObjectMapper();
+    final JsonNode node = mapper.readTree(entities);
+
+    final ObjectNode res;
+
+    final JsonNode value = node.get(JSON_VALUE_NAME);
+
+    if (value.isArray()) {
+      res = mapper.createObjectNode();
+      res.set("value", value);
+      final JsonNode next = node.get(JSON_NEXTLINK_NAME);
+      if (next != null) {
+        res.set(JSON_NEXTLINK_NAME, next);
+      }
+    } else {
+      res = (ObjectNode) value;
+    }
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    mapper.writeValue(bos, res);
+
+    final InputStream is = new ByteArrayInputStream(bos.toByteArray());
+    IOUtils.closeQuietly(bos);
+
+    return is;
+  }
+
+  @Override
+  public InputStream selectEntity(final InputStream src, final String[] propertyNames) throws Exception {
+    final ObjectMapper mapper = new ObjectMapper();
+    final ObjectNode srcNode = (ObjectNode) mapper.readTree(src);
+
+    final Set<String> retain = new HashSet<String>();
+    retain.add(JSON_ID_NAME);
+    retain.add(JSON_TYPE_NAME);
+    retain.add(JSON_EDITLINK_NAME);
+    retain.add(JSON_NEXTLINK_NAME);
+    retain.add(JSON_ODATAMETADATA_NAME);
+    retain.add(JSON_VALUE_NAME);
+
+    for (String name : propertyNames) {
+      retain.add(name);
+      retain.add(name + JSON_NAVIGATION_SUFFIX);
+      retain.add(name + JSON_MEDIA_SUFFIX);
+      retain.add(name + JSON_TYPE_SUFFIX);
+    }
+
+    srcNode.retain(retain);
+
+    return IOUtils.toInputStream(srcNode.toString());
+  }
+
+  @Override
+  public InputStream readEntities(
+          final List<String> links, final String linkName, final String next, final boolean forceFeed)
+          throws Exception {
+
+    if (links.isEmpty()) {
+      throw new NotFoundException();
+    }
+
+    final ObjectMapper mapper = new ObjectMapper();
+    final ObjectNode node = mapper.createObjectNode();
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+    if (forceFeed || links.size() > 1) {
+      bos.write("[".getBytes());
+    }
+
+    for (String link : links) {
+      try {
+        final Map.Entry<String, String> uri = Commons.parseEntityURI(link);
+        final Map.Entry<String, InputStream> entity =
+                readEntity(uri.getKey(), uri.getValue(), Accept.JSON_FULLMETA);
+
+        if (bos.size() > 1) {
+          bos.write(",".getBytes());
+        }
+
+        IOUtils.copy(entity.getValue(), bos);
+      } catch (Exception e) {
+        // log and ignore link
+        LOG.warn("Error parsing uri {}", link, e);
+      }
+    }
+
+    if (forceFeed || links.size() > 1) {
+      bos.write("]".getBytes());
+    }
+
+    node.set(JSON_VALUE_NAME, mapper.readTree(new ByteArrayInputStream(bos.toByteArray())));
+
+    if (StringUtils.isNotBlank(next)) {
+      node.set(JSON_NEXTLINK_NAME, new TextNode(next));
+    }
+
+    return IOUtils.toInputStream(node.toString());
+  }
+
+  @Override
+  protected InputStream replaceLink(
+          final InputStream toBeChanged, final String linkName, final InputStream replacement)
+          throws Exception {
+    final ObjectMapper mapper = new ObjectMapper();
+
+    final ObjectNode toBeChangedNode = (ObjectNode) mapper.readTree(toBeChanged);
+    final ObjectNode replacementNode = (ObjectNode) mapper.readTree(replacement);
+
+    if (toBeChangedNode.get(linkName + JSON_NAVIGATION_SUFFIX) == null) {
+      throw new NotFoundException();
+    }
+
+    toBeChangedNode.set(linkName, replacementNode.get(JSON_VALUE_NAME));
+
+    final JsonNode next = replacementNode.get(linkName + JSON_NEXTLINK_NAME);
+    if (next != null) {
+      toBeChangedNode.set(linkName + JSON_NEXTLINK_SUFFIX, next);
+    }
+
+    return IOUtils.toInputStream(toBeChangedNode.toString());
+  }
+
+  @Override
+  protected Map<String, InputStream> getChanges(final InputStream src) throws Exception {
+    final Map<String, InputStream> res = new HashMap<String, InputStream>();
+
+    final ObjectMapper mapper = new ObjectMapper();
+    final JsonNode srcObject = mapper.readTree(src);
+
+    final Iterator<Map.Entry<String, JsonNode>> fields = srcObject.fields();
+    while (fields.hasNext()) {
+      final Map.Entry<String, JsonNode> field = fields.next();
+      res.put(field.getKey(), IOUtils.toInputStream(field.getValue().toString()));
+    }
+
+    return res;
+  }
+
+  @Override
+  protected InputStream setChanges(
+          final InputStream toBeChanged, final Map<String, InputStream> properties) throws Exception {
+
+    final ObjectMapper mapper = new ObjectMapper();
+    final ObjectNode toBeChangedObject = (ObjectNode) mapper.readTree(toBeChanged);
+
+    for (Map.Entry<String, InputStream> property : properties.entrySet()) {
+      final JsonNode propertyNode = mapper.readTree(property.getValue());
+      toBeChangedObject.set(property.getKey(), propertyNode);
+    }
+
+    return IOUtils.toInputStream(toBeChangedObject.toString());
+  }
+
+  @Override
+  public Map.Entry<String, List<String>> extractLinkURIs(
+          final String entitySetName, final String entityId, final String linkName)
+          throws Exception {
+    final LinkInfo links = readLinks(entitySetName, entityId, linkName, Accept.JSON_FULLMETA);
+    return extractLinkURIs(links.getLinks());
+  }
+
+  @Override
+  public Map.Entry<String, List<String>> extractLinkURIs(final InputStream is)
+          throws Exception {
+    final ObjectMapper mapper = new ObjectMapper();
+    final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
+    IOUtils.closeQuietly(is);
+
+    final List<String> links = new ArrayList<String>();
+
+    JsonNode uris = srcNode.get("value");
+    if (uris == null) {
+      final JsonNode url = srcNode.get("url");
+      if (url != null) {
+        links.add(url.textValue());
+      }
+    } else {
+      final Iterator<JsonNode> iter = ((ArrayNode) uris).iterator();
+      while (iter.hasNext()) {
+        links.add(iter.next().get("url").textValue());
+      }
+    }
+
+    final JsonNode next = srcNode.get(JSON_NEXTLINK_NAME);
+
+    return new SimpleEntry<String, List<String>>(next == null ? null : next.asText(), links);
+  }
+
+  @Override
+  public InputStream addEditLink(
+          final InputStream content, final String title, final String href) throws Exception {
+    final ObjectMapper mapper = new ObjectMapper();
+    final ObjectNode srcNode = (ObjectNode) mapper.readTree(content);
+    IOUtils.closeQuietly(content);
+
+    srcNode.set(JSON_EDITLINK_NAME, new TextNode(href));
+    return IOUtils.toInputStream(srcNode.toString());
+  }
+
+  @Override
+  public InputStream replaceProperty(
+          final InputStream src, final InputStream replacement, final List<String> path, final boolean justValue)
+          throws Exception {
+    final ObjectMapper mapper = new ObjectMapper();
+    final ObjectNode srcNode = (ObjectNode) mapper.readTree(src);
+    IOUtils.closeQuietly(src);
+
+    final JsonNode replacementNode;
+    if (justValue) {
+      replacementNode = new TextNode(IOUtils.toString(replacement));
+    } else {
+      replacementNode = (ObjectNode) mapper.readTree(replacement);
+    }
+    IOUtils.closeQuietly(replacement);
+
+    JsonNode node = srcNode;
+    for (int i = 0; i < path.size() - 1; i++) {
+      node = node.get(path.get(i));
+      if (node == null) {
+        throw new NotFoundException();
+      }
+    }
+
+    ((ObjectNode) node).set(path.get(path.size() - 1), replacementNode);
+
+    return IOUtils.toInputStream(srcNode.toString());
+  }
+
+  @Override
+  public InputStream deleteProperty(final InputStream src, final List<String> path) throws Exception {
+    final ObjectMapper mapper = new ObjectMapper();
+    final ObjectNode srcNode = (ObjectNode) mapper.readTree(src);
+    IOUtils.closeQuietly(src);
+
+    JsonNode node = srcNode;
+    for (int i = 0; i < path.size() - 1; i++) {
+      node = node.get(path.get(i));
+      if (node == null) {
+        throw new NotFoundException();
+      }
+    }
+
+    ((ObjectNode) node).set(path.get(path.size() - 1), null);
+
+    return IOUtils.toInputStream(srcNode.toString());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/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 74653a1..7b74b62 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
@@ -384,7 +384,7 @@ public abstract class AbstractUtilities {
     }
 
     if (accept != null) {
-      builder.header("Content-Type", accept.toString());
+      builder.header("Content-Type", accept.toString(version));
     } else {
       builder.header("Content-Type", "*/*");
     }
@@ -423,7 +423,6 @@ public abstract class AbstractUtilities {
 
   public Response createFaultResponse(final String accept, final Exception e) {
     LOG.debug("Create fault response about .... ", e);
-    e.printStackTrace();
 
     final Response.ResponseBuilder builder = Response.serverError();
     if (version == ODataVersion.v3) {

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java
new file mode 100644
index 0000000..d02e828
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java
@@ -0,0 +1,1302 @@
+/*
+ * 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.utils;
+
+import static org.apache.olingo.fit.utils.Constants.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.StringWriter;
+import java.util.AbstractMap;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.NotFoundException;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemException;
+
+public abstract class AbstractXMLUtilities extends AbstractUtilities {
+
+  protected static XMLInputFactory ifactory = null;
+
+  protected static XMLOutputFactory ofactory = null;
+
+  public AbstractXMLUtilities(final ODataVersion version) throws Exception {
+    super(version);
+  }
+
+  public abstract void retrieveLinkInfoFromMetadata() throws Exception;
+
+  @Override
+  protected Accept getDefaultFormat() {
+    return Accept.ATOM;
+  }
+
+  protected XMLEventReader getEventReader(final InputStream is) throws XMLStreamException {
+    if (ifactory == null) {
+      ifactory = XMLInputFactory.newInstance();
+    }
+    ifactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false);
+    return ifactory.createXMLEventReader(is);
+  }
+
+  protected static XMLEventWriter getEventWriter(final OutputStream os) throws XMLStreamException {
+    if (ofactory == null) {
+      ofactory = XMLOutputFactory.newInstance();
+    }
+
+    return ofactory.createXMLEventWriter(os);
+  }
+
+  private void writeEvent(final XMLEvent event, final XMLEventWriter writer) {
+    if (writer != null) {
+      try {
+        writer.add(event);
+      } catch (XMLStreamException e) {
+        LOG.error("Error writing event {}", event, e);
+      }
+    }
+  }
+
+  private void skipElement(
+          final StartElement start,
+          final XMLEventReader reader,
+          final XMLEventWriter writer,
+          final boolean excludeStart)
+          throws Exception {
+
+    if (!excludeStart) {
+      writeEvent(start, writer);
+    }
+
+    int depth = 1;
+    boolean found = false;
+
+    while (reader.hasNext() && !found) {
+      final XMLEvent event = reader.nextEvent();
+
+      writeEvent(event, writer);
+
+      if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
+        depth++;
+      } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
+        depth--;
+        found = depth == 0 && start.getName().equals(event.asEndElement().getName());
+      }
+    }
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected InputStream addLinks(
+          final String entitySetName, final String entitykey, final InputStream is, final Set<String> links)
+          throws Exception {
+
+    // -----------------------------------------
+    // 0. Build reader and writer
+    // -----------------------------------------
+    final XMLEventReader reader = getEventReader(is);
+    final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    final XMLEventWriter writer = getEventWriter(bos);
+    // -----------------------------------------
+    final Map.Entry<Integer, XmlElement> entry =
+            extractElement(reader, writer, Collections.singletonList("entry"), 0, 1, 1);
+
+    writer.add(entry.getValue().getStart());
+
+    // add for links
+    for (String link : links) {
+      final Set<Attribute> attributes = new HashSet<Attribute>();
+      attributes.add(eventFactory.createAttribute(new QName("title"), link));
+      attributes.add(eventFactory.createAttribute(new QName("href"),
+              Commons.getLinksURI(version, entitySetName, entitykey, link)));
+      attributes.add(eventFactory.createAttribute(new QName("rel"), Constants.ATOM_LINK_REL + link));
+      attributes.add(eventFactory.createAttribute(new QName("type"),
+              Commons.linkInfo.get(version).isFeed(entitySetName, link) ? Constants.ATOM_LINK_FEED
+              : Constants.ATOM_LINK_ENTRY));
+
+      writer.add(eventFactory.createStartElement(new QName(LINK), attributes.iterator(), null));
+      writer.add(eventFactory.createEndElement(new QName(LINK), null));
+    }
+
+    writer.add(entry.getValue().getContentReader());
+    writer.add(entry.getValue().getEnd());
+    writer.add(reader);
+    IOUtils.closeQuietly(is);
+
+    writer.flush();
+    writer.close();
+    reader.close();
+
+    return new ByteArrayInputStream(bos.toByteArray());
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected Set<String> retrieveAllLinkNames(final InputStream is) throws Exception {
+    final Set<String> links = new HashSet<String>();
+
+    final XMLEventReader reader = getEventReader(is);
+
+    try {
+
+      int startDepth = 0;
+
+      while (true) {
+        final Map.Entry<Integer, XmlElement> linkInfo =
+                extractElement(reader, null, Collections.<String>singletonList(LINK), startDepth, 2, 2);
+
+        startDepth = linkInfo.getKey();
+
+        links.add(linkInfo.getValue().getStart().getAttributeByName(new QName("title")).getValue());
+      }
+    } catch (Exception ignore) {
+      // ignore
+    } finally {
+      reader.close();
+      IOUtils.closeQuietly(is);
+    }
+
+    return links;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected NavigationLinks retrieveNavigationInfo(
+          final String entitySetName, final InputStream is)
+          throws Exception {
+
+    final NavigationLinks links = new NavigationLinks();
+
+    final XMLEventReader reader = getEventReader(is);
+
+    try {
+      final List<Map.Entry<String, String>> filter = new ArrayList<Map.Entry<String, String>>();
+      filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=entry"));
+      filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=feed"));
+
+      int startDepth = 0;
+
+      while (true) {
+        // a. search for link with type attribute equals to "application/atom+xml;type=entry/feed"
+        final Map.Entry<Integer, XmlElement> linkInfo = extractElement(
+                reader, null, Collections.<String>singletonList(LINK), filter, true, startDepth, 2, 2);
+        final XmlElement link = linkInfo.getValue();
+        startDepth = linkInfo.getKey();
+
+        final String title = link.getStart().getAttributeByName(new QName("title")).getValue();
+
+        final Attribute hrefAttr = link.getStart().getAttributeByName(new QName("href"));
+        final String href = hrefAttr == null ? null : hrefAttr.getValue();
+
+        try {
+          final XmlElement inlineElement =
+                  extractElement(link.getContentReader(), null, Collections.<String>singletonList(INLINE), 0, -1, -1).
+                  getValue();
+          final XMLEventReader inlineReader = inlineElement.getContentReader();
+
+          try {
+            while (true) {
+              final XmlElement entry =
+                      extractElement(inlineReader, null, Collections.<String>singletonList("entry"), 0, -1, -1).
+                      getValue();
+              links.addInlines(title, entry.toStream());
+            }
+          } catch (Exception e) {
+            // Reached the end of document
+          }
+
+          inlineReader.close();
+        } catch (Exception ignore) {
+          // inline element not found (inlines are not mondatory).
+          if (StringUtils.isNotBlank(href) && entityUriPattern.matcher(href).matches()) {
+            links.addLinks(title, href.substring(href.lastIndexOf('/') + 1));
+          }
+        }
+      }
+    } catch (Exception ignore) {
+      // ignore
+    } finally {
+      reader.close();
+    }
+
+    return links;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected InputStream normalizeLinks(
+          final String entitySetName, final String entityKey, final InputStream is, final NavigationLinks links)
+          throws Exception {
+
+    // -----------------------------------------
+    // 0. Build reader and writer
+    // -----------------------------------------
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    IOUtils.copy(is, bos);
+    is.close();
+
+    final ByteArrayOutputStream tmpBos = new ByteArrayOutputStream();
+    final XMLEventWriter writer = getEventWriter(tmpBos);
+
+    final XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+    // -----------------------------------------
+
+    // -----------------------------------------
+    // 1. Normalize links
+    // -----------------------------------------
+    final Set<String> added = new HashSet<String>();
+
+    try {
+      final List<Map.Entry<String, String>> filter = new ArrayList<Map.Entry<String, String>>();
+      filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=entry"));
+      filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=feed"));
+
+      Map.Entry<Integer, XmlElement> linkInfo = null;
+
+      while (true) {
+        // a. search for link with type attribute equals to "application/atom+xml;type=entry/feed"
+        linkInfo = extractElement(
+                reader, writer, Collections.<String>singletonList(LINK), filter, true,
+                linkInfo == null ? 0 : linkInfo.getKey(), 2, 2);
+        final XmlElement link = linkInfo.getValue();
+
+        final String title = link.getStart().getAttributeByName(new QName("title")).getValue();
+
+        if (!added.contains(title)) {
+          added.add(title);
+
+          final String normalizedLink = String.format(
+                  "<link href=\"%s(%s)/%s\" rel=\"%s\" title=\"%s\" type=\"%s\"/>",
+                  entitySetName,
+                  entityKey,
+                  title,
+                  link.getStart().getAttributeByName(new QName("rel")).getValue(),
+                  title,
+                  link.getStart().getAttributeByName(new QName("type")).getValue());
+
+          addAtomElement(IOUtils.toInputStream(normalizedLink), writer);
+        }
+      }
+    } catch (Exception ignore) {
+      // ignore
+    } finally {
+      writer.close();
+      reader.close();
+    }
+    // -----------------------------------------
+
+    // -----------------------------------------
+    // 2. Add edit link if missing
+    // -----------------------------------------
+    final InputStream content = addEditLink(
+            new ByteArrayInputStream(tmpBos.toByteArray()),
+            entitySetName,
+            Constants.DEFAULT_SERVICE_URL + entitySetName + "(" + entityKey + ")");
+    // -----------------------------------------
+
+    // -----------------------------------------
+    // 3. Add content element if missing
+    // -----------------------------------------
+    return addAtomContent(
+            content,
+            entitySetName,
+            Constants.DEFAULT_SERVICE_URL + entitySetName + "(" + entityKey + ")");
+    // -----------------------------------------
+
+  }
+
+  public XmlElement getXmlElement(
+          final StartElement start,
+          final XMLEventReader reader)
+          throws Exception {
+
+    final XmlElement res = new XmlElement();
+    res.setStart(start);
+
+    StringWriter content = new StringWriter();
+
+    int depth = 1;
+
+    while (reader.hasNext() && depth > 0) {
+      final XMLEvent event = reader.nextEvent();
+
+      if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
+        depth++;
+      } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
+        depth--;
+      }
+
+      if (depth == 0) {
+        res.setEnd(event.asEndElement());
+      } else {
+        event.writeAsEncodedUnicode(content);
+      }
+    }
+
+    content.flush();
+    content.close();
+
+    res.setContent(new ByteArrayInputStream(content.toString().getBytes()));
+
+    return res;
+  }
+
+  private void addAtomElement(
+          final InputStream content,
+          final XMLEventWriter writer)
+          throws Exception {
+    final XMLEventReader reader = getEventReader(content);
+
+    final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+    XMLEvent newLine = eventFactory.createSpace("\n");
+
+    try {
+      writer.add(newLine);
+
+      while (reader.hasNext()) {
+        final XMLEvent event = reader.nextEvent();
+
+        if (event.getEventType() != XMLStreamConstants.START_DOCUMENT
+                && event.getEventType() != XMLStreamConstants.END_DOCUMENT
+                && event.getEventType() != XMLStreamConstants.COMMENT) {
+          writer.add(event);
+        }
+      }
+      writer.add(newLine);
+    } finally {
+      reader.close();
+      IOUtils.closeQuietly(content);
+    }
+  }
+
+  @Override
+  public InputStream addEditLink(
+          final InputStream content, final String title, final String href)
+          throws Exception {
+
+    final ByteArrayOutputStream copy = new ByteArrayOutputStream();
+    IOUtils.copy(content, copy);
+
+    IOUtils.closeQuietly(content);
+
+    XMLEventReader reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+    ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    XMLEventWriter writer = getEventWriter(bos);
+
+    final String editLinkElement = String.format("<link rel=\"edit\" title=\"%s\" href=\"%s\" />", title, href);
+
+    try {
+      // check edit link existence
+      extractElement(reader, writer, Collections.<String>singletonList(LINK),
+              Collections.<Map.Entry<String, String>>singletonList(
+              new AbstractMap.SimpleEntry<String, String>("rel", "edit")), false, 0, -1, -1);
+
+      addAtomElement(IOUtils.toInputStream(editLinkElement), writer);
+      writer.add(reader);
+
+    } catch (Exception e) {
+      reader.close();
+      reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+      bos = new ByteArrayOutputStream();
+      writer = getEventWriter(bos);
+
+      final XmlElement entryElement =
+              extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
+
+      writer.add(entryElement.getStart());
+
+      addAtomElement(IOUtils.toInputStream(editLinkElement), writer);
+
+      writer.add(entryElement.getContentReader());
+      writer.add(entryElement.getEnd());
+
+      writer.add(reader);
+
+      writer.flush();
+      writer.close();
+    } finally {
+      reader.close();
+    }
+
+    return new ByteArrayInputStream(bos.toByteArray());
+  }
+
+  public InputStream addAtomContent(
+          final InputStream content, final String title, final String href)
+          throws Exception {
+
+    final ByteArrayOutputStream copy = new ByteArrayOutputStream();
+    IOUtils.copy(content, copy);
+
+    IOUtils.closeQuietly(content);
+
+    XMLEventReader reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+    ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    XMLEventWriter writer = getEventWriter(bos);
+
+    try {
+      // check edit link existence
+      XmlElement contentElement =
+              extractElement(reader, writer, Collections.<String>singletonList("content"), 0, 2, 2).getValue();
+      writer.add(contentElement.getStart());
+      writer.add(contentElement.getContentReader());
+      writer.add(contentElement.getEnd());
+      writer.add(reader);
+    } catch (Exception e) {
+      reader.close();
+      reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+      bos = new ByteArrayOutputStream();
+      writer = getEventWriter(bos);
+
+      if (isMediaContent(title)) {
+        final XmlElement entryElement =
+                extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
+
+        writer.add(entryElement.getStart());
+        writer.add(entryElement.getContentReader());
+
+        addAtomElement(
+                IOUtils.toInputStream(String.format("<content type=\"*/*\" src=\"%s/$value\" />", href)),
+                writer);
+
+        writer.add(entryElement.getEnd());
+      } else {
+        try {
+          final XmlElement entryElement =
+                  extractElement(reader, writer, Collections.<String>singletonList(PROPERTIES), 0, 2, 3).getValue();
+
+          addAtomElement(
+                  IOUtils.toInputStream("<content type=\"application/xml\">"),
+                  writer);
+
+          writer.add(entryElement.getStart());
+          writer.add(entryElement.getContentReader());
+          writer.add(entryElement.getEnd());
+
+          addAtomElement(
+                  IOUtils.toInputStream("</content>"),
+                  writer);
+        } catch (Exception nf) {
+          reader.close();
+          reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
+
+          bos = new ByteArrayOutputStream();
+          writer = getEventWriter(bos);
+
+          final XmlElement entryElement =
+                  extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
+          writer.add(entryElement.getStart());
+          writer.add(entryElement.getContentReader());
+
+          addAtomElement(
+                  IOUtils.toInputStream("<content type=\"application/xml\"/>"),
+                  writer);
+
+          writer.add(entryElement.getEnd());
+        }
+      }
+
+      writer.add(reader);
+
+      writer.flush();
+      writer.close();
+    } finally {
+      reader.close();
+    }
+
+    return new ByteArrayInputStream(bos.toByteArray());
+  }
+
+  public int countAllElements(final String entitySetName) throws Exception {
+    final String basePath = entitySetName + File.separatorChar;
+    int count = countFeedElements(fsManager.readFile(basePath + FEED, Accept.XML), "entry");
+
+    final String skipTokenDirPath = fsManager.getAbsolutePath(basePath + SKIP_TOKEN, null);
+
+
+    try {
+      final FileObject skipToken = fsManager.resolve(skipTokenDirPath);
+      final FileObject[] files = fsManager.findByExtension(skipToken, Accept.XML.getExtension().substring(1));
+
+      for (FileObject file : files) {
+        count += countFeedElements(fsManager.readFile(
+                basePath + SKIP_TOKEN + File.separatorChar + file.getName().getBaseName(), null), "entry");
+      }
+    } catch (FileSystemException fse) {
+      LOG.debug("Resource path '{}' not found", skipTokenDirPath);
+    }
+
+
+    return count;
+  }
+
+  private int countFeedElements(final InputStream is, final String elementName) throws XMLStreamException {
+    final XMLEventReader reader = getEventReader(is);
+
+    int count = 0;
+
+    while (reader.hasNext()) {
+      final XMLEvent event = reader.nextEvent();
+
+      if (event.getEventType() == XMLStreamConstants.START_ELEMENT
+              && elementName.equals(event.asStartElement().getName().getLocalPart())) {
+        count++;
+      }
+    }
+
+    reader.close();
+    return count;
+  }
+
+  public Map.Entry<Integer, XmlElement> extractElement(
+          final XMLEventReader reader, final XMLEventWriter writer, final List<String> path,
+          final int startPathPos, final int minPathPos, final int maxPathPos)
+          throws Exception {
+    return extractElement(reader, writer, path, null, false, startPathPos, minPathPos, maxPathPos);
+  }
+
+  public Map.Entry<Integer, XmlElement> extractElement(
+          final XMLEventReader reader, final XMLEventWriter writer, final List<String> path,
+          final Collection<Map.Entry<String, String>> filter,
+          final boolean filterInOr,
+          final int startPathPos, final int minPathPos, final int maxPathPos)
+          throws Exception {
+
+    StartElement start = null;
+    int searchFor = 0;
+    int depth = startPathPos;
+
+    // Current inspected element
+    String current = null;
+
+    // set defaults
+    final List<String> pathElementNames = path == null ? Collections.<String>emptyList() : path;
+    final Collection<Map.Entry<String, String>> filterAttrs =
+            filter == null ? Collections.<Map.Entry<String, String>>emptySet() : filter;
+
+    while (reader.hasNext() && start == null) {
+      final XMLEvent event = reader.nextEvent();
+
+      if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
+        depth++;
+
+        if (current != null || ((minPathPos < 0 || minPathPos <= depth) && (maxPathPos < 0 || depth <= maxPathPos))) {
+          if (pathElementNames.isEmpty()
+                  || pathElementNames.get(searchFor).trim().equals(event.asStartElement().getName().getLocalPart())) {
+
+            if (searchFor < pathElementNames.size() - 1) {
+              // path exploring not completed
+              writeEvent(event, writer);
+              current = pathElementNames.get(searchFor).trim();
+              searchFor++;
+            } else {
+
+              // path exploring completed ... evaluate filter about path element name attribute
+              boolean match = filterAttrs.isEmpty() || !filterInOr;
+
+              for (Map.Entry<String, String> filterAttr : filterAttrs) {
+                final Attribute attr = event.asStartElement().getAttributeByName(new QName(filterAttr.getKey().trim()));
+
+                if (attr == null || !filterAttr.getValue().trim().equals(attr.getValue())) {
+                  match = filterInOr ? match : false;
+                } else {
+                  match = filterInOr ? true : match;
+                }
+              }
+
+              if (match) {
+                // found searched element
+                start = event.asStartElement();
+              } else {
+                skipElement(event.asStartElement(), reader, writer, false);
+                depth--;
+              }
+            }
+          } else if (current == null) {
+            writeEvent(event, writer);
+          } else {
+            // skip element
+            skipElement(event.asStartElement(), reader, writer, false);
+            depth--;
+          }
+        } else {
+          writeEvent(event, writer);
+        }
+
+      } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
+        depth--;
+
+        writeEvent(event, writer);
+
+        if (event.asEndElement().getName().getLocalPart().equals(current)) {
+          // back step ....
+          searchFor--;
+          current = searchFor > 0 ? pathElementNames.get(searchFor - 1).trim() : null;
+        }
+      } else {
+        writeEvent(event, writer);
+      }
+    }
+
+    if (start == null) {
+      throw new NotFoundException();
+    }
+
+    return new SimpleEntry<Integer, XmlElement>(Integer.valueOf(depth - 1), getXmlElement(start, reader));
+  }
+
+  public InputStream addAtomInlinecount(
+          final InputStream feed, final int count, final Accept accept)
+          throws Exception {
+    final XMLEventReader reader = getEventReader(feed);
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    final XMLEventWriter writer = getEventWriter(bos);
+
+    try {
+
+      final XmlElement feedElement =
+              extractElement(reader, writer, Collections.<String>singletonList("feed"), 0, 1, 1).getValue();
+
+      writer.add(feedElement.getStart());
+      addAtomElement(IOUtils.toInputStream(String.format("<m:count>%d</m:count>", count)), writer);
+      writer.add(feedElement.getContentReader());
+      writer.add(feedElement.getEnd());
+
+      while (reader.hasNext()) {
+        writer.add(reader.nextEvent());
+      }
+
+    } finally {
+      writer.flush();
+      writer.close();
+      reader.close();
+      IOUtils.closeQuietly(feed);
+    }
+
+    return new ByteArrayInputStream(bos.toByteArray());
+  }
+
+  @Override
+  public InputStream getPropertyValue(final InputStream is, final List<String> path)
+          throws Exception {
+
+    final List<String> pathElements = new ArrayList<String>();
+
+    for (String element : path) {
+      pathElements.add(ATOM_PROPERTY_PREFIX + element);
+    }
+
+    final XMLEventReader reader = getEventReader(is);
+    final Map.Entry<Integer, XmlElement> property = extractElement(reader, null, pathElements, 0, 3, 4);
+
+    reader.close();
+    IOUtils.closeQuietly(is);
+
+    return property.getValue().getContent();
+  }
+
+  @Override
+  public InputStream selectEntity(final InputStream entity, final String[] propertyNames) throws Exception {
+    final XMLEventReader reader = getEventReader(entity);
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    final XMLEventWriter writer = getEventWriter(bos);
+
+    final List<String> found = new ArrayList<String>(Arrays.asList(propertyNames));
+
+    boolean inProperties = false;
+    boolean writeCurrent = true;
+    Boolean writeNext = null;
+    String currentName = null;
+
+    final List<String> fieldToBeSaved = new ArrayList<String>(Arrays.asList(propertyNames));
+
+    while (reader.hasNext()) {
+      final XMLEvent event = reader.nextEvent();
+      if (event.getEventType() == XMLStreamConstants.START_ELEMENT
+              && LINK.equals(event.asStartElement().getName().getLocalPart())
+              && !fieldToBeSaved.contains(
+              event.asStartElement().getAttributeByName(new QName("title")).getValue())
+              && !"edit".equals(event.asStartElement().getAttributeByName(new QName("rel")).getValue())) {
+        writeCurrent = false;
+      } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
+              && LINK.equals(event.asEndElement().getName().getLocalPart())) {
+        writeNext = true;
+      } else if (event.getEventType() == XMLStreamConstants.START_ELEMENT
+              && (PROPERTIES).equals(event.asStartElement().getName().getLocalPart())) {
+        writeCurrent = true;
+        writeNext = false;
+        inProperties = true;
+      } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
+              && (PROPERTIES).equals(event.asEndElement().getName().getLocalPart())) {
+        writeCurrent = true;
+      } else if (inProperties) {
+        if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
+          final String elementName = event.asStartElement().getName().getLocalPart();
+
+          for (String propertyName : propertyNames) {
+            if ((ATOM_PROPERTY_PREFIX + propertyName.trim()).equals(elementName)) {
+              writeCurrent = true;
+              found.remove(propertyName);
+              currentName = propertyName;
+            }
+          }
+
+        } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
+                && StringUtils.isNotBlank(currentName)
+                && (ATOM_PROPERTY_PREFIX + currentName.trim()).equals(
+                event.asEndElement().getName().getLocalPart())) {
+          writeNext = false;
+          currentName = null;
+        }
+
+      }
+
+      if (writeCurrent) {
+        writer.add(event);
+      }
+
+      if (writeNext != null) {
+        writeCurrent = writeNext;
+        writeNext = null;
+      }
+    }
+
+    writer.flush();
+    writer.close();
+    reader.close();
+    IOUtils.closeQuietly(entity);
+
+    // Do not raise any exception in order to support FC properties as well
+    // if (!found.isEmpty()) {
+    //     throw new Exception(String.format("Could not find a properties '%s'", found));
+    // }
+
+    return new ByteArrayInputStream(bos.toByteArray());
+  }
+
+  @Override
+  public InputStream readEntities(
+          final List<String> links, final String linkName, final String next, final boolean forceFeed)
+          throws Exception {
+
+    if (links.isEmpty()) {
+      throw new NotFoundException();
+    }
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+    if (forceFeed || links.size() > 1) {
+      // build a feed
+      bos.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>".getBytes());
+
+      bos.write(("<feed xml:base=\"" + DEFAULT_SERVICE_URL + "\" "
+              + "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\">")
+              .getBytes());
+
+      bos.write(("<id>" + DEFAULT_SERVICE_URL + "entityset(entityid)/" + linkName + "</id>").getBytes());
+
+      bos.write(("<title type=\"text\">" + linkName + "</title>").getBytes());
+      bos.write("<updated>2014-03-03T13:40:49Z</updated>".getBytes());
+      bos.write(("<link rel=\"self\" title=\"" + linkName + "\" href=\"" + linkName + "\" />").getBytes());
+    }
+
+    for (String link : links) {
+      try {
+        final Map.Entry<String, String> uri = Commons.parseEntityURI(link);
+
+        final XmlElement entry =
+                extractElement(
+                getEventReader(readEntity(uri.getKey(), uri.getValue(), Accept.ATOM).getValue()),
+                null,
+                Collections.<String>singletonList("entry"),
+                0, 1, 1).getValue();
+
+        IOUtils.copy(entry.toStream(), bos);
+      } catch (Exception e) {
+        // log and ignore link
+        LOG.warn("Error parsing uri {}", link, e);
+      }
+    }
+
+    if (forceFeed || links.size() > 1) {
+
+      if (StringUtils.isNotBlank(next)) {
+        bos.write(String.format("<link rel=\"next\" href=\"%s\" />", next).getBytes());
+      }
+
+      bos.write("</feed>".getBytes());
+    }
+
+    return new ByteArrayInputStream(bos.toByteArray());
+  }
+
+  @Override
+  public Map<String, InputStream> getChanges(final InputStream src) throws Exception {
+    final Map<String, InputStream> res = new HashMap<String, InputStream>();
+
+    ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    IOUtils.copy(src, bos);
+    IOUtils.closeQuietly(src);
+
+    // retrieve properties ...
+    XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+    final Map.Entry<Integer, XmlElement> propertyElement =
+            extractElement(reader, null, Collections.<String>singletonList(PROPERTIES), 0, 2, 3);
+    reader.close();
+
+    reader = propertyElement.getValue().getContentReader();
+
+    try {
+      while (true) {
+        final XmlElement property = extractElement(reader, null, null, 0, -1, -1).getValue();
+        res.put(property.getStart().getName().getLocalPart(), property.toStream());
+      }
+    } catch (Exception ignore) {
+      // end
+    }
+
+    reader.close();
+
+    // retrieve links ...
+    reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+    try {
+      int pos = 0;
+      while (true) {
+        final Map.Entry<Integer, XmlElement> linkElement =
+                extractElement(reader, null, Collections.<String>singletonList(LINK), pos, 2, 2);
+
+        res.put("[LINK]" + linkElement.getValue().getStart().getAttributeByName(new QName("title")).getValue(),
+                linkElement.getValue().toStream());
+
+        pos = linkElement.getKey();
+      }
+    } catch (Exception ignore) {
+      // end
+    }
+
+    return res;
+  }
+
+  @Override
+  public InputStream setChanges(
+          final InputStream toBeChanged,
+          final Map<String, InputStream> properties)
+          throws Exception {
+    XMLEventReader reader = getEventReader(toBeChanged);
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    XMLEventWriter writer = getEventWriter(bos);
+
+    // ---------------------------------
+    // add property changes
+    // ---------------------------------
+    Map.Entry<Integer, XmlElement> propertyElement =
+            extractElement(reader, writer, Collections.<String>singletonList(PROPERTIES), 0, 2, 3);
+
+    writer.flush();
+
+    ByteArrayOutputStream pbos = new ByteArrayOutputStream();
+    OutputStreamWriter pwriter = new OutputStreamWriter(pbos);
+
+    final XMLEventReader propertyReader = propertyElement.getValue().getContentReader();
+
+    try {
+      while (true) {
+        final XmlElement property = extractElement(propertyReader, null, null, 0, -1, -1).getValue();
+        final String name = property.getStart().getName().getLocalPart();
+
+        if (properties.containsKey(name)) {
+          // replace
+          final InputStream replacement = properties.get(name);
+          properties.remove(property.getStart().getName().getLocalPart());
+          pwriter.append(IOUtils.toString(replacement));
+          IOUtils.closeQuietly(replacement);
+        } else {
+          pwriter.append(IOUtils.toString(property.toStream()));
+        }
+      }
+    } catch (Exception ignore) {
+      // end
+    }
+
+    for (Map.Entry<String, InputStream> remains : properties.entrySet()) {
+      if (!remains.getKey().startsWith("[LINK]")) {
+        pwriter.append(IOUtils.toString(remains.getValue()));
+        IOUtils.closeQuietly(remains.getValue());
+      }
+    }
+
+    pwriter.flush();
+    pwriter.close();
+
+    writer.add(propertyElement.getValue().getStart());
+    writer.add(new XMLEventReaderWrapper(new ByteArrayInputStream(pbos.toByteArray())));
+    writer.add(propertyElement.getValue().getEnd());
+
+    IOUtils.closeQuietly(pbos);
+
+    writer.add(reader);
+    reader.close();
+    writer.flush();
+    writer.close();
+    // ---------------------------------
+
+    // ---------------------------------
+    // add navigationm changes
+    // ---------------------------------
+
+    // remove existent links
+    for (Map.Entry<String, InputStream> remains : properties.entrySet()) {
+
+      if (remains.getKey().startsWith("[LINK]")) {
+        reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+        bos.reset();
+        writer = getEventWriter(bos);
+
+        try {
+          final String linkName = remains.getKey().substring(remains.getKey().indexOf("]") + 1);
+
+          extractElement(reader, writer, Collections.<String>singletonList(LINK),
+                  Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>("title", linkName)),
+                  false, 0, 2, 2);
+
+          writer.add(reader);
+
+        } catch (Exception ignore) {
+          // ignore
+        }
+
+        writer.flush();
+        writer.close();
+      }
+    }
+
+    reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+    bos.reset();
+    writer = getEventWriter(bos);
+
+    propertyElement = extractElement(reader, writer, Collections.<String>singletonList(CONTENT), 0, 2, 2);
+    writer.flush();
+
+    pbos.reset();
+    pwriter = new OutputStreamWriter(pbos);
+
+    for (Map.Entry<String, InputStream> remains : properties.entrySet()) {
+      if (remains.getKey().startsWith("[LINK]")) {
+        pwriter.append(IOUtils.toString(remains.getValue()));
+        IOUtils.closeQuietly(remains.getValue());
+      }
+    }
+
+    pwriter.flush();
+    pwriter.close();
+
+    writer.add(new XMLEventReaderWrapper(new ByteArrayInputStream(pbos.toByteArray())));
+    IOUtils.closeQuietly(pbos);
+
+    writer.add(propertyElement.getValue().getStart());
+    writer.add(propertyElement.getValue().getContentReader());
+    writer.add(propertyElement.getValue().getEnd());
+
+    writer.add(reader);
+    reader.close();
+    writer.flush();
+    writer.close();
+    // ---------------------------------
+
+    return new ByteArrayInputStream(bos.toByteArray());
+  }
+
+  @Override
+  protected InputStream replaceLink(
+          final InputStream toBeChanged, final String linkName, final InputStream replacement)
+          throws Exception {
+    final XMLEventReader reader = getEventReader(toBeChanged);
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    final XMLEventWriter writer = getEventWriter(bos);
+
+    final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+    XMLEvent newLine = eventFactory.createSpace("\n");
+
+    try {
+      final XmlElement linkElement =
+              extractElement(reader, writer, Collections.<String>singletonList(LINK),
+              Collections.<Map.Entry<String, String>>singletonList(new SimpleEntry<String, String>("title", linkName)),
+              false, 0, -1, -1).getValue();
+      writer.add(linkElement.getStart());
+
+      // ------------------------------------------
+      // write inline ...
+      // ------------------------------------------
+      writer.add(newLine);
+      writer.add(eventFactory.createStartElement("m", null, "inline"));
+
+      addAtomElement(replacement, writer);
+
+      writer.add(eventFactory.createEndElement("m", null, "inline"));
+      writer.add(newLine);
+      // ------------------------------------------
+
+      writer.add(linkElement.getEnd());
+
+      writer.add(reader);
+      writer.flush();
+      writer.close();
+    } finally {
+      reader.close();
+      IOUtils.closeQuietly(toBeChanged);
+    }
+
+    return new ByteArrayInputStream(bos.toByteArray());
+  }
+
+  public String getEdmTypeFromAtom(final String entitySetName, final String entityId, final List<String> path)
+          throws Exception {
+    InputStream src = fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) + ENTITY, Accept.XML);
+
+    final List<String> atomPathElements = new ArrayList<String>();
+
+    for (String element : path) {
+      atomPathElements.add(ATOM_PROPERTY_PREFIX + element);
+    }
+
+    final Map.Entry<Integer, XmlElement> prop = extractElement(getEventReader(src), null, atomPathElements, 0, 3, 4);
+    IOUtils.closeQuietly(src);
+
+    final Attribute type = prop.getValue().getStart().getAttributeByName(new QName(TYPE));
+
+    final String edmType;
+
+    if (type == null) {
+      edmType = Constants.ATOM_DEF_TYPE;
+    } else {
+      edmType = type.getValue();
+    }
+
+    return edmType;
+  }
+
+  @Override
+  public Map.Entry<String, List<String>> extractLinkURIs(
+          final String entitySetName, final String entityId, final String linkName)
+          throws Exception {
+    final LinkInfo links = readLinks(entitySetName, entityId, linkName, Accept.XML);
+    return extractLinkURIs(links.getLinks());
+  }
+
+  @Override
+  public Map.Entry<String, List<String>> extractLinkURIs(final InputStream is)
+          throws Exception {
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    IOUtils.copy(is, bos);
+    IOUtils.closeQuietly(is);
+
+    XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+    final List<String> links = new ArrayList<String>();
+    try {
+      while (true) {
+        links.add(IOUtils.toString(extractElement(reader, null, Collections.<String>singletonList("uri"), 0, -1, -1).
+                getValue().getContent()));
+      }
+    } catch (Exception ignore) {
+      // End document reached ...
+    }
+    reader.close();
+
+    String next;
+
+    reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+    try {
+      next = IOUtils.toString(extractElement(reader, null, Collections.<String>singletonList("next"), 0, -1, -1).
+              getValue().getContent());
+    } catch (Exception ignore) {
+      // next link is not mandatory
+      next = null;
+    }
+    reader.close();
+
+    return new AbstractMap.SimpleEntry<String, List<String>>(next, links);
+  }
+
+  @Override
+  public InputStream getProperty(
+          final String entitySetName, final String entityId, final List<String> path, final String edmType)
+          throws Exception {
+    final List<String> pathElements = new ArrayList<String>();
+
+    for (String element : path) {
+      pathElements.add(ATOM_PROPERTY_PREFIX + element);
+    }
+
+    final InputStream src =
+            fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) + ENTITY, Accept.XML);
+
+    final XMLEventReader reader = getEventReader(src);
+    final XmlElement property = extractElement(reader, null, pathElements, 0, 3, 4).getValue();
+
+    reader.close();
+    IOUtils.closeQuietly(src);
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    final XMLEventWriter writer = getEventWriter(bos);
+
+    final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+    writer.add(eventFactory.createStartDocument("UTF-8", "1.0"));
+    writer.add(property.getStart());
+
+    if (property.getStart().getAttributeByName(new QName(ATOM_DATASERVICE_NS)) == null) {
+      writer.add(eventFactory.createNamespace(ATOM_PROPERTY_PREFIX.substring(0, 1), DATASERVICES_NS));
+    }
+    if (property.getStart().getAttributeByName(new QName(ATOM_METADATA_NS)) == null) {
+      writer.add(eventFactory.createNamespace(ATOM_METADATA_PREFIX.substring(0, 1), METADATA_NS));
+    }
+
+    writer.add(property.getContentReader());
+    writer.add(property.getEnd());
+
+    writer.flush();
+    writer.close();
+
+    return new ByteArrayInputStream(bos.toByteArray());
+  }
+
+  @Override
+  public InputStream replaceProperty(
+          final InputStream src, final InputStream replacement, final List<String> path, final boolean justValue)
+          throws Exception {
+
+    final List<String> pathElements = new ArrayList<String>();
+
+    for (String element : path) {
+      pathElements.add(ATOM_PROPERTY_PREFIX + element);
+    }
+
+    final XMLEventReader reader = getEventReader(src);
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    final XMLEventWriter writer = getEventWriter(bos);
+
+    final Map.Entry<Integer, XmlElement> element = extractElement(reader, writer, pathElements, 0, 3, 4);
+
+    if (justValue) {
+      writer.add(element.getValue().getStart());
+    }
+
+    final XMLEventReader changesReader = new XMLEventReaderWrapper(replacement);
+
+    writer.add(changesReader);
+    changesReader.close();
+    IOUtils.closeQuietly(replacement);
+
+    if (justValue) {
+      writer.add(element.getValue().getEnd());
+    }
+
+    writer.add(reader);
+
+    reader.close();
+    IOUtils.closeQuietly(src);
+
+    writer.flush();
+    writer.close();
+
+    return new ByteArrayInputStream(bos.toByteArray());
+  }
+
+  @Override
+  public InputStream deleteProperty(final InputStream src, final List<String> path) throws Exception {
+
+    final List<String> pathElements = new ArrayList<String>();
+
+    for (String element : path) {
+      pathElements.add(ATOM_PROPERTY_PREFIX + element);
+    }
+
+    final XMLEventReader reader = getEventReader(src);
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    final XMLEventWriter writer = getEventWriter(bos);
+
+    final Map.Entry<Integer, XmlElement> element = extractElement(reader, writer, pathElements, 0, 3, 4);
+
+    final XMLEventReader changesReader = new XMLEventReaderWrapper(
+            IOUtils.toInputStream(String.format("<%s m:null=\"true\" />", path.get(path.size() - 1))));
+
+    writer.add(changesReader);
+    changesReader.close();
+
+    writer.add(reader);
+
+    reader.close();
+    IOUtils.closeQuietly(src);
+
+    writer.flush();
+    writer.close();
+
+    return new ByteArrayInputStream(bos.toByteArray());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java b/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
index 9fdf1da..2371843 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
@@ -28,24 +28,35 @@ public enum Accept {
   TEXT(ContentType.TEXT_PLAIN.getMimeType(), ".txt"),
   XML(ContentType.APPLICATION_XML.getMimeType(), ".xml"),
   ATOM(ContentType.APPLICATION_ATOM_XML.getMimeType(), ".xml"),
-  JSON(ContentType.APPLICATION_JSON.getMimeType() + ";odata=minimalmetadata", ".full.json"),
-  JSON_NOMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=nometadata", ".full.json"),
-  JSON_FULLMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=fullmetadata", ".full.json");
+  JSON(ContentType.APPLICATION_JSON.getMimeType() + ";odata=minimalmetadata",
+  ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=minimal", ".full.json"),
+  JSON_NOMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=nometadata",
+  ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=none", ".full.json"),
+  JSON_FULLMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=fullmetadata",
+  ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=full", ".full.json");
 
-  private final String contentType;
+  private final String contentTypeV3;
+
+  private final String contentTypeV4;
 
   private final String fileExtension;
 
   private static Pattern allTypesPattern = Pattern.compile("(.*,)?\\*/\\*([,;].*)?");
 
-  Accept(final String contentType, final String fileExtension) {
-    this.contentType = contentType;
+  Accept(final String contentTypeV3, final String fileExtension) {
+    this.contentTypeV3 = contentTypeV3;
+    this.contentTypeV4 = contentTypeV3;
+    this.fileExtension = fileExtension;
+  }
+
+  Accept(final String contentTypeV3, final String contentTypeV4, final String fileExtension) {
+    this.contentTypeV3 = contentTypeV3;
+    this.contentTypeV4 = contentTypeV4;
     this.fileExtension = fileExtension;
   }
 
-  @Override
-  public String toString() {
-    return contentType;
+  public String toString(final ODataVersion version) {
+    return ODataVersion.v3 == version ? contentTypeV3 : contentTypeV4;
   }
 
   public String getExtension() {
@@ -53,23 +64,30 @@ public enum Accept {
   }
 
   public static Accept parse(final String contentType, final ODataVersion version) {
-    return parse(contentType, version, ODataVersion.v3 == version ? ATOM : JSON_NOMETA);
+    final Accept def;
+    if (ODataVersion.v3 == version) {
+      def = ATOM;
+    } else {
+      def = JSON_NOMETA;
+    }
+
+    return parse(contentType, version, def);
   }
 
   public static Accept parse(final String contentType, final ODataVersion version, final Accept def) {
     if (StringUtils.isBlank(contentType) || allTypesPattern.matcher(contentType).matches()) {
       return def;
-    } else if (JSON_NOMETA.toString().equals(contentType)) {
+    } else if (JSON_NOMETA.toString(version).equals(contentType)) {
       return JSON_NOMETA;
-    } else if (JSON.toString().equals(contentType) || "application/json".equals(contentType)) {
+    } else if (JSON.toString(version).equals(contentType) || "application/json".equals(contentType)) {
       return JSON;
-    } else if (JSON_FULLMETA.toString().equals(contentType)) {
+    } else if (JSON_FULLMETA.toString(version).equals(contentType)) {
       return JSON_FULLMETA;
-    } else if (XML.toString().equals(contentType)) {
+    } else if (XML.toString(version).equals(contentType)) {
       return XML;
-    } else if (ATOM.toString().equals(contentType)) {
+    } else if (ATOM.toString(version).equals(contentType)) {
       return ATOM;
-    } else if (TEXT.toString().equals(contentType)) {
+    } else if (TEXT.toString(version).equals(contentType)) {
       return TEXT;
     } else {
       throw new UnsupportedMediaTypeException("Unsupported media type");

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
index 233e03d..dcc4807 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
@@ -74,6 +74,10 @@ public abstract class Commons {
     mediaContent.put("Car/Photo", null);
   }
 
+  public static Map<ODataVersion, MetadataLinkInfo> getLinkInfo() {
+    return linkInfo;
+  }
+
   public static String getEntityURI(final String entitySetName, final String entityKey) {
     return entitySetName + "(" + entityKey + ")";
   }
@@ -230,7 +234,7 @@ public abstract class Commons {
         break;
 
       default:
-        throw new UnsupportedOperationException(target.toString());
+        throw new UnsupportedOperationException(target.name());
     }
 
     for (String field : toBeRemoved) {


[7/8] git commit: [OLINGO-205, OLINGO-200, OLINGO-65] merge

Posted by fm...@apache.org.
[OLINGO-205, OLINGO-200, OLINGO-65] merge


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

Branch: refs/heads/olingo200
Commit: 5b5576f86cfa8d3fb07151ff774238ba2a87c0d9
Parents: 9aefb95 a55ed62
Author: fmartelli <fa...@gmail.com>
Authored: Mon Mar 24 10:05:44 2014 +0100
Committer: fmartelli <fa...@gmail.com>
Committed: Mon Mar 24 10:05:44 2014 +0100

----------------------------------------------------------------------
 lib/client-api/pom.xml                          |   5 -
 .../olingo/client/api/CommonConfiguration.java  |   8 +-
 .../olingo/client/api/CommonODataClient.java    |  12 +-
 .../org/apache/olingo/client/api/Constants.java | 258 ------------
 .../ODataClientErrorException.java              |   2 +-
 .../request/ODataBasicRequest.java              |   2 +-
 .../request/cud/CommonCUDRequestFactory.java    |   8 +-
 .../request/cud/ODataDeleteRequest.java         |   2 +-
 .../request/cud/ODataEntityCreateRequest.java   |   2 +-
 .../request/cud/ODataEntityUpdateRequest.java   |   2 +-
 .../request/cud/ODataLinkCreateRequest.java     |   2 +-
 .../request/cud/ODataLinkUpdateRequest.java     |   2 +-
 .../request/cud/ODataPropertyUpdateRequest.java |   2 +-
 .../request/cud/ODataValueUpdateRequest.java    |   2 +-
 .../invoke/CommonInvokeRequestFactory.java      |   4 +-
 .../request/invoke/ODataInvokeRequest.java      |   6 +-
 .../request/invoke/ODataNoContent.java          |   2 +-
 .../request/retrieve/ODataEntityRequest.java    |   4 +-
 .../retrieve/ODataEntitySetIteratorRequest.java |   2 +-
 .../request/retrieve/ODataEntitySetRequest.java |   4 +-
 .../request/retrieve/ODataMediaRequest.java     |   2 +-
 .../request/retrieve/ODataMetadataRequest.java  |   2 +-
 .../request/retrieve/ODataPropertyRequest.java  |   4 +-
 .../request/retrieve/ODataRetrieveRequest.java  |   2 +-
 .../retrieve/ODataServiceDocumentRequest.java   |   4 +-
 .../request/retrieve/ODataValueRequest.java     |   4 +-
 .../retrieve/v3/ODataLinkCollectionRequest.java |   2 +-
 .../streamed/ODataStreamedEntityRequest.java    |   2 +-
 .../response/ODataEntityCreateResponse.java     |   2 +-
 .../response/ODataEntityUpdateResponse.java     |   2 +-
 .../response/ODataInvokeResponse.java           |   2 +-
 .../ODataMediaEntityCreateResponse.java         |   2 +-
 .../ODataMediaEntityUpdateResponse.java         |   2 +-
 .../response/ODataPropertyUpdateResponse.java   |   2 +-
 .../response/ODataValueUpdateResponse.java      |   2 +-
 .../olingo/client/api/data/CollectionValue.java |  27 --
 .../olingo/client/api/data/ComplexValue.java    |  27 --
 .../apache/olingo/client/api/data/Entry.java    | 167 --------
 .../org/apache/olingo/client/api/data/Feed.java |  75 ----
 .../apache/olingo/client/api/data/GeoUtils.java |  90 -----
 .../olingo/client/api/data/GeospatialValue.java |  28 --
 .../org/apache/olingo/client/api/data/Link.java | 121 ------
 .../olingo/client/api/data/NullValue.java       |  26 --
 .../olingo/client/api/data/ODataError.java      |  67 ---
 .../olingo/client/api/data/PrimitiveValue.java  |  25 --
 .../apache/olingo/client/api/data/Property.java |  34 --
 .../apache/olingo/client/api/data/Value.java    |  44 --
 .../client/api/data/v3/LinkCollection.java      |  52 ---
 .../client/api/domain/AbstractODataValue.java   | 127 ------
 .../client/api/domain/ODataCollectionValue.java |  98 -----
 .../client/api/domain/ODataComplexValue.java    |  97 -----
 .../olingo/client/api/domain/ODataEntity.java   | 316 ---------------
 .../client/api/domain/ODataEntitySet.java       | 120 ------
 .../api/domain/ODataEntitySetIterator.java      |   8 +-
 .../client/api/domain/ODataGeospatialValue.java |  57 ---
 .../client/api/domain/ODataInlineEntity.java    |  74 ----
 .../client/api/domain/ODataInlineEntitySet.java |  74 ----
 .../client/api/domain/ODataInvokeResult.java    |  30 --
 .../olingo/client/api/domain/ODataItem.java     | 111 -----
 .../olingo/client/api/domain/ODataLink.java     | 190 ---------
 .../olingo/client/api/domain/ODataLinkType.java |  93 -----
 .../client/api/domain/ODataObjectFactory.java   | 218 ----------
 .../client/api/domain/ODataOperation.java       |  88 ----
 .../client/api/domain/ODataPrimitiveValue.java  |  67 ---
 .../olingo/client/api/domain/ODataProperty.java | 186 ---------
 .../client/api/domain/ODataPropertyType.java    |  40 --
 .../client/api/domain/ODataServiceDocument.java | 183 ---------
 .../olingo/client/api/domain/ODataValue.java    |  84 ----
 .../apache/olingo/client/api/format/Format.java |  26 --
 .../olingo/client/api/format/ODataFormat.java   | 103 -----
 .../client/api/format/ODataMediaFormat.java     |  77 ----
 .../client/api/format/ODataPubFormat.java       | 122 ------
 .../client/api/format/ODataValueFormat.java     |  82 ----
 .../client/api/op/ClientODataDeserializer.java  |  39 ++
 .../olingo/client/api/op/CommonODataBinder.java |  18 +-
 .../client/api/op/CommonODataDeserializer.java  |  84 ----
 .../olingo/client/api/op/CommonODataReader.java |  14 +-
 .../olingo/client/api/op/ODataSerializer.java   | 100 -----
 .../olingo/client/api/op/ODataWriter.java       |  10 +-
 .../olingo/client/api/op/v3/ODataBinder.java    |   2 +-
 .../client/api/op/v3/ODataDeserializer.java     |   8 +-
 .../olingo/client/api/op/v3/ODataReader.java    |   2 +-
 .../client/api/op/v4/ODataDeserializer.java     |   4 +-
 lib/client-core/pom.xml                         |  21 -
 .../client/core/AbstractConfiguration.java      |   8 +-
 .../olingo/client/core/AbstractODataClient.java |   8 +-
 .../request/AbstractODataBasicRequest.java      |   2 +-
 .../communication/request/ODataRequestImpl.java |  14 +-
 .../request/batch/ODataBatchUtilities.java      |   2 +-
 .../request/cud/AbstractCUDRequestFactory.java  |   8 +-
 .../request/cud/ODataDeleteRequestImpl.java     |   2 +-
 .../cud/ODataEntityCreateRequestImpl.java       |   4 +-
 .../cud/ODataEntityUpdateRequestImpl.java       |   4 +-
 .../request/cud/ODataLinkCreateRequestImpl.java |   4 +-
 .../request/cud/ODataLinkUpdateRequestImpl.java |   4 +-
 .../cud/ODataPropertyUpdateRequestImpl.java     |   4 +-
 .../cud/ODataValueUpdateRequestImpl.java        |   4 +-
 .../invoke/AbstractInvokeRequestFactory.java    |   2 +-
 .../request/invoke/ODataInvokeRequestImpl.java  |  14 +-
 .../invoke/v3/InvokeRequestFactoryImpl.java     |  10 +-
 .../invoke/v4/InvokeRequestFactoryImpl.java     |   4 +-
 .../retrieve/AbstractODataRetrieveRequest.java  |   2 +-
 .../retrieve/ODataEntityRequestImpl.java        |   4 +-
 .../ODataEntitySetIteratorRequestImpl.java      |   2 +-
 .../retrieve/ODataEntitySetRequestImpl.java     |   4 +-
 .../request/retrieve/ODataMediaRequestImpl.java |   2 +-
 .../retrieve/ODataMetadataRequestImpl.java      |   2 +-
 .../retrieve/ODataPropertyRequestImpl.java      |   4 +-
 .../request/retrieve/ODataRawRequestImpl.java   |   2 +-
 .../ODataServiceDocumentRequestImpl.java        |   4 +-
 .../request/retrieve/ODataValueRequestImpl.java |   4 +-
 .../v3/ODataLinkCollectionRequestImpl.java      |   2 +-
 .../AbstractODataStreamedEntityRequest.java     |   2 +-
 .../streamed/AbstractODataStreamedRequest.java  |   2 +-
 .../ODataMediaEntityCreateRequestImpl.java      |   2 +-
 .../ODataMediaEntityUpdateRequestImpl.java      |   2 +-
 .../batch/ODataBatchResponseManager.java        |   2 +-
 .../client/core/data/AbstractAtomDealer.java    |  87 ----
 .../client/core/data/AbstractAtomObject.java    |  78 ----
 .../olingo/client/core/data/AbstractEntry.java  | 159 --------
 .../core/data/AbstractJsonDeserializer.java     | 175 --------
 .../core/data/AbstractJsonSerializer.java       |  94 -----
 .../client/core/data/AbstractPayloadObject.java |  48 ---
 .../client/core/data/AbstractPropertyImpl.java  |  80 ----
 .../olingo/client/core/data/AbstractValue.java  |  98 -----
 .../client/core/data/AtomDeserializer.java      | 368 -----------------
 .../olingo/client/core/data/AtomEntryImpl.java  |  25 --
 .../olingo/client/core/data/AtomFeedImpl.java   |  66 ---
 .../core/data/AtomGeoValueDeserializer.java     | 253 ------------
 .../core/data/AtomGeoValueSerializer.java       | 222 ----------
 .../core/data/AtomPropertyDeserializer.java     | 218 ----------
 .../client/core/data/AtomPropertyImpl.java      |  25 --
 .../core/data/AtomPropertySerializer.java       |  88 ----
 .../olingo/client/core/data/AtomSerializer.java | 264 ------------
 .../client/core/data/CollectionValueImpl.java   |  40 --
 .../client/core/data/ComplexValueImpl.java      |  40 --
 .../client/core/data/GeospatialValueImpl.java   |  42 --
 .../client/core/data/JSONEntryDeserializer.java | 244 -----------
 .../olingo/client/core/data/JSONEntryImpl.java  |  94 -----
 .../client/core/data/JSONEntrySerializer.java   | 120 ------
 .../client/core/data/JSONErrorBundle.java       |  50 ---
 .../olingo/client/core/data/JSONErrorImpl.java  | 237 -----------
 .../client/core/data/JSONFeedDeserializer.java  |  68 ----
 .../olingo/client/core/data/JSONFeedImpl.java   | 113 ------
 .../client/core/data/JSONFeedSerializer.java    |  57 ---
 .../core/data/JSONGeoValueDeserializer.java     | 265 ------------
 .../core/data/JSONGeoValueSerializer.java       | 175 --------
 .../core/data/JSONPropertyDeserializer.java     |  71 ----
 .../client/core/data/JSONPropertyImpl.java      |  53 ---
 .../core/data/JSONPropertySerializer.java       |  59 ---
 .../data/JSONServiceDocumentDeserializer.java   |   5 +-
 .../olingo/client/core/data/LinkImpl.java       | 112 -----
 .../olingo/client/core/data/NullValueImpl.java  |  35 --
 .../core/data/ODataJacksonDeserializer.java     |  45 ---
 .../core/data/ODataJacksonSerializer.java       |  45 ---
 .../client/core/data/PrimitiveValueImpl.java    |  41 --
 .../olingo/client/core/data/XMLErrorImpl.java   | 213 ----------
 .../data/XMLServiceDocumentDeserializer.java    |   3 +-
 .../core/data/v3/JSONLinkCollectionImpl.java    | 118 ------
 .../core/data/v3/JSONServiceDocumentImpl.java   |   4 +-
 .../core/data/v3/XMLLinkCollectionImpl.java     |  70 ----
 .../core/data/v4/JSONServiceDocumentImpl.java   |   4 +-
 .../core/domain/ODataGeospatialValueImpl.java   |   4 +-
 .../core/domain/ODataPrimitiveValueImpl.java    |  13 +-
 .../client/core/edm/EdmActionImportImpl.java    |   2 +-
 .../olingo/client/core/edm/EdmClientImpl.java   |   1 +
 .../client/core/edm/EdmComplexTypeImpl.java     |   1 +
 .../client/core/edm/EdmEntityContainerImpl.java |   1 +
 .../client/core/edm/EdmEntityTypeImpl.java      |   1 +
 .../client/core/edm/EdmFunctionImportImpl.java  |   1 +
 .../core/edm/EdmNavigationPropertyImpl.java     |   1 +
 .../client/core/edm/EdmParameterImpl.java       |   1 +
 .../olingo/client/core/edm/EdmPropertyImpl.java |   1 +
 .../client/core/edm/EdmReturnTypeImpl.java      |   1 +
 .../olingo/client/core/edm/EdmTypeInfo.java     | 184 ---------
 .../core/edm/v3/EdmActionImportProxy.java       |   2 +-
 .../core/edm/v3/EdmFunctionImportProxy.java     |   2 +-
 .../core/edm/xml/AbstractComplexType.java       |   1 -
 .../core/edm/xml/AbstractEdmDeserializer.java   |  71 ++++
 .../core/edm/xml/AbstractEntityContainer.java   |   1 -
 .../client/core/edm/xml/AbstractEntitySet.java  |   1 -
 .../client/core/edm/xml/AbstractEntityType.java |   1 -
 .../client/core/edm/xml/AbstractEnumType.java   |   1 -
 .../client/core/edm/xml/AbstractSchema.java     |   1 -
 .../core/edm/xml/ComplexTypeDeserializer.java   |  82 ++++
 .../core/edm/xml/DataServicesDeserializer.java  |   3 +-
 .../client/core/edm/xml/EdmxDeserializer.java   |   3 +-
 .../edm/xml/EntityContainerDeserializer.java    | 101 +++++
 .../core/edm/xml/EntityKeyDeserializer.java     |  47 +++
 .../client/core/edm/xml/EntityKeyImpl.java      |   1 -
 .../core/edm/xml/EntitySetDeserializer.java     |  69 ++++
 .../core/edm/xml/EntityTypeDeserializer.java    |  90 +++++
 .../core/edm/xml/EnumTypeDeserializer.java      |  72 ++++
 .../core/edm/xml/ParameterDeserializer.java     |   3 +-
 .../core/edm/xml/PropertyDeserializer.java      |   3 +-
 .../client/core/edm/xml/SchemaDeserializer.java | 148 +++++++
 .../edm/xml/v3/AnnotationsDeserializer.java     |   2 +-
 .../edm/xml/v3/AssociationDeserializer.java     |   2 +-
 .../edm/xml/v3/AssociationSetDeserializer.java  |   2 +-
 .../edm/xml/v3/FunctionImportDeserializer.java  |   2 +-
 .../ReferentialConstraintRoleDeserializer.java  |   2 +-
 .../edm/xml/v3/TypeAnnotationDeserializer.java  |   2 +-
 .../core/edm/xml/v4/ActionDeserializer.java     |   2 +-
 .../core/edm/xml/v4/AnnotationDeserializer.java |   2 +-
 .../edm/xml/v4/AnnotationsDeserializer.java     |   2 +-
 .../core/edm/xml/v4/FunctionDeserializer.java   |   2 +-
 .../xml/v4/NavigationPropertyDeserializer.java  |   2 +-
 .../core/edm/xml/v4/ReferenceDeserializer.java  |   2 +-
 .../core/edm/xml/v4/ReturnTypeDeserializer.java |   2 +-
 .../core/edm/xml/v4/SingletonDeserializer.java  |   2 +-
 .../core/edm/xml/v4/TermDeserializer.java       |   2 +-
 .../edm/xml/v4/TypeDefinitionDeserializer.java  |   2 +-
 .../xml/v4/annotation/ApplyDeserializer.java    |   2 +-
 .../edm/xml/v4/annotation/CastDeserializer.java |   2 +-
 .../v4/annotation/CollectionDeserializer.java   |   2 +-
 .../DynExprConstructDeserializer.java           |   2 +-
 .../edm/xml/v4/annotation/IsOfDeserializer.java |   2 +-
 .../annotation/LabeledElementDeserializer.java  |   2 +-
 .../edm/xml/v4/annotation/NullDeserializer.java |   2 +-
 .../annotation/PropertyValueDeserializer.java   |   2 +-
 .../xml/v4/annotation/RecordDeserializer.java   |   2 +-
 .../xml/v4/annotation/UrlRefDeserializer.java   |   2 +-
 .../client/core/op/AbstractODataBinder.java     | 405 +++++++++++++++++++
 .../client/core/op/AbstractODataReader.java     | 117 ++++++
 .../olingo/client/core/op/ODataWriterImpl.java  | 102 +++++
 .../core/op/impl/AbstractEdmDeserializer.java   |  71 ----
 .../core/op/impl/AbstractJacksonTool.java       |  85 ----
 .../core/op/impl/AbstractODataBinder.java       | 404 ------------------
 .../core/op/impl/AbstractODataDeserializer.java | 106 -----
 .../core/op/impl/AbstractODataReader.java       | 117 ------
 .../core/op/impl/AbstractODataSerializer.java   | 141 -------
 .../core/op/impl/ComplexTypeDeserializer.java   |  83 ----
 .../op/impl/EntityContainerDeserializer.java    | 102 -----
 .../core/op/impl/EntityKeyDeserializer.java     |  50 ---
 .../core/op/impl/EntitySetDeserializer.java     |  70 ----
 .../core/op/impl/EntityTypeDeserializer.java    |  92 -----
 .../core/op/impl/EnumTypeDeserializer.java      |  73 ----
 .../op/impl/InjectableSerializerProvider.java   |  43 --
 .../core/op/impl/ODataObjectFactoryImpl.java    | 165 --------
 .../client/core/op/impl/ODataWriterImpl.java    | 101 -----
 .../client/core/op/impl/ResourceFactory.java    | 125 ------
 .../client/core/op/impl/SchemaDeserializer.java | 149 -------
 .../client/core/op/impl/v3/ODataBinderImpl.java |   4 +-
 .../core/op/impl/v3/ODataDeserializerImpl.java  |  16 +-
 .../client/core/op/impl/v3/ODataReaderImpl.java |   6 +-
 .../core/op/impl/v3/ODataSerializerImpl.java    |   8 +-
 .../client/core/op/impl/v4/ODataBinderImpl.java |   4 +-
 .../core/op/impl/v4/ODataDeserializerImpl.java  |  10 +-
 .../client/core/op/impl/v4/ODataReaderImpl.java |   6 +-
 .../core/op/impl/v4/ODataSerializerImpl.java    |   8 +-
 .../apache/olingo/client/core/uri/URIUtils.java |  22 +-
 .../olingo/client/core/v3/ODataClientImpl.java  |   6 +-
 .../olingo/client/core/v4/ODataClientImpl.java  |   6 +-
 .../client/core/AbstractPrimitiveTest.java      |  10 +-
 .../client/core/AbstractPropertyTest.java       |  12 +-
 .../apache/olingo/client/core/AbstractTest.java |   4 +-
 .../olingo/client/core/AtomLinksQualifier.java  |   2 +-
 .../client/core/it/AbstractTestITCase.java      |  28 +-
 .../client/core/it/v3/AsyncTestITCase.java      |   4 +-
 .../client/core/it/v3/CountTestITCase.java      |   4 +-
 .../core/it/v3/EntityCreateTestITCase.java      |  12 +-
 .../core/it/v3/EntityRetrieveTestITCase.java    |  16 +-
 .../client/core/it/v3/EntitySetTestITCase.java  |   6 +-
 .../core/it/v3/EntityUpdateTestITCase.java      |   4 +-
 .../client/core/it/v3/ErrorTestITCase.java      |   4 +-
 .../core/it/v3/FilterFactoryTestITCase.java     |   2 +-
 .../client/core/it/v3/FilterTestITCase.java     |   2 +-
 .../core/it/v3/KeyAsSegmentTestITCase.java      |   4 +-
 .../client/core/it/v3/LinkTestITCase.java       |   4 +-
 .../core/it/v3/MediaEntityTestITCase.java       |   8 +-
 .../it/v3/NavigationLinkCreateTestITCase.java   |  20 +-
 .../client/core/it/v3/OpenTypeTestITCase.java   |   6 +-
 .../core/it/v3/PrimitiveKeysTestITCase.java     |   4 +-
 .../core/it/v3/PropertyRetrieveTestITCase.java  |  14 +-
 .../client/core/it/v3/PropertyTestITCase.java   |  10 +-
 .../core/it/v3/PropertyValueTestITCase.java     |   6 +-
 .../core/it/v3/QueryOptionsTestITCase.java      |  12 +-
 .../v3/ServiceDocumentRetrieveTestITCase.java   |   4 +-
 .../core/it/v3/ServiceDocumentTestITCase.java   |   4 +-
 .../client/core/it/v4/EntitySetTestITCase.java  |   8 +-
 .../apache/olingo/client/core/v3/AtomTest.java  |   4 +-
 .../olingo/client/core/v3/EntitySetTest.java    |   6 +-
 .../olingo/client/core/v3/EntityTest.java       |  10 +-
 .../apache/olingo/client/core/v3/ErrorTest.java |   4 +-
 .../apache/olingo/client/core/v3/JSONTest.java  |   6 +-
 .../client/core/v3/PrimitiveValueTest.java      |   2 +-
 .../client/core/v3/ServiceDocumentTest.java     |   4 +-
 .../client/core/v4/PrimitiveValueTest.java      |   2 +-
 .../client/core/v4/ServiceDocumentTest.java     |   4 +-
 .../client/core/v3/AllGeoTypesSet_-10_Geom.xml  |  13 +-
 .../v3/AllGeoTypesSet_-3_GeomMultiPolygon.xml   |  43 +-
 .../olingo/client/core/v3/AllGeoTypesSet_-5.xml |  97 ++---
 .../v3/AllGeoTypesSet_-5_GeogCollection.xml     |  19 +-
 .../core/v3/AllGeoTypesSet_-5_GeogPolygon.xml   |  18 +-
 .../core/v3/AllGeoTypesSet_-6_GeomMultiLine.xml |  24 +-
 .../v3/AllGeoTypesSet_-7_GeomMultiPoint.xml     |  14 +-
 .../olingo/client/core/v3/AllGeoTypesSet_-8.xml |  81 ++--
 .../v3/AllGeoTypesSet_-8_GeomCollection.xml     |  18 +-
 lib/commons-api/pom.xml                         |   5 +
 .../apache/olingo/commons/api/Constants.java    | 243 +++++++++++
 .../commons/api/data/CollectionValue.java       |  27 ++
 .../olingo/commons/api/data/ComplexValue.java   |  27 ++
 .../apache/olingo/commons/api/data/Entry.java   | 167 ++++++++
 .../apache/olingo/commons/api/data/Feed.java    |  75 ++++
 .../olingo/commons/api/data/GeoUtils.java       |  90 +++++
 .../commons/api/data/GeospatialValue.java       |  28 ++
 .../apache/olingo/commons/api/data/Link.java    | 121 ++++++
 .../olingo/commons/api/data/NullValue.java      |  26 ++
 .../olingo/commons/api/data/PrimitiveValue.java |  25 ++
 .../olingo/commons/api/data/Property.java       |  34 ++
 .../apache/olingo/commons/api/data/Value.java   |  44 ++
 .../commons/api/data/v3/LinkCollection.java     |  52 +++
 .../commons/api/domain/AbstractODataValue.java  | 127 ++++++
 .../api/domain/ODataCollectionValue.java        |  98 +++++
 .../commons/api/domain/ODataComplexValue.java   |  97 +++++
 .../olingo/commons/api/domain/ODataEntity.java  | 316 +++++++++++++++
 .../commons/api/domain/ODataEntitySet.java      | 120 ++++++
 .../olingo/commons/api/domain/ODataError.java   |  67 +++
 .../api/domain/ODataGeospatialValue.java        |  57 +++
 .../commons/api/domain/ODataInlineEntity.java   |  74 ++++
 .../api/domain/ODataInlineEntitySet.java        |  74 ++++
 .../commons/api/domain/ODataInvokeResult.java   |  30 ++
 .../olingo/commons/api/domain/ODataItem.java    | 111 +++++
 .../olingo/commons/api/domain/ODataLink.java    | 190 +++++++++
 .../commons/api/domain/ODataLinkType.java       |  93 +++++
 .../commons/api/domain/ODataObjectFactory.java  | 218 ++++++++++
 .../commons/api/domain/ODataOperation.java      |  88 ++++
 .../commons/api/domain/ODataPrimitiveValue.java |  67 +++
 .../commons/api/domain/ODataProperty.java       | 186 +++++++++
 .../commons/api/domain/ODataPropertyType.java   |  40 ++
 .../api/domain/ODataServiceDocument.java        | 183 +++++++++
 .../olingo/commons/api/domain/ODataValue.java   |  84 ++++
 .../olingo/commons/api/format/ContentType.java  |  47 +++
 .../olingo/commons/api/format/Format.java       |  26 ++
 .../olingo/commons/api/format/ODataFormat.java  | 102 +++++
 .../commons/api/format/ODataMediaFormat.java    |  76 ++++
 .../commons/api/format/ODataPubFormat.java      | 121 ++++++
 .../commons/api/format/ODataValueFormat.java    |  81 ++++
 .../commons/api/op/CommonODataDeserializer.java |  71 ++++
 .../olingo/commons/api/op/ODataSerializer.java  | 100 +++++
 lib/commons-core/pom.xml                        |  21 +
 .../commons/core/data/AbstractAtomDealer.java   |  87 ++++
 .../commons/core/data/AbstractAtomObject.java   |  78 ++++
 .../olingo/commons/core/data/AbstractEntry.java | 159 ++++++++
 .../core/data/AbstractJsonDeserializer.java     | 175 ++++++++
 .../core/data/AbstractJsonSerializer.java       |  94 +++++
 .../core/data/AbstractPayloadObject.java        |  48 +++
 .../commons/core/data/AbstractPropertyImpl.java |  80 ++++
 .../olingo/commons/core/data/AbstractValue.java |  98 +++++
 .../commons/core/data/AtomDeserializer.java     | 368 +++++++++++++++++
 .../olingo/commons/core/data/AtomEntryImpl.java |  25 ++
 .../olingo/commons/core/data/AtomFeedImpl.java  |  66 +++
 .../core/data/AtomGeoValueDeserializer.java     | 261 ++++++++++++
 .../core/data/AtomGeoValueSerializer.java       | 221 ++++++++++
 .../core/data/AtomPropertyDeserializer.java     | 218 ++++++++++
 .../commons/core/data/AtomPropertyImpl.java     |  25 ++
 .../core/data/AtomPropertySerializer.java       |  88 ++++
 .../commons/core/data/AtomSerializer.java       | 264 ++++++++++++
 .../commons/core/data/CollectionValueImpl.java  |  40 ++
 .../commons/core/data/ComplexValueImpl.java     |  40 ++
 .../commons/core/data/GeospatialValueImpl.java  |  42 ++
 .../core/data/JSONEntryDeserializer.java        | 241 +++++++++++
 .../olingo/commons/core/data/JSONEntryImpl.java |  92 +++++
 .../commons/core/data/JSONEntrySerializer.java  | 120 ++++++
 .../commons/core/data/JSONErrorBundle.java      |  50 +++
 .../olingo/commons/core/data/JSONErrorImpl.java | 237 +++++++++++
 .../commons/core/data/JSONFeedDeserializer.java |  68 ++++
 .../olingo/commons/core/data/JSONFeedImpl.java  | 113 ++++++
 .../commons/core/data/JSONFeedSerializer.java   |  57 +++
 .../core/data/JSONGeoValueDeserializer.java     | 273 +++++++++++++
 .../core/data/JSONGeoValueSerializer.java       | 183 +++++++++
 .../core/data/JSONPropertyDeserializer.java     |  71 ++++
 .../commons/core/data/JSONPropertyImpl.java     |  53 +++
 .../core/data/JSONPropertySerializer.java       |  59 +++
 .../olingo/commons/core/data/LinkImpl.java      | 112 +++++
 .../olingo/commons/core/data/NullValueImpl.java |  35 ++
 .../core/data/ODataJacksonDeserializer.java     |  44 ++
 .../core/data/ODataJacksonSerializer.java       |  45 +++
 .../commons/core/data/PrimitiveValueImpl.java   |  41 ++
 .../olingo/commons/core/data/XMLErrorImpl.java  | 213 ++++++++++
 .../core/data/v3/JSONLinkCollectionImpl.java    | 118 ++++++
 .../core/data/v3/XMLLinkCollectionImpl.java     |  70 ++++
 .../olingo/commons/core/edm/EdmTypeInfo.java    | 184 +++++++++
 .../commons/core/op/AbstractJacksonTool.java    |  83 ++++
 .../core/op/AbstractODataDeserializer.java      | 106 +++++
 .../core/op/AbstractODataSerializer.java        | 141 +++++++
 .../core/op/InjectableSerializerProvider.java   |  43 ++
 .../commons/core/op/ODataObjectFactoryImpl.java | 162 ++++++++
 .../olingo/commons/core/op/ResourceFactory.java | 125 ++++++
 389 files changed, 11517 insertions(+), 11309 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonConfiguration.java
----------------------------------------------------------------------
diff --cc lib/client-api/src/main/java/org/apache/olingo/client/api/CommonConfiguration.java
index 48f2614,59786f3..af0ec21
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonConfiguration.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonConfiguration.java
@@@ -18,15 -18,15 +18,15 @@@
   */
  package org.apache.olingo.client.api;
  
- import org.apache.olingo.client.api.format.ODataFormat;
- import org.apache.olingo.client.api.format.ODataMediaFormat;
- import org.apache.olingo.client.api.format.ODataPubFormat;
- import org.apache.olingo.client.api.format.ODataValueFormat;
 -import org.apache.olingo.commons.api.format.ODataFormat;
 -import org.apache.olingo.commons.api.format.ODataMediaFormat;
 -import org.apache.olingo.commons.api.format.ODataPubFormat;
 -import org.apache.olingo.commons.api.format.ODataValueFormat;
  import org.apache.olingo.client.api.http.HttpClientFactory;
  import org.apache.olingo.client.api.http.HttpUriRequestFactory;
  
  import java.io.Serializable;
  import java.util.concurrent.ExecutorService;
++import org.apache.olingo.commons.api.format.ODataFormat;
++import org.apache.olingo.commons.api.format.ODataMediaFormat;
++import org.apache.olingo.commons.api.format.ODataPubFormat;
++import org.apache.olingo.commons.api.format.ODataValueFormat;
  
  /**
   * Configuration wrapper.

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
----------------------------------------------------------------------
diff --cc lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
index 7ba38f8,f64b233..1d97bcc
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
@@@ -20,7 -20,6 +20,7 @@@ package org.apache.olingo.client.api.co
  
  import java.util.concurrent.Future;
  import org.apache.olingo.client.api.communication.response.ODataResponse;
- import org.apache.olingo.client.api.format.Format;
++import org.apache.olingo.commons.api.format.Format;
  
  /**
   * Basic OData request.

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
----------------------------------------------------------------------
diff --cc lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
index 14f907e,edabb96..073f520
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
@@@ -20,7 -20,6 +20,7 @@@ package org.apache.olingo.client.api.co
  
  import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
  import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
- import org.apache.olingo.client.api.format.Format;
++import org.apache.olingo.commons.api.format.Format;
  
  /**
   * This is an abstract representation of an OData retrieve query request returning one or more result item.

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
----------------------------------------------------------------------
diff --cc lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
index 8cd5819,307cdc9..80eadf1
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
@@@ -31,7 -31,6 +31,7 @@@ import org.apache.olingo.client.api.com
  import org.apache.olingo.client.api.communication.request.ODataStreamer;
  import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
  import org.apache.olingo.client.api.communication.response.ODataResponse;
- import org.apache.olingo.client.api.format.Format;
++import org.apache.olingo.commons.api.format.Format;
  import org.apache.olingo.client.api.http.HttpMethod;
  
  /**

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
----------------------------------------------------------------------
diff --cc lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
index 2e60a7d,bec2f65..3e6c1bb
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
@@@ -42,22 -42,17 +42,22 @@@ import org.apache.olingo.client.api.com
  import org.apache.olingo.client.api.communication.header.ODataHeaders;
  import org.apache.olingo.client.api.communication.request.ODataRequest;
  import org.apache.olingo.client.api.communication.request.ODataStreamer;
 +import org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory;
 +import org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory;
 +import org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory;
 +import org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory;
  import org.apache.olingo.client.api.communication.response.ODataResponse;
- import org.apache.olingo.client.api.format.ODataMediaFormat;
- import org.apache.olingo.client.api.format.ODataPubFormat;
- import org.apache.olingo.client.api.format.ODataValueFormat;
++import org.apache.olingo.commons.api.format.Format;
 +import org.apache.olingo.client.api.http.HttpClientException;
 +import org.apache.olingo.client.api.http.HttpMethod;
- import org.apache.olingo.client.core.data.JSONErrorImpl;
- import org.apache.olingo.client.core.data.XMLErrorImpl;
- import org.apache.olingo.client.api.data.ODataError;
- import org.apache.olingo.client.api.format.Format;
 +import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
++import org.apache.olingo.commons.api.domain.ODataError;
 +import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+ import org.apache.olingo.commons.api.format.ODataMediaFormat;
+ import org.apache.olingo.commons.api.format.ODataPubFormat;
+ import org.apache.olingo.commons.api.format.ODataValueFormat;
 -import org.apache.olingo.client.api.http.HttpClientException;
 -import org.apache.olingo.client.api.http.HttpMethod;
+ import org.apache.olingo.commons.core.data.JSONErrorImpl;
+ import org.apache.olingo.commons.core.data.XMLErrorImpl;
 -import org.apache.olingo.commons.api.domain.ODataError;
 -import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
 -import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
----------------------------------------------------------------------
diff --cc lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
index 628e836,fe51722..7fd3966
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
@@@ -26,7 -26,6 +26,7 @@@ import org.apache.olingo.client.api.Com
  import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
  import org.apache.olingo.client.api.communication.request.retrieve.ODataRetrieveRequest;
  import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
- import org.apache.olingo.client.api.format.Format;
++import org.apache.olingo.commons.api.format.Format;
  import org.apache.olingo.client.api.http.HttpMethod;
  import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
  import org.apache.olingo.client.core.communication.response.AbstractODataResponse;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
----------------------------------------------------------------------
diff --cc lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
index bf047af,ae64d31..ae6b8d4
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
@@@ -40,5 -41,5 +41,4 @@@ public class EdmActionImportImpl extend
      return edm.getAction(new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(actionImport.getAction()).
              setDefaultNamespace(container.getNamespace()).build().getFullQualifiedName(), null, null);
    }
--
  }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
----------------------------------------------------------------------
diff --cc lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
index 0000000,0524c13..44e7ad4
mode 000000,100644..100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
@@@ -1,0 -1,405 +1,405 @@@
+ /*
+  * 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.client.core.op;
+ 
+ import org.apache.olingo.commons.core.op.ResourceFactory;
+ import java.io.StringWriter;
+ import java.net.URI;
+ import java.util.Iterator;
+ import org.apache.commons.lang3.StringUtils;
+ import org.apache.olingo.client.api.CommonODataClient;
+ import org.apache.olingo.commons.api.Constants;
+ import org.apache.olingo.commons.api.data.Entry;
+ import org.apache.olingo.commons.api.data.Feed;
+ import org.apache.olingo.commons.api.data.Link;
+ import org.apache.olingo.commons.api.data.Property;
+ import org.apache.olingo.client.api.data.ServiceDocument;
+ import org.apache.olingo.client.api.data.ServiceDocumentItem;
+ import org.apache.olingo.commons.api.data.Value;
+ import org.apache.olingo.commons.api.domain.ODataCollectionValue;
+ import org.apache.olingo.commons.api.domain.ODataComplexValue;
+ import org.apache.olingo.commons.api.domain.ODataEntity;
+ import org.apache.olingo.commons.api.domain.ODataEntitySet;
+ import org.apache.olingo.commons.api.domain.ODataInlineEntity;
+ import org.apache.olingo.commons.api.domain.ODataInlineEntitySet;
+ import org.apache.olingo.commons.api.domain.ODataLink;
+ import org.apache.olingo.commons.api.domain.ODataOperation;
+ import org.apache.olingo.commons.api.domain.ODataProperty;
+ import org.apache.olingo.commons.api.domain.ODataServiceDocument;
+ import org.apache.olingo.commons.api.domain.ODataValue;
+ import org.apache.olingo.commons.api.format.ODataPubFormat;
+ import org.apache.olingo.client.api.op.CommonODataBinder;
+ import org.apache.olingo.commons.core.data.CollectionValueImpl;
+ import org.apache.olingo.commons.core.data.ComplexValueImpl;
+ import org.apache.olingo.commons.core.data.GeospatialValueImpl;
+ import org.apache.olingo.commons.core.data.JSONPropertyImpl;
+ import org.apache.olingo.commons.core.data.LinkImpl;
+ import org.apache.olingo.commons.core.data.NullValueImpl;
+ import org.apache.olingo.commons.core.data.PrimitiveValueImpl;
+ import org.apache.olingo.client.core.uri.URIUtils;
+ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ 
+ public abstract class AbstractODataBinder implements CommonODataBinder {
+ 
+   private static final long serialVersionUID = 454285889193689536L;
+ 
+   /**
+    * Logger.
+    */
+   protected final Logger LOG = LoggerFactory.getLogger(AbstractODataBinder.class);
+ 
+   protected final CommonODataClient client;
+ 
+   protected AbstractODataBinder(final CommonODataClient client) {
+     this.client = client;
+   }
+ 
+   @Override
+   public ODataServiceDocument getODataServiceDocument(final ServiceDocument resource) {
+     final ODataServiceDocument serviceDocument = new ODataServiceDocument();
+ 
+     for (ServiceDocumentItem entitySet : resource.getEntitySets()) {
+       // handles V3 JSON format oddities, where title is not contained
+       serviceDocument.getEntitySets().put(StringUtils.isBlank(entitySet.getTitle())
+               ? entitySet.getName() : entitySet.getTitle(),
+               URIUtils.getURI(resource.getBaseURI(), entitySet.getHref()));
+     }
+ 
+     return serviceDocument;
+   }
+ 
+   @Override
+   public Feed getFeed(final ODataEntitySet feed, final Class<? extends Feed> reference) {
+     final Feed feedResource = ResourceFactory.newFeed(reference);
+ 
+     feedResource.setCount(feed.getCount());
+ 
+     final URI next = feed.getNext();
+     if (next != null) {
+       feedResource.setNext(next);
+     }
+ 
+     for (ODataEntity entity : feed.getEntities()) {
+       feedResource.getEntries().add(getEntry(entity, ResourceFactory.entryClassForFeed(reference)));
+     }
+ 
+     return feedResource;
+   }
+ 
+   @Override
+   public Entry getEntry(final ODataEntity entity, final Class<? extends Entry> reference) {
+     return getEntry(entity, reference, true);
+   }
+ 
+   @Override
+   public Entry getEntry(final ODataEntity entity, final Class<? extends Entry> reference, final boolean setType) {
+     final Entry entry = ResourceFactory.newEntry(reference);
+     entry.setType(entity.getName());
+ 
+     // -------------------------------------------------------------
+     // Add edit and self link
+     // -------------------------------------------------------------
+     final URI editLink = entity.getEditLink();
+     if (editLink != null) {
+       final LinkImpl entryEditLink = new LinkImpl();
+       entryEditLink.setTitle(entity.getName());
+       entryEditLink.setHref(editLink.toASCIIString());
+       entryEditLink.setRel(Constants.EDIT_LINK_REL);
+       entry.setEditLink(entryEditLink);
+     }
+ 
+     if (entity.isReadOnly()) {
+       final LinkImpl entrySelfLink = new LinkImpl();
+       entrySelfLink.setTitle(entity.getName());
+       entrySelfLink.setHref(entity.getLink().toASCIIString());
+       entrySelfLink.setRel(Constants.SELF_LINK_REL);
+       entry.setSelfLink(entrySelfLink);
+     }
+     // -------------------------------------------------------------
+ 
+     // -------------------------------------------------------------
+     // Append navigation links (handling inline entry / feed as well)
+     // -------------------------------------------------------------
+     // handle navigation links
+     for (ODataLink link : entity.getNavigationLinks()) {
+       // append link 
+       LOG.debug("Append navigation link\n{}", link);
+       entry.getNavigationLinks().add(getLink(link,
+               ResourceFactory.formatForEntryClass(reference) == ODataPubFormat.ATOM));
+     }
+     // -------------------------------------------------------------
+ 
+     // -------------------------------------------------------------
+     // Append edit-media links
+     // -------------------------------------------------------------
+     for (ODataLink link : entity.getEditMediaLinks()) {
+       LOG.debug("Append edit-media link\n{}", link);
+       entry.getMediaEditLinks().add(getLink(link,
+               ResourceFactory.formatForEntryClass(reference) == ODataPubFormat.ATOM));
+     }
+     // -------------------------------------------------------------
+ 
+     // -------------------------------------------------------------
+     // Append association links
+     // -------------------------------------------------------------
+     for (ODataLink link : entity.getAssociationLinks()) {
+       LOG.debug("Append association link\n{}", link);
+       entry.getAssociationLinks().add(getLink(link,
+               ResourceFactory.formatForEntryClass(reference) == ODataPubFormat.ATOM));
+     }
+     // -------------------------------------------------------------
+ 
+     if (entity.isMediaEntity()) {
+       entry.setMediaContentSource(entity.getMediaContentSource());
+       entry.setMediaContentType(entity.getMediaContentType());
+     }
+ 
+     for (ODataProperty property : entity.getProperties()) {
+       entry.getProperties().add(getProperty(property, reference, setType));
+     }
+ 
+     return entry;
+   }
+ 
+   @Override
+   public Link getLink(final ODataLink link, boolean isXML) {
+     final Link linkResource = new LinkImpl();
+     linkResource.setRel(link.getRel());
+     linkResource.setTitle(link.getName());
+     linkResource.setHref(link.getLink() == null ? null : link.getLink().toASCIIString());
+     linkResource.setType(link.getType().toString());
+     linkResource.setMediaETag(link.getMediaETag());
+ 
+     if (link instanceof ODataInlineEntity) {
+       // append inline entity
+       final ODataEntity inlineEntity = ((ODataInlineEntity) link).getEntity();
+       LOG.debug("Append in-line entity\n{}", inlineEntity);
+ 
+       linkResource.setInlineEntry(getEntry(inlineEntity, ResourceFactory.entryClassForFormat(isXML)));
+     } else if (link instanceof ODataInlineEntitySet) {
+       // append inline feed
+       final ODataEntitySet InlineFeed = ((ODataInlineEntitySet) link).getEntitySet();
+       LOG.debug("Append in-line feed\n{}", InlineFeed);
+ 
+       linkResource.setInlineFeed(getFeed(InlineFeed, ResourceFactory.feedClassForFormat(isXML)));
+     }
+ 
+     return linkResource;
+   }
+ 
+   @Override
+   public Property getProperty(final ODataProperty property, final Class<? extends Entry> reference,
+           final boolean setType) {
+ 
+     final Property propertyResource = ResourceFactory.newProperty(reference);
+     propertyResource.setName(property.getName());
+     propertyResource.setValue(getValue(property.getValue(), reference, setType));
+ 
+     if (setType) {
+       if (property.hasPrimitiveValue()) {
+         propertyResource.setType(property.getPrimitiveValue().getType().toString());
+       } else if (property.hasComplexValue()) {
+         propertyResource.setType(property.getComplexValue().getType());
+       } else if (property.hasCollectionValue()) {
+         propertyResource.setType(property.getCollectionValue().getType());
+       }
+     }
+ 
+     return propertyResource;
+   }
+ 
+   private Value getValue(final ODataValue value, final Class<? extends Entry> reference, final boolean setType) {
+     Value valueResource = null;
+ 
+     if (value == null) {
+       valueResource = new NullValueImpl();
+     } else if (value.isPrimitive()) {
+       valueResource = new PrimitiveValueImpl(value.asPrimitive().toString());
+     } else if (value.isGeospatial()) {
+       valueResource = new GeospatialValueImpl(value.asGeospatial().toValue());
+     } else if (value.isComplex()) {
+       final ODataComplexValue _value = value.asComplex();
+       valueResource = new ComplexValueImpl();
+ 
+       for (final Iterator<ODataProperty> itor = _value.iterator(); itor.hasNext();) {
+         valueResource.asComplex().get().add(getProperty(itor.next(), reference, setType));
+       }
+     } else if (value.isCollection()) {
+       final ODataCollectionValue _value = value.asCollection();
+       valueResource = new CollectionValueImpl();
+ 
+       for (final Iterator<ODataValue> itor = _value.iterator(); itor.hasNext();) {
+         valueResource.asCollection().get().add(getValue(itor.next(), reference, setType));
+       }
+     }
+ 
+     return valueResource;
+   }
+ 
+   @Override
+   public ODataEntitySet getODataEntitySet(final Feed resource) {
+     return getODataEntitySet(resource, null);
+   }
+ 
+   @Override
+   public ODataEntitySet getODataEntitySet(final Feed resource, final URI defaultBaseURI) {
+     if (LOG.isDebugEnabled()) {
+       final StringWriter writer = new StringWriter();
+       client.getSerializer().feed(resource, writer);
+       writer.flush();
+       LOG.debug("Feed -> ODataEntitySet:\n{}", writer.toString());
+     }
+ 
+     final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI;
 -
++    
+     final URI next = resource.getNext();
+ 
+     final ODataEntitySet entitySet = next == null
+             ? client.getObjectFactory().newEntitySet()
+             : client.getObjectFactory().newEntitySet(URIUtils.getURI(base, next.toASCIIString()));
+ 
+     if (resource.getCount() != null) {
+       entitySet.setCount(resource.getCount());
+     }
+ 
+     for (Entry entryResource : resource.getEntries()) {
+       entitySet.addEntity(getODataEntity(entryResource));
+     }
 -
++    
+     return entitySet;
+   }
+ 
+   @Override
+   public ODataEntity getODataEntity(final Entry resource) {
+     return getODataEntity(resource, null);
+   }
+ 
+   @Override
+   public ODataEntity getODataEntity(final Entry resource, final URI defaultBaseURI) {
+     if (LOG.isDebugEnabled()) {
+       final StringWriter writer = new StringWriter();
+       client.getSerializer().entry(resource, writer);
+       writer.flush();
+       LOG.debug("EntryResource -> ODataEntity:\n{}", writer.toString());
+     }
+ 
+     final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI;
+ 
+     final ODataEntity entity = resource.getSelfLink() == null
+             ? client.getObjectFactory().newEntity(resource.getType())
+             : client.getObjectFactory().newEntity(resource.getType(),
+                     URIUtils.getURI(base, resource.getSelfLink().getHref()));
+ 
+     if (StringUtils.isNotBlank(resource.getETag())) {
+       entity.setETag(resource.getETag());
+     }
 -
++    
+     if (resource.getEditLink() != null) {
+       entity.setEditLink(URIUtils.getURI(base, resource.getEditLink().getHref()));
+     }
 -
++    
+     for (Link link : resource.getAssociationLinks()) {
+       entity.addLink(client.getObjectFactory().newAssociationLink(link.getTitle(), base, link.getHref()));
+     }
+ 
+     for (Link link : resource.getNavigationLinks()) {
+       final Entry inlineEntry = link.getInlineEntry();
+       final Feed inlineFeed = link.getInlineFeed();
+ 
+       if (inlineEntry == null && inlineFeed == null) {
+         entity.addLink(
+                 client.getObjectFactory().newEntityNavigationLink(link.getTitle(), base, link.getHref()));
+       } else if (inlineFeed == null) {
+         entity.addLink(client.getObjectFactory().newInlineEntity(
+                 link.getTitle(), base, link.getHref(),
+                 getODataEntity(inlineEntry,
+                         inlineEntry.getBaseURI() == null ? base : inlineEntry.getBaseURI())));
+       } else {
+         entity.addLink(client.getObjectFactory().newInlineEntitySet(
+                 link.getTitle(), base, link.getHref(),
+                 getODataEntitySet(inlineFeed,
+                         inlineFeed.getBaseURI() == null ? base : inlineFeed.getBaseURI())));
+       }
+     }
+ 
+     for (Link link : resource.getMediaEditLinks()) {
+       entity.addLink(client.getObjectFactory().newMediaEditLink(link.getTitle(), base, link.getHref()));
+     }
+ 
+     for (ODataOperation operation : resource.getOperations()) {
+       operation.setTarget(URIUtils.getURI(base, operation.getTarget()));
+       entity.getOperations().add(operation);
+     }
+ 
+     if (resource.isMediaEntry()) {
+       entity.setMediaEntity(true);
+       entity.setMediaContentSource(resource.getMediaContentSource());
+       entity.setMediaContentType(resource.getMediaContentType());
+     }
+ 
+     for (Property property : resource.getProperties()) {
+       entity.getProperties().add(getODataProperty(property));
+     }
+ 
+     return entity;
+   }
+ 
+   @Override
+   public ODataProperty getODataProperty(final Property property) {
+     return new ODataProperty(property.getName(), getODataValue(property));
+   }
+ 
+   private ODataValue getODataValue(final Property resource) {
+     ODataValue value = null;
+ 
+     if (resource.getValue().isSimple()) {
+       value = client.getPrimitiveValueBuilder().
+               setText(resource.getValue().asSimple().get()).
+               setType(resource.getType() == null
+                       ? null
+                       : EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), resource.getType())).build();
+     } else if (resource.getValue().isGeospatial()) {
+       value = client.getGeospatialValueBuilder().
+               setValue(resource.getValue().asGeospatial().get()).
+               setType(resource.getType() == null
+                       || EdmPrimitiveTypeKind.Geography.getFullQualifiedName().toString().equals(resource.getType())
+                       || EdmPrimitiveTypeKind.Geometry.getFullQualifiedName().toString().equals(resource.getType())
+                       ? null
+                       : EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), resource.getType())).build();
+     } else if (resource.getValue().isComplex()) {
+       value = new ODataComplexValue(resource.getType());
+ 
+       for (Property property : resource.getValue().asComplex().get()) {
+         value.asComplex().add(getODataProperty(property));
+       }
+     } else if (resource.getValue().isCollection()) {
+       value = new ODataCollectionValue(resource.getType());
+ 
+       for (Value _value : resource.getValue().asCollection().get()) {
+         final JSONPropertyImpl fake = new JSONPropertyImpl();
+         fake.setValue(_value);
+         value.asCollection().add(getODataValue(fake));
+       }
+     }
+ 
+     return value;
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
----------------------------------------------------------------------
diff --cc lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
index 9e2527a,0000000..e3e8a1e
mode 100644,000000..100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
@@@ -1,152 -1,0 +1,152 @@@
 +/*
 + * 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.client.core.it.v4;
 +
++import static org.junit.Assert.assertNotNull;
 +import static org.junit.Assert.assertEquals;
 +
 +import java.io.IOException;
 +import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetIteratorRequest;
 +import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
 +import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
 +import org.apache.olingo.client.api.communication.response.ODataRawResponse;
 +import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
- import org.apache.olingo.client.api.domain.ODataEntitySet;
 +import org.apache.olingo.client.api.domain.ODataEntitySetIterator;
- import org.apache.olingo.client.api.format.ODataPubFormat;
 +import org.apache.olingo.client.api.uri.CommonURIBuilder;
- import org.apache.olingo.client.core.op.impl.ResourceFactory;
- import static org.junit.Assert.assertNotNull;
++import org.apache.olingo.commons.api.domain.ODataEntitySet;
++import org.apache.olingo.commons.api.format.ODataPubFormat;
++import org.apache.olingo.commons.core.op.ResourceFactory;
 +import org.junit.Ignore;
 +import org.junit.Test;
 +
 +/**
 + * This is the unit test class to check basic feed operations.
 + */
 +public class EntitySetTestITCase extends AbstractTestITCase {
 +
 +  protected String getServiceRoot() {
 +    return testStaticServiceRootURL;
 +  }
 +
 +  @Test
 +  public void rawRequestAsAtom() throws IOException {
 +    rawRequest(ODataPubFormat.ATOM);
 +  }
 +
 +  @Test
 +  @Ignore
 +  public void rawRequestAsJSON() throws IOException {
 +    rawRequest(ODataPubFormat.JSON);
 +  }
 +
 +  @Test
 +  public void readODataEntitySetIteratorFromAtom() {
 +    readODataEntitySetIterator(ODataPubFormat.ATOM);
 +  }
 +
 +  @Test
 +  @Ignore
 +  public void readODataEntitySetIteratorFromJSON() {
 +    readODataEntitySetIterator(ODataPubFormat.JSON);
 +  }
 +
 +  @Test
 +  @Ignore
 +  public void readODataEntitySetIteratorFromJSONFullMeta() {
 +    readODataEntitySetIterator(ODataPubFormat.JSON_FULL_METADATA);
 +  }
 +
 +  @Test
 +  @Ignore
 +  public void readODataEntitySetIteratorFromJSONNoMeta() {
 +    readODataEntitySetIterator(ODataPubFormat.JSON_NO_METADATA);
 +  }
 +
 +  @Test
 +  public void readODataEntitySetWithNextFromAtom() {
 +    readEntitySetWithNextLink(ODataPubFormat.ATOM);
 +  }
 +
 +  @Test
 +  @Ignore
 +  public void readODataEntitySetWithNextFromJSON() {
 +    readEntitySetWithNextLink(ODataPubFormat.JSON_FULL_METADATA);
 +  }
 +
 +  private void readEntitySetWithNextLink(final ODataPubFormat format) {
 +    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
 +    uriBuilder.appendEntitySetSegment("People");
 +
 +    final ODataEntitySetRequest req = client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.build());
 +    req.setFormat(format);
 +
 +    final ODataRetrieveResponse<ODataEntitySet> res = req.execute();
 +    final ODataEntitySet feed = res.getBody();
 +
 +    assertNotNull(feed);
 +
 +    debugFeed(client.getBinder().getFeed(feed, ResourceFactory.feedClassForFormat(
 +            ODataPubFormat.ATOM == format)), "Just retrieved feed");
 +
 +    assertEquals(5, feed.getEntities().size());
 +//    assertNotNull(feed.getNext());
 +
 +//    final URI expected = URI.create(getServiceRoot() + "/Customer?$skiptoken=-9");
 +//    final URI found = URIUtils.getURI(getServiceRoot(), feed.getNext().toASCIIString());
 +
 +//    assertEquals(expected, found);
 +  }
 +
 +  private void readODataEntitySetIterator(final ODataPubFormat format) {
 +    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
 +    uriBuilder.appendEntitySetSegment("People");
 +
 +    final ODataEntitySetIteratorRequest req =
 +            client.getRetrieveRequestFactory().getEntitySetIteratorRequest(uriBuilder.build());
 +    req.setFormat(format);
 +
 +    final ODataRetrieveResponse<ODataEntitySetIterator> res = req.execute();
 +    final ODataEntitySetIterator feedIterator = res.getBody();
 +
 +    assertNotNull(feedIterator);
 +
 +    int count = 0;
 +
 +    while (feedIterator.hasNext()) {
 +      assertNotNull(feedIterator.next());
 +      count++;
 +    }
 +    assertEquals(5, count);
 +//    assertTrue(feedIterator.getNext().toASCIIString().endsWith("Customer?$skiptoken=-9"));
 +  }
 +
 +  private void rawRequest(final ODataPubFormat format) {
 +    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
 +    uriBuilder.appendEntitySetSegment("People");
 +
 +    final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build());
 +    req.setFormat(format.toString(client.getServiceVersion()));
 +
 +    final ODataRawResponse res = req.execute();
 +    assertNotNull(res);
 +
 +    final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class);
 +    assertNotNull(entitySet);
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataLinkType.java
----------------------------------------------------------------------
diff --cc lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataLinkType.java
index 0000000,59dc834..28727ea
mode 000000,100644..100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataLinkType.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataLinkType.java
@@@ -1,0 -1,93 +1,93 @@@
+ /*
+  * 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.commons.api.domain;
+ 
+ import org.apache.commons.lang3.StringUtils;
+ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+ import org.apache.olingo.commons.api.format.ContentType;
 -import org.apache.olingo.commons.api.format.ODataPubFormat;
+ 
+ /**
+  * OData link types.
+  */
+ public enum ODataLinkType {
+ 
+   /**
+    * Entity navigation link.
+    */
 -  ENTITY_NAVIGATION(ODataPubFormat.ATOM + ";type=entry"),
++  ENTITY_NAVIGATION(ContentType.APPLICATION_ATOM_XML + ";type=entry"),
+   /**
+    * Entity set navigation link.
+    */
 -  ENTITY_SET_NAVIGATION(ODataPubFormat.ATOM + ";type=feed"),
++  ENTITY_SET_NAVIGATION(ContentType.APPLICATION_ATOM_XML + ";type=feed"),
+   /**
+    * Association link.
+    */
+   ASSOCIATION(ContentType.APPLICATION_XML),
+   /**
+    * Media-edit link.
+    */
+   MEDIA_EDIT("*/*");
+ 
+   private String type;
+ 
+   private ODataLinkType(final String type) {
+     this.type = type;
+   }
+ 
+   private ODataLinkType setType(final String type) {
+     this.type = type;
+     return this;
+   }
+ 
+   /**
 -   * Gets <code>LinkType</code> instance from the given rel and type.
++   * Gets
++   * <code>LinkType</code> instance from the given rel and type.
+    *
+    * @param version OData protocol version.
+    * @param rel rel.
+    * @param type type.
+    * @return <code>ODataLinkType</code> object.
+    */
+   public static ODataLinkType fromString(final ODataServiceVersion version, final String rel, final String type) {
+     if (StringUtils.isNotBlank(rel)
+             && rel.startsWith(version.getNamespaceMap().get(ODataServiceVersion.MEDIA_EDIT_LINK_REL))) {
+ 
+       return MEDIA_EDIT.setType(StringUtils.isBlank(type) ? "*/*" : type);
+     }
+ 
+     if (ODataLinkType.ENTITY_NAVIGATION.type.equals(type)) {
+       return ENTITY_NAVIGATION;
+     }
+ 
+     if (ODataLinkType.ENTITY_SET_NAVIGATION.type.equals(type)) {
+       return ENTITY_SET_NAVIGATION;
+     }
+ 
+     if (ODataLinkType.ASSOCIATION.type.equals(type)) {
+       return ASSOCIATION;
+     }
+ 
+     throw new IllegalArgumentException("Invalid link type: " + type);
+   }
+ 
+   @Override
+   public String toString() {
+     return type;
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/Format.java
----------------------------------------------------------------------
diff --cc lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/Format.java
index 0000000,0000000..f031018
new file mode 100644
--- /dev/null
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/Format.java
@@@ -1,0 -1,0 +1,26 @@@
++/*
++ * 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.commons.api.format;
++
++import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
++
++public interface Format {
++
++  String toString(ODataServiceVersion version);
++}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataFormat.java
----------------------------------------------------------------------
diff --cc lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataFormat.java
index 0000000,30d9e09..7401e0b
mode 000000,100644..100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataFormat.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataFormat.java
@@@ -1,0 -1,95 +1,102 @@@
+ /*
+  * 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.commons.api.format;
+ 
++import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
++
+ /**
+  * Available formats to be used in various contexts.
+  */
 -public enum ODataFormat {
++public enum ODataFormat implements Format{
+ 
+   /**
+    * JSON format with no metadata.
+    */
+   JSON_NO_METADATA(ContentType.APPLICATION_JSON + ";odata=nometadata"),
+   /**
+    * JSON format with minimal metadata (default).
+    */
+   JSON(ContentType.APPLICATION_JSON + ";odata=minimalmetadata"),
+   /**
+    * JSON format with no metadata.
+    */
+   JSON_FULL_METADATA(ContentType.APPLICATION_JSON + ";odata=fullmetadata"),
+   /**
+    * XML format.
+    */
+   XML(ContentType.APPLICATION_XML);
+ 
+   private final String format;
+ 
+   ODataFormat(final String format) {
+     this.format = format;
+   }
+ 
+   /**
+    * Gets format as a string.
+    *
+    * @return format as a string.
+    */
+   @Override
+   public String toString() {
+     return format;
+   }
+ 
+   /**
+    * Gets OData format from its string representation.
+    *
+    * @param format string representation of the format.
+    * @return OData format.
+    */
+   public static ODataFormat fromString(final String format) {
+     ODataFormat result = null;
+ 
+     final StringBuffer _format = new StringBuffer();
+ 
+     final String[] parts = format.split(";");
+     _format.append(parts[0].trim());
+     if (ContentType.APPLICATION_JSON.equals(parts[0].trim())) {
+       if (parts.length > 1) {
+         _format.append(';').append(parts[1].trim());
+       } else {
+         result = ODataFormat.JSON;
+       }
+     }
+ 
+     if (result == null) {
+       final String candidate = _format.toString();
+       for (ODataFormat value : values()) {
+         if (candidate.equals(value.toString())) {
+           result = value;
+         }
+       }
+     }
+ 
+     if (result == null) {
+       throw new IllegalArgumentException("Unsupported format: " + format);
+     }
+ 
+     return result;
+   }
++
++  @Override
++  public String toString(final ODataServiceVersion version) {
++    return this.toString();
++  }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataMediaFormat.java
----------------------------------------------------------------------
diff --cc lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataMediaFormat.java
index 0000000,c479de4..a9410d5
mode 000000,100644..100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataMediaFormat.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataMediaFormat.java
@@@ -1,0 -1,69 +1,76 @@@
+ /*
+  * 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.commons.api.format;
+ 
++import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
++
+ /**
+  * Available formats for media.
+  */
 -public enum ODataMediaFormat {
++public enum ODataMediaFormat implements Format{
+ 
+   CHARSET_PARAMETER("charset"),
+   MEDIA_TYPE_WILDCARD("*"),
+   WILDCARD(ContentType.WILDCARD),
+   APPLICATION_XML(ContentType.APPLICATION_XML),
+   APPLICATION_ATOM_XML(ContentType.APPLICATION_ATOM_XML),
+   APPLICATION_XHTML_XML(ContentType.APPLICATION_XHTML_XML),
+   APPLICATION_SVG_XML(ContentType.APPLICATION_SVG_XML),
+   APPLICATION_JSON(ContentType.APPLICATION_JSON),
+   APPLICATION_FORM_URLENCODED(ContentType.APPLICATION_FORM_URLENCODED),
+   MULTIPART_FORM_DATA(ContentType.MULTIPART_FORM_DATA),
+   APPLICATION_OCTET_STREAM(ContentType.APPLICATION_OCTET_STREAM),
+   TEXT_PLAIN(ContentType.TEXT_PLAIN),
+   TEXT_XML(ContentType.TEXT_XML),
+   TEXT_HTML(ContentType.TEXT_HTML);
+ 
+   private final String format;
+ 
+   private ODataMediaFormat(final String format) {
+     this.format = format;
+   }
+ 
+   @Override
+   public String toString() {
+     return format;
+   }
+ 
+   public static ODataMediaFormat fromFormat(final String format) {
+     final String _format = format.split(";")[0];
+ 
+     ODataMediaFormat result = null;
+ 
+     for (ODataMediaFormat value : values()) {
+       if (_format.equals(value.toString())) {
+         result = value;
+       }
+     }
+ 
+     if (result == null) {
+       throw new IllegalArgumentException("Unsupported format: " + format);
+     }
+ 
+     return result;
+   }
++
++  @Override
++  public String toString(final ODataServiceVersion version) {
++    return this.toString();
++  }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataPubFormat.java
----------------------------------------------------------------------
diff --cc lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataPubFormat.java
index 0000000,6cd6a05..62dc61b
mode 000000,100644..100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataPubFormat.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataPubFormat.java
@@@ -1,0 -1,95 +1,121 @@@
+ /*
+  * 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.commons.api.format;
+ 
++import java.util.EnumMap;
++import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
++
+ /**
+  * Available formats for AtomPub exchange.
+  */
 -public enum ODataPubFormat {
++public enum ODataPubFormat implements Format {
+ 
+   /**
+    * JSON format with no metadata.
+    */
 -  JSON_NO_METADATA(ContentType.APPLICATION_JSON + ";odata=nometadata"),
++  JSON_NO_METADATA(),
+   /**
+    * JSON format with minimal metadata (default).
+    */
 -  JSON(ContentType.APPLICATION_JSON + ";odata=minimalmetadata"),
++  JSON(),
+   /**
+    * JSON format with no metadata.
+    */
 -  JSON_FULL_METADATA(ContentType.APPLICATION_JSON + ";odata=fullmetadata"),
++  JSON_FULL_METADATA(),
+   /**
+    * Atom format.
+    */
 -  ATOM(ContentType.APPLICATION_ATOM_XML);
++  ATOM();
++
++  final static EnumMap<ODataServiceVersion, EnumMap<ODataPubFormat, String>> formatPerVersion =
++          new EnumMap<ODataServiceVersion, EnumMap<ODataPubFormat, String>>(ODataServiceVersion.class);
+ 
 -  private final String format;
++  static {
++    final EnumMap<ODataPubFormat, String> v3 = new EnumMap<ODataPubFormat, String>(ODataPubFormat.class);
++    v3.put(JSON_NO_METADATA, ContentType.APPLICATION_JSON + ";odata=nometadata");
++    v3.put(JSON, ContentType.APPLICATION_JSON + ";odata=minimalmetadata");
++    v3.put(JSON_FULL_METADATA, ContentType.APPLICATION_JSON + ";odata=fullmetadata");
++    v3.put(ATOM, ContentType.APPLICATION_ATOM_XML);
++    formatPerVersion.put(ODataServiceVersion.V30, v3);
+ 
 -  ODataPubFormat(final String format) {
 -    this.format = format;
++    final EnumMap<ODataPubFormat, String> v4 = new EnumMap<ODataPubFormat, String>(ODataPubFormat.class);
++    v4.put(JSON_NO_METADATA, ContentType.APPLICATION_JSON + ";odata.metadata=none");
++    v4.put(JSON, ContentType.APPLICATION_JSON + ";odata.metadata=minimal");
++    v4.put(JSON_FULL_METADATA, ContentType.APPLICATION_JSON + ";odata.metadata=full");
++    v4.put(ATOM, ContentType.APPLICATION_ATOM_XML);
++    formatPerVersion.put(ODataServiceVersion.V40, v4);
+   }
+ 
+   /**
+    * Gets format as a string.
+    *
+    * @return format as a string.
+    */
+   @Override
++  public String toString(final ODataServiceVersion version) {
++    if (version.ordinal() < ODataServiceVersion.V30.ordinal()) {
++      throw new IllegalArgumentException("Unsupported version " + version);
++    }
++
++    return ODataPubFormat.formatPerVersion.get(version).get(this);
++  }
++
++  @Override
+   public String toString() {
 -    return format;
++    throw new UnsupportedOperationException();
+   }
+ 
+   /**
+    * Gets OData format from its string representation.
+    *
+    * @param format string representation of the format.
+    * @return OData format.
+    */
+   public static ODataPubFormat fromString(final String format) {
+     ODataPubFormat result = null;
+ 
+     final StringBuffer _format = new StringBuffer();
+ 
+     final String[] parts = format.split(";");
+     _format.append(parts[0].trim());
+     if (ContentType.APPLICATION_JSON.equals(parts[0].trim())) {
 -      if (parts.length > 1 && parts[1].startsWith("odata=")) {
++      if (parts.length > 1 && parts[1].startsWith("odata")) {
+         _format.append(';').append(parts[1].trim());
+       } else {
+         result = ODataPubFormat.JSON;
+       }
+     }
+ 
+     if (result == null) {
+       final String candidate = _format.toString();
+       for (ODataPubFormat value : values()) {
 -        if (candidate.equals(value.toString())) {
++        if (candidate.equals(value.toString(ODataServiceVersion.V30))
++                || candidate.equals(value.toString(ODataServiceVersion.V40))) {
+           result = value;
+         }
+       }
+     }
+ 
+     if (result == null) {
+       throw new IllegalArgumentException("Unsupported format: " + format);
+     }
+ 
+     return result;
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataValueFormat.java
----------------------------------------------------------------------
diff --cc lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataValueFormat.java
index 0000000,1b290bf..28ce108
mode 000000,100644..100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataValueFormat.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ODataValueFormat.java
@@@ -1,0 -1,74 +1,81 @@@
+ /*
+  * 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.commons.api.format;
+ 
++import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
++
+ /**
+  * Available formats for property values.
+  */
 -public enum ODataValueFormat {
++public enum ODataValueFormat implements Format {
+ 
+   /**
+    * Application octet stream.
+    */
+   STREAM(ContentType.APPLICATION_OCTET_STREAM),
+   /**
+    * Plain text format.
+    */
+   TEXT(ContentType.TEXT_PLAIN);
+ 
+   private final String format;
+ 
+   ODataValueFormat(final String format) {
+     this.format = format;
+   }
+ 
+   /**
+    * Gets format as a string.
+    *
+    * @return format as a string.
+    */
+   @Override
+   public String toString() {
+     return format;
+   }
+ 
+   /**
+    * Gets format from its string representation.
+    *
+    * @param format string representation of the format.
+    * @return OData format.
+    */
+   public static ODataValueFormat fromString(final String format) {
+     final String _format = format.split(";")[0];
+ 
+     ODataValueFormat result = null;
+ 
+     for (ODataValueFormat value : values()) {
+       if (_format.equals(value.toString())) {
+         result = value;
+       }
+     }
+ 
+     if (result == null) {
+       throw new IllegalArgumentException("Unsupported format: " + format);
+     }
+ 
+     return result;
+   }
++
++  @Override
++  public String toString(final ODataServiceVersion version) {
++    return this.toString();
++  }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java
index 0000000,2d865ce..4c92ae6
mode 000000,100644..100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java
@@@ -1,0 -1,176 +1,175 @@@
+ /*
+  * 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.commons.core.data;
+ 
+ import com.fasterxml.jackson.databind.JsonNode;
+ import com.fasterxml.jackson.databind.node.ObjectNode;
+ import java.util.Iterator;
+ import java.util.Map;
+ import org.apache.commons.lang3.StringUtils;
+ import org.apache.olingo.commons.api.Constants;
+ import org.apache.olingo.commons.api.data.CollectionValue;
+ import org.apache.olingo.commons.api.data.ComplexValue;
+ import org.apache.olingo.commons.api.data.Value;
+ import org.apache.olingo.commons.api.domain.ODataPropertyType;
+ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+ import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+ 
+ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
+ 
+   private JSONGeoValueDeserializer geoDeserializer;
+ 
+   private JSONGeoValueDeserializer getGeoDeserializer() {
+     if (geoDeserializer == null) {
+       geoDeserializer = new JSONGeoValueDeserializer(version);
+     }
+     return geoDeserializer;
+   }
+ 
+   protected EdmPrimitiveTypeKind getPrimitiveType(final JsonNode node) {
+     EdmPrimitiveTypeKind result = EdmPrimitiveTypeKind.String;
+ 
+     if (node.isIntegralNumber()) {
+       result = EdmPrimitiveTypeKind.Int32;
+     } else if (node.isBoolean()) {
+       result = EdmPrimitiveTypeKind.Boolean;
+     } else if (node.isFloatingPointNumber()) {
+       result = EdmPrimitiveTypeKind.Double;
+     }
+ 
+     return result;
+   }
+ 
+   private ODataPropertyType guessPropertyType(final JsonNode node) {
 -    ODataPropertyType type = null;
++    final ODataPropertyType type;
+ 
+     if (node.isValueNode() || node.isNull()) {
+       type = ODataPropertyType.PRIMITIVE;
+     } else if (node.isArray()) {
+       type = ODataPropertyType.COLLECTION;
+     } else if (node.isObject()) {
+       type = ODataPropertyType.COMPLEX;
+     } else {
+       type = ODataPropertyType.EMPTY;
+     }
+ 
+     return type;
+   }
+ 
+   private Value fromPrimitive(final JsonNode node, final EdmTypeInfo typeInfo) {
 -    Value value = null;
++    final Value value;
+ 
+     if (node.isNull()) {
+       value = new NullValueImpl();
+     } else {
+       if (typeInfo != null && typeInfo.getPrimitiveTypeKind().isGeospatial()) {
+         value = new GeospatialValueImpl(getGeoDeserializer().deserialize(node, typeInfo));
+       } else {
+         value = new PrimitiveValueImpl(node.asText());
+       }
+     }
+ 
+     return value;
+   }
+ 
+   private ComplexValue fromComplex(final JsonNode node) {
+     final ComplexValue value = new ComplexValueImpl();
+ 
+     String type = null;
+     for (final Iterator<Map.Entry<String, JsonNode>> itor = node.fields(); itor.hasNext();) {
+       final Map.Entry<String, JsonNode> field = itor.next();
+ 
+       if (type == null && field.getKey().endsWith(Constants.JSON_TYPE_SUFFIX)) {
+         type = field.getValue().asText();
+       } else {
+         final JSONPropertyImpl property = new JSONPropertyImpl();
+         property.setName(field.getKey());
+         property.setType(type);
+         type = null;
+ 
+         value(property, field.getValue());
+         value.get().add(property);
+       }
+     }
+ 
+     return value;
+   }
+ 
+   private CollectionValue fromCollection(final Iterator<JsonNode> nodeItor, final EdmTypeInfo typeInfo) {
+     final CollectionValueImpl value = new CollectionValueImpl();
+ 
+     final EdmTypeInfo type = typeInfo == null
+             ? null
+             : new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
+ 
+     while (nodeItor.hasNext()) {
+       final JsonNode child = nodeItor.next();
+ 
+       if (child.isValueNode()) {
+         value.get().add(fromPrimitive(child, type));
+       } else if (child.isContainerNode()) {
+         if (child.has(Constants.JSON_TYPE)) {
+           ((ObjectNode) child).remove(Constants.JSON_TYPE);
+         }
+         value.get().add(fromComplex(child));
+       }
+     }
+ 
+     return value;
+   }
+ 
+   protected void value(final JSONPropertyImpl property, final JsonNode node) {
+     final EdmTypeInfo typeInfo = StringUtils.isBlank(property.getType())
+             ? null
+             : new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
+ 
+     final ODataPropertyType propType = typeInfo == null
+             ? guessPropertyType(node)
+             : typeInfo.isCollection()
+             ? ODataPropertyType.COLLECTION
+             : typeInfo.isPrimitiveType()
+             ? ODataPropertyType.PRIMITIVE
+             : ODataPropertyType.COMPLEX;
+ 
+     switch (propType) {
+       case COLLECTION:
+         property.setValue(fromCollection(node.elements(), typeInfo));
+         break;
+ 
+       case COMPLEX:
+         if (node.has(Constants.JSON_TYPE)) {
+           property.setType(node.get(Constants.JSON_TYPE).asText());
+           ((ObjectNode) node).remove(Constants.JSON_TYPE);
+         }
+         property.setValue(fromComplex(node));
+         break;
+ 
+       case PRIMITIVE:
+         if (property.getType() == null) {
+           property.setType(getPrimitiveType(node).getFullQualifiedName().toString());
+         }
+         property.setValue(fromPrimitive(node, typeInfo));
+         break;
+ 
+       case EMPTY:
+       default:
+         property.setValue(new PrimitiveValueImpl(StringUtils.EMPTY));
+     }
+   }
 -
+ }


[6/8] [OLINGO-205, OLINGO-200, OLINGO-65] merge

Posted by fm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
index 0000000,f42fe00..b8775d5
mode 000000,100644..100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
@@@ -1,0 -1,370 +1,368 @@@
+ /*
+  * 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.commons.core.data;
+ 
+ import java.io.InputStream;
+ import java.net.URI;
+ import java.text.ParseException;
+ import javax.xml.namespace.QName;
+ import javax.xml.stream.XMLEventReader;
+ import javax.xml.stream.XMLInputFactory;
+ import javax.xml.stream.XMLStreamException;
+ import javax.xml.stream.events.Attribute;
+ import javax.xml.stream.events.StartElement;
+ import javax.xml.stream.events.XMLEvent;
+ import org.apache.olingo.commons.api.Constants;
+ import org.apache.olingo.commons.api.domain.ODataOperation;
+ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+ import org.apache.olingo.commons.api.format.ContentType;
+ import org.apache.olingo.commons.core.data.v3.XMLLinkCollectionImpl;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ 
+ public class AtomDeserializer extends AbstractAtomDealer {
+ 
+   private static final Logger LOG = LoggerFactory.getLogger(AtomDeserializer.class);
+ 
+   private static final XMLInputFactory FACTORY = XMLInputFactory.newInstance();
+ 
+   private final AtomPropertyDeserializer propDeserializer;
+ 
+   public AtomDeserializer(final ODataServiceVersion version) {
+     super(version);
+     this.propDeserializer = new AtomPropertyDeserializer(version);
+   }
+ 
+   private AtomPropertyImpl property(final InputStream input) throws XMLStreamException {
+     final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+     return propDeserializer.deserialize(reader, skipBeforeFirstStartElement(reader));
+   }
+ 
+   private StartElement skipBeforeFirstStartElement(final XMLEventReader reader) throws XMLStreamException {
+     StartElement startEvent = null;
+     while (reader.hasNext() && startEvent == null) {
+       final XMLEvent event = reader.nextEvent();
+       if (event.isStartElement()) {
+         startEvent = event.asStartElement();
+       }
+     }
+     if (startEvent == null) {
+       throw new IllegalArgumentException("Cannot find any XML start element");
+     }
+ 
+     return startEvent;
+   }
+ 
+   private void common(final XMLEventReader reader, final StartElement start,
+           final AbstractAtomObject object, final String key) throws XMLStreamException {
+ 
+     boolean foundEndElement = false;
+     while (reader.hasNext() && !foundEndElement) {
+       final XMLEvent event = reader.nextEvent();
+ 
+       if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+         try {
+           object.setCommonProperty(key, event.asCharacters().getData());
+         } catch (ParseException e) {
+           throw new XMLStreamException("While parsing Atom entry or feed common elements", e);
+         }
+       }
+ 
+       if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+         foundEndElement = true;
+       }
+     }
+   }
+ 
+   private void inline(final XMLEventReader reader, final StartElement start, final LinkImpl link)
+           throws XMLStreamException {
+ 
+     boolean foundEndElement = false;
+     while (reader.hasNext() && !foundEndElement) {
+       final XMLEvent event = reader.nextEvent();
+ 
+       if (event.isStartElement() && inlineQName.equals(event.asStartElement().getName())) {
+         StartElement inline = null;
+         while (reader.hasNext() && inline == null) {
+           final XMLEvent innerEvent = reader.peek();
+           if (innerEvent.isCharacters() && innerEvent.asCharacters().isWhiteSpace()) {
+             reader.nextEvent();
+           } else if (innerEvent.isStartElement()) {
+             inline = innerEvent.asStartElement();
+           }
+         }
+         if (inline != null) {
+           if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(inline.getName())) {
+             link.setInlineEntry(entry(reader, inline));
+           }
+           if (Constants.QNAME_ATOM_ELEM_FEED.equals(inline.getName())) {
+             link.setInlineFeed(feed(reader, inline));
+           }
+         }
+       }
+ 
+       if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+         foundEndElement = true;
+       }
+     }
+   }
+ 
+   private XMLLinkCollectionImpl linkCollection(final InputStream input) throws XMLStreamException {
+     final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+ 
+     final XMLLinkCollectionImpl linkCollection = new XMLLinkCollectionImpl();
+ 
+     boolean isURI = false;
+     boolean isNext = false;
+     while (reader.hasNext()) {
+       final XMLEvent event = reader.nextEvent();
+       if (event.isStartElement()) {
+         isURI = uriQName.equals(event.asStartElement().getName());
+         isNext = nextQName.equals(event.asStartElement().getName());
+       }
+ 
+       if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+         if (isURI) {
+           linkCollection.getLinks().add(URI.create(event.asCharacters().getData()));
+           isURI = false;
+         } else if (isNext) {
+           linkCollection.setNext(URI.create(event.asCharacters().getData()));
+           isNext = false;
+         }
+       }
+     }
+ 
+     return linkCollection;
+   }
+ 
+   private void properties(final XMLEventReader reader, final StartElement start, final AtomEntryImpl entry)
+           throws XMLStreamException {
 -
+     boolean foundEndProperties = false;
+     while (reader.hasNext() && !foundEndProperties) {
+       final XMLEvent event = reader.nextEvent();
+ 
+       if (event.isStartElement()) {
+         entry.getProperties().add(propDeserializer.deserialize(reader, event.asStartElement()));
+       }
+ 
+       if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+         foundEndProperties = true;
+       }
+     }
+   }
+ 
+   private AtomEntryImpl entry(final XMLEventReader reader, final StartElement start) throws XMLStreamException {
+     if (!Constants.QNAME_ATOM_ELEM_ENTRY.equals(start.getName())) {
+       return null;
+     }
+ 
+     final AtomEntryImpl entry = new AtomEntryImpl();
+     final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE);
+     if (xmlBase != null) {
+       entry.setBaseURI(xmlBase.getValue());
+     }
+     final Attribute etag = start.getAttributeByName(etagQName);
+     if (etag != null) {
+       entry.setETag(etag.getValue());
+     }
+ 
+     boolean foundEndEntry = false;
+     while (reader.hasNext() && !foundEndEntry) {
+       final XMLEvent event = reader.nextEvent();
+ 
+       if (event.isStartElement()) {
+         if (Constants.QNAME_ATOM_ELEM_ID.equals(event.asStartElement().getName())) {
+           common(reader, event.asStartElement(), entry, "id");
+         } else if (Constants.QNAME_ATOM_ELEM_TITLE.equals(event.asStartElement().getName())) {
+           common(reader, event.asStartElement(), entry, "title");
+         } else if (Constants.QNAME_ATOM_ELEM_SUMMARY.equals(event.asStartElement().getName())) {
+           common(reader, event.asStartElement(), entry, "summary");
+         } else if (Constants.QNAME_ATOM_ELEM_UPDATED.equals(event.asStartElement().getName())) {
+           common(reader, event.asStartElement(), entry, "updated");
+         } else if (Constants.QNAME_ATOM_ELEM_CATEGORY.equals(event.asStartElement().getName())) {
+           final Attribute term = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_TERM));
+           if (term != null) {
+             entry.setType(term.getValue());
+           }
+         } else if (Constants.QNAME_ATOM_ELEM_LINK.equals(event.asStartElement().getName())) {
+           final LinkImpl link = new LinkImpl();
+           final Attribute rel = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_REL));
+           if (rel != null) {
+             link.setRel(rel.getValue());
+           }
+           final Attribute title = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TITLE));
+           if (title != null) {
+             link.setTitle(title.getValue());
+           }
+           final Attribute href = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_HREF));
+           if (href != null) {
+             link.setHref(href.getValue());
+           }
+           final Attribute type = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
+           if (type != null) {
+             link.setType(type.getValue());
+           }
+ 
+           if (Constants.SELF_LINK_REL.equals(link.getRel())) {
+             entry.setSelfLink(link);
+           } else if (Constants.EDIT_LINK_REL.equals(link.getRel())) {
+             entry.setEditLink(link);
+           } else if (link.getRel().startsWith(version.getNamespaceMap().get(ODataServiceVersion.NAVIGATION_LINK_REL))) {
+             entry.getNavigationLinks().add(link);
+             inline(reader, event.asStartElement(), link);
+           } else if (link.getRel().startsWith(
+                   version.getNamespaceMap().get(ODataServiceVersion.ASSOCIATION_LINK_REL))) {
+ 
+             entry.getAssociationLinks().add(link);
+           } else if (link.getRel().startsWith(
+                   version.getNamespaceMap().get(ODataServiceVersion.MEDIA_EDIT_LINK_REL))) {
+ 
+             final Attribute metag = event.asStartElement().getAttributeByName(etagQName);
+             if (metag != null) {
+               link.setMediaETag(metag.getValue());
+             }
+             entry.getMediaEditLinks().add(link);
+           }
+         } else if (actionQName.equals(event.asStartElement().getName())) {
+           final ODataOperation operation = new ODataOperation();
+           final Attribute metadata = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_METADATA));
+           if (metadata != null) {
+             operation.setMetadataAnchor(metadata.getValue());
+           }
+           final Attribute title = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TITLE));
+           if (title != null) {
+             operation.setTitle(title.getValue());
+           }
+           final Attribute target = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TARGET));
+           if (target != null) {
+             operation.setTarget(URI.create(target.getValue()));
+           }
+ 
+           entry.getOperations().add(operation);
+         } else if (Constants.QNAME_ATOM_ELEM_CONTENT.equals(event.asStartElement().getName())) {
+           final Attribute type = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
+           if (type == null || ContentType.APPLICATION_XML.equals(type.getValue())) {
+             properties(reader, skipBeforeFirstStartElement(reader), entry);
+           } else {
+             entry.setMediaContentType(type.getValue());
+             final Attribute src = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_SRC));
+             if (src != null) {
+               entry.setMediaContentSource(src.getValue());
+             }
+           }
+         } else if (propertiesQName.equals(event.asStartElement().getName())) {
+           properties(reader, event.asStartElement(), entry);
+         }
+       }
+ 
+       if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+         foundEndEntry = true;
+       }
+     }
+ 
+     return entry;
+   }
+ 
+   private AtomEntryImpl entry(final InputStream input) throws XMLStreamException {
+     final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+     return entry(reader, skipBeforeFirstStartElement(reader));
+   }
+ 
+   private void count(final XMLEventReader reader, final StartElement start, final AtomFeedImpl feed)
+           throws XMLStreamException {
+ 
+     boolean foundEndElement = false;
+     while (reader.hasNext() && !foundEndElement) {
+       final XMLEvent event = reader.nextEvent();
+ 
+       if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+         feed.setCount(Integer.valueOf(event.asCharacters().getData()));
+       }
+ 
+       if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+         foundEndElement = true;
+       }
+     }
+   }
+ 
+   private AtomFeedImpl feed(final XMLEventReader reader, final StartElement start) throws XMLStreamException {
+     if (!Constants.QNAME_ATOM_ELEM_FEED.equals(start.getName())) {
+       return null;
+     }
+ 
+     final AtomFeedImpl feed = new AtomFeedImpl();
+     final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE);
+     if (xmlBase != null) {
+       feed.setBaseURI(xmlBase.getValue());
+     }
+ 
+     boolean foundEndFeed = false;
+     while (reader.hasNext() && !foundEndFeed) {
+       final XMLEvent event = reader.nextEvent();
 -
+       if (event.isStartElement()) {
+         if (countQName.equals(event.asStartElement().getName())) {
+           count(reader, event.asStartElement(), feed);
+         } else if (Constants.QNAME_ATOM_ELEM_ID.equals(event.asStartElement().getName())) {
+           common(reader, event.asStartElement(), feed, "id");
+         } else if (Constants.QNAME_ATOM_ELEM_TITLE.equals(event.asStartElement().getName())) {
+           common(reader, event.asStartElement(), feed, "title");
+         } else if (Constants.QNAME_ATOM_ELEM_SUMMARY.equals(event.asStartElement().getName())) {
+           common(reader, event.asStartElement(), feed, "summary");
+         } else if (Constants.QNAME_ATOM_ELEM_UPDATED.equals(event.asStartElement().getName())) {
+           common(reader, event.asStartElement(), feed, "updated");
+         } else if (Constants.QNAME_ATOM_ELEM_LINK.equals(event.asStartElement().getName())) {
+           final Attribute rel = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_REL));
+           if (rel != null && Constants.NEXT_LINK_REL.equals(rel.getValue())) {
+             final Attribute href = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_HREF));
+             if (href != null) {
+               feed.setNext(URI.create(href.getValue()));
+             }
+           }
+         } else if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(event.asStartElement().getName())) {
+           feed.getEntries().add(entry(reader, event.asStartElement()));
+         }
+       }
+ 
+       if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+         foundEndFeed = true;
+       }
+     }
+ 
+     return feed;
+   }
+ 
+   private AtomFeedImpl feed(final InputStream input) throws XMLStreamException {
+     final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+     return feed(reader, skipBeforeFirstStartElement(reader));
+   }
+ 
+   @SuppressWarnings("unchecked")
+   public <T> T read(final InputStream input, final Class<T> reference) throws XMLStreamException {
+     if (AtomFeedImpl.class.equals(reference)) {
+       return (T) feed(input);
+     } else if (AtomEntryImpl.class.equals(reference)) {
+       return (T) entry(input);
+     } else if (AtomPropertyImpl.class.equals(reference)) {
+       return (T) property(input);
+     } else if (XMLLinkCollectionImpl.class.equals(reference)) {
+       return (T) linkCollection(input);
+     }
+     return null;
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomPropertyDeserializer.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomPropertyDeserializer.java
index 0000000,99231b4..91ad49a
mode 000000,100644..100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomPropertyDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomPropertyDeserializer.java
@@@ -1,0 -1,214 +1,218 @@@
+ /*
+  * 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.commons.core.data;
+ 
+ import javax.xml.stream.XMLEventReader;
+ import javax.xml.stream.XMLStreamException;
+ import javax.xml.stream.events.Attribute;
+ import javax.xml.stream.events.StartElement;
+ import javax.xml.stream.events.XMLEvent;
+ import org.apache.commons.lang3.StringUtils;
+ import org.apache.olingo.commons.api.Constants;
+ import org.apache.olingo.commons.api.data.CollectionValue;
+ import org.apache.olingo.commons.api.data.ComplexValue;
+ import org.apache.olingo.commons.api.data.Value;
+ import org.apache.olingo.commons.api.domain.ODataPropertyType;
+ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+ import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+ 
+ class AtomPropertyDeserializer extends AbstractAtomDealer {
+ 
+   private final AtomGeoValueDeserializer geoDeserializer;
+ 
+   public AtomPropertyDeserializer(final ODataServiceVersion version) {
+     super(version);
+     this.geoDeserializer = new AtomGeoValueDeserializer();
+   }
+ 
+   private Value fromPrimitive(final XMLEventReader reader, final StartElement start,
+           final EdmTypeInfo typeInfo) throws XMLStreamException {
+ 
+     Value value = null;
+ 
+     boolean foundEndProperty = false;
+     while (reader.hasNext() && !foundEndProperty) {
+       final XMLEvent event = reader.nextEvent();
+ 
+       if (event.isStartElement() && typeInfo != null && typeInfo.getPrimitiveTypeKind().isGeospatial()) {
+         final EdmPrimitiveTypeKind geoType = EdmPrimitiveTypeKind.valueOfFQN(
+                 version, typeInfo.getFullQualifiedName().toString());
+         value = new GeospatialValueImpl(this.geoDeserializer.deserialize(reader, event.asStartElement(), geoType));
+       }
+ 
+       if (event.isCharacters() && !event.asCharacters().isWhiteSpace()
+               && (typeInfo == null || !typeInfo.getPrimitiveTypeKind().isGeospatial())) {
+ 
+         value = new PrimitiveValueImpl(event.asCharacters().getData());
+       }
+ 
+       if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+         foundEndProperty = true;
+       }
+     }
+ 
+     return value;
+   }
+ 
+   private ComplexValue fromComplex(final XMLEventReader reader, final StartElement start)
+           throws XMLStreamException {
+ 
+     final ComplexValue value = new ComplexValueImpl();
+ 
+     boolean foundEndProperty = false;
+     while (reader.hasNext() && !foundEndProperty) {
+       final XMLEvent event = reader.nextEvent();
+ 
+       if (event.isStartElement()) {
+         value.get().add(deserialize(reader, event.asStartElement()));
+       }
+ 
+       if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+         foundEndProperty = true;
+       }
+     }
+ 
+     return value;
+   }
+ 
+   private CollectionValue fromCollection(final XMLEventReader reader, final StartElement start,
+           final EdmTypeInfo typeInfo) throws XMLStreamException {
+ 
+     final CollectionValueImpl value = new CollectionValueImpl();
+ 
+     final EdmTypeInfo type = typeInfo == null
+             ? null
+             : new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
+ 
+     boolean foundEndProperty = false;
+     while (reader.hasNext() && !foundEndProperty) {
+       final XMLEvent event = reader.nextEvent();
+ 
+       if (event.isStartElement()) {
+         switch (guessPropertyType(reader)) {
+           case COMPLEX:
+             value.get().add(fromComplex(reader, event.asStartElement()));
+             break;
+ 
+           case PRIMITIVE:
+             value.get().add(fromPrimitive(reader, event.asStartElement(), type));
+             break;
+ 
+           default:
+           // do not add null or empty values
+         }
+       }
+ 
+       if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+         foundEndProperty = true;
+       }
+     }
+ 
+     return value;
+   }
+ 
+   private ODataPropertyType guessPropertyType(final XMLEventReader reader) throws XMLStreamException {
+     XMLEvent child = null;
+     while (reader.hasNext() && child == null) {
+       final XMLEvent event = reader.peek();
+       if (event.isCharacters() && event.asCharacters().isWhiteSpace()) {
+         reader.nextEvent();
+       } else {
+         child = event;
+       }
+     }
+ 
 -    ODataPropertyType type = null;
++    final ODataPropertyType type;
+     if (child == null) {
+       type = ODataPropertyType.PRIMITIVE;
+     } else {
+       if (child.isStartElement()) {
+         if (Constants.NS_GML.equals(child.asStartElement().getName().getNamespaceURI())) {
+           type = ODataPropertyType.PRIMITIVE;
+         } else if (elementQName.equals(child.asStartElement().getName())) {
+           type = ODataPropertyType.COLLECTION;
+         } else {
+           type = ODataPropertyType.COMPLEX;
+         }
+       } else if (child.isCharacters()) {
+         type = ODataPropertyType.PRIMITIVE;
+       } else {
+         type = ODataPropertyType.EMPTY;
+       }
+     }
+ 
+     return type;
+   }
+ 
+   public AtomPropertyImpl deserialize(final XMLEventReader reader, final StartElement start)
+           throws XMLStreamException {
+ 
+     final AtomPropertyImpl property = new AtomPropertyImpl();
+     property.setName(start.getName().getLocalPart());
+ 
+     final Attribute typeAttr = start.getAttributeByName(this.typeQName);
 -    if (typeAttr != null) {
 -      property.setType(typeAttr.getValue());
 -    }
+ 
+     Value value;
+     final Attribute nullAttr = start.getAttributeByName(this.nullQName);
++    final String typeAttrValue = typeAttr == null ? null : typeAttr.getValue();
++
+     if (nullAttr == null) {
 -      final EdmTypeInfo typeInfo = StringUtils.isBlank(property.getType())
++      final EdmTypeInfo typeInfo = StringUtils.isBlank(typeAttrValue)
+               ? null
 -              : new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
++              : new EdmTypeInfo.Builder().setTypeExpression(typeAttrValue).build();
++
++      if (typeInfo != null) {
++        property.setType(typeInfo.getTypeExpression());
++      }
+ 
+       final ODataPropertyType propType = typeInfo == null
+               ? guessPropertyType(reader)
+               : typeInfo.isCollection()
+               ? ODataPropertyType.COLLECTION
+               : typeInfo.isPrimitiveType()
+               ? ODataPropertyType.PRIMITIVE
+               : ODataPropertyType.COMPLEX;
+ 
+       switch (propType) {
+         case COLLECTION:
+           value = fromCollection(reader, start, typeInfo);
+           break;
+ 
+         case COMPLEX:
+           value = fromComplex(reader, start);
+           break;
+ 
+         case PRIMITIVE:
+           value = fromPrimitive(reader, start, typeInfo);
+           break;
+ 
+         case EMPTY:
+         default:
+           value = new PrimitiveValueImpl(StringUtils.EMPTY);
+       }
+     } else {
+       value = new NullValueImpl();
+     }
++
+     property.setValue(value);
+ 
+     return property;
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONGeoValueDeserializer.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONGeoValueDeserializer.java
index 0000000,f1863a7..c544f73
mode 000000,100644..100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONGeoValueDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONGeoValueDeserializer.java
@@@ -1,0 -1,274 +1,273 @@@
+ /*
+  * 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.commons.core.data;
+ 
+ import com.fasterxml.jackson.databind.JsonNode;
+ import java.util.ArrayList;
+ import java.util.Collections;
+ import java.util.Iterator;
+ import java.util.List;
+ import org.apache.olingo.commons.api.Constants;
+ import org.apache.olingo.commons.api.data.GeoUtils;
+ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+ 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 org.apache.olingo.commons.core.edm.EdmTypeInfo;
+ import org.apache.olingo.commons.core.edm.primitivetype.EdmDouble;
+ 
+ class JSONGeoValueDeserializer {
+ 
+   private final ODataServiceVersion version;
+ 
+   public JSONGeoValueDeserializer(final ODataServiceVersion version) {
+     this.version = version;
+   }
+ 
+   private Point point(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type, final String crs) {
+     Point point = null;
+ 
+     if (itor.hasNext()) {
+       point = new Point(GeoUtils.getDimension(type), crs);
+       try {
+         point.setX(EdmDouble.getInstance().valueOfString(itor.next().asText(), null, null,
+                 Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null, Double.class));
+         point.setY(EdmDouble.getInstance().valueOfString(itor.next().asText(), null, null,
+                 Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null, Double.class));
+       } catch (EdmPrimitiveTypeException e) {
+         throw new IllegalArgumentException("While deserializing point coordinates as double", e);
+       }
+     }
+ 
+     return point;
+   }
+ 
+   private MultiPoint multipoint(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
+           final String crs) {
+ 
 -    MultiPoint multiPoint = null;
++    final MultiPoint multiPoint;
+ 
+     if (itor.hasNext()) {
+       final List<Point> points = new ArrayList<Point>();
+       while (itor.hasNext()) {
+         final Iterator<JsonNode> mpItor = itor.next().elements();
+         points.add(point(mpItor, type, crs));
+       }
+       multiPoint = new MultiPoint(GeoUtils.getDimension(type), crs, points);
+     } else {
+       multiPoint = new MultiPoint(GeoUtils.getDimension(type), crs, Collections.<Point>emptyList());
+     }
+ 
+     return multiPoint;
+   }
+ 
+   private LineString lineString(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
+           final String crs) {
+ 
 -    LineString lineString = null;
++    final LineString lineString;
+ 
+     if (itor.hasNext()) {
+       final List<Point> points = new ArrayList<Point>();
+       while (itor.hasNext()) {
+         final Iterator<JsonNode> mpItor = itor.next().elements();
+         points.add(point(mpItor, type, crs));
+       }
+       lineString = new LineString(GeoUtils.getDimension(type), crs, points);
+     } else {
+       lineString = new LineString(GeoUtils.getDimension(type), crs, Collections.<Point>emptyList());
+     }
+ 
+     return lineString;
+   }
+ 
+   private MultiLineString multiLineString(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
+           final String crs) {
+ 
 -    MultiLineString multiLineString = null;
++    final MultiLineString multiLineString;
+ 
+     if (itor.hasNext()) {
+       final List<LineString> lineStrings = new ArrayList<LineString>();
+       while (itor.hasNext()) {
+         final Iterator<JsonNode> mlsItor = itor.next().elements();
+         lineStrings.add(lineString(mlsItor, type, crs));
+       }
+       multiLineString = new MultiLineString(GeoUtils.getDimension(type), crs, lineStrings);
+     } else {
+       multiLineString = new MultiLineString(GeoUtils.getDimension(type), crs, Collections.<LineString>emptyList());
+     }
+ 
+     return multiLineString;
+   }
+ 
+   private Polygon polygon(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
+           final String crs) {
+ 
+     List<Point> extPoints = null;
+     if (itor.hasNext()) {
+       final Iterator<JsonNode> extItor = itor.next().elements();
+       if (extItor.hasNext()) {
+         extPoints = new ArrayList<Point>();
+         while (extItor.hasNext()) {
+           final Iterator<JsonNode> mpItor = extItor.next().elements();
+           extPoints.add(point(mpItor, type, crs));
+         }
+       }
+     }
+ 
+     List<Point> intPoints = null;
+     if (itor.hasNext()) {
+       final Iterator<JsonNode> intItor = itor.next().elements();
+       if (intItor.hasNext()) {
+         intPoints = new ArrayList<Point>();
+         while (intItor.hasNext()) {
+           final Iterator<JsonNode> mpItor = intItor.next().elements();
+           intPoints.add(point(mpItor, type, crs));
+         }
+       }
+     }
+ 
+     return new Polygon(GeoUtils.getDimension(type), crs, intPoints, extPoints);
+   }
+ 
+   private MultiPolygon multiPolygon(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
+           final String crs) {
+ 
 -    MultiPolygon multiPolygon = null;
++    final MultiPolygon multiPolygon;
+ 
+     if (itor.hasNext()) {
+       final List<Polygon> polygons = new ArrayList<Polygon>();
+       while (itor.hasNext()) {
+         final Iterator<JsonNode> mpItor = itor.next().elements();
+         polygons.add(polygon(mpItor, type, crs));
+       }
+       multiPolygon = new MultiPolygon(GeoUtils.getDimension(type), crs, polygons);
+     } else {
+       multiPolygon = new MultiPolygon(GeoUtils.getDimension(type), crs, Collections.<Polygon>emptyList());
+     }
+ 
+     return multiPolygon;
+   }
+ 
+   private GeospatialCollection collection(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
+           final String crs) {
+ 
 -    GeospatialCollection collection = null;
++    final GeospatialCollection collection;
+ 
+     if (itor.hasNext()) {
+       final List<Geospatial> geospatials = new ArrayList<Geospatial>();
+ 
+       while (itor.hasNext()) {
+         final JsonNode geo = itor.next();
+         final String collItemType = geo.get(Constants.ATTR_TYPE).asText();
+         final String callAsType;
+         if (EdmPrimitiveTypeKind.GeographyCollection.name().equals(collItemType)
+                 || EdmPrimitiveTypeKind.GeometryCollection.name().equals(collItemType)) {
+ 
+           callAsType = collItemType;
+         } else {
+           callAsType = (type == EdmPrimitiveTypeKind.GeographyCollection ? "Geography" : "Geometry")
+                   + collItemType;
+         }
+ 
+         geospatials.add(deserialize(geo, new EdmTypeInfo.Builder().setTypeExpression(callAsType).build()));
+       }
+ 
+       collection = new GeospatialCollection(GeoUtils.getDimension(type), crs, geospatials);
+     } else {
+       collection = new GeospatialCollection(GeoUtils.getDimension(type), crs, Collections.<Geospatial>emptyList());
+     }
+ 
+     return collection;
+   }
+ 
+   public Geospatial deserialize(final JsonNode node, final EdmTypeInfo typeInfo) {
+     final EdmPrimitiveTypeKind actualType;
+     if ((typeInfo.getPrimitiveTypeKind() == EdmPrimitiveTypeKind.Geography
+             || typeInfo.getPrimitiveTypeKind() == EdmPrimitiveTypeKind.Geometry)
+             && node.has(Constants.ATTR_TYPE)) {
+ 
+       String nodeType = node.get(Constants.ATTR_TYPE).asText();
+       if (nodeType.startsWith("Geo")) {
+         final int yIdx = nodeType.indexOf('y');
+         nodeType = nodeType.substring(yIdx + 1);
+       }
+       actualType = EdmPrimitiveTypeKind.valueOfFQN(version, typeInfo.getFullQualifiedName().toString() + nodeType);
+     } else {
+       actualType = typeInfo.getPrimitiveTypeKind();
+     }
+ 
+     final Iterator<JsonNode> cooItor = node.has(Constants.JSON_COORDINATES)
+             ? node.get(Constants.JSON_COORDINATES).elements()
+             : Collections.<JsonNode>emptyList().iterator();
+ 
+     String crs = null;
+     if (node.has(Constants.JSON_CRS)) {
+       crs = node.get(Constants.JSON_CRS).get(Constants.PROPERTIES).get(Constants.JSON_NAME).asText().split(":")[1];
+     }
+ 
+     Geospatial value = null;
+     switch (actualType) {
+       case GeographyPoint:
+       case GeometryPoint:
+         value = point(cooItor, actualType, crs);
+         break;
+ 
+       case GeographyMultiPoint:
+       case GeometryMultiPoint:
+         value = multipoint(cooItor, actualType, crs);
+         break;
+ 
+       case GeographyLineString:
+       case GeometryLineString:
+         value = lineString(cooItor, actualType, crs);
+         break;
+ 
+       case GeographyMultiLineString:
+       case GeometryMultiLineString:
+         value = multiLineString(cooItor, actualType, crs);
+         break;
+ 
+       case GeographyPolygon:
+       case GeometryPolygon:
+         value = polygon(cooItor, actualType, crs);
+         break;
+ 
+       case GeographyMultiPolygon:
+       case GeometryMultiPolygon:
+         value = multiPolygon(cooItor, actualType, crs);
+         break;
+ 
+       case GeographyCollection:
+       case GeometryCollection:
+         value = collection(node.get(Constants.JSON_GEOMETRIES).elements(), actualType, crs);
+         break;
+ 
+       default:
+     }
+ 
+     return value;
+   }
 -
+ }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java
index 0000000,567950d..09e70cb
mode 000000,100644..100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java
@@@ -1,0 -1,172 +1,184 @@@
+ /*
+  * 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.commons.core.edm;
+ 
+ import org.apache.commons.lang3.StringUtils;
+ import org.apache.olingo.commons.api.edm.Edm;
+ import org.apache.olingo.commons.api.edm.EdmComplexType;
+ import org.apache.olingo.commons.api.edm.EdmEntityType;
+ import org.apache.olingo.commons.api.edm.EdmEnumType;
++import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+ import org.apache.olingo.commons.api.edm.FullQualifiedName;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ 
+ public class EdmTypeInfo {
+ 
+   private static final Logger LOG = LoggerFactory.getLogger(EdmTypeInfo.class);
+ 
+   public static class Builder {
+ 
+     private String typeExpression;
+ 
+     private String defaultNamespace;
+ 
+     private Edm edm;
+ 
+     public Builder setTypeExpression(final String typeExpression) {
+       this.typeExpression = typeExpression;
+       return this;
+     }
+ 
+     public Builder setDefaultNamespace(final String defaultNamespace) {
+       this.defaultNamespace = defaultNamespace;
+       return this;
+     }
+ 
+     public Builder setEdm(final Edm edm) {
+       this.edm = edm;
+       return this;
+     }
+ 
+     public EdmTypeInfo build() {
 -      return new EdmTypeInfo(edm, typeExpression.indexOf('.') == -1
++      return new EdmTypeInfo(edm, typeExpression.indexOf('.') == -1 && StringUtils.isNotBlank(defaultNamespace)
+               ? defaultNamespace + "." + typeExpression
+               : typeExpression);
+     }
+   }
 -
+   private final Edm edm;
+ 
+   private final String typeExpression;
+ 
+   private final boolean collection;
+ 
+   private final FullQualifiedName fullQualifiedName;
+ 
+   private EdmPrimitiveTypeKind primitiveType;
+ 
+   private EdmEnumType enumType;
+ 
+   private EdmComplexType complexType;
+ 
+   private EdmEntityType entityType;
+ 
+   private EdmTypeInfo(final Edm edm, final String typeExpression) {
+     this.edm = edm;
 -    this.typeExpression = typeExpression;
+ 
+     String baseType;
+     final int collStartIdx = typeExpression.indexOf("Collection(");
+     final int collEndIdx = typeExpression.lastIndexOf(')');
+     if (collStartIdx == -1) {
+       baseType = typeExpression;
+       this.collection = false;
+     } else {
+       if (collEndIdx == -1) {
+         throw new IllegalArgumentException("Malformed type: " + typeExpression);
+       }
+ 
+       this.collection = true;
+       baseType = typeExpression.substring(collStartIdx + 11, collEndIdx);
+     }
+ 
++
++    baseType = baseType.replaceAll("^#", "");
++
++    final String typeName;
++    final String namespace;
++
+     final int lastDotIdx = baseType.lastIndexOf('.');
+     if (lastDotIdx == -1) {
 -      throw new IllegalArgumentException("Cannot find namespace or alias in " + typeExpression);
++      namespace = EdmPrimitiveType.EDM_NAMESPACE;
++      typeName = baseType;
++      baseType = new FullQualifiedName(EdmPrimitiveType.EDM_NAMESPACE, baseType).toString();
++    } else {
++      namespace = baseType.substring(0, lastDotIdx);
++      typeName = baseType.substring(lastDotIdx + 1);
+     }
 -    final String namespace = baseType.substring(0, lastDotIdx);
 -    final String typeName = baseType.substring(lastDotIdx + 1);
++
+     if (StringUtils.isBlank(typeName)) {
+       throw new IllegalArgumentException("Null or empty type name in " + typeExpression);
+     }
+ 
++    final StringBuilder exp = new StringBuilder();
++    exp.append(baseType);
++
++    this.typeExpression = (this.collection ? exp.insert(0, "Collection(").append(")") : exp).toString();
+     this.fullQualifiedName = new FullQualifiedName(namespace, typeName);
+ 
+     try {
+       this.primitiveType = EdmPrimitiveTypeKind.valueOf(this.fullQualifiedName.getName());
+     } catch (IllegalArgumentException e) {
+       LOG.debug("{} does not appear to refer to an Edm primitive type", this.fullQualifiedName);
+     }
+     if (this.primitiveType == null && this.edm != null) {
+       this.enumType = this.edm.getEnumType(this.fullQualifiedName);
+       if (this.enumType == null) {
+         this.complexType = this.edm.getComplexType(this.fullQualifiedName);
+         if (this.complexType == null) {
+           this.entityType = this.edm.getEntityType(this.fullQualifiedName);
+         }
+       }
+     }
+   }
+ 
+   public String getTypeExpression() {
+     return typeExpression;
+   }
+ 
+   public boolean isCollection() {
+     return collection;
+   }
+ 
+   public FullQualifiedName getFullQualifiedName() {
+     return fullQualifiedName;
+   }
+ 
+   public boolean isPrimitiveType() {
+     return this.primitiveType != null;
+   }
+ 
+   public EdmPrimitiveTypeKind getPrimitiveTypeKind() {
+     return primitiveType;
+   }
+ 
+   public boolean isEnumType() {
+     return this.enumType != null;
+   }
+ 
+   public EdmEnumType getEnumType() {
+     return enumType;
+   }
+ 
+   public boolean isComplexType() {
+     return this.complexType != null;
+   }
+ 
+   public EdmComplexType getComplexType() {
+     return complexType;
+   }
+ 
+   public boolean isEntityType() {
+     return this.entityType != null;
+   }
+ 
+   public EdmEntityType getEntityType() {
+     return entityType;
+   }
 -
+ }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/5b5576f8/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java
index 0000000,94c43da..991e723
mode 000000,100644..100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java
@@@ -1,0 -1,107 +1,106 @@@
+ /*
+  * 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.commons.core.op;
+ 
+ import java.io.InputStream;
+ import org.apache.olingo.commons.api.data.Entry;
+ import org.apache.olingo.commons.api.domain.ODataError;
+ import org.apache.olingo.commons.api.data.Feed;
+ import org.apache.olingo.commons.api.data.Property;
+ import org.apache.olingo.commons.api.format.ODataFormat;
+ import org.apache.olingo.commons.api.format.ODataPubFormat;
+ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+ import org.apache.olingo.commons.api.op.CommonODataDeserializer;
+ import org.apache.olingo.commons.core.data.AtomDeserializer;
+ import org.apache.olingo.commons.core.data.AtomEntryImpl;
+ import org.apache.olingo.commons.core.data.AtomFeedImpl;
+ import org.apache.olingo.commons.core.data.AtomPropertyImpl;
+ import org.apache.olingo.commons.core.data.JSONEntryImpl;
+ import org.apache.olingo.commons.core.data.JSONErrorBundle;
+ import org.apache.olingo.commons.core.data.JSONFeedImpl;
+ import org.apache.olingo.commons.core.data.JSONPropertyImpl;
+ import org.apache.olingo.commons.core.data.XMLErrorImpl;
+ 
+ public abstract class AbstractODataDeserializer extends AbstractJacksonTool implements CommonODataDeserializer {
+ 
+   private static final long serialVersionUID = -4244158979195609909L;
+ 
+   private final AtomDeserializer atomDeserializer;
+ 
+   public AbstractODataDeserializer(final ODataServiceVersion version) {
+     super(version);
+ 
+     this.atomDeserializer = new AtomDeserializer(version);
+   }
+ 
+   @Override
+   public Feed toFeed(final InputStream input, final ODataPubFormat format) {
+     return format == ODataPubFormat.ATOM
+             ? atom(input, AtomFeedImpl.class)
+             : json(input, JSONFeedImpl.class);
+   }
+ 
+   @Override
+   public Entry toEntry(final InputStream input, final ODataPubFormat format) {
+     return format == ODataPubFormat.ATOM
+             ? atom(input, AtomEntryImpl.class)
+             : json(input, JSONEntryImpl.class);
+   }
+ 
+   @Override
+   public Property toProperty(final InputStream input, final ODataFormat format) {
+     return format == ODataFormat.XML
+             ? atom(input, AtomPropertyImpl.class)
+             : json(input, JSONPropertyImpl.class);
+   }
+ 
+   @Override
+   public ODataError toError(final InputStream input, final boolean isXML) {
+     return isXML
+             ? xml(input, XMLErrorImpl.class)
+             : json(input, JSONErrorBundle.class).getError();
+   }
+ 
+   /*
+    * ------------------ Protected methods ------------------
+    */
+   protected <T> T xml(final InputStream input, final Class<T> reference) {
+     try {
+       return getXmlMapper().readValue(input, reference);
+     } catch (Exception e) {
+       throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
+     }
+   }
+ 
+   protected <T> T atom(final InputStream input, final Class<T> reference) {
+     try {
+       return atomDeserializer.read(input, reference);
+     } catch (Exception e) {
+       throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
+     }
+   }
+ 
+   protected <T> T json(final InputStream input, final Class<T> reference) {
+     try {
+       return getObjectMapper().readValue(input, reference);
+     } catch (Exception e) {
+       throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
+     }
+   }
 -
+ }


[4/8] [OLINGO-205, OLINGO-200] provided atom v4 deserialization for entity type/set + entity set request

Posted by fm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
deleted file mode 100644
index 79d2d8f..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
+++ /dev/null
@@ -1,503 +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.fit.utils;
-
-import static org.apache.olingo.fit.utils.Constants.*;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.JsonNodeFactory;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fasterxml.jackson.databind.node.TextNode;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.util.AbstractMap.SimpleEntry;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.ws.rs.NotFoundException;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-
-public class JSONUtilities extends AbstractUtilities {
-
-  public JSONUtilities(final ODataVersion version) throws Exception {
-    super(version);
-  }
-
-  @Override
-  protected Accept getDefaultFormat() {
-    return Accept.JSON_FULLMETA;
-  }
-
-  @Override
-  protected InputStream addLinks(
-          final String entitySetName, final String entitykey, final InputStream is, final Set<String> links)
-          throws Exception {
-    final ObjectMapper mapper = new ObjectMapper();
-    final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
-    IOUtils.closeQuietly(is);
-
-    for (String link : links) {
-      srcNode.set(link + JSON_NAVIGATION_SUFFIX,
-              new TextNode(Commons.getLinksURI(version, entitySetName, entitykey, link)));
-    }
-
-    return IOUtils.toInputStream(srcNode.toString());
-  }
-
-  @Override
-  protected Set<String> retrieveAllLinkNames(InputStream is) throws Exception {
-    final ObjectMapper mapper = new ObjectMapper();
-    final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
-    IOUtils.closeQuietly(is);
-
-    final Set<String> links = new HashSet<String>();
-
-    final Iterator<String> fieldIter = srcNode.fieldNames();
-
-    while (fieldIter.hasNext()) {
-      final String field = fieldIter.next();
-
-      if (field.endsWith(JSON_NAVIGATION_BIND_SUFFIX)
-              || field.endsWith(JSON_NAVIGATION_SUFFIX)
-              || field.endsWith(JSON_MEDIA_SUFFIX)
-              || field.endsWith(JSON_EDITLINK_NAME)) {
-        if (field.indexOf('@') > 0) {
-          links.add(field.substring(0, field.indexOf('@')));
-        } else {
-          links.add(field);
-        }
-      }
-    }
-
-    return links;
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  protected NavigationLinks retrieveNavigationInfo(
-          final String entitySetName, final InputStream is)
-          throws Exception {
-    final ObjectMapper mapper = new ObjectMapper();
-    final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
-    IOUtils.closeQuietly(is);
-
-    final NavigationLinks links = new NavigationLinks();
-
-    final Iterator<Map.Entry<String, JsonNode>> fieldIter = srcNode.fields();
-
-    while (fieldIter.hasNext()) {
-      final Map.Entry<String, JsonNode> field = fieldIter.next();
-      if (field.getKey().endsWith(JSON_NAVIGATION_BIND_SUFFIX)) {
-        final String title = field.getKey().substring(0, field.getKey().indexOf('@'));
-        final List<String> hrefs = new ArrayList<String>();
-        if (field.getValue().isArray()) {
-          for (JsonNode href : ((ArrayNode) field.getValue())) {
-            final String uri = href.asText();
-            hrefs.add(uri.substring(uri.lastIndexOf('/') + 1));
-          }
-        } else {
-          final String uri = field.getValue().asText();
-          hrefs.add(uri.substring(uri.lastIndexOf('/') + 1));
-        }
-
-        links.addLinks(title, hrefs);
-      } else if (Commons.linkInfo.get(version).exists(entitySetName, field.getKey())) {
-        links.addInlines(field.getKey(), IOUtils.toInputStream(field.getValue().toString()));
-      }
-    }
-
-    return links;
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  protected InputStream normalizeLinks(
-          final String entitySetName, final String entityKey, final InputStream is, final NavigationLinks links)
-          throws Exception {
-    final ObjectMapper mapper = new ObjectMapper();
-    final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
-
-    if (links != null) {
-      for (String linkTitle : links.getLinkNames()) {
-        // normalize link
-        srcNode.remove(linkTitle + JSON_NAVIGATION_BIND_SUFFIX);
-        srcNode.set(
-                linkTitle + JSON_NAVIGATION_SUFFIX,
-                new TextNode(String.format("%s(%s)/%s", entitySetName, entityKey, linkTitle)));
-      }
-
-      for (String linkTitle : links.getInlineNames()) {
-        // normalize link if exist; declare a new one if missing
-        srcNode.remove(linkTitle + JSON_NAVIGATION_BIND_SUFFIX);
-        srcNode.set(
-                linkTitle + JSON_NAVIGATION_SUFFIX,
-                new TextNode(String.format("%s(%s)/%s", entitySetName, entityKey, linkTitle)));
-
-        // remove inline
-        srcNode.remove(linkTitle);
-
-        // remove from links
-        links.removeLink(linkTitle);
-      }
-    }
-
-    srcNode.set(
-            JSON_EDITLINK_NAME,
-            new TextNode(Constants.DEFAULT_SERVICE_URL + entitySetName + "(" + entityKey + ")"));
-
-    return IOUtils.toInputStream(srcNode.toString());
-  }
-
-  @Override
-  public InputStream getPropertyValue(final InputStream src, final List<String> path)
-          throws Exception {
-    final ObjectMapper mapper = new ObjectMapper();
-    final JsonNode srcNode = mapper.readTree(src);
-    JsonNode node = getProperty(srcNode, path);
-    return IOUtils.toInputStream(node.asText());
-  }
-
-  @Override
-  public InputStream getProperty(
-          final String entitySetName, final String entityId, final List<String> path, final String edmType)
-          throws Exception {
-
-    final InputStream src =
-            fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) + ENTITY, Accept.JSON_FULLMETA);
-
-    final ObjectMapper mapper = new ObjectMapper();
-    final JsonNode srcNode = mapper.readTree(src);
-
-    final ObjectNode propertyNode = new ObjectNode(JsonNodeFactory.instance);
-
-    if (StringUtils.isNotBlank(edmType)) {
-      propertyNode.put(JSON_ODATAMETADATA_NAME, ODATA_METADATA_PREFIX + edmType);
-    }
-
-    JsonNode jsonNode = getProperty(srcNode, path);
-
-    if (jsonNode.isArray()) {
-      propertyNode.put("value", (ArrayNode) jsonNode);
-    } else if (jsonNode.isObject()) {
-      propertyNode.putAll((ObjectNode) jsonNode);
-    } else {
-      propertyNode.put("value", jsonNode.asText());
-    }
-
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    mapper.writeValue(bos, propertyNode);
-
-    final InputStream res = new ByteArrayInputStream(bos.toByteArray());
-    IOUtils.closeQuietly(bos);
-
-    return res;
-  }
-
-  private JsonNode getProperty(final JsonNode node, final List<String> path)
-          throws NotFoundException {
-
-    JsonNode propertyNode = node;
-    for (int i = 0; i < path.size(); i++) {
-      propertyNode = propertyNode.get(path.get(i));
-      if (propertyNode == null) {
-        throw new NotFoundException();
-      }
-    }
-
-    return propertyNode;
-  }
-
-  public InputStream addJsonInlinecount(
-          final InputStream src, final int count, final Accept accept)
-          throws Exception {
-    final ObjectMapper mapper = new ObjectMapper();
-    final JsonNode srcNode = mapper.readTree(src);
-
-    ((ObjectNode) srcNode).put(ODATA_COUNT_NAME, count);
-
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    mapper.writeValue(bos, srcNode);
-
-    final InputStream res = new ByteArrayInputStream(bos.toByteArray());
-    IOUtils.closeQuietly(bos);
-
-    return res;
-  }
-
-  public InputStream wrapJsonEntities(final InputStream entities) throws Exception {
-    final ObjectMapper mapper = new ObjectMapper();
-    final JsonNode node = mapper.readTree(entities);
-
-    final ObjectNode res;
-
-    final JsonNode value = node.get(JSON_VALUE_NAME);
-
-    if (value.isArray()) {
-      res = mapper.createObjectNode();
-      res.set("value", value);
-      final JsonNode next = node.get(JSON_NEXTLINK_NAME);
-      if (next != null) {
-        res.set(JSON_NEXTLINK_NAME, next);
-      }
-    } else {
-      res = (ObjectNode) value;
-    }
-
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    mapper.writeValue(bos, res);
-
-    final InputStream is = new ByteArrayInputStream(bos.toByteArray());
-    IOUtils.closeQuietly(bos);
-
-    return is;
-  }
-
-  @Override
-  public InputStream selectEntity(final InputStream src, final String[] propertyNames) throws Exception {
-    final ObjectMapper mapper = new ObjectMapper();
-    final ObjectNode srcNode = (ObjectNode) mapper.readTree(src);
-
-    final Set<String> retain = new HashSet<String>();
-    retain.add(JSON_ID_NAME);
-    retain.add(JSON_TYPE_NAME);
-    retain.add(JSON_EDITLINK_NAME);
-    retain.add(JSON_NEXTLINK_NAME);
-    retain.add(JSON_ODATAMETADATA_NAME);
-    retain.add(JSON_VALUE_NAME);
-
-    for (String name : propertyNames) {
-      retain.add(name);
-      retain.add(name + JSON_NAVIGATION_SUFFIX);
-      retain.add(name + JSON_MEDIA_SUFFIX);
-      retain.add(name + JSON_TYPE_SUFFIX);
-    }
-
-    srcNode.retain(retain);
-
-    return IOUtils.toInputStream(srcNode.toString());
-  }
-
-  @Override
-  public InputStream readEntities(
-          final List<String> links, final String linkName, final String next, final boolean forceFeed)
-          throws Exception {
-
-    if (links.isEmpty()) {
-      throw new NotFoundException();
-    }
-
-    final ObjectMapper mapper = new ObjectMapper();
-    final ObjectNode node = mapper.createObjectNode();
-
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
-    if (forceFeed || links.size() > 1) {
-      bos.write("[".getBytes());
-    }
-
-    for (String link : links) {
-      try {
-        final Map.Entry<String, String> uri = Commons.parseEntityURI(link);
-        final Map.Entry<String, InputStream> entity =
-                readEntity(uri.getKey(), uri.getValue(), Accept.JSON_FULLMETA);
-
-        if (bos.size() > 1) {
-          bos.write(",".getBytes());
-        }
-
-        IOUtils.copy(entity.getValue(), bos);
-      } catch (Exception e) {
-        // log and ignore link
-        LOG.warn("Error parsing uri {}", link, e);
-      }
-    }
-
-    if (forceFeed || links.size() > 1) {
-      bos.write("]".getBytes());
-    }
-
-    node.set(JSON_VALUE_NAME, mapper.readTree(new ByteArrayInputStream(bos.toByteArray())));
-
-    if (StringUtils.isNotBlank(next)) {
-      node.set(JSON_NEXTLINK_NAME, new TextNode(next));
-    }
-
-    return IOUtils.toInputStream(node.toString());
-  }
-
-  @Override
-  protected InputStream replaceLink(
-          final InputStream toBeChanged, final String linkName, final InputStream replacement)
-          throws Exception {
-    final ObjectMapper mapper = new ObjectMapper();
-
-    final ObjectNode toBeChangedNode = (ObjectNode) mapper.readTree(toBeChanged);
-    final ObjectNode replacementNode = (ObjectNode) mapper.readTree(replacement);
-
-    if (toBeChangedNode.get(linkName + JSON_NAVIGATION_SUFFIX) == null) {
-      throw new NotFoundException();
-    }
-
-    toBeChangedNode.set(linkName, replacementNode.get(JSON_VALUE_NAME));
-
-    final JsonNode next = replacementNode.get(linkName + JSON_NEXTLINK_NAME);
-    if (next != null) {
-      toBeChangedNode.set(linkName + JSON_NEXTLINK_SUFFIX, next);
-    }
-
-    return IOUtils.toInputStream(toBeChangedNode.toString());
-  }
-
-  @Override
-  protected Map<String, InputStream> getChanges(final InputStream src) throws Exception {
-    final Map<String, InputStream> res = new HashMap<String, InputStream>();
-
-    final ObjectMapper mapper = new ObjectMapper();
-    final JsonNode srcObject = mapper.readTree(src);
-
-    final Iterator<Map.Entry<String, JsonNode>> fields = srcObject.fields();
-    while (fields.hasNext()) {
-      final Map.Entry<String, JsonNode> field = fields.next();
-      res.put(field.getKey(), IOUtils.toInputStream(field.getValue().toString()));
-    }
-
-    return res;
-  }
-
-  @Override
-  protected InputStream setChanges(
-          final InputStream toBeChanged, final Map<String, InputStream> properties) throws Exception {
-
-    final ObjectMapper mapper = new ObjectMapper();
-    final ObjectNode toBeChangedObject = (ObjectNode) mapper.readTree(toBeChanged);
-
-    for (Map.Entry<String, InputStream> property : properties.entrySet()) {
-      final JsonNode propertyNode = mapper.readTree(property.getValue());
-      toBeChangedObject.set(property.getKey(), propertyNode);
-    }
-
-    return IOUtils.toInputStream(toBeChangedObject.toString());
-  }
-
-  @Override
-  public Map.Entry<String, List<String>> extractLinkURIs(
-          final String entitySetName, final String entityId, final String linkName)
-          throws Exception {
-    final LinkInfo links = readLinks(entitySetName, entityId, linkName, Accept.JSON_FULLMETA);
-    return extractLinkURIs(links.getLinks());
-  }
-
-  @Override
-  public Map.Entry<String, List<String>> extractLinkURIs(final InputStream is)
-          throws Exception {
-    final ObjectMapper mapper = new ObjectMapper();
-    final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
-    IOUtils.closeQuietly(is);
-
-    final List<String> links = new ArrayList<String>();
-
-    JsonNode uris = srcNode.get("value");
-    if (uris == null) {
-      final JsonNode url = srcNode.get("url");
-      if (url != null) {
-        links.add(url.textValue());
-      }
-    } else {
-      final Iterator<JsonNode> iter = ((ArrayNode) uris).iterator();
-      while (iter.hasNext()) {
-        links.add(iter.next().get("url").textValue());
-      }
-    }
-
-    final JsonNode next = srcNode.get(JSON_NEXTLINK_NAME);
-
-    return new SimpleEntry<String, List<String>>(next == null ? null : next.asText(), links);
-  }
-
-  @Override
-  public InputStream addEditLink(
-          final InputStream content, final String title, final String href) throws Exception {
-    final ObjectMapper mapper = new ObjectMapper();
-    final ObjectNode srcNode = (ObjectNode) mapper.readTree(content);
-    IOUtils.closeQuietly(content);
-
-    srcNode.set(JSON_EDITLINK_NAME, new TextNode(href));
-    return IOUtils.toInputStream(srcNode.toString());
-  }
-
-  @Override
-  public InputStream replaceProperty(
-          final InputStream src, final InputStream replacement, final List<String> path, final boolean justValue)
-          throws Exception {
-    final ObjectMapper mapper = new ObjectMapper();
-    final ObjectNode srcNode = (ObjectNode) mapper.readTree(src);
-    IOUtils.closeQuietly(src);
-
-    final JsonNode replacementNode;
-    if (justValue) {
-      replacementNode = new TextNode(IOUtils.toString(replacement));
-    } else {
-      replacementNode = (ObjectNode) mapper.readTree(replacement);
-    }
-    IOUtils.closeQuietly(replacement);
-
-    JsonNode node = srcNode;
-    for (int i = 0; i < path.size() - 1; i++) {
-      node = node.get(path.get(i));
-      if (node == null) {
-        throw new NotFoundException();
-      }
-    }
-
-    ((ObjectNode) node).set(path.get(path.size() - 1), replacementNode);
-
-    return IOUtils.toInputStream(srcNode.toString());
-  }
-
-  @Override
-  public InputStream deleteProperty(final InputStream src, final List<String> path) throws Exception {
-    final ObjectMapper mapper = new ObjectMapper();
-    final ObjectNode srcNode = (ObjectNode) mapper.readTree(src);
-    IOUtils.closeQuietly(src);
-
-    JsonNode node = srcNode;
-    for (int i = 0; i < path.size() - 1; i++) {
-      node = node.get(path.get(i));
-      if (node == null) {
-        throw new NotFoundException();
-      }
-    }
-
-    ((ObjectNode) node).set(path.get(path.size() - 1), null);
-
-    return IOUtils.toInputStream(srcNode.toString());
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
deleted file mode 100644
index 0009eea..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
+++ /dev/null
@@ -1,1388 +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.fit.utils;
-
-import static org.apache.olingo.fit.utils.Constants.*;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.StringWriter;
-import java.util.AbstractMap;
-import java.util.AbstractMap.SimpleEntry;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.ws.rs.NotFoundException;
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLEventFactory;
-import javax.xml.stream.XMLEventReader;
-import javax.xml.stream.XMLEventWriter;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.Attribute;
-import javax.xml.stream.events.StartElement;
-import javax.xml.stream.events.XMLEvent;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemException;
-
-public class XMLUtilities extends AbstractUtilities {
-
-  protected static XMLInputFactory ifactory = null;
-
-  protected static XMLOutputFactory ofactory = null;
-
-  public XMLUtilities(final ODataVersion version) throws Exception {
-    super(version);
-  }
-
-  public void retrieveLinkInfoFromMetadata() throws Exception {
-
-    final MetadataLinkInfo metadataLinkInfo = new MetadataLinkInfo();
-    Commons.linkInfo.put(version, metadataLinkInfo);
-
-    final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
-    final XMLEventReader reader = getEventReader(metadata);
-
-    int initialDepth = 0;
-    try {
-      while (true) {
-        Map.Entry<Integer, XmlElement> entityType =
-                extractElement(reader, null, Collections.<String>singletonList("EntityType"),
-                null, false, initialDepth, 4, 4);
-        initialDepth = entityType.getKey();
-
-        final String entitySetName =
-                entityType.getValue().getStart().getAttributeByName(new QName("Name")).getValue();
-
-        final XMLEventReader entityReader = getEventReader(entityType.getValue().toStream());
-        int size = 0;
-
-        try {
-          while (true) {
-            final XmlElement navProperty =
-                    extractElement(entityReader, null, Collections.<String>singletonList("NavigationProperty"),
-                    null, false, 0, -1, -1).getValue();
-
-            final String linkName = navProperty.getStart().getAttributeByName(new QName("Name")).getValue();
-            final Map.Entry<String, Boolean> target = getTargetInfo(navProperty.getStart(), linkName);
-
-            metadataLinkInfo.addLink(
-                    entitySetName,
-                    linkName,
-                    target.getKey(),
-                    target.getValue());
-
-            size++;
-          }
-        } catch (Exception e) {
-        } finally {
-          entityReader.close();
-        }
-
-        if (size == 0) {
-          metadataLinkInfo.addEntitySet(entitySetName);
-        }
-      }
-    } catch (Exception e) {
-    } finally {
-      reader.close();
-    }
-  }
-
-  private Map.Entry<String, Boolean> getTargetInfo(final StartElement element, final String linkName)
-          throws Exception {
-    final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
-    XMLEventReader reader = getEventReader(metadata);
-
-    final String associationName = element.getAttributeByName(new QName("Relationship")).getValue();
-
-    final Map.Entry<Integer, XmlElement> association = extractElement(
-            reader, null, Collections.<String>singletonList("Association"),
-            Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>(
-            "Name", associationName.substring(associationName.lastIndexOf(".") + 1))), false,
-            0, 4, 4);
-
-    reader.close();
-    IOUtils.closeQuietly(metadata);
-
-    final InputStream associationContent = association.getValue().toStream();
-    reader = getEventReader(associationContent);
-
-    final Map.Entry<Integer, XmlElement> associationEnd = extractElement(
-            reader, null, Collections.<String>singletonList("End"),
-            Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>("Role", linkName)),
-            false, 0, -1, -1);
-
-    reader.close();
-    IOUtils.closeQuietly(associationContent);
-
-    final String target = associationEnd.getValue().getStart().getAttributeByName(new QName("Type")).getValue();
-    final boolean feed = associationEnd.getValue().getStart().getAttributeByName(
-            new QName("Multiplicity")).getValue().equals("*");
-
-    return new SimpleEntry<String, Boolean>(target, feed);
-  }
-
-  @Override
-  protected Accept getDefaultFormat() {
-    return Accept.ATOM;
-  }
-
-  protected XMLEventReader getEventReader(final InputStream is) throws XMLStreamException {
-    if (ifactory == null) {
-      ifactory = XMLInputFactory.newInstance();
-    }
-    ifactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false);
-    return ifactory.createXMLEventReader(is);
-  }
-
-  protected static XMLEventWriter getEventWriter(final OutputStream os) throws XMLStreamException {
-    if (ofactory == null) {
-      ofactory = XMLOutputFactory.newInstance();
-    }
-
-    return ofactory.createXMLEventWriter(os);
-  }
-
-  private void writeEvent(final XMLEvent event, final XMLEventWriter writer) {
-    if (writer != null) {
-      try {
-        writer.add(event);
-      } catch (XMLStreamException e) {
-        LOG.error("Error writing event {}", event, e);
-      }
-    }
-  }
-
-  private void skipElement(
-          final StartElement start,
-          final XMLEventReader reader,
-          final XMLEventWriter writer,
-          final boolean excludeStart)
-          throws Exception {
-
-    if (!excludeStart) {
-      writeEvent(start, writer);
-    }
-
-    int depth = 1;
-    boolean found = false;
-
-    while (reader.hasNext() && !found) {
-      final XMLEvent event = reader.nextEvent();
-
-      writeEvent(event, writer);
-
-      if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
-        depth++;
-      } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
-        depth--;
-        found = depth == 0 && start.getName().equals(event.asEndElement().getName());
-      }
-    }
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  protected InputStream addLinks(
-          final String entitySetName, final String entitykey, final InputStream is, final Set<String> links)
-          throws Exception {
-
-    // -----------------------------------------
-    // 0. Build reader and writer
-    // -----------------------------------------
-    final XMLEventReader reader = getEventReader(is);
-    final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
-
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    final XMLEventWriter writer = getEventWriter(bos);
-    // -----------------------------------------
-    final Map.Entry<Integer, XmlElement> entry =
-            extractElement(reader, writer, Collections.singletonList("entry"), 0, 1, 1);
-
-    writer.add(entry.getValue().getStart());
-
-    // add for links
-    for (String link : links) {
-      final Set<Attribute> attributes = new HashSet<Attribute>();
-      attributes.add(eventFactory.createAttribute(new QName("title"), link));
-      attributes.add(eventFactory.createAttribute(new QName("href"),
-              Commons.getLinksURI(version, entitySetName, entitykey, link)));
-      attributes.add(eventFactory.createAttribute(new QName("rel"), Constants.ATOM_LINK_REL + link));
-      attributes.add(eventFactory.createAttribute(new QName("type"),
-              Commons.linkInfo.get(version).isFeed(entitySetName, link) ? Constants.ATOM_LINK_FEED
-              : Constants.ATOM_LINK_ENTRY));
-
-      writer.add(eventFactory.createStartElement(new QName(LINK), attributes.iterator(), null));
-      writer.add(eventFactory.createEndElement(new QName(LINK), null));
-    }
-
-    writer.add(entry.getValue().getContentReader());
-    writer.add(entry.getValue().getEnd());
-    writer.add(reader);
-    IOUtils.closeQuietly(is);
-
-    writer.flush();
-    writer.close();
-    reader.close();
-
-    return new ByteArrayInputStream(bos.toByteArray());
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  protected Set<String> retrieveAllLinkNames(final InputStream is) throws Exception {
-    final Set<String> links = new HashSet<String>();
-
-    final XMLEventReader reader = getEventReader(is);
-
-    try {
-
-      int startDepth = 0;
-
-      while (true) {
-        final Map.Entry<Integer, XmlElement> linkInfo =
-                extractElement(reader, null, Collections.<String>singletonList(LINK), startDepth, 2, 2);
-
-        startDepth = linkInfo.getKey();
-
-        links.add(linkInfo.getValue().getStart().getAttributeByName(new QName("title")).getValue());
-      }
-    } catch (Exception ignore) {
-      // ignore
-    } finally {
-      reader.close();
-      IOUtils.closeQuietly(is);
-    }
-
-    return links;
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  protected NavigationLinks retrieveNavigationInfo(
-          final String entitySetName, final InputStream is)
-          throws Exception {
-
-    final NavigationLinks links = new NavigationLinks();
-
-    final XMLEventReader reader = getEventReader(is);
-
-    try {
-      final List<Map.Entry<String, String>> filter = new ArrayList<Map.Entry<String, String>>();
-      filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=entry"));
-      filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=feed"));
-
-      int startDepth = 0;
-
-      while (true) {
-        // a. search for link with type attribute equals to "application/atom+xml;type=entry/feed"
-        final Map.Entry<Integer, XmlElement> linkInfo = extractElement(
-                reader, null, Collections.<String>singletonList(LINK), filter, true, startDepth, 2, 2);
-        final XmlElement link = linkInfo.getValue();
-        startDepth = linkInfo.getKey();
-
-        final String title = link.getStart().getAttributeByName(new QName("title")).getValue();
-
-        final Attribute hrefAttr = link.getStart().getAttributeByName(new QName("href"));
-        final String href = hrefAttr == null ? null : hrefAttr.getValue();
-
-        try {
-          final XmlElement inlineElement =
-                  extractElement(link.getContentReader(), null, Collections.<String>singletonList(INLINE), 0, -1, -1).
-                  getValue();
-          final XMLEventReader inlineReader = inlineElement.getContentReader();
-
-          try {
-            while (true) {
-              final XmlElement entry =
-                      extractElement(inlineReader, null, Collections.<String>singletonList("entry"), 0, -1, -1).
-                      getValue();
-              links.addInlines(title, entry.toStream());
-            }
-          } catch (Exception e) {
-            // Reached the end of document
-          }
-
-          inlineReader.close();
-        } catch (Exception ignore) {
-          // inline element not found (inlines are not mondatory).
-          if (StringUtils.isNotBlank(href) && entityUriPattern.matcher(href).matches()) {
-            links.addLinks(title, href.substring(href.lastIndexOf('/') + 1));
-          }
-        }
-      }
-    } catch (Exception ignore) {
-      // ignore
-    } finally {
-      reader.close();
-    }
-
-    return links;
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  protected InputStream normalizeLinks(
-          final String entitySetName, final String entityKey, final InputStream is, final NavigationLinks links)
-          throws Exception {
-
-    // -----------------------------------------
-    // 0. Build reader and writer
-    // -----------------------------------------
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    IOUtils.copy(is, bos);
-    is.close();
-
-    final ByteArrayOutputStream tmpBos = new ByteArrayOutputStream();
-    final XMLEventWriter writer = getEventWriter(tmpBos);
-
-    final XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
-    // -----------------------------------------
-
-    // -----------------------------------------
-    // 1. Normalize links
-    // -----------------------------------------
-    final Set<String> added = new HashSet<String>();
-
-    try {
-      final List<Map.Entry<String, String>> filter = new ArrayList<Map.Entry<String, String>>();
-      filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=entry"));
-      filter.add(new AbstractMap.SimpleEntry<String, String>("type", "application/atom+xml;type=feed"));
-
-      Map.Entry<Integer, XmlElement> linkInfo = null;
-
-      while (true) {
-        // a. search for link with type attribute equals to "application/atom+xml;type=entry/feed"
-        linkInfo = extractElement(
-                reader, writer, Collections.<String>singletonList(LINK), filter, true,
-                linkInfo == null ? 0 : linkInfo.getKey(), 2, 2);
-        final XmlElement link = linkInfo.getValue();
-
-        final String title = link.getStart().getAttributeByName(new QName("title")).getValue();
-
-        if (!added.contains(title)) {
-          added.add(title);
-
-          final String normalizedLink = String.format(
-                  "<link href=\"%s(%s)/%s\" rel=\"%s\" title=\"%s\" type=\"%s\"/>",
-                  entitySetName,
-                  entityKey,
-                  title,
-                  link.getStart().getAttributeByName(new QName("rel")).getValue(),
-                  title,
-                  link.getStart().getAttributeByName(new QName("type")).getValue());
-
-          addAtomElement(IOUtils.toInputStream(normalizedLink), writer);
-        }
-      }
-    } catch (Exception ignore) {
-      // ignore
-    } finally {
-      writer.close();
-      reader.close();
-    }
-    // -----------------------------------------
-
-    // -----------------------------------------
-    // 2. Add edit link if missing
-    // -----------------------------------------
-    final InputStream content = addEditLink(
-            new ByteArrayInputStream(tmpBos.toByteArray()),
-            entitySetName,
-            Constants.DEFAULT_SERVICE_URL + entitySetName + "(" + entityKey + ")");
-    // -----------------------------------------
-
-    // -----------------------------------------
-    // 3. Add content element if missing
-    // -----------------------------------------
-    return addAtomContent(
-            content,
-            entitySetName,
-            Constants.DEFAULT_SERVICE_URL + entitySetName + "(" + entityKey + ")");
-    // -----------------------------------------
-
-  }
-
-  public XmlElement getXmlElement(
-          final StartElement start,
-          final XMLEventReader reader)
-          throws Exception {
-
-    final XmlElement res = new XmlElement();
-    res.setStart(start);
-
-    StringWriter content = new StringWriter();
-
-    int depth = 1;
-
-    while (reader.hasNext() && depth > 0) {
-      final XMLEvent event = reader.nextEvent();
-
-      if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
-        depth++;
-      } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
-        depth--;
-      }
-
-      if (depth == 0) {
-        res.setEnd(event.asEndElement());
-      } else {
-        event.writeAsEncodedUnicode(content);
-      }
-    }
-
-    content.flush();
-    content.close();
-
-    res.setContent(new ByteArrayInputStream(content.toString().getBytes()));
-
-    return res;
-  }
-
-  private void addAtomElement(
-          final InputStream content,
-          final XMLEventWriter writer)
-          throws Exception {
-    final XMLEventReader reader = getEventReader(content);
-
-    final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
-    XMLEvent newLine = eventFactory.createSpace("\n");
-
-    try {
-      writer.add(newLine);
-
-      while (reader.hasNext()) {
-        final XMLEvent event = reader.nextEvent();
-
-        if (event.getEventType() != XMLStreamConstants.START_DOCUMENT
-                && event.getEventType() != XMLStreamConstants.END_DOCUMENT
-                && event.getEventType() != XMLStreamConstants.COMMENT) {
-          writer.add(event);
-        }
-      }
-      writer.add(newLine);
-    } finally {
-      reader.close();
-      IOUtils.closeQuietly(content);
-    }
-  }
-
-  @Override
-  public InputStream addEditLink(
-          final InputStream content, final String title, final String href)
-          throws Exception {
-
-    final ByteArrayOutputStream copy = new ByteArrayOutputStream();
-    IOUtils.copy(content, copy);
-
-    IOUtils.closeQuietly(content);
-
-    XMLEventReader reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
-
-    ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    XMLEventWriter writer = getEventWriter(bos);
-
-    final String editLinkElement = String.format("<link rel=\"edit\" title=\"%s\" href=\"%s\" />", title, href);
-
-    try {
-      // check edit link existence
-      extractElement(reader, writer, Collections.<String>singletonList(LINK),
-              Collections.<Map.Entry<String, String>>singletonList(
-              new AbstractMap.SimpleEntry<String, String>("rel", "edit")), false, 0, -1, -1);
-
-      addAtomElement(IOUtils.toInputStream(editLinkElement), writer);
-      writer.add(reader);
-
-    } catch (Exception e) {
-      reader.close();
-      reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
-
-      bos = new ByteArrayOutputStream();
-      writer = getEventWriter(bos);
-
-      final XmlElement entryElement =
-              extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
-
-      writer.add(entryElement.getStart());
-
-      addAtomElement(IOUtils.toInputStream(editLinkElement), writer);
-
-      writer.add(entryElement.getContentReader());
-      writer.add(entryElement.getEnd());
-
-      writer.add(reader);
-
-      writer.flush();
-      writer.close();
-    } finally {
-      reader.close();
-    }
-
-    return new ByteArrayInputStream(bos.toByteArray());
-  }
-
-  public InputStream addAtomContent(
-          final InputStream content, final String title, final String href)
-          throws Exception {
-
-    final ByteArrayOutputStream copy = new ByteArrayOutputStream();
-    IOUtils.copy(content, copy);
-
-    IOUtils.closeQuietly(content);
-
-    XMLEventReader reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
-
-    ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    XMLEventWriter writer = getEventWriter(bos);
-
-    try {
-      // check edit link existence
-      XmlElement contentElement =
-              extractElement(reader, writer, Collections.<String>singletonList("content"), 0, 2, 2).getValue();
-      writer.add(contentElement.getStart());
-      writer.add(contentElement.getContentReader());
-      writer.add(contentElement.getEnd());
-      writer.add(reader);
-    } catch (Exception e) {
-      reader.close();
-      reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
-
-      bos = new ByteArrayOutputStream();
-      writer = getEventWriter(bos);
-
-      if (isMediaContent(title)) {
-        final XmlElement entryElement =
-                extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
-
-        writer.add(entryElement.getStart());
-        writer.add(entryElement.getContentReader());
-
-        addAtomElement(
-                IOUtils.toInputStream(String.format("<content type=\"*/*\" src=\"%s/$value\" />", href)),
-                writer);
-
-        writer.add(entryElement.getEnd());
-      } else {
-        try {
-          final XmlElement entryElement =
-                  extractElement(reader, writer, Collections.<String>singletonList(PROPERTIES), 0, 2, 3).getValue();
-
-          addAtomElement(
-                  IOUtils.toInputStream("<content type=\"application/xml\">"),
-                  writer);
-
-          writer.add(entryElement.getStart());
-          writer.add(entryElement.getContentReader());
-          writer.add(entryElement.getEnd());
-
-          addAtomElement(
-                  IOUtils.toInputStream("</content>"),
-                  writer);
-        } catch (Exception nf) {
-          reader.close();
-          reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
-
-          bos = new ByteArrayOutputStream();
-          writer = getEventWriter(bos);
-
-          final XmlElement entryElement =
-                  extractElement(reader, writer, Collections.<String>singletonList("entry"), 0, 1, 1).getValue();
-          writer.add(entryElement.getStart());
-          writer.add(entryElement.getContentReader());
-
-          addAtomElement(
-                  IOUtils.toInputStream("<content type=\"application/xml\"/>"),
-                  writer);
-
-          writer.add(entryElement.getEnd());
-        }
-      }
-
-      writer.add(reader);
-
-      writer.flush();
-      writer.close();
-    } finally {
-      reader.close();
-    }
-
-    return new ByteArrayInputStream(bos.toByteArray());
-  }
-
-  public int countAllElements(final String entitySetName) throws Exception {
-    final String basePath = entitySetName + File.separatorChar;
-    int count = countFeedElements(fsManager.readFile(basePath + FEED, Accept.XML), "entry");
-
-    final String skipTokenDirPath = fsManager.getAbsolutePath(basePath + SKIP_TOKEN, null);
-
-
-    try {
-      final FileObject skipToken = fsManager.resolve(skipTokenDirPath);
-      final FileObject[] files = fsManager.findByExtension(skipToken, Accept.XML.getExtension().substring(1));
-
-      for (FileObject file : files) {
-        count += countFeedElements(fsManager.readFile(
-                basePath + SKIP_TOKEN + File.separatorChar + file.getName().getBaseName(), null), "entry");
-      }
-    } catch (FileSystemException fse) {
-      LOG.debug("Resource path '{}' not found", skipTokenDirPath);
-    }
-
-
-    return count;
-  }
-
-  private int countFeedElements(final InputStream is, final String elementName) throws XMLStreamException {
-    final XMLEventReader reader = getEventReader(is);
-
-    int count = 0;
-
-    while (reader.hasNext()) {
-      final XMLEvent event = reader.nextEvent();
-
-      if (event.getEventType() == XMLStreamConstants.START_ELEMENT
-              && elementName.equals(event.asStartElement().getName().getLocalPart())) {
-        count++;
-      }
-    }
-
-    reader.close();
-    return count;
-  }
-
-  public Map.Entry<Integer, XmlElement> extractElement(
-          final XMLEventReader reader, final XMLEventWriter writer, final List<String> path,
-          final int startPathPos, final int minPathPos, final int maxPathPos)
-          throws Exception {
-    return extractElement(reader, writer, path, null, false, startPathPos, minPathPos, maxPathPos);
-  }
-
-  public Map.Entry<Integer, XmlElement> extractElement(
-          final XMLEventReader reader, final XMLEventWriter writer, final List<String> path,
-          final Collection<Map.Entry<String, String>> filter,
-          final boolean filterInOr,
-          final int startPathPos, final int minPathPos, final int maxPathPos)
-          throws Exception {
-
-    StartElement start = null;
-    int searchFor = 0;
-    int depth = startPathPos;
-
-    // Current inspected element
-    String current = null;
-
-    // set defaults
-    final List<String> pathElementNames = path == null ? Collections.<String>emptyList() : path;
-    final Collection<Map.Entry<String, String>> filterAttrs =
-            filter == null ? Collections.<Map.Entry<String, String>>emptySet() : filter;
-
-    while (reader.hasNext() && start == null) {
-      final XMLEvent event = reader.nextEvent();
-
-      if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
-        depth++;
-
-        if (current != null || ((minPathPos < 0 || minPathPos <= depth) && (maxPathPos < 0 || depth <= maxPathPos))) {
-          if (pathElementNames.isEmpty()
-                  || pathElementNames.get(searchFor).trim().equals(event.asStartElement().getName().getLocalPart())) {
-
-            if (searchFor < pathElementNames.size() - 1) {
-              // path exploring not completed
-              writeEvent(event, writer);
-              current = pathElementNames.get(searchFor).trim();
-              searchFor++;
-            } else {
-
-              // path exploring completed ... evaluate filter about path element name attribute
-              boolean match = filterAttrs.isEmpty() || !filterInOr;
-
-              for (Map.Entry<String, String> filterAttr : filterAttrs) {
-                final Attribute attr = event.asStartElement().getAttributeByName(new QName(filterAttr.getKey().trim()));
-
-                if (attr == null || !filterAttr.getValue().trim().equals(attr.getValue())) {
-                  match = filterInOr ? match : false;
-                } else {
-                  match = filterInOr ? true : match;
-                }
-              }
-
-              if (match) {
-                // found searched element
-                start = event.asStartElement();
-              } else {
-                skipElement(event.asStartElement(), reader, writer, false);
-                depth--;
-              }
-            }
-          } else if (current == null) {
-            writeEvent(event, writer);
-          } else {
-            // skip element
-            skipElement(event.asStartElement(), reader, writer, false);
-            depth--;
-          }
-        } else {
-          writeEvent(event, writer);
-        }
-
-      } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
-        depth--;
-
-        writeEvent(event, writer);
-
-        if (event.asEndElement().getName().getLocalPart().equals(current)) {
-          // back step ....
-          searchFor--;
-          current = searchFor > 0 ? pathElementNames.get(searchFor - 1).trim() : null;
-        }
-      } else {
-        writeEvent(event, writer);
-      }
-    }
-
-    if (start == null) {
-      throw new NotFoundException();
-    }
-
-    return new SimpleEntry<Integer, XmlElement>(Integer.valueOf(depth - 1), getXmlElement(start, reader));
-  }
-
-  public InputStream addAtomInlinecount(
-          final InputStream feed, final int count, final Accept accept)
-          throws Exception {
-    final XMLEventReader reader = getEventReader(feed);
-
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    final XMLEventWriter writer = getEventWriter(bos);
-
-    try {
-
-      final XmlElement feedElement =
-              extractElement(reader, writer, Collections.<String>singletonList("feed"), 0, 1, 1).getValue();
-
-      writer.add(feedElement.getStart());
-      addAtomElement(IOUtils.toInputStream(String.format("<m:count>%d</m:count>", count)), writer);
-      writer.add(feedElement.getContentReader());
-      writer.add(feedElement.getEnd());
-
-      while (reader.hasNext()) {
-        writer.add(reader.nextEvent());
-      }
-
-    } finally {
-      writer.flush();
-      writer.close();
-      reader.close();
-      IOUtils.closeQuietly(feed);
-    }
-
-    return new ByteArrayInputStream(bos.toByteArray());
-  }
-
-  @Override
-  public InputStream getPropertyValue(final InputStream is, final List<String> path)
-          throws Exception {
-
-    final List<String> pathElements = new ArrayList<String>();
-
-    for (String element : path) {
-      pathElements.add(ATOM_PROPERTY_PREFIX + element);
-    }
-
-    final XMLEventReader reader = getEventReader(is);
-    final Map.Entry<Integer, XmlElement> property = extractElement(reader, null, pathElements, 0, 3, 4);
-
-    reader.close();
-    IOUtils.closeQuietly(is);
-
-    return property.getValue().getContent();
-  }
-
-  @Override
-  public InputStream selectEntity(final InputStream entity, final String[] propertyNames) throws Exception {
-    final XMLEventReader reader = getEventReader(entity);
-
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    final XMLEventWriter writer = getEventWriter(bos);
-
-    final List<String> found = new ArrayList<String>(Arrays.asList(propertyNames));
-
-    boolean inProperties = false;
-    boolean writeCurrent = true;
-    Boolean writeNext = null;
-    String currentName = null;
-
-    final List<String> fieldToBeSaved = new ArrayList<String>(Arrays.asList(propertyNames));
-
-    while (reader.hasNext()) {
-      final XMLEvent event = reader.nextEvent();
-      if (event.getEventType() == XMLStreamConstants.START_ELEMENT
-              && LINK.equals(event.asStartElement().getName().getLocalPart())
-              && !fieldToBeSaved.contains(
-              event.asStartElement().getAttributeByName(new QName("title")).getValue())
-              && !"edit".equals(event.asStartElement().getAttributeByName(new QName("rel")).getValue())) {
-        writeCurrent = false;
-      } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
-              && LINK.equals(event.asEndElement().getName().getLocalPart())) {
-        writeNext = true;
-      } else if (event.getEventType() == XMLStreamConstants.START_ELEMENT
-              && (PROPERTIES).equals(event.asStartElement().getName().getLocalPart())) {
-        writeCurrent = true;
-        writeNext = false;
-        inProperties = true;
-      } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
-              && (PROPERTIES).equals(event.asEndElement().getName().getLocalPart())) {
-        writeCurrent = true;
-      } else if (inProperties) {
-        if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
-          final String elementName = event.asStartElement().getName().getLocalPart();
-
-          for (String propertyName : propertyNames) {
-            if ((ATOM_PROPERTY_PREFIX + propertyName.trim()).equals(elementName)) {
-              writeCurrent = true;
-              found.remove(propertyName);
-              currentName = propertyName;
-            }
-          }
-
-        } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
-                && StringUtils.isNotBlank(currentName)
-                && (ATOM_PROPERTY_PREFIX + currentName.trim()).equals(
-                event.asEndElement().getName().getLocalPart())) {
-          writeNext = false;
-          currentName = null;
-        }
-
-      }
-
-      if (writeCurrent) {
-        writer.add(event);
-      }
-
-      if (writeNext != null) {
-        writeCurrent = writeNext;
-        writeNext = null;
-      }
-    }
-
-    writer.flush();
-    writer.close();
-    reader.close();
-    IOUtils.closeQuietly(entity);
-
-    // Do not raise any exception in order to support FC properties as well
-    // if (!found.isEmpty()) {
-    //     throw new Exception(String.format("Could not find a properties '%s'", found));
-    // }
-
-    return new ByteArrayInputStream(bos.toByteArray());
-  }
-
-  @Override
-  public InputStream readEntities(
-          final List<String> links, final String linkName, final String next, final boolean forceFeed)
-          throws Exception {
-
-    if (links.isEmpty()) {
-      throw new NotFoundException();
-    }
-
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
-    if (forceFeed || links.size() > 1) {
-      // build a feed
-      bos.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>".getBytes());
-
-      bos.write(("<feed xml:base=\"" + DEFAULT_SERVICE_URL + "\" "
-              + "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\">")
-              .getBytes());
-
-      bos.write(("<id>" + DEFAULT_SERVICE_URL + "entityset(entityid)/" + linkName + "</id>").getBytes());
-
-      bos.write(("<title type=\"text\">" + linkName + "</title>").getBytes());
-      bos.write("<updated>2014-03-03T13:40:49Z</updated>".getBytes());
-      bos.write(("<link rel=\"self\" title=\"" + linkName + "\" href=\"" + linkName + "\" />").getBytes());
-    }
-
-    for (String link : links) {
-      try {
-        final Map.Entry<String, String> uri = Commons.parseEntityURI(link);
-
-        final XmlElement entry =
-                extractElement(
-                getEventReader(readEntity(uri.getKey(), uri.getValue(), Accept.ATOM).getValue()),
-                null,
-                Collections.<String>singletonList("entry"),
-                0, 1, 1).getValue();
-
-        IOUtils.copy(entry.toStream(), bos);
-      } catch (Exception e) {
-        // log and ignore link
-        LOG.warn("Error parsing uri {}", link, e);
-      }
-    }
-
-    if (forceFeed || links.size() > 1) {
-
-      if (StringUtils.isNotBlank(next)) {
-        bos.write(String.format("<link rel=\"next\" href=\"%s\" />", next).getBytes());
-      }
-
-      bos.write("</feed>".getBytes());
-    }
-
-    return new ByteArrayInputStream(bos.toByteArray());
-  }
-
-  @Override
-  public Map<String, InputStream> getChanges(final InputStream src) throws Exception {
-    final Map<String, InputStream> res = new HashMap<String, InputStream>();
-
-    ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    IOUtils.copy(src, bos);
-    IOUtils.closeQuietly(src);
-
-    // retrieve properties ...
-    XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
-
-    final Map.Entry<Integer, XmlElement> propertyElement =
-            extractElement(reader, null, Collections.<String>singletonList(PROPERTIES), 0, 2, 3);
-    reader.close();
-
-    reader = propertyElement.getValue().getContentReader();
-
-    try {
-      while (true) {
-        final XmlElement property = extractElement(reader, null, null, 0, -1, -1).getValue();
-        res.put(property.getStart().getName().getLocalPart(), property.toStream());
-      }
-    } catch (Exception ignore) {
-      // end
-    }
-
-    reader.close();
-
-    // retrieve links ...
-    reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
-
-    try {
-      int pos = 0;
-      while (true) {
-        final Map.Entry<Integer, XmlElement> linkElement =
-                extractElement(reader, null, Collections.<String>singletonList(LINK), pos, 2, 2);
-
-        res.put("[LINK]" + linkElement.getValue().getStart().getAttributeByName(new QName("title")).getValue(),
-                linkElement.getValue().toStream());
-
-        pos = linkElement.getKey();
-      }
-    } catch (Exception ignore) {
-      // end
-    }
-
-    return res;
-  }
-
-  @Override
-  public InputStream setChanges(
-          final InputStream toBeChanged,
-          final Map<String, InputStream> properties)
-          throws Exception {
-    XMLEventReader reader = getEventReader(toBeChanged);
-
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    XMLEventWriter writer = getEventWriter(bos);
-
-    // ---------------------------------
-    // add property changes
-    // ---------------------------------
-    Map.Entry<Integer, XmlElement> propertyElement =
-            extractElement(reader, writer, Collections.<String>singletonList(PROPERTIES), 0, 2, 3);
-
-    writer.flush();
-
-    ByteArrayOutputStream pbos = new ByteArrayOutputStream();
-    OutputStreamWriter pwriter = new OutputStreamWriter(pbos);
-
-    final XMLEventReader propertyReader = propertyElement.getValue().getContentReader();
-
-    try {
-      while (true) {
-        final XmlElement property = extractElement(propertyReader, null, null, 0, -1, -1).getValue();
-        final String name = property.getStart().getName().getLocalPart();
-
-        if (properties.containsKey(name)) {
-          // replace
-          final InputStream replacement = properties.get(name);
-          properties.remove(property.getStart().getName().getLocalPart());
-          pwriter.append(IOUtils.toString(replacement));
-          IOUtils.closeQuietly(replacement);
-        } else {
-          pwriter.append(IOUtils.toString(property.toStream()));
-        }
-      }
-    } catch (Exception ignore) {
-      // end
-    }
-
-    for (Map.Entry<String, InputStream> remains : properties.entrySet()) {
-      if (!remains.getKey().startsWith("[LINK]")) {
-        pwriter.append(IOUtils.toString(remains.getValue()));
-        IOUtils.closeQuietly(remains.getValue());
-      }
-    }
-
-    pwriter.flush();
-    pwriter.close();
-
-    writer.add(propertyElement.getValue().getStart());
-    writer.add(new XMLEventReaderWrapper(new ByteArrayInputStream(pbos.toByteArray())));
-    writer.add(propertyElement.getValue().getEnd());
-
-    IOUtils.closeQuietly(pbos);
-
-    writer.add(reader);
-    reader.close();
-    writer.flush();
-    writer.close();
-    // ---------------------------------
-
-    // ---------------------------------
-    // add navigationm changes
-    // ---------------------------------
-
-    // remove existent links
-    for (Map.Entry<String, InputStream> remains : properties.entrySet()) {
-
-      if (remains.getKey().startsWith("[LINK]")) {
-        reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
-
-        bos.reset();
-        writer = getEventWriter(bos);
-
-        try {
-          final String linkName = remains.getKey().substring(remains.getKey().indexOf("]") + 1);
-
-          extractElement(reader, writer, Collections.<String>singletonList(LINK),
-                  Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>("title", linkName)),
-                  false, 0, 2, 2);
-
-          writer.add(reader);
-
-        } catch (Exception ignore) {
-          // ignore
-        }
-
-        writer.flush();
-        writer.close();
-      }
-    }
-
-    reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
-
-    bos.reset();
-    writer = getEventWriter(bos);
-
-    propertyElement = extractElement(reader, writer, Collections.<String>singletonList(CONTENT), 0, 2, 2);
-    writer.flush();
-
-    pbos.reset();
-    pwriter = new OutputStreamWriter(pbos);
-
-    for (Map.Entry<String, InputStream> remains : properties.entrySet()) {
-      if (remains.getKey().startsWith("[LINK]")) {
-        pwriter.append(IOUtils.toString(remains.getValue()));
-        IOUtils.closeQuietly(remains.getValue());
-      }
-    }
-
-    pwriter.flush();
-    pwriter.close();
-
-    writer.add(new XMLEventReaderWrapper(new ByteArrayInputStream(pbos.toByteArray())));
-    IOUtils.closeQuietly(pbos);
-
-    writer.add(propertyElement.getValue().getStart());
-    writer.add(propertyElement.getValue().getContentReader());
-    writer.add(propertyElement.getValue().getEnd());
-
-    writer.add(reader);
-    reader.close();
-    writer.flush();
-    writer.close();
-    // ---------------------------------
-
-    return new ByteArrayInputStream(bos.toByteArray());
-  }
-
-  @Override
-  protected InputStream replaceLink(
-          final InputStream toBeChanged, final String linkName, final InputStream replacement)
-          throws Exception {
-    final XMLEventReader reader = getEventReader(toBeChanged);
-
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    final XMLEventWriter writer = getEventWriter(bos);
-
-    final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
-    XMLEvent newLine = eventFactory.createSpace("\n");
-
-    try {
-      final XmlElement linkElement =
-              extractElement(reader, writer, Collections.<String>singletonList(LINK),
-              Collections.<Map.Entry<String, String>>singletonList(new SimpleEntry<String, String>("title", linkName)),
-              false, 0, -1, -1).getValue();
-      writer.add(linkElement.getStart());
-
-      // ------------------------------------------
-      // write inline ...
-      // ------------------------------------------
-      writer.add(newLine);
-      writer.add(eventFactory.createStartElement("m", null, "inline"));
-
-      addAtomElement(replacement, writer);
-
-      writer.add(eventFactory.createEndElement("m", null, "inline"));
-      writer.add(newLine);
-      // ------------------------------------------
-
-      writer.add(linkElement.getEnd());
-
-      writer.add(reader);
-      writer.flush();
-      writer.close();
-    } finally {
-      reader.close();
-      IOUtils.closeQuietly(toBeChanged);
-    }
-
-    return new ByteArrayInputStream(bos.toByteArray());
-  }
-
-  public String getEdmTypeFromAtom(final String entitySetName, final String entityId, final List<String> path)
-          throws Exception {
-    InputStream src = fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) + ENTITY, Accept.XML);
-
-    final List<String> atomPathElements = new ArrayList<String>();
-
-    for (String element : path) {
-      atomPathElements.add(ATOM_PROPERTY_PREFIX + element);
-    }
-
-    final Map.Entry<Integer, XmlElement> prop = extractElement(getEventReader(src), null, atomPathElements, 0, 3, 4);
-    IOUtils.closeQuietly(src);
-
-    final Attribute type = prop.getValue().getStart().getAttributeByName(new QName(TYPE));
-
-    final String edmType;
-
-    if (type == null) {
-      edmType = Constants.ATOM_DEF_TYPE;
-    } else {
-      edmType = type.getValue();
-    }
-
-    return edmType;
-  }
-
-  @Override
-  public Map.Entry<String, List<String>> extractLinkURIs(
-          final String entitySetName, final String entityId, final String linkName)
-          throws Exception {
-    final LinkInfo links = readLinks(entitySetName, entityId, linkName, Accept.XML);
-    return extractLinkURIs(links.getLinks());
-  }
-
-  @Override
-  public Map.Entry<String, List<String>> extractLinkURIs(final InputStream is)
-          throws Exception {
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    IOUtils.copy(is, bos);
-    IOUtils.closeQuietly(is);
-
-    XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
-    final List<String> links = new ArrayList<String>();
-    try {
-      while (true) {
-        links.add(IOUtils.toString(extractElement(reader, null, Collections.<String>singletonList("uri"), 0, -1, -1).
-                getValue().getContent()));
-      }
-    } catch (Exception ignore) {
-      // End document reached ...
-    }
-    reader.close();
-
-    String next;
-
-    reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
-    try {
-      next = IOUtils.toString(extractElement(reader, null, Collections.<String>singletonList("next"), 0, -1, -1).
-              getValue().getContent());
-    } catch (Exception ignore) {
-      // next link is not mandatory
-      next = null;
-    }
-    reader.close();
-
-    return new AbstractMap.SimpleEntry<String, List<String>>(next, links);
-  }
-
-  @Override
-  public InputStream getProperty(
-          final String entitySetName, final String entityId, final List<String> path, final String edmType)
-          throws Exception {
-    final List<String> pathElements = new ArrayList<String>();
-
-    for (String element : path) {
-      pathElements.add(ATOM_PROPERTY_PREFIX + element);
-    }
-
-    final InputStream src =
-            fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId) + ENTITY, Accept.XML);
-
-    final XMLEventReader reader = getEventReader(src);
-    final XmlElement property = extractElement(reader, null, pathElements, 0, 3, 4).getValue();
-
-    reader.close();
-    IOUtils.closeQuietly(src);
-
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    final XMLEventWriter writer = getEventWriter(bos);
-
-    final XMLEventFactory eventFactory = XMLEventFactory.newInstance();
-    writer.add(eventFactory.createStartDocument("UTF-8", "1.0"));
-    writer.add(property.getStart());
-
-    if (property.getStart().getAttributeByName(new QName(ATOM_DATASERVICE_NS)) == null) {
-      writer.add(eventFactory.createNamespace(ATOM_PROPERTY_PREFIX.substring(0, 1), DATASERVICES_NS));
-    }
-    if (property.getStart().getAttributeByName(new QName(ATOM_METADATA_NS)) == null) {
-      writer.add(eventFactory.createNamespace(ATOM_METADATA_PREFIX.substring(0, 1), METADATA_NS));
-    }
-
-    writer.add(property.getContentReader());
-    writer.add(property.getEnd());
-
-    writer.flush();
-    writer.close();
-
-    return new ByteArrayInputStream(bos.toByteArray());
-  }
-
-  @Override
-  public InputStream replaceProperty(
-          final InputStream src, final InputStream replacement, final List<String> path, final boolean justValue)
-          throws Exception {
-
-    final List<String> pathElements = new ArrayList<String>();
-
-    for (String element : path) {
-      pathElements.add(ATOM_PROPERTY_PREFIX + element);
-    }
-
-    final XMLEventReader reader = getEventReader(src);
-
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    final XMLEventWriter writer = getEventWriter(bos);
-
-    final Map.Entry<Integer, XmlElement> element = extractElement(reader, writer, pathElements, 0, 3, 4);
-
-    if (justValue) {
-      writer.add(element.getValue().getStart());
-    }
-
-    final XMLEventReader changesReader = new XMLEventReaderWrapper(replacement);
-
-    writer.add(changesReader);
-    changesReader.close();
-    IOUtils.closeQuietly(replacement);
-
-    if (justValue) {
-      writer.add(element.getValue().getEnd());
-    }
-
-    writer.add(reader);
-
-    reader.close();
-    IOUtils.closeQuietly(src);
-
-    writer.flush();
-    writer.close();
-
-    return new ByteArrayInputStream(bos.toByteArray());
-  }
-
-  @Override
-  public InputStream deleteProperty(final InputStream src, final List<String> path) throws Exception {
-
-    final List<String> pathElements = new ArrayList<String>();
-
-    for (String element : path) {
-      pathElements.add(ATOM_PROPERTY_PREFIX + element);
-    }
-
-    final XMLEventReader reader = getEventReader(src);
-
-    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-    final XMLEventWriter writer = getEventWriter(bos);
-
-    final Map.Entry<Integer, XmlElement> element = extractElement(reader, writer, pathElements, 0, 3, 4);
-
-    final XMLEventReader changesReader = new XMLEventReaderWrapper(
-            IOUtils.toInputStream(String.format("<%s m:null=\"true\" />", path.get(path.size() - 1))));
-
-    writer.add(changesReader);
-    changesReader.close();
-
-    writer.add(reader);
-
-    reader.close();
-    IOUtils.closeQuietly(src);
-
-    writer.flush();
-    writer.close();
-
-    return new ByteArrayInputStream(bos.toByteArray());
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/v3/JSONUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v3/JSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/v3/JSONUtilities.java
new file mode 100644
index 0000000..0f2a3f2
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/v3/JSONUtilities.java
@@ -0,0 +1,28 @@
+/*
+ * 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.utils.v3;
+
+import org.apache.olingo.fit.utils.ODataVersion;
+
+public class JSONUtilities extends org.apache.olingo.fit.utils.AbstractJSONUtilities {
+
+  public JSONUtilities() throws Exception {
+    super(ODataVersion.v3);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java
new file mode 100644
index 0000000..c1a58bf
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/v3/XMLUtilities.java
@@ -0,0 +1,191 @@
+/*
+ * 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.utils.v3;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.StartElement;
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.fit.utils.Accept;
+import org.apache.olingo.fit.utils.Commons;
+import org.apache.olingo.fit.utils.Constants;
+import org.apache.olingo.fit.utils.MetadataLinkInfo;
+import org.apache.olingo.fit.utils.ODataVersion;
+import org.apache.olingo.fit.utils.XmlElement;
+
+public class XMLUtilities extends org.apache.olingo.fit.utils.AbstractXMLUtilities {
+
+  public XMLUtilities() throws Exception {
+    super(ODataVersion.v3);
+  }
+
+  @Override
+  public void retrieveLinkInfoFromMetadata() throws Exception {
+
+    final MetadataLinkInfo metadataLinkInfo = new MetadataLinkInfo();
+    Commons.getLinkInfo().put(version, metadataLinkInfo);
+
+    final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
+    final XMLEventReader reader = getEventReader(metadata);
+
+    try {
+      while (true) {
+        final Map.Entry<Integer, XmlElement> entitySetElement =
+                extractElement(reader, null, Collections.<String>singletonList("EntitySet"),
+                null, false, 0, -1, -1);
+
+        retrieveLinks(entitySetElement.getValue(), metadataLinkInfo);
+      }
+    } catch (Exception e) {
+    } finally {
+      reader.close();
+    }
+  }
+
+  private void retrieveLinks(final XmlElement entitySetElement, final MetadataLinkInfo metadataLinkInfo)
+          throws Exception {
+
+    final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    IOUtils.copy(metadata, bos);
+    IOUtils.closeQuietly(metadata);
+
+    final String entitySetName = entitySetElement.getStart().getAttributeByName(new QName("Name")).getValue().trim();
+    final String entityType = entitySetElement.getStart().getAttributeByName(new QName("EntityType")).getValue().trim();
+
+    final Collection<Map.Entry<String, String>> filter = new HashSet<Map.Entry<String, String>>();
+    filter.add(new SimpleEntry<String, String>(
+            "Name", entityType.substring(entityType.lastIndexOf(".") + 1, entityType.length())));
+    filter.add(new SimpleEntry<String, String>("BaseType", entityType));
+
+    final XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+    final Map.Entry<Integer, XmlElement> entityTypeElement = extractElement(
+            reader, null, Collections.<String>singletonList("EntityType"), filter, true, 0, -1, -1);
+
+    final XMLEventReader entityReader = entityTypeElement.getValue().getContentReader();
+    int size = 0;
+
+    try {
+      while (true) {
+        final XmlElement navProperty =
+                extractElement(entityReader, null, Collections.<String>singletonList("NavigationProperty"),
+                null, false, 0, -1, -1).getValue();
+
+        final String linkName = navProperty.getStart().getAttributeByName(new QName("Name")).getValue();
+        final Map.Entry<String, Boolean> target = getTargetInfo(navProperty.getStart(), linkName);
+
+        metadataLinkInfo.addLink(
+                entitySetName,
+                linkName,
+                target.getKey(),
+                target.getValue());
+
+        size++;
+      }
+    } catch (Exception e) {
+    } finally {
+      entityReader.close();
+    }
+
+    if (size == 0) {
+      metadataLinkInfo.addEntitySet(entitySetName);
+    }
+  }
+
+  private Map.Entry<String, Boolean> getTargetInfo(final StartElement element, final String linkName)
+          throws Exception {
+    final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    IOUtils.copy(metadata, bos);
+    IOUtils.closeQuietly(metadata);
+
+    // ------------------------------------
+    // Retrieve association
+    // ------------------------------------
+    XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+    final String associationName = element.getAttributeByName(new QName("Relationship")).getValue();
+
+    final Map.Entry<Integer, XmlElement> association = extractElement(
+            reader, null, Collections.<String>singletonList("Association"),
+            Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>(
+            "Name", associationName.substring(associationName.lastIndexOf(".") + 1))), false,
+            0, 4, 4);
+
+    reader.close();
+    // ------------------------------------
+
+    // ------------------------------------
+    // check for feed or not from Association role
+    // ------------------------------------
+    InputStream associationContent = association.getValue().toStream();
+    reader = getEventReader(associationContent);
+
+    Map.Entry<Integer, XmlElement> associationEnd = extractElement(
+            reader, null, Collections.<String>singletonList("End"),
+            Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>("Role", linkName)),
+            false, 0, -1, -1);
+
+    reader.close();
+    IOUtils.closeQuietly(associationContent);
+
+    final boolean feed = associationEnd.getValue().getStart().getAttributeByName(
+            new QName("Multiplicity")).getValue().equals("*");
+    // ------------------------------------
+
+    // ------------------------------------
+    // Retrieve target association set name
+    // ------------------------------------
+    reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+    final Map.Entry<Integer, XmlElement> associationSet = extractElement(
+            reader, null, Collections.<String>singletonList("AssociationSet"),
+            Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>(
+            "Association", associationName)), false, 0, -1, -1);
+
+    reader.close();
+
+    associationContent = associationSet.getValue().toStream();
+    reader = getEventReader(associationContent);
+
+    associationEnd = extractElement(
+            reader, null, Collections.<String>singletonList("End"),
+            Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>("Role", linkName)),
+            false, 0, -1, -1);
+
+    reader.close();
+    IOUtils.closeQuietly(associationContent);
+
+    final String target = associationEnd.getValue().getStart().getAttributeByName(new QName("EntitySet")).getValue();
+    // ------------------------------------
+
+    return new SimpleEntry<String, Boolean>(target, feed);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java
new file mode 100644
index 0000000..daf75f4
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/v4/JSONUtilities.java
@@ -0,0 +1,28 @@
+/*
+ * 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.utils.v4;
+
+import org.apache.olingo.fit.utils.ODataVersion;
+
+public class JSONUtilities extends org.apache.olingo.fit.utils.AbstractJSONUtilities {
+
+  public JSONUtilities() throws Exception {
+    super(ODataVersion.v4);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/java/org/apache/olingo/fit/utils/v4/XMLUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/v4/XMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/v4/XMLUtilities.java
new file mode 100644
index 0000000..c61d272
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/v4/XMLUtilities.java
@@ -0,0 +1,142 @@
+/*
+ * 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.utils.v4;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.fit.utils.Accept;
+import org.apache.olingo.fit.utils.Commons;
+import org.apache.olingo.fit.utils.Constants;
+import org.apache.olingo.fit.utils.MetadataLinkInfo;
+import org.apache.olingo.fit.utils.ODataVersion;
+import org.apache.olingo.fit.utils.XmlElement;
+
+public class XMLUtilities extends org.apache.olingo.fit.utils.AbstractXMLUtilities {
+
+  public XMLUtilities() throws Exception {
+    super(ODataVersion.v4);
+  }
+
+  @Override
+  public void retrieveLinkInfoFromMetadata() throws Exception {
+
+    final MetadataLinkInfo metadataLinkInfo = new MetadataLinkInfo();
+    Commons.getLinkInfo().put(version, metadataLinkInfo);
+
+    final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
+
+    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    IOUtils.copy(metadata, bos);
+    IOUtils.closeQuietly(metadata);
+
+    XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+    final Set<String> singletons = new HashSet<String>();
+
+    try {
+      while (true) {
+        final Map.Entry<Integer, XmlElement> entitySetElement =
+                extractElement(reader, null, Collections.<String>singletonList("Singleton"),
+                null, false, 0, -1, -1);
+
+        final String entitySetName =
+                entitySetElement.getValue().getStart().getAttributeByName(new QName("Name")).getValue().trim();
+        singletons.add(entitySetName);
+      }
+    } catch (Exception e) {
+    } finally {
+      reader.close();
+    }
+
+    reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+    try {
+      while (true) {
+        final Map.Entry<Integer, XmlElement> entitySetElement =
+                extractElement(reader, null, Collections.<String>singletonList("EntitySet"),
+                null, false, 0, -1, -1);
+
+        retrieveLinks(entitySetElement.getValue(), metadataLinkInfo, singletons);
+      }
+    } catch (Exception e) {
+    } finally {
+      reader.close();
+    }
+
+    reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
+
+    try {
+      while (true) {
+        final Map.Entry<Integer, XmlElement> entitySetElement =
+                extractElement(reader, null, Collections.<String>singletonList("Singleton"),
+                null, false, 0, -1, -1);
+
+        retrieveLinks(entitySetElement.getValue(), metadataLinkInfo, singletons);
+      }
+    } catch (Exception e) {
+    } finally {
+      reader.close();
+    }
+  }
+
+  private void retrieveLinks(
+          final XmlElement entitySetElement, final MetadataLinkInfo metadataLinkInfo, final Set<String> singletons)
+          throws Exception {
+
+    final String entitySetName = entitySetElement.getStart().getAttributeByName(new QName("Name")).getValue().trim();
+
+    final XMLEventReader entityReader = entitySetElement.getContentReader();
+    int size = 0;
+
+    try {
+      while (true) {
+        final XmlElement navProperty =
+                extractElement(entityReader, null, Collections.<String>singletonList("NavigationPropertyBinding"),
+                null, false, 0, -1, -1).getValue();
+
+        final String linkName = navProperty.getStart().getAttributeByName(new QName("Path")).getValue();
+        final String target = navProperty.getStart().getAttributeByName(new QName("Target")).getValue();
+        final boolean feed = !singletons.contains(target);
+
+        metadataLinkInfo.addLink(
+                entitySetName,
+                linkName,
+                target,
+                feed);
+
+        size++;
+      }
+    } catch (Exception e) {
+    } finally {
+      entityReader.close();
+    }
+
+    if (size == 0) {
+      metadataLinkInfo.addEntitySet(entitySetName);
+    }
+  }
+}


[2/8] [OLINGO-205, OLINGO-200] provided atom v4 deserialization for entity type/set + entity set request

Posted by fm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
index f64b233..7ba38f8 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
@@ -20,6 +20,7 @@ package org.apache.olingo.client.api.communication.request;
 
 import java.util.concurrent.Future;
 import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.format.Format;
 
 /**
  * Basic OData request.
@@ -27,7 +28,7 @@ import org.apache.olingo.client.api.communication.response.ODataResponse;
  * @param <V> OData response type corresponding to the request implementation.
  * @param <T> Accepted content-type formats by the request in object.
  */
-public interface ODataBasicRequest<V extends ODataResponse, T extends Enum<T>> extends ODataRequest {
+public interface ODataBasicRequest<V extends ODataResponse, T extends Format> extends ODataRequest {
 
   /**
    * Request execute.

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
index edabb96..14f907e 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
@@ -20,9 +20,10 @@ package org.apache.olingo.client.api.communication.request.retrieve;
 
 import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
 import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.format.Format;
 
 /**
  * This is an abstract representation of an OData retrieve query request returning one or more result item.
  */
-public interface ODataRetrieveRequest<V, T extends Enum<T>> extends ODataBasicRequest<ODataRetrieveResponse<V>, T> {
+public interface ODataRetrieveRequest<V, T extends Format> extends ODataBasicRequest<ODataRetrieveResponse<V>, T> {
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataLinkType.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataLinkType.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataLinkType.java
index 6702c00..179f9cc 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataLinkType.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataLinkType.java
@@ -20,7 +20,6 @@ package org.apache.olingo.client.api.domain;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.entity.ContentType;
-import org.apache.olingo.client.api.format.ODataPubFormat;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 
 /**
@@ -31,11 +30,11 @@ public enum ODataLinkType {
   /**
    * Entity navigation link.
    */
-  ENTITY_NAVIGATION(ODataPubFormat.ATOM + ";type=entry"),
+  ENTITY_NAVIGATION(ContentType.APPLICATION_ATOM_XML.getMimeType() + ";type=entry"),
   /**
    * Entity set navigation link.
    */
-  ENTITY_SET_NAVIGATION(ODataPubFormat.ATOM + ";type=feed"),
+  ENTITY_SET_NAVIGATION(ContentType.APPLICATION_ATOM_XML.getMimeType() + ";type=feed"),
   /**
    * Association link.
    */
@@ -57,7 +56,8 @@ public enum ODataLinkType {
   }
 
   /**
-   * Gets <code>LinkType</code> instance from the given rel and type.
+   * Gets
+   * <code>LinkType</code> instance from the given rel and type.
    *
    * @param client OData client.
    * @param rel rel.

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/format/Format.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/Format.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/Format.java
new file mode 100644
index 0000000..1d52664
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/Format.java
@@ -0,0 +1,26 @@
+/*
+ * 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.client.api.format;
+
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+
+public interface Format {
+
+  String toString(ODataServiceVersion version);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataFormat.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataFormat.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataFormat.java
index 2ee704b..8f52ea3 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataFormat.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataFormat.java
@@ -19,11 +19,12 @@
 package org.apache.olingo.client.api.format;
 
 import org.apache.http.entity.ContentType;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 
 /**
  * Available formats to be used in various contexts.
  */
-public enum ODataFormat {
+public enum ODataFormat implements Format{
 
   /**
    * JSON format with no metadata.
@@ -94,4 +95,9 @@ public enum ODataFormat {
 
     return result;
   }
+
+  @Override
+  public String toString(final ODataServiceVersion version) {
+    return this.toString();
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataMediaFormat.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataMediaFormat.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataMediaFormat.java
index 353edc4..5d49ddb 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataMediaFormat.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataMediaFormat.java
@@ -19,11 +19,12 @@
 package org.apache.olingo.client.api.format;
 
 import org.apache.http.entity.ContentType;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 
 /**
  * Available formats for media.
  */
-public enum ODataMediaFormat {
+public enum ODataMediaFormat implements Format{
 
   CHARSET_PARAMETER("charset"),
   MEDIA_TYPE_WILDCARD("*"),
@@ -68,4 +69,9 @@ public enum ODataMediaFormat {
 
     return result;
   }
+
+  @Override
+  public String toString(final ODataServiceVersion version) {
+    return this.toString();
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataPubFormat.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataPubFormat.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataPubFormat.java
index 62e5322..aea294f 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataPubFormat.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataPubFormat.java
@@ -18,34 +18,49 @@
  */
 package org.apache.olingo.client.api.format;
 
+import java.util.EnumMap;
 import org.apache.http.entity.ContentType;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 
 /**
  * Available formats for AtomPub exchange.
  */
-public enum ODataPubFormat {
+public enum ODataPubFormat implements Format {
 
   /**
    * JSON format with no metadata.
    */
-  JSON_NO_METADATA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=nometadata"),
+  JSON_NO_METADATA(),
   /**
    * JSON format with minimal metadata (default).
    */
-  JSON(ContentType.APPLICATION_JSON.getMimeType() + ";odata=minimalmetadata"),
+  JSON(),
   /**
    * JSON format with no metadata.
    */
-  JSON_FULL_METADATA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=fullmetadata"),
+  JSON_FULL_METADATA(),
   /**
    * Atom format.
    */
-  ATOM(ContentType.APPLICATION_ATOM_XML.getMimeType());
+  ATOM();
 
-  private final String format;
+  final static EnumMap<ODataServiceVersion, EnumMap<ODataPubFormat, String>> formatPerVersion =
+          new EnumMap<ODataServiceVersion, EnumMap<ODataPubFormat, String>>(ODataServiceVersion.class);
 
-  ODataPubFormat(final String format) {
-    this.format = format;
+  static {
+    final EnumMap<ODataPubFormat, String> v3 = new EnumMap<ODataPubFormat, String>(ODataPubFormat.class);
+    v3.put(JSON_NO_METADATA, ContentType.APPLICATION_JSON.getMimeType() + ";odata=nometadata");
+    v3.put(JSON, ContentType.APPLICATION_JSON.getMimeType() + ";odata=minimalmetadata");
+    v3.put(JSON_FULL_METADATA, ContentType.APPLICATION_JSON.getMimeType() + ";odata=fullmetadata");
+    v3.put(ATOM, ContentType.APPLICATION_ATOM_XML.getMimeType());
+    formatPerVersion.put(ODataServiceVersion.V30, v3);
+
+    final EnumMap<ODataPubFormat, String> v4 = new EnumMap<ODataPubFormat, String>(ODataPubFormat.class);
+    v4.put(JSON_NO_METADATA, ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=none");
+    v4.put(JSON, ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=minimal");
+    v4.put(JSON_FULL_METADATA, ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=full");
+    v4.put(ATOM, ContentType.APPLICATION_ATOM_XML.getMimeType());
+    formatPerVersion.put(ODataServiceVersion.V40, v4);
   }
 
   /**
@@ -54,8 +69,17 @@ public enum ODataPubFormat {
    * @return format as a string.
    */
   @Override
+  public String toString(final ODataServiceVersion version) {
+    if (version.ordinal() < ODataServiceVersion.V30.ordinal()) {
+      throw new IllegalArgumentException("Unsupported version " + version);
+    }
+
+    return ODataPubFormat.formatPerVersion.get(version).get(this);
+  }
+
+  @Override
   public String toString() {
-    return format;
+    throw new UnsupportedOperationException();
   }
 
   /**
@@ -72,7 +96,7 @@ public enum ODataPubFormat {
     final String[] parts = format.split(";");
     _format.append(parts[0].trim());
     if (ContentType.APPLICATION_JSON.getMimeType().equals(parts[0].trim())) {
-      if (parts.length > 1 && parts[1].startsWith("odata=")) {
+      if (parts.length > 1 && parts[1].startsWith("odata")) {
         _format.append(';').append(parts[1].trim());
       } else {
         result = ODataPubFormat.JSON;
@@ -82,7 +106,8 @@ public enum ODataPubFormat {
     if (result == null) {
       final String candidate = _format.toString();
       for (ODataPubFormat value : values()) {
-        if (candidate.equals(value.toString())) {
+        if (candidate.equals(value.toString(ODataServiceVersion.V30))
+                || candidate.equals(value.toString(ODataServiceVersion.V40))) {
           result = value;
         }
       }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataValueFormat.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataValueFormat.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataValueFormat.java
index b04ce7d..818b104 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataValueFormat.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/format/ODataValueFormat.java
@@ -19,11 +19,12 @@
 package org.apache.olingo.client.api.format;
 
 import org.apache.http.entity.ContentType;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 
 /**
  * Available formats for property values.
  */
-public enum ODataValueFormat {
+public enum ODataValueFormat implements Format{
 
   /**
    * Application octet stream.
@@ -73,4 +74,9 @@ public enum ODataValueFormat {
 
     return result;
   }
+
+  @Override
+  public String toString(final ODataServiceVersion version) {
+    return this.toString();
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
index 307cdc9..8cd5819 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
@@ -31,6 +31,7 @@ import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
 import org.apache.olingo.client.api.communication.request.ODataStreamer;
 import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
 import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.format.Format;
 import org.apache.olingo.client.api.http.HttpMethod;
 
 /**
@@ -39,88 +40,87 @@ import org.apache.olingo.client.api.http.HttpMethod;
  * @param <V> OData response type corresponding to the request implementation.
  * @param <T> OData format being used.
  */
-public abstract class AbstractODataBasicRequest<V extends ODataResponse, T extends Enum<T>>
+public abstract class AbstractODataBasicRequest<V extends ODataResponse, T extends Format>
         extends ODataRequestImpl<T>
         implements ODataBasicRequest<V, T> {
 
-    /**
-     * Constructor.
-     *
-     * @param odataClient client instance getting this request
-     * @param formatRef reference class for the format being used
-     * @param method request method.
-     * @param uri OData request URI.
-     */
-    public AbstractODataBasicRequest(final CommonODataClient odataClient,
-            final Class<T> formatRef, final HttpMethod method, final URI uri) {
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param formatRef reference class for the format being used
+   * @param method request method.
+   * @param uri OData request URI.
+   */
+  public AbstractODataBasicRequest(final CommonODataClient odataClient,
+          final Class<T> formatRef, final HttpMethod method, final URI uri) {
 
-        super(odataClient, formatRef, method, uri);
-    }
+    super(odataClient, formatRef, method, uri);
+  }
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setFormat(final T format) {
-        if (format != null) {
-            setAccept(format.toString());
-            setContentType(format.toString());
-        }
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void setFormat(final T format) {
+    if (format != null) {
+      setAccept(format.toString(odataClient.getServiceVersion()));
+      setContentType(format.toString(odataClient.getServiceVersion()));
     }
+  }
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public final Future<V> asyncExecute() {
-        return odataClient.getConfiguration().getExecutor().submit(new Callable<V>() {
-
-            @Override
-            public V call() throws Exception {
-                return execute();
-            }
-        });
-    }
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public final Future<V> asyncExecute() {
+    return odataClient.getConfiguration().getExecutor().submit(new Callable<V>() {
+      @Override
+      public V call() throws Exception {
+        return execute();
+      }
+    });
+  }
 
-    /**
-     * Gets payload as an InputStream.
-     *
-     * @return InputStream for entire payload.
-     */
-    protected abstract InputStream getPayload();
+  /**
+   * Gets payload as an InputStream.
+   *
+   * @return InputStream for entire payload.
+   */
+  protected abstract InputStream getPayload();
 
-    /**
-     * Serializes the full request into the given batch request.
-     *
-     * @param req destination batch request.
-     */
-    public void batch(final ODataBatchRequest req) {
-        batch(req, null);
-    }
+  /**
+   * Serializes the full request into the given batch request.
+   *
+   * @param req destination batch request.
+   */
+  public void batch(final ODataBatchRequest req) {
+    batch(req, null);
+  }
 
-    /**
-     * Serializes the full request into the given batch request.
-     * <p>
-     * This method have to be used to serialize a changeset item with the specified contentId.
-     *
-     * @param req destination batch request.
-     * @param contentId contentId of the changeset item.
-     */
-    public void batch(final ODataBatchRequest req, final String contentId) {
-        try {
-            req.rawAppend(toByteArray());
-            if (StringUtils.isNotBlank(contentId)) {
-                req.rawAppend((ODataBatchConstants.CHANGESET_CONTENT_ID_NAME + ": " + contentId).getBytes());
-                req.rawAppend(ODataStreamer.CRLF);
-            }
-            req.rawAppend(ODataStreamer.CRLF);
+  /**
+   * Serializes the full request into the given batch request.
+   * <p>
+   * This method have to be used to serialize a changeset item with the specified contentId.
+   *
+   * @param req destination batch request.
+   * @param contentId contentId of the changeset item.
+   */
+  public void batch(final ODataBatchRequest req, final String contentId) {
+    try {
+      req.rawAppend(toByteArray());
+      if (StringUtils.isNotBlank(contentId)) {
+        req.rawAppend((ODataBatchConstants.CHANGESET_CONTENT_ID_NAME + ": " + contentId).getBytes());
+        req.rawAppend(ODataStreamer.CRLF);
+      }
+      req.rawAppend(ODataStreamer.CRLF);
 
-            final InputStream payload = getPayload();
-            if (payload != null) {
-                req.rawAppend(IOUtils.toByteArray(getPayload()));
-            }
-        } catch (IOException e) {
-            throw new IllegalStateException(e);
-        }
+      final InputStream payload = getPayload();
+      if (payload != null) {
+        req.rawAppend(IOUtils.toByteArray(getPayload()));
+      }
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
     }
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
index d088e97..2e60a7d 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
@@ -42,6 +42,10 @@ import org.apache.olingo.client.api.communication.header.ODataHeaderValues;
 import org.apache.olingo.client.api.communication.header.ODataHeaders;
 import org.apache.olingo.client.api.communication.request.ODataRequest;
 import org.apache.olingo.client.api.communication.request.ODataStreamer;
+import org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory;
+import org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory;
+import org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory;
+import org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory;
 import org.apache.olingo.client.api.communication.response.ODataResponse;
 import org.apache.olingo.client.api.format.ODataMediaFormat;
 import org.apache.olingo.client.api.format.ODataPubFormat;
@@ -51,6 +55,7 @@ import org.apache.olingo.client.api.http.HttpMethod;
 import org.apache.olingo.client.core.data.JSONErrorImpl;
 import org.apache.olingo.client.core.data.XMLErrorImpl;
 import org.apache.olingo.client.api.data.ODataError;
+import org.apache.olingo.client.api.format.Format;
 import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.slf4j.Logger;
@@ -66,7 +71,7 @@ import org.slf4j.LoggerFactory;
  * @see InvokeRequestFactory
  * @see StreamedRequestFactory
  */
-public class ODataRequestImpl<T extends Enum<T>> implements ODataRequest {
+public class ODataRequestImpl<T extends Format> implements ODataRequest {
 
   /**
    * Logger.
@@ -251,7 +256,7 @@ public class ODataRequestImpl<T extends Enum<T>> implements ODataRequest {
   @Override
   public String getAccept() {
     final String acceptHead = odataHeaders.getHeader(HeaderName.accept);
-    return StringUtils.isBlank(acceptHead) ? getDefaultFormat().toString() : acceptHead;
+    return StringUtils.isBlank(acceptHead) ? getDefaultFormat().toString(odataClient.getServiceVersion()) : acceptHead;
   }
 
   /**
@@ -284,7 +289,8 @@ public class ODataRequestImpl<T extends Enum<T>> implements ODataRequest {
   @Override
   public String getContentType() {
     final String contentTypeHead = odataHeaders.getHeader(HeaderName.contentType);
-    return StringUtils.isBlank(contentTypeHead) ? getDefaultFormat().toString() : contentTypeHead;
+    return StringUtils.isBlank(contentTypeHead)
+            ? getDefaultFormat().toString(odataClient.getServiceVersion()) : contentTypeHead;
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java
index c6355e4..abef76c 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java
@@ -100,7 +100,7 @@ public class ODataInvokeRequestImpl<T extends ODataInvokeResult>
   public void setFormat(final ODataPubFormat format) {
     final String _format = (reference.isAssignableFrom(ODataProperty.class) && format == ODataPubFormat.ATOM)
             ? ODataFormat.XML.toString()
-            : format.toString();
+            : format.toString(odataClient.getServiceVersion());
     setAccept(_format);
     setContentType(_format);
   }
@@ -163,7 +163,7 @@ public class ODataInvokeRequestImpl<T extends ODataInvokeResult>
       } else if (this.method == HttpMethod.POST) {
         ((HttpPost) request).setEntity(URIUtils.buildInputStreamEntity(odataClient, input));
 
-        setContentType(ODataPubFormat.JSON.toString());
+        setContentType(ODataPubFormat.JSON.toString(odataClient.getServiceVersion()));
       }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
index fe51722..628e836 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
@@ -26,6 +26,7 @@ import org.apache.olingo.client.api.CommonODataClient;
 import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.retrieve.ODataRetrieveRequest;
 import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.format.Format;
 import org.apache.olingo.client.api.http.HttpMethod;
 import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
 import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
@@ -33,7 +34,7 @@ import org.apache.olingo.client.core.communication.response.AbstractODataRespons
 /**
  * This is an abstract representation of an OData retrieve query request returning one or more result item.
  */
-public abstract class AbstractODataRetrieveRequest<V, T extends Enum<T>>
+public abstract class AbstractODataRetrieveRequest<V, T extends Format>
         extends AbstractODataBasicRequest<ODataRetrieveResponse<V>, T>
         implements ODataRetrieveRequest<V, T>, ODataBatchableRequest {
 

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
index 4226cc2..777d86a 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
@@ -92,7 +92,7 @@ public class ODataRawRequestImpl extends ODataRequestImpl<ODataPubFormat>
           this.close();
         }
       }
-
+      
       return odataClient.getReader().read(new ByteArrayInputStream(obj), getContentType(), reference);
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java
index d19d0d5..c7f7c52 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java
@@ -48,7 +48,7 @@ public abstract class AbstractODataStreamedEntityRequest<V extends ODataResponse
   public AbstractODataStreamedEntityRequest(final CommonODataClient odataClient, final HttpMethod method,
           URI uri) {
     super(odataClient, method, uri);
-    setAccept(getFormat().toString());
+    setAccept(getFormat().toString(odataClient.getServiceVersion()));
   }
 
   /**
@@ -65,6 +65,6 @@ public abstract class AbstractODataStreamedEntityRequest<V extends ODataResponse
   @Override
   public final void setFormat(final ODataPubFormat format) {
     this.format = format;
-    setAccept(format.toString());
+    setAccept(format.toString(odataClient.getServiceVersion()));
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
index 74b29fb..3aca585 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
@@ -57,7 +57,7 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
   }
 
   private ODataPropertyType guessPropertyType(final JsonNode node) {
-    ODataPropertyType type = null;
+    final ODataPropertyType type;
 
     if (node.isValueNode() || node.isNull()) {
       type = ODataPropertyType.PRIMITIVE;
@@ -73,7 +73,7 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
   }
 
   private Value fromPrimitive(final JsonNode node, final EdmTypeInfo typeInfo) {
-    Value value = null;
+    final Value value;
 
     if (node.isNull()) {
       value = new NullValueImpl();
@@ -172,5 +172,4 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
         property.setValue(new PrimitiveValueImpl(StringUtils.EMPTY));
     }
   }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
index 8893b91..835d174 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
@@ -153,7 +153,6 @@ public class AtomDeserializer extends AbstractAtomDealer {
 
   private void properties(final XMLEventReader reader, final StartElement start, final AtomEntryImpl entry)
           throws XMLStreamException {
-
     boolean foundEndProperties = false;
     while (reader.hasNext() && !foundEndProperties) {
       final XMLEvent event = reader.nextEvent();
@@ -316,7 +315,6 @@ public class AtomDeserializer extends AbstractAtomDealer {
     boolean foundEndFeed = false;
     while (reader.hasNext() && !foundEndFeed) {
       final XMLEvent event = reader.nextEvent();
-
       if (event.isStartElement()) {
         if (countQName.equals(event.asStartElement().getName())) {
           count(reader, event.asStartElement(), feed);

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomPropertyDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomPropertyDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomPropertyDeserializer.java
index 884d815..42d2504 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomPropertyDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomPropertyDeserializer.java
@@ -139,7 +139,7 @@ class AtomPropertyDeserializer extends AbstractAtomDealer {
       }
     }
 
-    ODataPropertyType type = null;
+    final ODataPropertyType type;
     if (child == null) {
       type = ODataPropertyType.PRIMITIVE;
     } else {
@@ -168,16 +168,19 @@ class AtomPropertyDeserializer extends AbstractAtomDealer {
     property.setName(start.getName().getLocalPart());
 
     final Attribute typeAttr = start.getAttributeByName(this.typeQName);
-    if (typeAttr != null) {
-      property.setType(typeAttr.getValue());
-    }
 
     Value value;
     final Attribute nullAttr = start.getAttributeByName(this.nullQName);
+    final String typeAttrValue = typeAttr == null ? null : typeAttr.getValue();
+
     if (nullAttr == null) {
-      final EdmTypeInfo typeInfo = StringUtils.isBlank(property.getType())
+      final EdmTypeInfo typeInfo = StringUtils.isBlank(typeAttrValue)
               ? null
-              : new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
+              : new EdmTypeInfo.Builder().setTypeExpression(typeAttrValue).build();
+
+      if (typeInfo != null) {
+        property.setType(typeInfo.getTypeExpression());
+      }
 
       final ODataPropertyType propType = typeInfo == null
               ? guessPropertyType(reader)
@@ -207,6 +210,7 @@ class AtomPropertyDeserializer extends AbstractAtomDealer {
     } else {
       value = new NullValueImpl();
     }
+
     property.setValue(value);
 
     return property;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java
index eebfef3..c77369a 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java
@@ -60,7 +60,7 @@ class JSONGeoValueDeserializer {
   private MultiPoint multipoint(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
           final String crs) {
 
-    MultiPoint multiPoint = null;
+    final MultiPoint multiPoint;
 
     if (itor.hasNext()) {
       final List<Point> points = new ArrayList<Point>();
@@ -79,7 +79,7 @@ class JSONGeoValueDeserializer {
   private LineString lineString(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
           final String crs) {
 
-    LineString lineString = null;
+    final LineString lineString;
 
     if (itor.hasNext()) {
       final List<Point> points = new ArrayList<Point>();
@@ -98,7 +98,7 @@ class JSONGeoValueDeserializer {
   private MultiLineString multiLineString(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
           final String crs) {
 
-    MultiLineString multiLineString = null;
+    final MultiLineString multiLineString;
 
     if (itor.hasNext()) {
       final List<LineString> lineStrings = new ArrayList<LineString>();
@@ -147,7 +147,7 @@ class JSONGeoValueDeserializer {
   private MultiPolygon multiPolygon(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
           final String crs) {
 
-    MultiPolygon multiPolygon = null;
+    final MultiPolygon multiPolygon;
 
     if (itor.hasNext()) {
       final List<Polygon> polygons = new ArrayList<Polygon>();
@@ -166,7 +166,7 @@ class JSONGeoValueDeserializer {
   private GeospatialCollection collection(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
           final String crs) {
 
-    GeospatialCollection collection = null;
+    final GeospatialCollection collection;
 
     if (itor.hasNext()) {
       final List<Geospatial> geospatials = new ArrayList<Geospatial>();
@@ -262,5 +262,4 @@ class JSONGeoValueDeserializer {
 
     return value;
   }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
index 3827418..bf047af 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmActionImportImpl.java
@@ -19,7 +19,6 @@
 package org.apache.olingo.client.core.edm;
 
 import org.apache.olingo.client.api.edm.xml.v4.ActionImport;
-import org.apache.olingo.client.core.edm.EdmTypeInfo;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmAction;
 import org.apache.olingo.commons.api.edm.EdmActionImport;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmOperationImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmOperationImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmOperationImpl.java
index f54d6c1..da29a68 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmOperationImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmOperationImpl.java
@@ -70,12 +70,12 @@ public abstract class EdmOperationImpl extends AbstractEdmOperation {
 
   @Override
   public FullQualifiedName getBindingParameterTypeFqn() {
-    FullQualifiedName fqn = null;
+    FullQualifiedName bpfqn = null;
     final EdmParameter bindingParam = getBindingParameter();
     if (bindingParam != null) {
-      fqn = new FullQualifiedName(bindingParam.getType().getNamespace(), bindingParam.getType().getName());
+      bpfqn = new FullQualifiedName(bindingParam.getType().getNamespace(), bindingParam.getType().getName());
     }
-    return fqn;
+    return bpfqn;
   }
 
   @Override
@@ -85,6 +85,6 @@ public abstract class EdmOperationImpl extends AbstractEdmOperation {
     if (bindingParam != null) {
       result = bindingParam.isCollection();
     }
-    return null;
+    return result;
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java
index 461e829..abf1a54 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java
@@ -23,6 +23,7 @@ import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmComplexType;
 import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.edm.EdmEnumType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.slf4j.Logger;
@@ -56,12 +57,11 @@ public class EdmTypeInfo {
     }
 
     public EdmTypeInfo build() {
-      return new EdmTypeInfo(edm, typeExpression.indexOf('.') == -1
+      return new EdmTypeInfo(edm, typeExpression.indexOf('.') == -1 && StringUtils.isNotBlank(defaultNamespace)
               ? defaultNamespace + "." + typeExpression
               : typeExpression);
     }
   }
-
   private final Edm edm;
 
   private final String typeExpression;
@@ -80,7 +80,6 @@ public class EdmTypeInfo {
 
   private EdmTypeInfo(final Edm edm, final String typeExpression) {
     this.edm = edm;
-    this.typeExpression = typeExpression;
 
     String baseType;
     final int collStartIdx = typeExpression.indexOf("Collection(");
@@ -97,16 +96,30 @@ public class EdmTypeInfo {
       baseType = typeExpression.substring(collStartIdx + 11, collEndIdx);
     }
 
+
+    baseType = baseType.replaceAll("^#", "");
+
+    final String typeName;
+    final String namespace;
+
     final int lastDotIdx = baseType.lastIndexOf('.');
     if (lastDotIdx == -1) {
-      throw new IllegalArgumentException("Cannot find namespace or alias in " + typeExpression);
+      namespace = EdmPrimitiveType.EDM_NAMESPACE;
+      typeName = baseType;
+      baseType = new FullQualifiedName(EdmPrimitiveType.EDM_NAMESPACE, baseType).toString();
+    } else {
+      namespace = baseType.substring(0, lastDotIdx);
+      typeName = baseType.substring(lastDotIdx + 1);
     }
-    final String namespace = baseType.substring(0, lastDotIdx);
-    final String typeName = baseType.substring(lastDotIdx + 1);
+
     if (StringUtils.isBlank(typeName)) {
       throw new IllegalArgumentException("Null or empty type name in " + typeExpression);
     }
 
+    final StringBuilder exp = new StringBuilder();
+    exp.append(baseType);
+
+    this.typeExpression = (this.collection ? exp.insert(0, "Collection(").append(")") : exp).toString();
     this.fullQualifiedName = new FullQualifiedName(namespace, typeName);
 
     try {
@@ -168,5 +181,4 @@ public class EdmTypeInfo {
   public EdmEntityType getEntityType() {
     return entityType;
   }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
index 2c2cdea..09c39ef 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
@@ -268,7 +268,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
     }
 
     final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI;
-
+    
     final URI next = resource.getNext();
 
     final ODataEntitySet entitySet = next == null
@@ -282,7 +282,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
     for (Entry entryResource : resource.getEntries()) {
       entitySet.addEntity(getODataEntity(entryResource));
     }
-
+    
     return entitySet;
   }
 
@@ -310,11 +310,11 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
     if (StringUtils.isNotBlank(resource.getETag())) {
       entity.setETag(resource.getETag());
     }
-
+    
     if (resource.getEditLink() != null) {
       entity.setEditLink(URIUtils.getURI(base, resource.getEditLink().getHref()));
     }
-
+    
     for (Link link : resource.getAssociationLinks()) {
       entity.addLink(client.getObjectFactory().newAssociationLink(link.getTitle(), base, link.getHref()));
     }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
index 67acc09..103f81d 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
@@ -103,5 +103,4 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl
       throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
     }
   }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java
index 6637346..c69b469 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java
@@ -148,7 +148,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
             appendEntitySetSegment("Car").appendKeySegment(16);
 
     final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build());
-    req.setFormat(format.toString());
+    req.setFormat(format.toString(client.getServiceVersion()));
 
     final ODataRawResponse res = req.execute();
     assertNotNull(res);

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java
index 35cc3d6..3e69aff 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java
@@ -138,7 +138,7 @@ public class EntitySetTestITCase extends AbstractTestITCase {
     uriBuilder.appendEntitySetSegment("Car");
 
     final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build());
-    req.setFormat(format.toString());
+    req.setFormat(format.toString(client.getServiceVersion()));
 
     final ODataRawResponse res = req.execute();
     assertNotNull(res);

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java
index 3501482..21cf9ae 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java
@@ -107,7 +107,8 @@ public class QueryOptionsTestITCase extends AbstractTestITCase {
 
     final ODataRetrieveResponse<ODataEntity> res = req.execute();
     assertNotNull(res);
-    assertTrue(res.getContentType().replaceAll(" ", "").startsWith(ODataPubFormat.JSON.toString()));
+    assertTrue(res.getContentType().replaceAll(" ", "").
+            startsWith(ODataPubFormat.JSON.toString(client.getServiceVersion())));
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java
index 46a59bd..a745380 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/AbstractTestITCase.java
@@ -35,8 +35,8 @@ public abstract class AbstractTestITCase extends org.apache.olingo.client.core.i
 
   @BeforeClass
   public static void setUpODataServiceRoot() throws IOException {
-    testStaticServiceRootURL = "http://localhost:9080/StaticService/V30/Static.svc";
-    testLargeModelServiceRootURL = "http://localhost:9080/StaticService/V30/Static.svc/large";
+    testStaticServiceRootURL = "http://localhost:9080/StaticService/V40/Static.svc";
+    testLargeModelServiceRootURL = "http://localhost:9080/StaticService/V40/Static.svc/large";
     testAuthServiceRootURL = "http://localhost:9080/DefaultService.svc";
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
new file mode 100644
index 0000000..9e2527a
--- /dev/null
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
@@ -0,0 +1,152 @@
+/*
+ * 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.client.core.it.v4;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetIteratorRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
+import org.apache.olingo.client.api.communication.response.ODataRawResponse;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.domain.ODataEntitySet;
+import org.apache.olingo.client.api.domain.ODataEntitySetIterator;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+import org.apache.olingo.client.api.uri.CommonURIBuilder;
+import org.apache.olingo.client.core.op.impl.ResourceFactory;
+import static org.junit.Assert.assertNotNull;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * This is the unit test class to check basic feed operations.
+ */
+public class EntitySetTestITCase extends AbstractTestITCase {
+
+  protected String getServiceRoot() {
+    return testStaticServiceRootURL;
+  }
+
+  @Test
+  public void rawRequestAsAtom() throws IOException {
+    rawRequest(ODataPubFormat.ATOM);
+  }
+
+  @Test
+  @Ignore
+  public void rawRequestAsJSON() throws IOException {
+    rawRequest(ODataPubFormat.JSON);
+  }
+
+  @Test
+  public void readODataEntitySetIteratorFromAtom() {
+    readODataEntitySetIterator(ODataPubFormat.ATOM);
+  }
+
+  @Test
+  @Ignore
+  public void readODataEntitySetIteratorFromJSON() {
+    readODataEntitySetIterator(ODataPubFormat.JSON);
+  }
+
+  @Test
+  @Ignore
+  public void readODataEntitySetIteratorFromJSONFullMeta() {
+    readODataEntitySetIterator(ODataPubFormat.JSON_FULL_METADATA);
+  }
+
+  @Test
+  @Ignore
+  public void readODataEntitySetIteratorFromJSONNoMeta() {
+    readODataEntitySetIterator(ODataPubFormat.JSON_NO_METADATA);
+  }
+
+  @Test
+  public void readODataEntitySetWithNextFromAtom() {
+    readEntitySetWithNextLink(ODataPubFormat.ATOM);
+  }
+
+  @Test
+  @Ignore
+  public void readODataEntitySetWithNextFromJSON() {
+    readEntitySetWithNextLink(ODataPubFormat.JSON_FULL_METADATA);
+  }
+
+  private void readEntitySetWithNextLink(final ODataPubFormat format) {
+    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
+    uriBuilder.appendEntitySetSegment("People");
+
+    final ODataEntitySetRequest req = client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.build());
+    req.setFormat(format);
+
+    final ODataRetrieveResponse<ODataEntitySet> res = req.execute();
+    final ODataEntitySet feed = res.getBody();
+
+    assertNotNull(feed);
+
+    debugFeed(client.getBinder().getFeed(feed, ResourceFactory.feedClassForFormat(
+            ODataPubFormat.ATOM == format)), "Just retrieved feed");
+
+    assertEquals(5, feed.getEntities().size());
+//    assertNotNull(feed.getNext());
+
+//    final URI expected = URI.create(getServiceRoot() + "/Customer?$skiptoken=-9");
+//    final URI found = URIUtils.getURI(getServiceRoot(), feed.getNext().toASCIIString());
+
+//    assertEquals(expected, found);
+  }
+
+  private void readODataEntitySetIterator(final ODataPubFormat format) {
+    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
+    uriBuilder.appendEntitySetSegment("People");
+
+    final ODataEntitySetIteratorRequest req =
+            client.getRetrieveRequestFactory().getEntitySetIteratorRequest(uriBuilder.build());
+    req.setFormat(format);
+
+    final ODataRetrieveResponse<ODataEntitySetIterator> res = req.execute();
+    final ODataEntitySetIterator feedIterator = res.getBody();
+
+    assertNotNull(feedIterator);
+
+    int count = 0;
+
+    while (feedIterator.hasNext()) {
+      assertNotNull(feedIterator.next());
+      count++;
+    }
+    assertEquals(5, count);
+//    assertTrue(feedIterator.getNext().toASCIIString().endsWith("Customer?$skiptoken=-9"));
+  }
+
+  private void rawRequest(final ODataPubFormat format) {
+    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
+    uriBuilder.appendEntitySetSegment("People");
+
+    final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build());
+    req.setFormat(format.toString(client.getServiceVersion()));
+
+    final ODataRawResponse res = req.execute();
+    assertNotNull(res);
+
+    final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class);
+    assertNotNull(entitySet);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java
index c7aeff0..32e6fc8 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java
@@ -26,92 +26,93 @@ import java.util.List;
  * Interface representing a Entity Data Model as described in the Conceptual Schema Definition.
  */
 public interface Edm {
-  
-  /**
-   * This method DOES NOT support lazy loading. All schemas are loaded completely!
-   * @return all schemas defined for this EDM
-   */
-  List<EdmSchema> getSchemas();
 
-  /**
-   * Get entity container by full qualified name.
-   * <br/>
-   * See {@link EdmEntityContainer} for more information.
-   *
-   * @param name
-   * @return {@link EdmEntityContainer}
-   */
-  EdmEntityContainer getEntityContainer(FullQualifiedName name);
+    /**
+     * This method DOES NOT support lazy loading. All schemas are loaded completely!
+     *
+     * @return all schemas defined for this EDM
+     */
+    List<EdmSchema> getSchemas();
 
-  /**
-   * Get enum type by full qualified name.
-   * <br/>
-   * See {@link EdmEnumType} for more information
-   *
-   * @param name
-   * @return {@link EdmEnumType}
-   */
-  EdmEnumType getEnumType(FullQualifiedName name);
+    /**
+     * Get entity container by full qualified name.
+     * <br/>
+     * See {@link EdmEntityContainer} for more information.
+     *
+     * @param name
+     * @return {@link EdmEntityContainer}
+     */
+    EdmEntityContainer getEntityContainer(FullQualifiedName name);
 
-  /**
-   * Get a type definition by full qualified name.
-   * <br/>
-   * See {@link EdmTypeDefinition} for more information
-   *
-   * @param name
-   * @return {@link EdmTypeDefinition}
-   */
-  EdmTypeDefinition getTypeDefinition(FullQualifiedName name);
+    /**
+     * Get enum type by full qualified name.
+     * <br/>
+     * See {@link EdmEnumType} for more information
+     *
+     * @param name
+     * @return {@link EdmEnumType}
+     */
+    EdmEnumType getEnumType(FullQualifiedName name);
 
-  /**
-   * Get entity type by full qualified name.
-   * <br/>
-   * See {@link EdmEntityType} for more information.
-   *
-   * @param name
-   * @return {@link EdmEntityType}
-   */
-  EdmEntityType getEntityType(FullQualifiedName name);
+    /**
+     * Get a type definition by full qualified name.
+     * <br/>
+     * See {@link EdmTypeDefinition} for more information
+     *
+     * @param name
+     * @return {@link EdmTypeDefinition}
+     */
+    EdmTypeDefinition getTypeDefinition(FullQualifiedName name);
 
-  /**
-   * Get complex type by full qualified name..
-   * <br/>
-   * See {@link EdmComplexType} for more information.
-   *
-   * @param name
-   * @return {@link EdmComplexType}
-   */
-  EdmComplexType getComplexType(FullQualifiedName name);
+    /**
+     * Get entity type by full qualified name.
+     * <br/>
+     * See {@link EdmEntityType} for more information.
+     *
+     * @param name
+     * @return {@link EdmEntityType}
+     */
+    EdmEntityType getEntityType(FullQualifiedName name);
 
-  /**
-   * Get Action by full qualified name and binding parameter type.
-   *
-   * @param actionName must not be null
-   * @param bindingParameterTypeName may be null if it is an unbound action
-   * @param isBindingParameterCollection may be null if it is an unbound action
-   * @return {@link EdmAction}
-   */
-  EdmAction getAction(FullQualifiedName actionName, FullQualifiedName bindingParameterTypeName,
-          Boolean isBindingParameterCollection);
+    /**
+     * Get complex type by full qualified name..
+     * <br/>
+     * See {@link EdmComplexType} for more information.
+     *
+     * @param name
+     * @return {@link EdmComplexType}
+     */
+    EdmComplexType getComplexType(FullQualifiedName name);
 
-  /**
-   * Get Function by full qualified name and binding parameter type and binding parameter names.
-   *
-   * @param functionName
-   * @param bindingParameterTypeName may be null if it is an unbound function
-   * @param isBindingParameterCollection may be null if it is an unbound function
-   * @param parameterNames may be null if it is an unbound function
-   * @return {@link EdmFunction}
-   */
-  EdmFunction getFunction(FullQualifiedName functionName, FullQualifiedName bindingParameterTypeName,
-          Boolean isBindingParameterCollection, List<String> parameterNames);
+    /**
+     * Get Action by full qualified name and binding parameter type.
+     *
+     * @param actionName must not be null
+     * @param bindingParameterTypeName may be null if it is an unbound action
+     * @param isBindingParameterCollection may be null if it is an unbound action
+     * @return {@link EdmAction}
+     */
+    EdmAction getAction(FullQualifiedName actionName, FullQualifiedName bindingParameterTypeName,
+            Boolean isBindingParameterCollection);
 
-  /**
-   * Get service metadata.
-   * <br/>
-   * See {@link EdmServiceMetadata} for more information.
-   *
-   * @return {@link EdmServiceMetadata}
-   */
-  EdmServiceMetadata getServiceMetadata();
+    /**
+     * Get Function by full qualified name and binding parameter type and binding parameter names.
+     *
+     * @param functionName
+     * @param bindingParameterTypeName may be null if it is an unbound function
+     * @param isBindingParameterCollection may be null if it is an unbound function
+     * @param parameterNames may be null if it is an unbound function
+     * @return {@link EdmFunction}
+     */
+    EdmFunction getFunction(FullQualifiedName functionName, FullQualifiedName bindingParameterTypeName,
+            Boolean isBindingParameterCollection, List<String> parameterNames);
+
+    /**
+     * Get service metadata.
+     * <br/>
+     * See {@link EdmServiceMetadata} for more information.
+     *
+     * @return {@link EdmServiceMetadata}
+     */
+    EdmServiceMetadata getServiceMetadata();
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmActionImport.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmActionImport.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmActionImport.java
index 428fbdf..a302b9e 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmActionImport.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmActionImport.java
@@ -23,5 +23,5 @@ package org.apache.olingo.commons.api.edm;
  */
 public interface EdmActionImport extends EdmOperationImport {
 
-  EdmAction getAction();
+    EdmAction getAction();
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
index f50d400..d637814 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
@@ -40,8 +40,6 @@ public enum ODataServiceVersion {
 
   public static final String NS_METADATA = "metadata";
 
-  public static final String NS_DATA = "data";
-
   public static final String NS_SCHEME = "scheme";
 
   public static final String NAVIGATION_LINK_REL = "navigationLinkRel";
@@ -70,8 +68,11 @@ public enum ODataServiceVersion {
 
     {
       put(NS_METADATA, "http://docs.oasis-open.org/odata/ns/metadata");
-      put(NS_DATA, "http://docs.oasis-open.org/odata/ns/data");
+      put(NS_DATASERVICES, "http://docs.oasis-open.org/odata/ns/data");
       put(NS_SCHEME, "http://docs.oasis-open.org/odata/ns/scheme");
+      put(NAVIGATION_LINK_REL, "http://docs.oasis-open.org/odata/ns/related/");
+      put(ASSOCIATION_LINK_REL, "http://docs.oasis-open.org/odata/ns/relatedlinks/");
+      put(MEDIA_EDIT_LINK_REL, "http://docs.oasis-open.org/odata/ns/edit-media/");
     }
   });
 

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmComplexType.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmComplexType.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmComplexType.java
index 346eb2e..732f29f 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmComplexType.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmComplexType.java
@@ -27,24 +27,29 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
 
 public abstract class AbstractEdmComplexType extends AbstractEdmStructuredType implements EdmComplexType {
 
-  public AbstractEdmComplexType(final Edm edm, final FullQualifiedName fqn, final FullQualifiedName baseTypeName) {
-    super(edm, fqn, EdmTypeKind.COMPLEX, baseTypeName);
-  }
+    public AbstractEdmComplexType(
+            final Edm edm,
+            final FullQualifiedName fqn,
+            final FullQualifiedName baseTypeName) {
+        super(edm, fqn, EdmTypeKind.COMPLEX, baseTypeName);
+    }
 
-  @Override
-  protected EdmStructuredType buildBaseType(final FullQualifiedName baseTypeName) {
-    EdmComplexType baseType = null;
-    if (baseTypeName != null) {
-      baseType = edm.getComplexType(baseTypeName);
-      if (baseType == null) {
-        throw new EdmException("Can't find base type with name: " + baseTypeName + " for complex type: " + getName());
-      }
+    @Override
+    protected EdmStructuredType buildBaseType(final FullQualifiedName baseTypeName) {
+        // TODO: check for comment
+        EdmComplexType baseType = null;
+        if (baseTypeName != null) {
+            baseType = edm.getComplexType(baseTypeName);
+            if (baseType == null) {
+                throw new EdmException("Can't find base type with name: " + baseTypeName + " for complex type: "
+                        + getName());
+            }
+        }
+        return baseType;
     }
-    return baseType;
-  }
 
-  @Override
-  public EdmComplexType getBaseType() {
-    return (EdmComplexType) baseType;
-  }
+    @Override
+    public EdmComplexType getBaseType() {
+        return (EdmComplexType) baseType;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmEntityContainer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmEntityContainer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmEntityContainer.java
index aba62ba..41eb368 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmEntityContainer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmEntityContainer.java
@@ -33,119 +33,123 @@ import org.apache.olingo.commons.api.edm.FullQualifiedName;
 
 public abstract class AbstractEdmEntityContainer extends EdmNamedImpl implements EdmEntityContainer {
 
-  protected final FullQualifiedName entityContainerName;
+    protected final FullQualifiedName entityContainerName;
 
-  protected final Map<String, EdmSingleton> singletons = new HashMap<String, EdmSingleton>();
-  private boolean allSingletonsLoaded = false;
+    protected final Map<String, EdmSingleton> singletons = new HashMap<String, EdmSingleton>();
 
-  protected final Map<String, EdmEntitySet> entitySets = new HashMap<String, EdmEntitySet>();
-  private boolean allEntitySetsLoaded = false;
+    private boolean allSingletonsLoaded = false;
 
-  protected final Map<String, EdmActionImport> actionImports = new HashMap<String, EdmActionImport>();
-  private boolean allActionImportsLoaded = false;
+    protected final Map<String, EdmEntitySet> entitySets = new HashMap<String, EdmEntitySet>();
 
-  protected final Map<String, EdmFunctionImport> functionImports = new HashMap<String, EdmFunctionImport>();
-  private boolean allFunctionImportsLoaded = false;
+    private boolean allEntitySetsLoaded = false;
 
-  public AbstractEdmEntityContainer(final Edm edm, final FullQualifiedName entityContainerName) {
-    super(edm, entityContainerName.getName());
-    this.entityContainerName = entityContainerName;
-  }
+    protected final Map<String, EdmActionImport> actionImports = new HashMap<String, EdmActionImport>();
 
-  @Override
-  public String getNamespace() {
-    return entityContainerName.getNamespace();
-  }
+    private boolean allActionImportsLoaded = false;
 
-  protected abstract EdmSingleton createSingleton(String singletonName);
+    protected final Map<String, EdmFunctionImport> functionImports = new HashMap<String, EdmFunctionImport>();
 
-  @Override
-  public EdmSingleton getSingleton(final String singletonName) {
-    EdmSingleton singleton = singletons.get(singletonName);
-    if (singleton == null) {
-      singleton = createSingleton(singletonName);
-      singletons.put(singletonName, singleton);
+    private boolean allFunctionImportsLoaded = false;
+
+    public AbstractEdmEntityContainer(final Edm edm, final FullQualifiedName entityContainerName) {
+        super(edm, entityContainerName.getName());
+        this.entityContainerName = entityContainerName;
+    }
+
+    @Override
+    public String getNamespace() {
+        return entityContainerName.getNamespace();
     }
-    return singleton;
-  }
 
-  protected abstract EdmEntitySet createEntitySet(String entitySetName);
+    protected abstract EdmSingleton createSingleton(String singletonName);
 
-  @Override
-  public EdmEntitySet getEntitySet(final String entitySetName) {
-    EdmEntitySet entitySet = entitySets.get(entitySetName);
-    if (entitySet == null) {
-      entitySet = createEntitySet(entitySetName);
-      entitySets.put(entitySetName, entitySet);
+    @Override
+    public EdmSingleton getSingleton(final String singletonName) {
+        EdmSingleton singleton = singletons.get(singletonName);
+        if (singleton == null) {
+            singleton = createSingleton(singletonName);
+            singletons.put(singletonName, singleton);
+        }
+        return singleton;
     }
-    return entitySet;
-  }
 
-  protected abstract EdmActionImport createActionImport(String actionImportName);
+    protected abstract EdmEntitySet createEntitySet(String entitySetName);
 
-  @Override
-  public EdmActionImport getActionImport(final String actionImportName) {
-    EdmActionImport actionImport = actionImports.get(actionImportName);
-    if (actionImport == null) {
-      actionImport = createActionImport(actionImportName);
-      actionImports.put(actionImportName, actionImport);
+    @Override
+    public EdmEntitySet getEntitySet(final String entitySetName) {
+        EdmEntitySet entitySet = entitySets.get(entitySetName);
+        if (entitySet == null) {
+            entitySet = createEntitySet(entitySetName);
+            entitySets.put(entitySetName, entitySet);
+        }
+        return entitySet;
     }
-    return actionImport;
-  }
 
-  protected abstract EdmFunctionImport createFunctionImport(String functionImportName);
+    protected abstract EdmActionImport createActionImport(String actionImportName);
 
-  @Override
-  public EdmFunctionImport getFunctionImport(final String functionImportName) {
-    EdmFunctionImport functionImport = functionImports.get(functionImportName);
-    if (functionImport == null) {
-      functionImport = createFunctionImport(functionImportName);
-      functionImports.put(functionImportName, functionImport);
+    @Override
+    public EdmActionImport getActionImport(final String actionImportName) {
+        EdmActionImport actionImport = actionImports.get(actionImportName);
+        if (actionImport == null) {
+            actionImport = createActionImport(actionImportName);
+            actionImports.put(actionImportName, actionImport);
+        }
+        return actionImport;
     }
-    return functionImport;
-  }
-
-  @Override
-  public List<EdmEntitySet> getEntitySets() {
-    if (!allEntitySetsLoaded) {
-      loadAllEntitySets();
-      allEntitySetsLoaded = true;
+
+    protected abstract EdmFunctionImport createFunctionImport(String functionImportName);
+
+    @Override
+    public EdmFunctionImport getFunctionImport(final String functionImportName) {
+        EdmFunctionImport functionImport = functionImports.get(functionImportName);
+        if (functionImport == null) {
+            functionImport = createFunctionImport(functionImportName);
+            functionImports.put(functionImportName, functionImport);
+        }
+        return functionImport;
+    }
+
+    @Override
+    public List<EdmEntitySet> getEntitySets() {
+        if (!allEntitySetsLoaded) {
+            loadAllEntitySets();
+            allEntitySetsLoaded = true;
+        }
+        return new ArrayList<EdmEntitySet>(entitySets.values());
     }
-    return new ArrayList<EdmEntitySet>(entitySets.values());
-  }
 
-  protected abstract void loadAllEntitySets();
+    protected abstract void loadAllEntitySets();
 
-  @Override
-  public List<EdmFunctionImport> getFunctionImports() {
-    if (!allFunctionImportsLoaded) {
-      loadAllFunctionImports();
-      allFunctionImportsLoaded = true;
+    @Override
+    public List<EdmFunctionImport> getFunctionImports() {
+        if (!allFunctionImportsLoaded) {
+            loadAllFunctionImports();
+            allFunctionImportsLoaded = true;
+        }
+        return new ArrayList<EdmFunctionImport>(functionImports.values());
     }
-    return new ArrayList<EdmFunctionImport>(functionImports.values());
-  }
 
-  protected abstract void loadAllFunctionImports();
+    protected abstract void loadAllFunctionImports();
 
-  @Override
-  public List<EdmSingleton> getSingletons() {
-    if (!allSingletonsLoaded) {
-      loadAllSingletons();
-      allSingletonsLoaded = true;
+    @Override
+    public List<EdmSingleton> getSingletons() {
+        if (!allSingletonsLoaded) {
+            loadAllSingletons();
+            allSingletonsLoaded = true;
+        }
+        return new ArrayList<EdmSingleton>(singletons.values());
     }
-    return new ArrayList<EdmSingleton>(singletons.values());
-  }
 
-  protected abstract void loadAllSingletons();
+    protected abstract void loadAllSingletons();
 
-  @Override
-  public List<EdmActionImport> getActionImports() {
-    if (!allActionImportsLoaded) {
-      loadAllActionImports();
-      allActionImportsLoaded = true;
+    @Override
+    public List<EdmActionImport> getActionImports() {
+        if (!allActionImportsLoaded) {
+            loadAllActionImports();
+            allActionImportsLoaded = true;
+        }
+        return new ArrayList<EdmActionImport>(actionImports.values());
     }
-    return new ArrayList<EdmActionImport>(actionImports.values());
-  }
 
-  protected abstract void loadAllActionImports();
+    protected abstract void loadAllActionImports();
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperation.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperation.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperation.java
index b848540..3c2f894 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperation.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperation.java
@@ -35,80 +35,83 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
 
 public abstract class AbstractEdmOperation extends EdmTypeImpl implements EdmOperation {
 
-  private final Map<String, EdmParameter> parameters = new LinkedHashMap<String, EdmParameter>();
+    private final Map<String, EdmParameter> parameters = new LinkedHashMap<String, EdmParameter>();
 
-  private String entitySetPath;
+    private String entitySetPath;
 
-  private boolean isBound;
+    private boolean isBound;
 
-  private EdmReturnType returnType;
+    private EdmReturnType returnType;
 
-  private List<String> parameterNames;
+    private List<String> parameterNames;
 
-  protected AbstractEdmOperation(final Edm edm, final FullQualifiedName fqn, final EdmTypeKind kind) {
-    super(edm, fqn, kind);
-  }
+    protected AbstractEdmOperation(
+            final Edm edm,
+            final FullQualifiedName fqn,
+            final EdmTypeKind kind) {
+        super(edm, fqn, kind);
+    }
+
+    protected void setParameters(final List<EdmParameter> _parameters) {
+        for (EdmParameter parameter : _parameters) {
+            parameters.put(parameter.getName(), parameter);
+        }
+    }
+
+    protected void setEntitySetPath(final String entitySetPath) {
+        this.entitySetPath = entitySetPath;
+    }
+
+    protected void setIsBound(final boolean isBound) {
+        this.isBound = isBound;
+    }
 
-  protected void setParameters(final List<EdmParameter> _parameters) {
-    for (EdmParameter parameter : _parameters) {
-      parameters.put(parameter.getName(), parameter);
+    protected void setReturnType(final EdmReturnType returnType) {
+        this.returnType = returnType;
     }
-  }
-
-  protected void setEntitySetPath(final String entitySetPath) {
-    this.entitySetPath = entitySetPath;
-  }
-
-  protected void setIsBound(final boolean isBound) {
-    this.isBound = isBound;
-  }
-
-  protected void setReturnType(final EdmReturnType returnType) {
-    this.returnType = returnType;
-  }
-
-  @Override
-  public EdmParameter getParameter(final String name) {
-    return parameters.get(name);
-  }
-
-  @Override
-  public List<String> getParameterNames() {
-    if (parameterNames == null) {
-      parameterNames = new ArrayList<String>(parameters.size());
-      for (String parameterName : parameters.keySet()) {
-        parameterNames.add(parameterName);
-      }
+
+    @Override
+    public EdmParameter getParameter(final String name) {
+        return parameters.get(name);
     }
-    return parameterNames;
-  }
-
-  @Override
-  public EdmEntitySet getReturnedEntitySet(final EdmEntitySet bindingParameterEntitySet) {
-    EdmEntitySet returnedEntitySet = null;
-    if (bindingParameterEntitySet != null && entitySetPath != null) {
-      final EdmBindingTarget relatedBindingTarget = bindingParameterEntitySet.
-              getRelatedBindingTarget(entitySetPath);
-      if (relatedBindingTarget == null) {
-        throw new EdmException("Cannot find entity set with path: " + entitySetPath);
-      }
-      if (relatedBindingTarget instanceof EdmEntitySet) {
-        returnedEntitySet = (EdmEntitySet) relatedBindingTarget;
-      } else {
-        throw new EdmException("BindingTarget with name: " + relatedBindingTarget.getName() + " must be an entity set");
-      }
+
+    @Override
+    public List<String> getParameterNames() {
+        if (parameterNames == null) {
+            parameterNames = new ArrayList<String>(parameters.size());
+            for (String parameterName : parameters.keySet()) {
+                parameterNames.add(parameterName);
+            }
+        }
+        return parameterNames;
     }
-    return returnedEntitySet;
-  }
 
-  @Override
-  public EdmReturnType getReturnType() {
-    return returnType;
-  }
+    @Override
+    public EdmEntitySet getReturnedEntitySet(final EdmEntitySet bindingParameterEntitySet) {
+        EdmEntitySet returnedEntitySet = null;
+        if (bindingParameterEntitySet != null && entitySetPath != null) {
+            final EdmBindingTarget relatedBindingTarget = bindingParameterEntitySet.
+                    getRelatedBindingTarget(entitySetPath);
+            if (relatedBindingTarget == null) {
+                throw new EdmException("Cannot find entity set with path: " + entitySetPath);
+            }
+            if (relatedBindingTarget instanceof EdmEntitySet) {
+                returnedEntitySet = (EdmEntitySet) relatedBindingTarget;
+            } else {
+                throw new EdmException("BindingTarget with name: " + relatedBindingTarget.getName()
+                        + " must be an entity set");
+            }
+        }
+        return returnedEntitySet;
+    }
 
-  @Override
-  public boolean isBound() {
-    return isBound;
-  }
+    @Override
+    public EdmReturnType getReturnType() {
+        return returnType;
+    }
 
+    @Override
+    public boolean isBound() {
+        return isBound;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperationImport.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperationImport.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperationImport.java
index 96aa49f..fe81533 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperationImport.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmOperationImport.java
@@ -27,37 +27,40 @@ import org.apache.olingo.commons.api.edm.Target;
 
 public abstract class AbstractEdmOperationImport extends EdmNamedImpl implements EdmOperationImport {
 
-  protected final EdmEntityContainer container;
-
-  private final Target entitySet;
-
-  private EdmEntitySet returnedEntitySet;
-
-  public AbstractEdmOperationImport(final Edm edm, final EdmEntityContainer container, final String name,
-          final Target entitySet) {
-
-    super(edm, name);
-    this.container = container;
-    this.entitySet = entitySet;
-  }
-
-  @Override
-  public EdmEntitySet getReturnedEntitySet() {
-    if (entitySet != null && returnedEntitySet == null) {
-      EdmEntityContainer entityContainer = edm.getEntityContainer(entitySet.getEntityContainer());
-      if (entityContainer == null) {
-        throw new EdmException("Can´t find entity container with name: " + entitySet.getEntityContainer());
-      }
-      returnedEntitySet = entityContainer.getEntitySet(entitySet.getTargetName());
-      if (returnedEntitySet == null) {
-        throw new EdmException("Can´t find entity set with name: " + entitySet.getTargetName());
-      }
+    protected final EdmEntityContainer container;
+
+    private final Target entitySet;
+
+    private EdmEntitySet returnedEntitySet;
+
+    public AbstractEdmOperationImport(
+            final Edm edm,
+            final EdmEntityContainer container,
+            final String name,
+            final Target entitySet) {
+
+        super(edm, name);
+        this.container = container;
+        this.entitySet = entitySet;
     }
-    return returnedEntitySet;
-  }
 
-  @Override
-  public EdmEntityContainer getEntityContainer() {
-    return container;
-  }
+    @Override
+    public EdmEntitySet getReturnedEntitySet() {
+        if (entitySet != null && returnedEntitySet == null) {
+            EdmEntityContainer entityContainer = edm.getEntityContainer(entitySet.getEntityContainer());
+            if (entityContainer == null) {
+                throw new EdmException("Can´t find entity container with name: " + entitySet.getEntityContainer());
+            }
+            returnedEntitySet = entityContainer.getEntitySet(entitySet.getTargetName());
+            if (returnedEntitySet == null) {
+                throw new EdmException("Can´t find entity set with name: " + entitySet.getTargetName());
+            }
+        }
+        return returnedEntitySet;
+    }
+
+    @Override
+    public EdmEntityContainer getEntityContainer() {
+        return container;
+    }
 }


[8/8] git commit: [OLINGO-175, OLINGO-205] provided (V4) next link check

Posted by fm...@apache.org.
[OLINGO-175, OLINGO-205] provided (V4) next link check


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

Branch: refs/heads/olingo200
Commit: f0edb5081363d9e9f9ab0192541a943325e12dbb
Parents: 5b5576f
Author: fmartelli <fa...@gmail.com>
Authored: Mon Mar 24 10:38:32 2014 +0100
Committer: fmartelli <fa...@gmail.com>
Committed: Mon Mar 24 10:38:32 2014 +0100

----------------------------------------------------------------------
 fit/src/main/resources/v4/People/feed.full.json        |  3 ++-
 fit/src/main/resources/v4/People/feed.xml              |  1 +
 .../olingo/client/core/it/v4/EntitySetTestITCase.java  | 13 ++++++++-----
 3 files changed, 11 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/f0edb508/fit/src/main/resources/v4/People/feed.full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/v4/People/feed.full.json b/fit/src/main/resources/v4/People/feed.full.json
index 0c998f6..a0e3db0 100644
--- a/fit/src/main/resources/v4/People/feed.full.json
+++ b/fit/src/main/resources/v4/People/feed.full.json
@@ -328,5 +328,6 @@
                         "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
                       }
             }
-          ]
+          ],
+  "odata.nextLink": "People?$skiptoken=5"
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/f0edb508/fit/src/main/resources/v4/People/feed.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/v4/People/feed.xml b/fit/src/main/resources/v4/People/feed.xml
index f79bb49..609c669 100644
--- a/fit/src/main/resources/v4/People/feed.xml
+++ b/fit/src/main/resources/v4/People/feed.xml
@@ -215,4 +215,5 @@
       </m:properties>
     </content>
   </entry>
+  <link rel="next" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People?$skiptoken=5"/>
 </feed>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/f0edb508/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
index e3e8a1e..8455ecd 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
@@ -20,8 +20,10 @@ package org.apache.olingo.client.core.it.v4;
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
+import java.net.URI;
 import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetIteratorRequest;
 import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
 import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
@@ -29,6 +31,7 @@ import org.apache.olingo.client.api.communication.response.ODataRawResponse;
 import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
 import org.apache.olingo.client.api.domain.ODataEntitySetIterator;
 import org.apache.olingo.client.api.uri.CommonURIBuilder;
+import org.apache.olingo.client.core.uri.URIUtils;
 import org.apache.olingo.commons.api.domain.ODataEntitySet;
 import org.apache.olingo.commons.api.format.ODataPubFormat;
 import org.apache.olingo.commons.core.op.ResourceFactory;
@@ -105,12 +108,12 @@ public class EntitySetTestITCase extends AbstractTestITCase {
             ODataPubFormat.ATOM == format)), "Just retrieved feed");
 
     assertEquals(5, feed.getEntities().size());
-//    assertNotNull(feed.getNext());
+    assertNotNull(feed.getNext());
 
-//    final URI expected = URI.create(getServiceRoot() + "/Customer?$skiptoken=-9");
-//    final URI found = URIUtils.getURI(getServiceRoot(), feed.getNext().toASCIIString());
+    final URI expected = URI.create(getServiceRoot() + "/People?$skiptoken=5");
+    final URI found = URIUtils.getURI(getServiceRoot(), feed.getNext().toASCIIString());
 
-//    assertEquals(expected, found);
+    assertEquals(expected, found);
   }
 
   private void readODataEntitySetIterator(final ODataPubFormat format) {
@@ -133,7 +136,7 @@ public class EntitySetTestITCase extends AbstractTestITCase {
       count++;
     }
     assertEquals(5, count);
-//    assertTrue(feedIterator.getNext().toASCIIString().endsWith("Customer?$skiptoken=-9"));
+    assertTrue(feedIterator.getNext().toASCIIString().endsWith("People?$skiptoken=5"));
   }
 
   private void rawRequest(final ODataPubFormat format) {


[3/8] [OLINGO-205, OLINGO-200] provided atom v4 deserialization for entity type/set + entity set request

Posted by fm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/resources/v4/People/feed.full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/v4/People/feed.full.json b/fit/src/main/resources/v4/People/feed.full.json
new file mode 100644
index 0000000..0c998f6
--- /dev/null
+++ b/fit/src/main/resources/v4/People/feed.full.json
@@ -0,0 +1,332 @@
+{
+  "@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#People",
+  "value":
+          [
+            {
+              "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Customer",
+              "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)",
+              "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer",
+              "PersonID": 1,
+              "FirstName": "Bob",
+              "LastName": "Cat",
+              "MiddleName": null,
+              "HomeAddress":
+                      {
+                        "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress",
+                        "Street": "1 Microsoft Way",
+                        "City": "London",
+                        "PostalCode": "98052",
+                        "FamilyName": "Cats"
+                      },
+              "Home@odata.type": "#GeographyPoint",
+              "Home":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  23.1,
+                                  32.1
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers@odata.type": "#Collection(String)",
+              "Numbers":
+                      [
+                        "111-111-1111"
+                      ],
+              "Emails@odata.type": "#Collection(String)",
+              "Emails":
+                      [
+                        "abc@abc.com"
+                      ],
+              "City": "London",
+              "Birthday@odata.type": "#DateTimeOffset",
+              "Birthday": "1957-04-03T00:00:00Z",
+              "TimeBetweenLastTwoOrders@odata.type": "#Duration",
+              "TimeBetweenLastTwoOrders": "PT0.0000001S",
+              "Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent/$ref",
+              "Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent",
+              "Orders@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders/$ref",
+              "Orders@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders",
+              "Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company/$ref",
+              "Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company",
+              "#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
+                      {
+                        "title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
+                        "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
+                      },
+              "#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
+                      {
+                        "title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
+                        "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
+                      }
+            },
+            {
+              "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Customer",
+              "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)",
+              "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer",
+              "PersonID": 2,
+              "FirstName": "Jill",
+              "LastName": "Jones",
+              "MiddleName": null,
+              "HomeAddress": null,
+              "Home@odata.type": "#GeographyPoint",
+              "Home":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  161.8,
+                                  15
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers@odata.type": "#Collection(String)",
+              "Numbers":
+                      [
+                      ],
+              "Emails@odata.type": "#Collection(String)",
+              "Emails":
+                      [
+                      ],
+              "City": "Sydney",
+              "Birthday@odata.type": "#DateTimeOffset",
+              "Birthday": "1983-01-15T00:00:00Z",
+              "TimeBetweenLastTwoOrders@odata.type": "#Duration",
+              "TimeBetweenLastTwoOrders": "PT0.0000002S",
+              "Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent/$ref",
+              "Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent",
+              "Orders@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders/$ref",
+              "Orders@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders",
+              "Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company/$ref",
+              "Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company",
+              "#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
+                      {
+                        "title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
+                        "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
+                      },
+              "#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
+                      {
+                        "title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
+                        "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
+                      }
+            },
+            {
+              "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Employee",
+              "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)",
+              "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee",
+              "PersonID": 3,
+              "FirstName": "Jacob",
+              "LastName": "Zip",
+              "MiddleName": null,
+              "HomeAddress":
+                      {
+                        "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Address",
+                        "Street": "1 Microsoft Way",
+                        "City": "Sydney",
+                        "PostalCode": "98052"
+                      },
+              "Home@odata.type": "#GeographyPoint",
+              "Home":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  161.8,
+                                  15
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers@odata.type": "#Collection(String)",
+              "Numbers":
+                      [
+                        "333-333-3333"
+                      ],
+              "Emails@odata.type": "#Collection(String)",
+              "Emails":
+                      [
+                        null
+                      ],
+              "DateHired@odata.type": "#DateTimeOffset",
+              "DateHired": "2010-12-13T00:00:00Z",
+              "Office@odata.type": "#GeographyPoint",
+              "Office":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  162,
+                                  15
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent/$ref",
+              "Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent",
+              "Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company/$ref",
+              "Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company",
+              "#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
+                      {
+                        "title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
+                        "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
+                      },
+              "#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
+                      {
+                        "title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
+                        "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
+                      }
+            },
+            {
+              "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Employee",
+              "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)",
+              "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee",
+              "PersonID": 4,
+              "FirstName": "Elmo",
+              "LastName": "Rogers",
+              "MiddleName": null,
+              "HomeAddress": null,
+              "Home@odata.type": "#GeographyPoint",
+              "Home":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  -61.8,
+                                  -15
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers@odata.type": "#Collection(String)",
+              "Numbers":
+                      [
+                        "444-444-4444",
+                        "555-555-5555",
+                        "666-666-6666"
+                      ],
+              "Emails@odata.type": "#Collection(String)",
+              "Emails":
+                      [
+                        "def@def.org",
+                        "lmn@lmn.com"
+                      ],
+              "DateHired@odata.type": "#DateTimeOffset",
+              "DateHired": "2008-03-27T00:00:00Z",
+              "Office@odata.type": "#GeographyPoint",
+              "Office":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  -62,
+                                  -15
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent/$ref",
+              "Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent",
+              "Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company/$ref",
+              "Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company",
+              "#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
+                      {
+                        "title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
+                        "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
+                      },
+              "#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
+                      {
+                        "title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
+                        "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
+                      }
+            },
+            {
+              "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Person",
+              "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)",
+              "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)",
+              "PersonID": 5,
+              "FirstName": "Peter",
+              "LastName": "Bee",
+              "MiddleName": null,
+              "HomeAddress": null,
+              "Home@odata.type": "#GeographyPoint",
+              "Home":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  -261.8,
+                                  -16
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers@odata.type": "#Collection(String)",
+              "Numbers":
+                      [
+                        "555-555-5555"
+                      ],
+              "Emails@odata.type": "#Collection(String)",
+              "Emails":
+                      [
+                        "def@test.msn"
+                      ],
+              "Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Parent/$ref",
+              "Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Parent",
+              "#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
+                      {
+                        "title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
+                        "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
+                      },
+              "#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
+                      {
+                        "title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
+                        "target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
+                      }
+            }
+          ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/resources/v4/People/feed.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/v4/People/feed.xml b/fit/src/main/resources/v4/People/feed.xml
new file mode 100644
index 0000000..f79bb49
--- /dev/null
+++ b/fit/src/main/resources/v4/People/feed.xml
@@ -0,0 +1,218 @@
+<?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}/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}/StaticService/V40/Static.svc/$metadata#People">
+  <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People</id>
+  <title />
+  <updated>2014-03-20T14:31:00Z</updated>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)</id>
+    <category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+    <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company" />
+    <title />
+    <updated>2014-03-20T14:31:00Z</updated>
+    <author>
+      <name />
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PersonID m:type="Int32">1</d:PersonID>
+        <d:FirstName>Bob</d:FirstName>
+        <d:LastName>Cat</d:LastName>
+        <d:MiddleName m:null="true" />
+        <d:HomeAddress m:type="#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress">
+          <d:Street>1 Microsoft Way</d:Street>
+          <d:City>London</d:City>
+          <d:PostalCode>98052</d:PostalCode>
+          <d:FamilyName>Cats</d:FamilyName>
+        </d:HomeAddress>
+        <d:Home m:type="GeographyPoint">
+          <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+            <gml:pos>32.1 23.1</gml:pos>
+          </gml:Point>
+        </d:Home>
+        <d:Numbers m:type="#Collection(String)">
+          <m:element>111-111-1111</m:element>
+        </d:Numbers>
+        <d:Emails m:type="#Collection(String)">
+          <m:element>abc@abc.com</m:element>
+        </d:Emails>
+        <d:City>London</d:City>
+        <d:Birthday m:type="DateTimeOffset">1957-04-03T00:00:00Z</d:Birthday>
+        <d:TimeBetweenLastTwoOrders m:type="Duration">PT0.0000001S</d:TimeBetweenLastTwoOrders>
+      </m:properties>
+    </content>
+  </entry>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)</id>
+    <category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+    <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company" />
+    <title />
+    <updated>2014-03-20T14:31:00Z</updated>
+    <author>
+      <name />
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PersonID m:type="Int32">2</d:PersonID>
+        <d:FirstName>Jill</d:FirstName>
+        <d:LastName>Jones</d:LastName>
+        <d:MiddleName m:null="true" />
+        <d:HomeAddress m:null="true" />
+        <d:Home m:type="GeographyPoint">
+          <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+            <gml:pos>15 161.8</gml:pos>
+          </gml:Point>
+        </d:Home>
+        <d:Numbers m:type="#Collection(String)" />
+        <d:Emails m:type="#Collection(String)" />
+        <d:City>Sydney</d:City>
+        <d:Birthday m:type="DateTimeOffset">1983-01-15T00:00:00Z</d:Birthday>
+        <d:TimeBetweenLastTwoOrders m:type="Duration">PT0.0000002S</d:TimeBetweenLastTwoOrders>
+      </m:properties>
+    </content>
+  </entry>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)</id>
+    <category term="#Microsoft.Test.OData.Services.ODataWCFService.Employee" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+    <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company" />
+    <title />
+    <updated>2014-03-20T14:31:00Z</updated>
+    <author>
+      <name />
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PersonID m:type="Int32">3</d:PersonID>
+        <d:FirstName>Jacob</d:FirstName>
+        <d:LastName>Zip</d:LastName>
+        <d:MiddleName m:null="true" />
+        <d:HomeAddress m:type="#Microsoft.Test.OData.Services.ODataWCFService.Address">
+          <d:Street>1 Microsoft Way</d:Street>
+          <d:City>Sydney</d:City>
+          <d:PostalCode>98052</d:PostalCode>
+        </d:HomeAddress>
+        <d:Home m:type="GeographyPoint">
+          <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+            <gml:pos>15 161.8</gml:pos>
+          </gml:Point>
+        </d:Home>
+        <d:Numbers m:type="#Collection(String)">
+          <m:element>333-333-3333</m:element>
+        </d:Numbers>
+        <d:Emails m:type="#Collection(String)">
+          <m:element m:null="true" />
+        </d:Emails>
+        <d:DateHired m:type="DateTimeOffset">2010-12-13T00:00:00Z</d:DateHired>
+        <d:Office m:type="GeographyPoint">
+          <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+            <gml:pos>15 162</gml:pos>
+          </gml:Point>
+        </d:Office>
+      </m:properties>
+    </content>
+  </entry>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)</id>
+    <category term="#Microsoft.Test.OData.Services.ODataWCFService.Employee" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+    <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company" />
+    <title />
+    <updated>2014-03-20T14:31:00Z</updated>
+    <author>
+      <name />
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PersonID m:type="Int32">4</d:PersonID>
+        <d:FirstName>Elmo</d:FirstName>
+        <d:LastName>Rogers</d:LastName>
+        <d:MiddleName m:null="true" />
+        <d:HomeAddress m:null="true" />
+        <d:Home m:type="GeographyPoint">
+          <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+            <gml:pos>-15 -61.8</gml:pos>
+          </gml:Point>
+        </d:Home>
+        <d:Numbers m:type="#Collection(String)">
+          <m:element>444-444-4444</m:element>
+          <m:element>555-555-5555</m:element>
+          <m:element>666-666-6666</m:element>
+        </d:Numbers>
+        <d:Emails m:type="#Collection(String)">
+          <m:element>def@def.org</m:element>
+          <m:element>lmn@lmn.com</m:element>
+        </d:Emails>
+        <d:DateHired m:type="DateTimeOffset">2008-03-27T00:00:00Z</d:DateHired>
+        <d:Office m:type="GeographyPoint">
+          <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+            <gml:pos>-15 -62</gml:pos>
+          </gml:Point>
+        </d:Office>
+      </m:properties>
+    </content>
+  </entry>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)</id>
+    <category term="#Microsoft.Test.OData.Services.ODataWCFService.Person" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+    <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Parent" />
+    <title />
+    <updated>2014-03-20T14:31:00Z</updated>
+    <author>
+      <name />
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PersonID m:type="Int32">5</d:PersonID>
+        <d:FirstName>Peter</d:FirstName>
+        <d:LastName>Bee</d:LastName>
+        <d:MiddleName m:null="true" />
+        <d:HomeAddress m:null="true" />
+        <d:Home m:type="GeographyPoint">
+          <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+            <gml:pos>-16 -261.8</gml:pos>
+          </gml:Point>
+        </d:Home>
+        <d:Numbers m:type="#Collection(String)">
+          <m:element>555-555-5555</m:element>
+        </d:Numbers>
+        <d:Emails m:type="#Collection(String)">
+          <m:element>def@test.msn</m:element>
+        </d:Emails>
+      </m:properties>
+    </content>
+  </entry>
+</feed>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aefb959/fit/src/main/resources/v4/metadata.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/v4/metadata.xml b/fit/src/main/resources/v4/metadata.xml
index ae13a4e..b51bf0f 100644
--- a/fit/src/main/resources/v4/metadata.xml
+++ b/fit/src/main/resources/v4/metadata.xml
@@ -21,499 +21,418 @@
 -->
 <edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
   <edmx:DataServices>
-    <Schema Namespace="NorthwindModel" xmlns="http://docs.oasis-open.org/odata/ns/edm">
-      <!-- EnumType with values -->
-      <EnumType Name="FileAccess" UnderlyingType="Edm.Int32" IsFlags="true">
-        <Member Name="Read"   Value="1" />
-        <Member Name="Write"  Value="2" />
-        <Member Name="Create" Value="4" />
-        <Member Name="Delete" Value="8" />
-      </EnumType>
-      <!-- EnumType without any values -->
-      <EnumType Name="ShippingMethod">
-        <Member Name="FirstClass" />
-        <Member Name="TwoDay" />
-        <Member Name="Overnight" />
-      </EnumType>
-      <!-- ComplexType -->
-      <ComplexType Name="Dimensions">
-        <Property Name="Height" Nullable="false" Type="Edm.Decimal" />
-        <Property Name="Weight" Nullable="false" Type="Edm.Decimal" />
-        <Property Name="Length" Nullable="false" Type="Edm.Decimal" />
+    <Schema Namespace="Microsoft.Test.OData.Services.ODataWCFService" xmlns="http://docs.oasis-open.org/odata/ns/edm">
+      <ComplexType Name="Address">
+        <Property Name="Street" Type="Edm.String" Nullable="false" />
+        <Property Name="City" Type="Edm.String" Nullable="false" />
+        <Property Name="PostalCode" Type="Edm.String" Nullable="false" />
       </ComplexType>
-      <!-- ComplexType with enum property -->
-      <ComplexType Name="ACL">
-        <Property Name="Filename" Nullable="false" Type="Edm.String" />
-        <Property Name="Access" Nullable="false" Type="NorthwindModel.FileAccess" />
+      <ComplexType Name="HomeAddress" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Address">
+        <Property Name="FamilyName" Type="Edm.String" />
       </ComplexType>
-      <EntityType Name="Category">
-        <Key>
-          <PropertyRef Name="CategoryID" />
-        </Key>
-        <Property Name="CategoryID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
-        <Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
-        <Property Name="Description" Type="Edm.String" MaxLength="max" />
-        <Property Name="Picture" Type="Edm.Binary" MaxLength="max" />
-        <NavigationProperty Name="Products" Type="Collection(NorthwindModel.Product)" Partner="Category" />
-      </EntityType>
-      <EntityType Name="CustomerDemographic">
+      <ComplexType Name="CompanyAddress" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Address">
+        <Property Name="CompanyName" Type="Edm.String" Nullable="false" />
+      </ComplexType>
+      <EnumType Name="AccessLevel" IsFlags="true">
+        <Member Name="None" Value="0" />
+        <Member Name="Read" Value="1" />
+        <Member Name="Write" Value="2" />
+        <Member Name="Execute" Value="4" />
+        <Member Name="ReadWrite" Value="3" />
+      </EnumType>
+      <EnumType Name="Color">
+        <Member Name="Red" Value="1" />
+        <Member Name="Green" Value="2" />
+        <Member Name="Blue" Value="4" />
+      </EnumType>
+      <EnumType Name="CompanyCategory">
+        <Member Name="IT" Value="0" />
+        <Member Name="Communication" Value="1" />
+        <Member Name="Electronics" Value="2" />
+        <Member Name="Others" Value="4" />
+      </EnumType>
+      <EntityType Name="Person">
         <Key>
-          <PropertyRef Name="CustomerTypeID" />
+          <PropertyRef Name="PersonID" />
         </Key>
-        <Property Name="CustomerTypeID" Type="Edm.String" Nullable="false" MaxLength="10" />
-        <Property Name="CustomerDesc" Type="Edm.String" MaxLength="max" />
-        <NavigationProperty Name="Customers" Type="Collection(NorthwindModel.Customer)" Partner="CustomerDemographics" />
+        <Property Name="PersonID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="FirstName" Type="Edm.String" Nullable="false" />
+        <Property Name="LastName" Type="Edm.String" Nullable="false" />
+        <Property Name="MiddleName" Type="Edm.String" />
+        <Property Name="HomeAddress" Type="Microsoft.Test.OData.Services.ODataWCFService.Address" />
+        <Property Name="Home" Type="Edm.GeographyPoint" SRID="4326" />
+        <Property Name="Numbers" Type="Collection(Edm.String)" Nullable="false" />
+        <Property Name="Emails" Type="Collection(Edm.String)" />
+        <NavigationProperty Name="Parent" Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
       </EntityType>
-      <EntityType Name="Customer">
-        <Key>
-          <PropertyRef Name="CustomerID" />
-        </Key>
-        <Property Name="CustomerID" Type="Edm.String" Nullable="false" MaxLength="5" />
-        <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="ContactName" Type="Edm.String" MaxLength="30" />
-        <Property Name="ContactTitle" Type="Edm.String" MaxLength="30" />
-        <Property Name="Address" Type="Edm.String" MaxLength="60" />
-        <Property Name="City" Type="Edm.String" MaxLength="15" />
-        <Property Name="Region" Type="Edm.String" MaxLength="15" />
-        <Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
-        <Property Name="Country" Type="Edm.String" MaxLength="15" />
-        <Property Name="Phone" Type="Edm.String" MaxLength="24" />
-        <Property Name="Fax" Type="Edm.String" MaxLength="24" />
-        <!-- EnumType attribute -->
-        <Property Name="FileAccess" Type="NorthwindModel.FileAccess" />
-        <NavigationProperty Name="Orders" Type="Collection(NorthwindModel.Order)" Partner="Customer" />
-        <NavigationProperty Name="CustomerDemographics" Type="Collection(NorthwindModel.CustomerDemographic)" Partner="Customers" />
+      <EntityType Name="Customer" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Person">
+        <Property Name="City" Type="Edm.String" Nullable="false" />
+        <Property Name="Birthday" Type="Edm.DateTimeOffset" Nullable="false" />
+        <Property Name="TimeBetweenLastTwoOrders" Type="Edm.Duration" Nullable="false" />
+        <NavigationProperty Name="Orders" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Order)" />
+        <NavigationProperty Name="Company" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" Partner="VipCustomer" />
       </EntityType>
-      <EntityType Name="Employee">
-        <Key>
-          <PropertyRef Name="EmployeeID" />
-        </Key>
-        <Property Name="EmployeeID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
-        <Property Name="LastName" Type="Edm.String" Nullable="false" MaxLength="20" />
-        <Property Name="FirstName" Type="Edm.String" Nullable="false" MaxLength="10" />
-        <Property Name="Title" Type="Edm.String" MaxLength="30" />
-        <Property Name="TitleOfCourtesy" Type="Edm.String" MaxLength="25" />
-        <Property Name="BirthDate" Type="Edm.DateTimeOffset" />
-        <Property Name="HireDate" Type="Edm.DateTimeOffset" />
-        <Property Name="Address" Type="Edm.String" MaxLength="60" />
-        <Property Name="City" Type="Edm.String" MaxLength="15" />
-        <Property Name="Region" Type="Edm.String" MaxLength="15" />
-        <Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
-        <Property Name="Country" Type="Edm.String" MaxLength="15" />
-        <Property Name="HomePhone" Type="Edm.String" MaxLength="24" />
-        <Property Name="Extension" Type="Edm.String" MaxLength="4" />
-        <Property Name="Photo" Type="Edm.Binary" MaxLength="max" />
-        <Property Name="Notes" Type="Edm.String" MaxLength="max" />
-        <Property Name="ReportsTo" Type="Edm.Int32" />
-        <Property Name="PhotoPath" Type="Edm.String" MaxLength="255" />
-        <NavigationProperty Name="Employees1" Type="Collection(NorthwindModel.Employee)" Partner="Employee1" />
-        <NavigationProperty Name="Employee1" Type="NorthwindModel.Employee" Partner="Employees1">
-          <ReferentialConstraint Property="ReportsTo" ReferencedProperty="EmployeeID" />
-        </NavigationProperty>
-        <NavigationProperty Name="Orders" Type="Collection(NorthwindModel.Order)" Partner="Employee" />
-        <NavigationProperty Name="Territories" Type="Collection(NorthwindModel.Territory)" Partner="Employees" />
+      <EntityType Name="Employee" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Person">
+        <Property Name="DateHired" Type="Edm.DateTimeOffset" Nullable="false" />
+        <Property Name="Office" Type="Edm.GeographyPoint" SRID="4326" />
+        <NavigationProperty Name="Company" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" Partner="Employees" />
       </EntityType>
-      <EntityType Name="Order_Detail">
+      <EntityType Name="Product">
         <Key>
-          <PropertyRef Name="OrderID" />
           <PropertyRef Name="ProductID" />
         </Key>
-        <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
         <Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="UnitPrice" Type="Edm.Decimal" Nullable="false" Precision="19" Scale="4" />
-        <Property Name="Quantity" Type="Edm.Int16" Nullable="false" />
-        <Property Name="Discount" Type="Edm.Single" Nullable="false" />
-        <NavigationProperty Name="Order" Type="NorthwindModel.Order" Nullable="false" Partner="Order_Details">
-          <ReferentialConstraint Property="OrderID" ReferencedProperty="OrderID" />
-        </NavigationProperty>
-        <NavigationProperty Name="Product" Type="NorthwindModel.Product" Nullable="false" Partner="Order_Details">
+        <Property Name="Name" Type="Edm.String" Nullable="false" />
+        <Property Name="QuantityPerUnit" Type="Edm.String" Nullable="false" />
+        <Property Name="UnitPrice" Type="Edm.Single" Nullable="false" />
+        <Property Name="QuantityInStock" Type="Edm.Int32" Nullable="false" />
+        <Property Name="Discontinued" Type="Edm.Boolean" Nullable="false" />
+        <Property Name="UserAccess" Type="Microsoft.Test.OData.Services.ODataWCFService.AccessLevel" />
+        <Property Name="SkinColor" Type="Microsoft.Test.OData.Services.ODataWCFService.Color" />
+        <Property Name="CoverColors" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Color)" Nullable="false" />
+        <NavigationProperty Name="Details" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.ProductDetail)">
           <ReferentialConstraint Property="ProductID" ReferencedProperty="ProductID" />
         </NavigationProperty>
       </EntityType>
-      <EntityType Name="Order">
-        <Key>
-          <PropertyRef Name="OrderID" />
-        </Key>
-        <Property Name="OrderID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
-        <Property Name="CustomerID" Type="Edm.String" MaxLength="5" />
-        <Property Name="EmployeeID" Type="Edm.Int32" />
-        <Property Name="OrderDate" Type="Edm.DateTimeOffset" />
-        <Property Name="RequiredDate" Type="Edm.DateTimeOffset" />
-        <Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
-        <Property Name="ShipVia" Type="Edm.Int32" />
-        <Property Name="Freight" Type="Edm.Decimal" Precision="19" Scale="4" />
-        <Property Name="ShipName" Type="Edm.String" MaxLength="40" />
-        <Property Name="ShipAddress" Type="Edm.String" MaxLength="60" />
-        <Property Name="ShipCity" Type="Edm.String" MaxLength="15" />
-        <Property Name="ShipRegion" Type="Edm.String" MaxLength="15" />
-        <Property Name="ShipPostalCode" Type="Edm.String" MaxLength="10" />
-        <Property Name="ShipCountry" Type="Edm.String" MaxLength="15" />
-        <NavigationProperty Name="Customer" Type="NorthwindModel.Customer" Partner="Orders">
-          <ReferentialConstraint Property="CustomerID" ReferencedProperty="CustomerID" />
-        </NavigationProperty>
-        <NavigationProperty Name="Employee" Type="NorthwindModel.Employee" Partner="Orders">
-          <ReferentialConstraint Property="EmployeeID" ReferencedProperty="EmployeeID" />
-        </NavigationProperty>
-        <NavigationProperty Name="Order_Details" Type="Collection(NorthwindModel.Order_Detail)" Partner="Order" />
-        <NavigationProperty Name="Shipper" Type="NorthwindModel.Shipper" Partner="Orders">
-          <ReferentialConstraint Property="ShipVia" ReferencedProperty="ShipperID" />
-        </NavigationProperty>
-      </EntityType>
-      <EntityType Name="Product">
+      <EntityType Name="ProductDetail">
         <Key>
           <PropertyRef Name="ProductID" />
+          <PropertyRef Name="ProductDetailID" />
         </Key>
-        <Property Name="ProductID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
-        <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="SupplierID" Type="Edm.Int32" />
-        <Property Name="CategoryID" Type="Edm.Int32" />
-        <Property Name="QuantityPerUnit" Type="Edm.String" MaxLength="20" />
-        <Property Name="UnitPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
-        <Property Name="UnitsInStock" Type="Edm.Int16" />
-        <Property Name="UnitsOnOrder" Type="Edm.Int16" />
-        <Property Name="ReorderLevel" Type="Edm.Int16" />
-        <Property Name="Discontinued" Type="Edm.Boolean" Nullable="false" />
-        <!-- ComplexType attributes -->
-        <Property Name="ProductDimensions" Type="NorthwindModel.Dimensions" />
-        <Property Name="ShippingDimensions" Type="NorthwindModel.Dimensions" />
-        <NavigationProperty Name="Category" Type="NorthwindModel.Category" Partner="Products">
-          <ReferentialConstraint Property="CategoryID" ReferencedProperty="CategoryID" />
-        </NavigationProperty>
-        <NavigationProperty Name="Order_Details" Type="Collection(NorthwindModel.Order_Detail)" Partner="Product" />
-        <NavigationProperty Name="Supplier" Type="NorthwindModel.Supplier" Partner="Products">
-          <ReferentialConstraint Property="SupplierID" ReferencedProperty="SupplierID" />
+        <Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="ProductDetailID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="ProductName" Type="Edm.String" Nullable="false" />
+        <Property Name="Description" Type="Edm.String" Nullable="false" />
+        <NavigationProperty Name="RelatedProduct" Type="Microsoft.Test.OData.Services.ODataWCFService.Product" />
+        <NavigationProperty Name="Reviews" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.ProductReview)">
+          <ReferentialConstraint Property="ProductID" ReferencedProperty="ProductID" />
+          <ReferentialConstraint Property="ProductDetailID" ReferencedProperty="ProductDetailID" />
         </NavigationProperty>
       </EntityType>
-      <EntityType Name="Region">
+      <EntityType Name="ProductReview">
         <Key>
-          <PropertyRef Name="RegionID" />
-        </Key>
-        <Property Name="RegionID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="RegionDescription" Type="Edm.String" Nullable="false" MaxLength="50" />
-        <NavigationProperty Name="Territories" Type="Collection(NorthwindModel.Territory)" Partner="Region" />
-      </EntityType>
-      <EntityType Name="Shipper">
-        <Key>
-          <PropertyRef Name="ShipperID" />
-        </Key>
-        <Property Name="ShipperID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
-        <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="Phone" Type="Edm.String" MaxLength="24" />
-        <NavigationProperty Name="Orders" Type="Collection(NorthwindModel.Order)" Partner="Shipper" />
-      </EntityType>
-      <EntityType Name="Supplier">
-        <Key>
-          <PropertyRef Name="SupplierID" />
+          <PropertyRef Name="ProductID" />
+          <PropertyRef Name="ProductDetailID" />
+          <PropertyRef Name="ReviewTitle" />
+          <PropertyRef Name="RevisionID" />
         </Key>
-        <Property Name="SupplierID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
-        <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="ContactName" Type="Edm.String" MaxLength="30" />
-        <Property Name="ContactTitle" Type="Edm.String" MaxLength="30" />
-        <Property Name="Address" Type="Edm.String" MaxLength="60" />
-        <Property Name="City" Type="Edm.String" MaxLength="15" />
-        <Property Name="Region" Type="Edm.String" MaxLength="15" />
-        <Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
-        <Property Name="Country" Type="Edm.String" MaxLength="15" />
-        <Property Name="Phone" Type="Edm.String" MaxLength="24" />
-        <Property Name="Fax" Type="Edm.String" MaxLength="24" />
-        <Property Name="HomePage" Type="Edm.String" MaxLength="max" />
-        <NavigationProperty Name="Products" Type="Collection(NorthwindModel.Product)" Partner="Supplier" />
+        <Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="ProductDetailID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="ReviewTitle" Type="Edm.String" Nullable="false" />
+        <Property Name="RevisionID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="Comment" Type="Edm.String" Nullable="false" />
+        <Property Name="Author" Type="Edm.String" Nullable="false" />
       </EntityType>
-      <EntityType Name="Territory">
+      <EntityType Name="Order">
         <Key>
-          <PropertyRef Name="TerritoryID" />
+          <PropertyRef Name="OrderID" />
         </Key>
-        <Property Name="TerritoryID" Type="Edm.String" Nullable="false" MaxLength="20" />
-        <Property Name="TerritoryDescription" Type="Edm.String" Nullable="false" MaxLength="50" />
-        <Property Name="RegionID" Type="Edm.Int32" Nullable="false" />
-        <NavigationProperty Name="Region" Type="NorthwindModel.Region" Nullable="false" Partner="Territories">
-          <ReferentialConstraint Property="RegionID" ReferencedProperty="RegionID" />
-        </NavigationProperty>
-        <NavigationProperty Name="Employees" Type="Collection(NorthwindModel.Employee)" Partner="Territories" />
+        <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="OrderDate" Type="Edm.DateTimeOffset" Nullable="false" />
+        <Property Name="ShelfLife" Type="Edm.Duration" />
+        <Property Name="OrderShelfLifes" Type="Collection(Edm.Duration)" />
+        <NavigationProperty Name="LoggedInEmployee" Type="Microsoft.Test.OData.Services.ODataWCFService.Employee" Nullable="false" />
+        <NavigationProperty Name="CustomerForOrder" Type="Microsoft.Test.OData.Services.ODataWCFService.Customer" Nullable="false" />
+        <NavigationProperty Name="OrderDetails" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.OrderDetail)" />
       </EntityType>
-      <EntityType Name="Alphabetical_list_of_product">
+      <EntityType Name="OrderDetail">
         <Key>
-          <PropertyRef Name="CategoryName" />
-          <PropertyRef Name="Discontinued" />
+          <PropertyRef Name="OrderID" />
           <PropertyRef Name="ProductID" />
-          <PropertyRef Name="ProductName" />
         </Key>
+        <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
         <Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="SupplierID" Type="Edm.Int32" />
-        <Property Name="CategoryID" Type="Edm.Int32" />
-        <Property Name="QuantityPerUnit" Type="Edm.String" MaxLength="20" />
-        <Property Name="UnitPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
-        <Property Name="UnitsInStock" Type="Edm.Int16" />
-        <Property Name="UnitsOnOrder" Type="Edm.Int16" />
-        <Property Name="ReorderLevel" Type="Edm.Int16" />
-        <Property Name="Discontinued" Type="Edm.Boolean" Nullable="false" />
-        <Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
+        <Property Name="OrderPlaced" Type="Edm.DateTimeOffset" Nullable="false" />
+        <Property Name="Quantity" Type="Edm.Int32" Nullable="false" />
+        <Property Name="UnitPrice" Type="Edm.Single" Nullable="false" />
+        <NavigationProperty Name="ProductOrdered" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Product)" />
+        <NavigationProperty Name="AssociatedOrder" Type="Microsoft.Test.OData.Services.ODataWCFService.Order" Nullable="false" />
       </EntityType>
-      <EntityType Name="Category_Sales_for_1997">
+      <EntityType Name="Department">
         <Key>
-          <PropertyRef Name="CategoryName" />
+          <PropertyRef Name="DepartmentID" />
         </Key>
-        <Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
-        <Property Name="CategorySales" Type="Edm.Decimal" Precision="19" Scale="4" />
+        <Property Name="DepartmentID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="Name" Type="Edm.String" Nullable="false" />
+        <NavigationProperty Name="Company" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" Partner="Departments" />
       </EntityType>
-      <EntityType Name="Current_Product_List">
+      <EntityType Name="Company">
         <Key>
-          <PropertyRef Name="ProductID" />
-          <PropertyRef Name="ProductName" />
+          <PropertyRef Name="CompanyID" />
         </Key>
-        <Property Name="ProductID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
-        <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
+        <Property Name="CompanyID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="CompanyCategory" Type="Microsoft.Test.OData.Services.ODataWCFService.CompanyCategory" />
+        <Property Name="Revenue" Type="Edm.Int64" Nullable="false" />
+        <Property Name="Name" Type="Edm.String" />
+        <Property Name="Address" Type="Microsoft.Test.OData.Services.ODataWCFService.Address" />
+        <NavigationProperty Name="Employees" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Employee)" Partner="Company" />
+        <NavigationProperty Name="VipCustomer" Type="Microsoft.Test.OData.Services.ODataWCFService.Customer" Nullable="false" Partner="Company" />
+        <NavigationProperty Name="Departments" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Department)" Partner="Company" />
+        <NavigationProperty Name="CoreDepartment" Type="Microsoft.Test.OData.Services.ODataWCFService.Department" Nullable="false" />
       </EntityType>
-      <EntityType Name="Customer_and_Suppliers_by_City">
-        <Key>
-          <PropertyRef Name="CompanyName" />
-          <PropertyRef Name="Relationship" />
-        </Key>
-        <Property Name="City" Type="Edm.String" MaxLength="15" />
-        <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="ContactName" Type="Edm.String" MaxLength="30" />
-        <Property Name="Relationship" Type="Edm.String" Nullable="false" MaxLength="9" Unicode="false" />
+      <EntityType Name="PublicCompany" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Company">
+        <Property Name="StockExchange" Type="Edm.String" />
+        <NavigationProperty Name="Assets" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Asset)" ContainsTarget="true" />
+        <NavigationProperty Name="Club" Type="Microsoft.Test.OData.Services.ODataWCFService.Club" Nullable="false" ContainsTarget="true" />
+        <NavigationProperty Name="LabourUnion" Type="Microsoft.Test.OData.Services.ODataWCFService.LabourUnion" Nullable="false" />
       </EntityType>
-      <EntityType Name="Invoice">
+      <EntityType Name="Asset">
         <Key>
-          <PropertyRef Name="CustomerName" />
-          <PropertyRef Name="Discount" />
-          <PropertyRef Name="OrderID" />
-          <PropertyRef Name="ProductID" />
-          <PropertyRef Name="ProductName" />
-          <PropertyRef Name="Quantity" />
-          <PropertyRef Name="Salesperson" />
-          <PropertyRef Name="ShipperName" />
-          <PropertyRef Name="UnitPrice" />
+          <PropertyRef Name="AssetID" />
         </Key>
-        <Property Name="ShipName" Type="Edm.String" MaxLength="40" />
-        <Property Name="ShipAddress" Type="Edm.String" MaxLength="60" />
-        <Property Name="ShipCity" Type="Edm.String" MaxLength="15" />
-        <Property Name="ShipRegion" Type="Edm.String" MaxLength="15" />
-        <Property Name="ShipPostalCode" Type="Edm.String" MaxLength="10" />
-        <Property Name="ShipCountry" Type="Edm.String" MaxLength="15" />
-        <Property Name="CustomerID" Type="Edm.String" MaxLength="5" />
-        <Property Name="CustomerName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="Address" Type="Edm.String" MaxLength="60" />
-        <Property Name="City" Type="Edm.String" MaxLength="15" />
-        <Property Name="Region" Type="Edm.String" MaxLength="15" />
-        <Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
-        <Property Name="Country" Type="Edm.String" MaxLength="15" />
-        <Property Name="Salesperson" Type="Edm.String" Nullable="false" MaxLength="31" />
-        <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="OrderDate" Type="Edm.DateTimeOffset" />
-        <Property Name="RequiredDate" Type="Edm.DateTimeOffset" />
-        <Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
-        <Property Name="ShipperName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="UnitPrice" Type="Edm.Decimal" Nullable="false" Precision="19" Scale="4" />
-        <Property Name="Quantity" Type="Edm.Int16" Nullable="false" />
-        <Property Name="Discount" Type="Edm.Single" Nullable="false" />
-        <Property Name="ExtendedPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
-        <Property Name="Freight" Type="Edm.Decimal" Precision="19" Scale="4" />
+        <Property Name="AssetID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="Name" Type="Edm.String" />
+        <Property Name="Number" Type="Edm.Int32" Nullable="false" />
       </EntityType>
-      <EntityType Name="Order_Details_Extended">
+      <EntityType Name="Club">
         <Key>
-          <PropertyRef Name="Discount" />
-          <PropertyRef Name="OrderID" />
-          <PropertyRef Name="ProductID" />
-          <PropertyRef Name="ProductName" />
-          <PropertyRef Name="Quantity" />
-          <PropertyRef Name="UnitPrice" />
+          <PropertyRef Name="ClubID" />
         </Key>
-        <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="UnitPrice" Type="Edm.Decimal" Nullable="false" Precision="19" Scale="4" />
-        <Property Name="Quantity" Type="Edm.Int16" Nullable="false" />
-        <Property Name="Discount" Type="Edm.Single" Nullable="false" />
-        <Property Name="ExtendedPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
+        <Property Name="ClubID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="Name" Type="Edm.String" />
       </EntityType>
-      <EntityType Name="Order_Subtotal">
+      <EntityType Name="LabourUnion">
         <Key>
-          <PropertyRef Name="OrderID" />
+          <PropertyRef Name="LabourUnionID" />
         </Key>
-        <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="Subtotal" Type="Edm.Decimal" Precision="19" Scale="4" />
+        <Property Name="LabourUnionID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="Name" Type="Edm.String" />
       </EntityType>
-      <EntityType Name="Orders_Qry">
+      <Action Name="AddAccessRight" IsBound="true">
+        <Parameter Name="product" Type="Microsoft.Test.OData.Services.ODataWCFService.Product" Nullable="false" />
+        <Parameter Name="accessRight" Type="Microsoft.Test.OData.Services.ODataWCFService.AccessLevel" />
+        <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.AccessLevel" />
+      </Action>
+      <Action Name="IncreaseRevenue" IsBound="true">
+        <Parameter Name="p" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" />
+        <Parameter Name="IncreaseValue" Type="Edm.Int64" />
+        <ReturnType Type="Edm.Int64" Nullable="false" />
+      </Action>
+      <Action Name="ResetAddress" IsBound="true" EntitySetPath="person">
+        <Parameter Name="person" Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
+        <Parameter Name="addresses" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Address)" Nullable="false" />
+        <Parameter Name="index" Type="Edm.Int32" Nullable="false" />
+        <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
+      </Action>
+      <Action Name="Discount" IsBound="true" EntitySetPath="products">
+        <Parameter Name="products" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Product)" Nullable="false" />
+        <Parameter Name="percentage" Type="Edm.Int32" Nullable="false" />
+        <ReturnType Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Product)" Nullable="false" />
+      </Action>
+      <Action Name="Discount">
+        <Parameter Name="percentage" Type="Edm.Int32" Nullable="false" />
+      </Action>
+      <Action Name="ResetBossEmail">
+        <Parameter Name="emails" Type="Collection(Edm.String)" Nullable="false" />
+        <ReturnType Type="Collection(Edm.String)" Nullable="false" />
+      </Action>
+      <Action Name="ResetBossAddress">
+        <Parameter Name="address" Type="Microsoft.Test.OData.Services.ODataWCFService.Address" Nullable="false" />
+        <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Address" Nullable="false" />
+      </Action>
+      <Function Name="GetEmployeesCount" IsBound="true">
+        <Parameter Name="p" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" />
+        <ReturnType Type="Edm.Int32" Nullable="false" />
+      </Function>
+      <Function Name="GetProductDetails" IsBound="true" EntitySetPath="product/Details" IsComposable="true">
+        <Parameter Name="product" Type="Microsoft.Test.OData.Services.ODataWCFService.Product" Nullable="false" />
+        <Parameter Name="count" Type="Edm.Int32" />
+        <ReturnType Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.ProductDetail)" Nullable="false" />
+      </Function>
+      <Function Name="GetRelatedProduct" IsBound="true" EntitySetPath="productDetail/Products" IsComposable="true">
+        <Parameter Name="productDetail" Type="Microsoft.Test.OData.Services.ODataWCFService.ProductDetail" Nullable="false" />
+        <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Product" Nullable="false" />
+      </Function>
+      <Function Name="GetDefaultColor" IsComposable="true">
+        <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Color" />
+      </Function>
+      <Function Name="GetPerson" IsComposable="true">
+        <Parameter Name="address" Type="Microsoft.Test.OData.Services.ODataWCFService.Address" Nullable="false" />
+        <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
+      </Function>
+      <Function Name="GetPerson2" IsComposable="true">
+        <Parameter Name="city" Type="Edm.String" Nullable="false" />
+        <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
+      </Function>
+      <Function Name="GetAllProducts" IsComposable="true">
+        <ReturnType Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Product)" Nullable="false" />
+      </Function>
+      <Function Name="GetBossEmails">
+        <Parameter Name="start" Type="Edm.Int32" Nullable="false" />
+        <Parameter Name="count" Type="Edm.Int32" Nullable="false" />
+        <ReturnType Type="Collection(Edm.String)" Nullable="false" />
+      </Function>
+      <Function Name="GetProductsByAccessLevel">
+        <Parameter Name="accessLevel" Type="Microsoft.Test.OData.Services.ODataWCFService.AccessLevel" />
+        <ReturnType Type="Collection(Edm.String)" Nullable="false" />
+      </Function>
+      <Function Name="GetActualAmount" IsBound="true">
+        <Parameter Name="giftcard" Type="Microsoft.Test.OData.Services.ODataWCFService.GiftCard" Nullable="false" />
+        <Parameter Name="bonusRate" Type="Edm.Double" />
+        <ReturnType Type="Edm.Double" Nullable="false" />
+      </Function>
+      <Function Name="GetDefaultPI" IsBound="true" EntitySetPath="account/MyPaymentInstruments">
+        <Parameter Name="account" Type="Microsoft.Test.OData.Services.ODataWCFService.Account" Nullable="false" />
+        <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument" />
+      </Function>
+      <Action Name="RefreshDefaultPI" IsBound="true" EntitySetPath="account/MyPaymentInstruments">
+        <Parameter Name="account" Type="Microsoft.Test.OData.Services.ODataWCFService.Account" Nullable="false" />
+        <Parameter Name="newDate" Type="Edm.DateTimeOffset" />
+        <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument" />
+      </Action>
+      <Function Name="GetHomeAddress" IsBound="true" IsComposable="true">
+        <Parameter Name="person" Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
+        <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.HomeAddress" Nullable="false" />
+      </Function>
+      <Function Name="GetAccountInfo" IsBound="true" IsComposable="true">
+        <Parameter Name="account" Type="Microsoft.Test.OData.Services.ODataWCFService.Account" Nullable="false" />
+        <ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.AccountInfo" Nullable="false" />
+      </Function>
+      <ComplexType Name="AccountInfo" OpenType="true">
+        <Property Name="FirstName" Type="Edm.String" Nullable="false" />
+        <Property Name="LastName" Type="Edm.String" Nullable="false" />
+      </ComplexType>
+      <EntityType Name="Account">
         <Key>
-          <PropertyRef Name="CompanyName" />
-          <PropertyRef Name="OrderID" />
+          <PropertyRef Name="AccountID" />
         </Key>
-        <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="CustomerID" Type="Edm.String" MaxLength="5" />
-        <Property Name="EmployeeID" Type="Edm.Int32" />
-        <Property Name="OrderDate" Type="Edm.DateTimeOffset" />
-        <Property Name="RequiredDate" Type="Edm.DateTimeOffset" />
-        <Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
-        <Property Name="ShipVia" Type="Edm.Int32" />
-        <Property Name="Freight" Type="Edm.Decimal" Precision="19" Scale="4" />
-        <Property Name="ShipName" Type="Edm.String" MaxLength="40" />
-        <Property Name="ShipAddress" Type="Edm.String" MaxLength="60" />
-        <Property Name="ShipCity" Type="Edm.String" MaxLength="15" />
-        <Property Name="ShipRegion" Type="Edm.String" MaxLength="15" />
-        <Property Name="ShipPostalCode" Type="Edm.String" MaxLength="10" />
-        <Property Name="ShipCountry" Type="Edm.String" MaxLength="15" />
-        <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="Address" Type="Edm.String" MaxLength="60" />
-        <Property Name="City" Type="Edm.String" MaxLength="15" />
-        <Property Name="Region" Type="Edm.String" MaxLength="15" />
-        <Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
-        <Property Name="Country" Type="Edm.String" MaxLength="15" />
+        <Property Name="AccountID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="Country" Type="Edm.String" Nullable="false" />
+        <Property Name="AccountInfo" Type="Microsoft.Test.OData.Services.ODataWCFService.AccountInfo" />
+        <NavigationProperty Name="MyGiftCard" Type="Microsoft.Test.OData.Services.ODataWCFService.GiftCard" ContainsTarget="true" />
+        <NavigationProperty Name="MyPaymentInstruments" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument)" ContainsTarget="true" />
+        <NavigationProperty Name="ActiveSubscriptions" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Subscription)" ContainsTarget="true" />
+        <NavigationProperty Name="AvailableSubscriptionTemplatess" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Subscription)" />
       </EntityType>
-      <EntityType Name="Product_Sales_for_1997">
+      <EntityType Name="GiftCard">
         <Key>
-          <PropertyRef Name="CategoryName" />
-          <PropertyRef Name="ProductName" />
+          <PropertyRef Name="GiftCardID" />
         </Key>
-        <Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
-        <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="ProductSales" Type="Edm.Decimal" Precision="19" Scale="4" />
+        <Property Name="GiftCardID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="GiftCardNO" Type="Edm.String" Nullable="false" />
+        <Property Name="Amount" Type="Edm.Double" Nullable="false" />
+        <Property Name="ExperationDate" Type="Edm.DateTimeOffset" Nullable="false" />
       </EntityType>
-      <EntityType Name="Products_Above_Average_Price">
+      <EntityType Name="PaymentInstrument">
         <Key>
-          <PropertyRef Name="ProductName" />
+          <PropertyRef Name="PaymentInstrumentID" />
         </Key>
-        <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="UnitPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
+        <Property Name="PaymentInstrumentID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="FriendlyName" Type="Edm.String" Nullable="false" />
+        <Property Name="CreatedDate" Type="Edm.DateTimeOffset" Nullable="false" />
+        <NavigationProperty Name="TheStoredPI" Type="Microsoft.Test.OData.Services.ODataWCFService.StoredPI" Nullable="false" />
+        <NavigationProperty Name="BillingStatements" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Statement)" ContainsTarget="true" />
+        <NavigationProperty Name="BackupStoredPI" Type="Microsoft.Test.OData.Services.ODataWCFService.StoredPI" Nullable="false" />
       </EntityType>
-      <EntityType Name="Products_by_Category">
-        <Key>
-          <PropertyRef Name="CategoryName" />
-          <PropertyRef Name="Discontinued" />
-          <PropertyRef Name="ProductName" />
-        </Key>
-        <Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
-        <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="QuantityPerUnit" Type="Edm.String" MaxLength="20" />
-        <Property Name="UnitsInStock" Type="Edm.Int16" />
-        <Property Name="Discontinued" Type="Edm.Boolean" Nullable="false" />
+      <EntityType Name="CreditCardPI" BaseType="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument">
+        <Property Name="CardNumber" Type="Edm.String" Nullable="false" />
+        <Property Name="CVV" Type="Edm.String" Nullable="false" />
+        <Property Name="HolderName" Type="Edm.String" Nullable="false" />
+        <Property Name="Balance" Type="Edm.Double" Nullable="false" />
+        <Property Name="ExperationDate" Type="Edm.DateTimeOffset" Nullable="false" />
+        <NavigationProperty Name="CreditRecords" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.CreditRecord)" ContainsTarget="true" />
       </EntityType>
-      <EntityType Name="Sales_by_Category">
+      <EntityType Name="StoredPI">
         <Key>
-          <PropertyRef Name="CategoryID" />
-          <PropertyRef Name="CategoryName" />
-          <PropertyRef Name="ProductName" />
+          <PropertyRef Name="StoredPIID" />
         </Key>
-        <Property Name="CategoryID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
-        <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="ProductSales" Type="Edm.Decimal" Precision="19" Scale="4" />
+        <Property Name="StoredPIID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="PIName" Type="Edm.String" Nullable="false" />
+        <Property Name="PIType" Type="Edm.String" Nullable="false" />
+        <Property Name="CreatedDate" Type="Edm.DateTimeOffset" Nullable="false" />
       </EntityType>
-      <EntityType Name="Sales_Totals_by_Amount">
+      <EntityType Name="Statement">
         <Key>
-          <PropertyRef Name="CompanyName" />
-          <PropertyRef Name="OrderID" />
+          <PropertyRef Name="StatementID" />
         </Key>
-        <Property Name="SaleAmount" Type="Edm.Decimal" Precision="19" Scale="4" />
-        <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
-        <Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
+        <Property Name="StatementID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="TransactionType" Type="Edm.String" Nullable="false" />
+        <Property Name="TransactionDescription" Type="Edm.String" Nullable="false" />
+        <Property Name="Amount" Type="Edm.Double" Nullable="false" />
       </EntityType>
-      <EntityType Name="Summary_of_Sales_by_Quarter">
+      <EntityType Name="CreditRecord">
         <Key>
-          <PropertyRef Name="OrderID" />
+          <PropertyRef Name="CreditRecordID" />
         </Key>
-        <Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
-        <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="Subtotal" Type="Edm.Decimal" Precision="19" Scale="4" />
+        <Property Name="CreditRecordID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="IsGood" Type="Edm.Boolean" Nullable="false" />
+        <Property Name="Reason" Type="Edm.String" Nullable="false" />
+        <Property Name="CreatedDate" Type="Edm.DateTimeOffset" Nullable="false" />
       </EntityType>
-      <EntityType Name="Summary_of_Sales_by_Year">
+      <EntityType Name="Subscription">
         <Key>
-          <PropertyRef Name="OrderID" />
+          <PropertyRef Name="SubscriptionID" />
         </Key>
-        <Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
-        <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="Subtotal" Type="Edm.Decimal" Precision="19" Scale="4" />
+        <Property Name="SubscriptionID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="TemplateGuid" Type="Edm.String" Nullable="false" />
+        <Property Name="Title" Type="Edm.String" Nullable="false" />
+        <Property Name="Category" Type="Edm.String" Nullable="false" />
+        <Property Name="CreatedDate" Type="Edm.DateTimeOffset" Nullable="false" />
       </EntityType>
-      <Annotations Target="ODataWebExperimental.Northwind.Model.NorthwindEntities">
-        <Annotation Term="Com.Microsoft.OData.Service.Conventions.V1.UrlConventions" String="KeyAsSegment" />
-      </Annotations>
-      <!-- Function -->
-      <Function Name="TopSellingProducts" ReturnType="Collection(NorthwindModel.Product)" IsComposable="true" EntitySetPath="ODataWebExperimental.Northwind.Model.Products">
-        <Parameter Name="Year" Type="Edm.Decimal" Precision="4" Scale="0" />
-      </Function>
-      <Function Name="TopSellingProducts2" ReturnType="Collection(NorthwindModel.Product)" IsComposable="true" EntitySetPath="ODataWebExperimental.Northwind.Model.Products" IsBound="true">
-        <Parameter Name="Product" Type="NorthwindModel.Product" />
-        <Parameter Name="Year" Type="Edm.Decimal" Precision="4" Scale="0" />
-      </Function>
-      <!-- Action -->
-      <Action Name="TopSellingProducts" EntitySetPath="ODataWebExperimental.Northwind.Model.Products" IsBound="true">
-        <Parameter Name="Product" Type="NorthwindModel.Product" />
-        <Parameter Name="Year" Type="Edm.Decimal" Precision="4" Scale="0" />
-      </Action>
-    </Schema>
-    <Schema Namespace="ODataWebExperimental.Northwind.Model" xmlns="http://docs.oasis-open.org/odata/ns/edm">
-      <EntityContainer Name="NorthwindEntities" p4:LazyLoadingEnabled="true" xmlns:p4="http://schemas.microsoft.com/ado/2009/02/edm/annotation">
-        <EntitySet Name="Categories" EntityType="NorthwindModel.Category">
-          <NavigationPropertyBinding Path="Products" Target="Products" />
-        </EntitySet>
-        <EntitySet Name="CustomerDemographics" EntityType="NorthwindModel.CustomerDemographic">
-          <NavigationPropertyBinding Path="Customers" Target="Customers" />
+      <EntityContainer Name="InMemoryEntities">
+        <EntitySet Name="People" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Person">
+          <NavigationPropertyBinding Path="Parent" Target="People" />
         </EntitySet>
-        <EntitySet Name="Customers" EntityType="NorthwindModel.Customer">
-          <NavigationPropertyBinding Path="CustomerDemographics" Target="CustomerDemographics" />
+        <Singleton Name="Boss" Type="Microsoft.Test.OData.Services.ODataWCFService.Person" />
+        <EntitySet Name="Customers" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Customer">
           <NavigationPropertyBinding Path="Orders" Target="Orders" />
         </EntitySet>
-        <EntitySet Name="Employees" EntityType="NorthwindModel.Employee">
-          <NavigationPropertyBinding Path="Employees1" Target="Employees" />
-          <NavigationPropertyBinding Path="Employee1" Target="Employees" />
+        <Singleton Name="VipCustomer" Type="Microsoft.Test.OData.Services.ODataWCFService.Customer">
           <NavigationPropertyBinding Path="Orders" Target="Orders" />
-          <NavigationPropertyBinding Path="Territories" Target="Territories" />
-        </EntitySet>
-        <EntitySet Name="Order_Details" EntityType="NorthwindModel.Order_Detail">
-          <NavigationPropertyBinding Path="Order" Target="Orders" />
-          <NavigationPropertyBinding Path="Product" Target="Products" />
+          <NavigationPropertyBinding Path="Company" Target="Company" />
+        </Singleton>
+        <EntitySet Name="Employees" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Employee">
+          <NavigationPropertyBinding Path="Company" Target="Company" />
         </EntitySet>
-        <EntitySet Name="Orders" EntityType="NorthwindModel.Order">
-          <NavigationPropertyBinding Path="Customer" Target="Customers" />
-          <NavigationPropertyBinding Path="Employee" Target="Employees" />
-          <NavigationPropertyBinding Path="Order_Details" Target="Order_Details" />
-          <NavigationPropertyBinding Path="Shipper" Target="Shippers" />
+        <EntitySet Name="Products" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Product">
+          <NavigationPropertyBinding Path="Details" Target="ProductDetails" />
         </EntitySet>
-        <EntitySet Name="Products" EntityType="NorthwindModel.Product">
-          <NavigationPropertyBinding Path="Category" Target="Categories" />
-          <NavigationPropertyBinding Path="Order_Details" Target="Order_Details" />
-          <NavigationPropertyBinding Path="Supplier" Target="Suppliers" />
+        <EntitySet Name="ProductDetails" EntityType="Microsoft.Test.OData.Services.ODataWCFService.ProductDetail">
+          <NavigationPropertyBinding Path="RelatedProduct" Target="Products" />
+          <NavigationPropertyBinding Path="Reviews" Target="ProductReviews" />
         </EntitySet>
-        <EntitySet Name="Regions" EntityType="NorthwindModel.Region">
-          <NavigationPropertyBinding Path="Territories" Target="Territories" />
+        <EntitySet Name="ProductReviews" EntityType="Microsoft.Test.OData.Services.ODataWCFService.ProductReview" />
+        <EntitySet Name="Orders" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Order">
+          <NavigationPropertyBinding Path="LoggedInEmployee" Target="Employees" />
+          <NavigationPropertyBinding Path="CustomerForOrder" Target="Customers" />
+          <NavigationPropertyBinding Path="OrderDetails" Target="OrderDetails" />
         </EntitySet>
-        <EntitySet Name="Shippers" EntityType="NorthwindModel.Shipper">
-          <NavigationPropertyBinding Path="Orders" Target="Orders" />
+        <EntitySet Name="OrderDetails" EntityType="Microsoft.Test.OData.Services.ODataWCFService.OrderDetail">
+          <NavigationPropertyBinding Path="AssociatedOrder" Target="Orders" />
+          <NavigationPropertyBinding Path="ProductOrdered" Target="Products" />
         </EntitySet>
-        <EntitySet Name="Suppliers" EntityType="NorthwindModel.Supplier">
-          <NavigationPropertyBinding Path="Products" Target="Products" />
+        <EntitySet Name="Departments" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Department">
+          <NavigationPropertyBinding Path="Company" Target="Company" />
         </EntitySet>
-        <EntitySet Name="Territories" EntityType="NorthwindModel.Territory">
+        <Singleton Name="Company" Type="Microsoft.Test.OData.Services.ODataWCFService.Company">
           <NavigationPropertyBinding Path="Employees" Target="Employees" />
-          <NavigationPropertyBinding Path="Region" Target="Regions" />
-        </EntitySet>
-        <EntitySet Name="Alphabetical_list_of_products" EntityType="NorthwindModel.Alphabetical_list_of_product" />
-        <EntitySet Name="Category_Sales_for_1997" EntityType="NorthwindModel.Category_Sales_for_1997" />
-        <EntitySet Name="Current_Product_Lists" EntityType="NorthwindModel.Current_Product_List" />
-        <EntitySet Name="Customer_and_Suppliers_by_Cities" EntityType="NorthwindModel.Customer_and_Suppliers_by_City" />
-        <EntitySet Name="Invoices" EntityType="NorthwindModel.Invoice" />
-        <EntitySet Name="Order_Details_Extendeds" EntityType="NorthwindModel.Order_Details_Extended" />
-        <EntitySet Name="Order_Subtotals" EntityType="NorthwindModel.Order_Subtotal" />
-        <EntitySet Name="Orders_Qries" EntityType="NorthwindModel.Orders_Qry" />
-        <EntitySet Name="Product_Sales_for_1997" EntityType="NorthwindModel.Product_Sales_for_1997" />
-        <EntitySet Name="Products_Above_Average_Prices" EntityType="NorthwindModel.Products_Above_Average_Price" />
-        <EntitySet Name="Products_by_Categories" EntityType="NorthwindModel.Products_by_Category" />
-        <EntitySet Name="Sales_by_Categories" EntityType="NorthwindModel.Sales_by_Category" />
-        <EntitySet Name="Sales_Totals_by_Amounts" EntityType="NorthwindModel.Sales_Totals_by_Amount" />
-        <EntitySet Name="Summary_of_Sales_by_Quarters" EntityType="NorthwindModel.Summary_of_Sales_by_Quarter" />
-        <EntitySet Name="Summary_of_Sales_by_Years" EntityType="NorthwindModel.Summary_of_Sales_by_Year" />
-        <!-- Singleton -->
-        <Singleton Name="Contoso" Type="NorthwindModel.Supplier">
-          <NavigationPropertyBinding Path="Products" Target="Products"/>
+          <NavigationPropertyBinding Path="VipCustomer" Target="VipCustomer" />
+          <NavigationPropertyBinding Path="Departments" Target="Departments" />
+          <NavigationPropertyBinding Path="CoreDepartment" Target="Departments" />
         </Singleton>
-        <!-- FunctionImport -->
-        <FunctionImport Name="TopSellingProducts" EntitySet="Products" Function="NorthwindModel.TopSellingProducts"/>
+        <Singleton Name="PublicCompany" Type="Microsoft.Test.OData.Services.ODataWCFService.Company">
+          <NavigationPropertyBinding Path="Microsoft.Test.OData.Services.ODataWCFService.PublicCompany/LabourUnion" Target="LabourUnion" />
+        </Singleton>
+        <Singleton Name="LabourUnion" Type="Microsoft.Test.OData.Services.ODataWCFService.LabourUnion" />
+        <ActionImport Name="Discount" Action="Microsoft.Test.OData.Services.ODataWCFService.Discount" />
+        <ActionImport Name="ResetBossEmail" Action="Microsoft.Test.OData.Services.ODataWCFService.ResetBossEmail" />
+        <ActionImport Name="ResetBossAddress" Action="Microsoft.Test.OData.Services.ODataWCFService.ResetBossAddress" />
+        <FunctionImport Name="GetDefaultColor" Function="Microsoft.Test.OData.Services.ODataWCFService.GetDefaultColor" />
+        <FunctionImport Name="GetPerson" Function="Microsoft.Test.OData.Services.ODataWCFService.GetPerson" EntitySet="People" />
+        <FunctionImport Name="GetPerson2" Function="Microsoft.Test.OData.Services.ODataWCFService.GetPerson2" EntitySet="People" />
+        <FunctionImport Name="GetAllProducts" Function="Microsoft.Test.OData.Services.ODataWCFService.GetAllProducts" EntitySet="Products" />
+        <FunctionImport Name="GetBossEmails" Function="Microsoft.Test.OData.Services.ODataWCFService.GetBossEmails" />
+        <FunctionImport Name="GetProductsByAccessLevel" Function="Microsoft.Test.OData.Services.ODataWCFService.GetProductsByAccessLevel" />
+        <EntitySet Name="Accounts" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Account">
+          <NavigationPropertyBinding Path="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument/TheStoredPI" Target="StoredPIs" />
+          <NavigationPropertyBinding Path="AvailableSubscriptionTemplatess" Target="SubscriptionTemplates" />
+          <NavigationPropertyBinding Path="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument/BackupStoredPI" Target="DefaultStoredPI" />
+        </EntitySet>
+        <EntitySet Name="StoredPIs" EntityType="Microsoft.Test.OData.Services.ODataWCFService.StoredPI" />
+        <EntitySet Name="SubscriptionTemplates" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Subscription" />
+        <Singleton Name="DefaultStoredPI" Type="Microsoft.Test.OData.Services.ODataWCFService.StoredPI" />
       </EntityContainer>
     </Schema>
   </edmx:DataServices>
 </edmx:Edmx>
+