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/04/24 17:31:54 UTC

git commit: [OLINGO-253] fix v4 compliance + added tests for , ,

Repository: olingo-odata4
Updated Branches:
  refs/heads/master fac8c0ae6 -> 149c51c7a


[OLINGO-253] fix  v4 compliance + added tests for , ,


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

Branch: refs/heads/master
Commit: 149c51c7a7e52be9deea7745dc7cb2cc2432d370
Parents: fac8c0a
Author: fmartelli <fa...@gmail.com>
Authored: Thu Apr 24 17:31:39 2014 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Thu Apr 24 17:31:39 2014 +0200

----------------------------------------------------------------------
 .../org/apache/olingo/fit/AbstractServices.java |  46 ++--
 .../java/org/apache/olingo/fit/V4Services.java  |  62 ++++--
 .../main/resources/V40/Customers/feed.full.json |  10 +-
 fit/src/main/resources/V40/Customers/feed.xml   |  24 +--
 .../V40/People/filter/(PersonID eq 5).full.json |  55 +++++
 .../V40/People/filter/(PersonID eq 5).xml       |  58 +++++
 .../V40/People/filter/(PersonID lt 3).full.json |  91 ++++++++
 .../V40/People/filter/(PersonID lt 3).xml       | 103 +++++++++
 .../filter/(PersonID lt 3).full.json            |  91 ++++++++
 .../PersonID desc/filter/(PersonID lt 3).xml    | 103 +++++++++
 .../resources/V40/People/skiptoken/5.full.json  |  56 +++++
 .../main/resources/V40/People/skiptoken/5.xml   |  62 ++++++
 fit/src/main/resources/V40/crossjoin.full.json  |  18 ++
 .../olingo/client/api/uri/v4/URIBuilder.java    |  12 ++
 .../client/core/uri/AbstractURIBuilder.java     |  26 +--
 .../client/core/uri/v4/URIBuilderImpl.java      |   5 +
 .../core/it/v3/QueryOptionsTestITCase.java      |   6 +-
 .../core/it/v4/FilterFactoryTestITCase.java     |  64 ++++++
 .../core/it/v4/KeyAsSegmentTestITCase.java      |   1 -
 .../core/it/v4/QueryOptionsTestITCase.java      | 215 +++++++++++++++++++
 .../apache/olingo/client/core/v4/JSONTest.java  |  18 +-
 .../apache/olingo/client/core/v4/crossjoin.json |  18 ++
 22 files changed, 1074 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/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 8e888bd..9777381 100644
--- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
+++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
@@ -29,6 +29,7 @@ import java.io.InputStream;
 import java.io.OutputStreamWriter;
 import java.net.URI;
 import java.util.AbstractMap;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.ConcurrentModificationException;
@@ -417,7 +418,7 @@ public abstract class AbstractServices {
       } else {
         final Container<JSONEntryImpl> jcont = mapper.readValue(IOUtils.toInputStream(changes, Constants.ENCODING),
                 new TypeReference<JSONEntryImpl>() {
-                });
+        });
 
         entryChanges = dataBinder.toAtomEntry(jcont.getObject());
       }
@@ -607,8 +608,8 @@ public abstract class AbstractServices {
         } else {
           final Container<JSONEntryImpl> jcontainer =
                   mapper.readValue(IOUtils.toInputStream(entity, Constants.ENCODING),
-                          new TypeReference<JSONEntryImpl>() {
-                          });
+                  new TypeReference<JSONEntryImpl>() {
+          });
 
           entry = dataBinder.toAtomEntry(jcontainer.getObject());
 
@@ -635,7 +636,7 @@ public abstract class AbstractServices {
       Container<AtomEntryImpl> result = atomDeserializer.read(serialization, AtomEntryImpl.class);
       result = new Container<AtomEntryImpl>(
               URI.create(Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL)
-                      + "$metadata#" + entitySetName + "/$entity"), null, result.getObject());
+              + "$metadata#" + entitySetName + "/$entity"), null, result.getObject());
 
       final String path = Commons.getEntityBasePath(entitySetName, entityKey);
       FSManager.instance(version).putInMemory(
@@ -697,13 +698,13 @@ public abstract class AbstractServices {
               replaceAll("\"Salary\":[0-9]*,", "\"Salary\":0,").
               replaceAll("\"Title\":\".*\"", "\"Title\":\"[Sacked]\"").
               replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>.*\\</d:Salary\\>",
-                      "<d:Salary m:type=\"Edm.Int32\">0</d:Salary>").
+              "<d:Salary m:type=\"Edm.Int32\">0</d:Salary>").
               replaceAll("\\<d:Title\\>.*\\</d:Title\\>", "<d:Title>[Sacked]</d:Title>");
 
       final FSManager fsManager = FSManager.instance(version);
       fsManager.putInMemory(IOUtils.toInputStream(newContent, Constants.ENCODING),
               fsManager.getAbsolutePath(Commons.getEntityBasePath("Person", entityId) + Constants.get(version,
-                              ConstantKey.ENTITY), utils.getKey()));
+              ConstantKey.ENTITY), utils.getKey()));
 
       return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
     } catch (Exception e) {
@@ -755,9 +756,9 @@ public abstract class AbstractServices {
         final Long newSalary = Long.valueOf(salaryMatcher.group(1)) + n;
         newContent = newContent.
                 replaceAll("\"Salary\":" + salaryMatcher.group(1) + ",",
-                        "\"Salary\":" + newSalary + ",").
+                "\"Salary\":" + newSalary + ",").
                 replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>" + salaryMatcher.group(1) + "</d:Salary\\>",
-                        "<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
+                "<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
       }
 
       FSManager.instance(version).putInMemory(IOUtils.toInputStream(newContent, Constants.ENCODING),
@@ -824,6 +825,8 @@ public abstract class AbstractServices {
           @Context UriInfo uriInfo,
           @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
           @PathParam("name") String name,
+          @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) String top,
+          @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) String skip,
           @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format,
           @QueryParam("$inlinecount") @DefaultValue(StringUtils.EMPTY) String count,
           @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) String filter,
@@ -880,6 +883,23 @@ public abstract class AbstractServices {
         final ByteArrayOutputStream content = new ByteArrayOutputStream();
         final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
 
+        // -----------------------------------------------
+        // Evaluate $skip and $top
+        // -----------------------------------------------
+        List<Entry> entries = new ArrayList<Entry>(container.getObject().getEntries());
+
+        if (StringUtils.isNotBlank(skip)) {
+          entries = entries.subList(Integer.valueOf(skip), entries.size());
+        }
+
+        if (StringUtils.isNotBlank(top)) {
+          entries = entries.subList(0, Integer.valueOf(top));
+        }
+
+        container.getObject().getEntries().clear();
+        container.getObject().getEntries().addAll(entries);
+        // -----------------------------------------------
+
         if (acceptType == Accept.ATOM) {
           atomSerializer.write(writer, container);
           writer.flush();
@@ -887,7 +907,7 @@ public abstract class AbstractServices {
         } else {
           mapper.writeValue(
                   writer, new JSONFeedContainer(container.getContextURL(), container.getMetadataETag(),
-                          dataBinder.toJSONFeed(container.getObject())));
+                  dataBinder.toJSONFeed(container.getObject())));
         }
 
         return xml.createResponse(
@@ -1503,8 +1523,8 @@ public abstract class AbstractServices {
               mapper.writeValue(
                       writer,
                       new JSONFeedContainer(container.getContextURL(),
-                              container.getMetadataETag(),
-                              dataBinder.toJSONFeed((AtomFeedImpl) container.getObject())));
+                      container.getMetadataETag(),
+                      dataBinder.toJSONFeed((AtomFeedImpl) container.getObject())));
             }
           } else {
             final Container<Entry> container = atomDeserializer.<Entry, AtomEntryImpl>read(stream, AtomEntryImpl.class);
@@ -1516,8 +1536,8 @@ public abstract class AbstractServices {
               mapper.writeValue(
                       writer,
                       new JSONEntryContainer(container.getContextURL(),
-                              container.getMetadataETag(),
-                              dataBinder.toJSONEntry((AtomEntryImpl) container.getObject())));
+                      container.getMetadataETag(),
+                      dataBinder.toJSONEntry((AtomEntryImpl) container.getObject())));
             }
           }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/fit/src/main/java/org/apache/olingo/fit/V4Services.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/V4Services.java b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
index 3a8459a..fde79c2 100644
--- a/fit/src/main/java/org/apache/olingo/fit/V4Services.java
+++ b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
@@ -30,6 +30,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.regex.Pattern;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMultipart;
 import javax.ws.rs.DELETE;
@@ -84,7 +85,12 @@ public class V4Services extends AbstractServices {
   /**
    * CR/LF.
    */
-  public static final byte[] CRLF = {13, 10};
+  protected static final byte[] CRLF = {13, 10};
+
+  protected static final Pattern RELENTITY_SELECT_PATTERN = Pattern.compile("^.*\\(\\$select=.*\\)$");
+
+  protected static final Pattern CROSSJOIN_PATTERN = Pattern.compile(
+          "^\\$crossjoin\\(.*\\)\\?\\$filter=\\([a-zA-Z/]+ eq [a-zA-Z/]+\\)$");
 
   private Map<String, String> providedAsync = new HashMap<String, String>();
 
@@ -92,6 +98,38 @@ public class V4Services extends AbstractServices {
     super(ODataServiceVersion.V40);
   }
 
+  @GET
+  @Path("/$crossjoin({elements:.*})")
+  public Response crossjoin(
+          @PathParam("elements") String elements,
+          @QueryParam("$filter") String filter) {
+
+    try {
+      if (CROSSJOIN_PATTERN.matcher("$crossjoin(" + elements + ")?$filter=" + filter).matches()) {
+        final InputStream feed = FSManager.instance(version).readFile("crossjoin", Accept.JSON);
+
+        return xml.createResponse(feed, null, Accept.JSON_FULLMETA);
+      } else {
+        throw new Exception("Unexpected crossjoin pattern");
+      }
+    } catch (Exception e) {
+      return xml.createFaultResponse(Accept.JSON.toString(version), e);
+    }
+  }
+
+  @GET
+  @Path("/relatedEntitySelect/{path:.*}")
+  public Response relatedEntitySelect(
+          @PathParam("path") String path,
+          @QueryParam("$expand") String expand) {
+
+    if (RELENTITY_SELECT_PATTERN.matcher(expand).matches()) {
+      return xml.createResponse(null, null, Accept.JSON_FULLMETA);
+    } else {
+      return xml.createFaultResponse(Accept.JSON.toString(version), new Exception("Unexpected expand pattern"));
+    }
+  }
+
   @DELETE
   @Path("/monitor/{name}")
   public Response removeMonitor(@Context final UriInfo uriInfo, @PathParam("name") final String name) {
@@ -530,7 +568,7 @@ public class V4Services extends AbstractServices {
 
       return utils.getValue().createResponse(
               FSManager.instance(version).readFile(Constants.get(version, ConstantKey.REF)
-                      + File.separatorChar + filename, utils.getKey()),
+              + File.separatorChar + filename, utils.getKey()),
               null,
               utils.getKey());
     } catch (Exception e) {
@@ -552,7 +590,7 @@ public class V4Services extends AbstractServices {
 
     final Response response =
             getEntityInternal(uriInfo.getRequestUri().toASCIIString(),
-                    accept, entitySetName, entityId, accept, StringUtils.EMPTY, StringUtils.EMPTY, false);
+            accept, entitySetName, entityId, accept, StringUtils.EMPTY, StringUtils.EMPTY, false);
     return response.getStatus() >= 400
             ? postNewEntity(uriInfo, accept, contentType, prefer, entitySetName, changes)
             : super.patchEntity(uriInfo, accept, contentType, prefer, ifMatch, entitySetName, entityId, changes);
@@ -650,8 +688,8 @@ public class V4Services extends AbstractServices {
       } else {
         final Container<JSONEntryImpl> jcontainer =
                 mapper.readValue(IOUtils.toInputStream(entity, Constants.ENCODING),
-                        new TypeReference<JSONEntryImpl>() {
-                        });
+                new TypeReference<JSONEntryImpl>() {
+        });
 
         entry = dataBinder.toAtomEntry(jcontainer.getObject());
 
@@ -749,7 +787,7 @@ public class V4Services extends AbstractServices {
 
         final Container<JSONEntryImpl> jsonContainer = mapper.readValue(
                 IOUtils.toInputStream(changes, Constants.ENCODING), new TypeReference<JSONEntryImpl>() {
-                });
+        });
         jsonContainer.getObject().setType(typeInfo.getFullQualifiedName().toString());
         entryChanges = dataBinder.toAtomEntry(jsonContainer.getObject());
       }
@@ -782,7 +820,7 @@ public class V4Services extends AbstractServices {
       // 1. Fetch the contained entity to be removed
       final InputStream entry = FSManager.instance(version).
               readFile(containedPath(entityId, containedEntitySetName).
-                      append('(').append(containedEntityId).append(')').toString(), Accept.ATOM);
+              append('(').append(containedEntityId).append(')').toString(), Accept.ATOM);
       final Container<AtomEntryImpl> container = atomDeserializer.read(entry, AtomEntryImpl.class);
 
       // 2. Remove the contained entity
@@ -910,7 +948,7 @@ public class V4Services extends AbstractServices {
           @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
           @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) {
 
-    return getEntitySet(uriInfo, accept, "Products", format, null, null, null, null);
+    return getEntitySet(uriInfo, accept, "Products", null, null, format, null, null, null, null);
   }
 
   @GET
@@ -1011,8 +1049,8 @@ public class V4Services extends AbstractServices {
       } else {
         final Container<JSONPropertyImpl> paramContainer =
                 mapper.readValue(IOUtils.toInputStream(param, Constants.ENCODING),
-                        new TypeReference<JSONPropertyImpl>() {
-                        });
+                new TypeReference<JSONPropertyImpl>() {
+        });
         property = paramContainer.getObject();
       }
 
@@ -1053,8 +1091,8 @@ public class V4Services extends AbstractServices {
       } else {
         final Container<JSONPropertyImpl> paramContainer =
                 mapper.readValue(IOUtils.toInputStream(param, Constants.ENCODING),
-                        new TypeReference<JSONPropertyImpl>() {
-                        });
+                new TypeReference<JSONPropertyImpl>() {
+        });
         property = paramContainer.getObject();
       }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/fit/src/main/resources/V40/Customers/feed.full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Customers/feed.full.json b/fit/src/main/resources/V40/Customers/feed.full.json
index 54af904..89cd2bc 100644
--- a/fit/src/main/resources/V40/Customers/feed.full.json
+++ b/fit/src/main/resources/V40/Customers/feed.full.json
@@ -1,10 +1,10 @@
 {
-  "@odata.context": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Customers",
+  "@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Customers",
   "value":
           [
             {
-              "@odata.id": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)",
-              "@odata.editLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)",
+              "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)",
+              "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)",
               "PersonID": 1,
               "FirstName": "Bob",
               "LastName": "Cat",
@@ -51,8 +51,8 @@
               "TimeBetweenLastTwoOrders": "PT0.0000001S"
             },
             {
-              "@odata.id": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)",
-              "@odata.editLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)",
+              "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)",
+              "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)",
               "PersonID": 2,
               "FirstName": "Jill",
               "LastName": "Jones",

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/fit/src/main/resources/V40/Customers/feed.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Customers/feed.xml b/fit/src/main/resources/V40/Customers/feed.xml
index 198acd5..ffab6da 100644
--- a/fit/src/main/resources/V40/Customers/feed.xml
+++ b/fit/src/main/resources/V40/Customers/feed.xml
@@ -19,17 +19,17 @@
     under the License.
 
 -->
-<feed xml:base="http://odatae2etest.azurewebsites.net/javatest/DefaultService/" 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://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Customers">
-  <id>http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers</id>
+<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#Customers">
+  <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers</id>
   <title />
   <updated>2014-04-23T10:01:18Z</updated>
   <entry>
-    <id>http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)</id>
+    <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)</id>
     <category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
-    <link rel="edit" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)" />
-    <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Parent" />
-    <link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Orders" />
-    <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Company" />
+    <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)" />
+    <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/Customers(PersonID=1)/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/Customers(PersonID=1)/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/Customers(PersonID=1)/Company" />
     <title />
     <updated>2014-04-23T10:01:18Z</updated>
     <author>
@@ -69,12 +69,12 @@
     </content>
   </entry>
   <entry>
-    <id>http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)</id>
+    <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)</id>
     <category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
-    <link rel="edit" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)" />
-    <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)/Parent" />
-    <link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)/Orders" />
-    <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)/Company" />
+    <link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=2)" />
+    <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/Customers(PersonID=2)/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/Customers(PersonID=2)/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/Customers(PersonID=2)/Company" />
     <title />
     <updated>2014-04-23T10:01:18Z</updated>
     <author>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/fit/src/main/resources/V40/People/filter/(PersonID eq 5).full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/People/filter/(PersonID eq 5).full.json b/fit/src/main/resources/V40/People/filter/(PersonID eq 5).full.json
new file mode 100644
index 0000000..29ffaea
--- /dev/null
+++ b/fit/src/main/resources/V40/People/filter/(PersonID eq 5).full.json	
@@ -0,0 +1,55 @@
+{
+  "@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(5)",
+              "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Microsoft.Test.OData.Services.ODataWCFService.Customer",
+              "PersonID": 5,
+              "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":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  23.1,
+                                  32.1
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers":
+                      [
+                        "111-111-1111",
+                        "012",
+                        "310",
+                        "bca",
+                        "ayz"
+                      ],
+              "Emails":
+                      [
+                        "abc@abc.com"
+                      ],
+              "City": "London",
+              "Birthday": "1957-04-03T00:00:00Z",
+              "TimeBetweenLastTwoOrders": "PT0.0000001S"
+            }
+          ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/fit/src/main/resources/V40/People/filter/(PersonID eq 5).xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/People/filter/(PersonID eq 5).xml b/fit/src/main/resources/V40/People/filter/(PersonID eq 5).xml
new file mode 100644
index 0000000..56fc822
--- /dev/null
+++ b/fit/src/main/resources/V40/People/filter/(PersonID eq 5).xml	
@@ -0,0 +1,58 @@
+<?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-04-24T11:35:03Z</updated>
+  <entry>
+    <id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)</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(5)/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(5)/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(5)/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(5)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company" />
+    <title />
+    <updated>2014-04-24T11:35:03Z</updated>
+    <author>
+      <name />
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PersonID m:type="Int32">5</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>
+</feed>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/fit/src/main/resources/V40/People/filter/(PersonID lt 3).full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/People/filter/(PersonID lt 3).full.json b/fit/src/main/resources/V40/People/filter/(PersonID lt 3).full.json
new file mode 100644
index 0000000..017984d
--- /dev/null
+++ b/fit/src/main/resources/V40/People/filter/(PersonID lt 3).full.json	
@@ -0,0 +1,91 @@
+{
+  "@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":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  23.1,
+                                  32.1
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers":
+                      [
+                        "111-111-1111",
+                        "012",
+                        "310",
+                        "bca",
+                        "ayz"
+                      ],
+              "Emails":
+                      [
+                        "abc@abc.com"
+                      ],
+              "City": "London",
+              "Birthday": "1957-04-03T00:00:00Z",
+              "TimeBetweenLastTwoOrders": "PT0.0000001S"
+            },
+            {
+              "@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":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  161.8,
+                                  15
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers":
+                      [
+                      ],
+              "Emails":
+                      [
+                      ],
+              "City": "Sydney",
+              "Birthday": "1983-01-15T00:00:00Z",
+              "TimeBetweenLastTwoOrders": "PT0.0000002S"
+            }
+          ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/fit/src/main/resources/V40/People/filter/(PersonID lt 3).xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/People/filter/(PersonID lt 3).xml b/fit/src/main/resources/V40/People/filter/(PersonID lt 3).xml
new file mode 100644
index 0000000..7debda6
--- /dev/null
+++ b/fit/src/main/resources/V40/People/filter/(PersonID lt 3).xml	
@@ -0,0 +1,103 @@
+<?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-04-24T11:33:37Z</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-04-24T11:33:37Z</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>
+          <m:element>012</m:element>
+          <m:element>310</m:element>
+          <m:element>bca</m:element>
+          <m:element>ayz</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-04-24T11:33:37Z</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>
+</feed>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/fit/src/main/resources/V40/People/orderby/PersonID desc/filter/(PersonID lt 3).full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/People/orderby/PersonID desc/filter/(PersonID lt 3).full.json b/fit/src/main/resources/V40/People/orderby/PersonID desc/filter/(PersonID lt 3).full.json
new file mode 100644
index 0000000..2951c5c
--- /dev/null
+++ b/fit/src/main/resources/V40/People/orderby/PersonID desc/filter/(PersonID lt 3).full.json	
@@ -0,0 +1,91 @@
+{
+  "@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(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":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  161.8,
+                                  15
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers":
+                      [
+                      ],
+              "Emails":
+                      [
+                      ],
+              "City": "Sydney",
+              "Birthday": "1983-01-15T00:00:00Z",
+              "TimeBetweenLastTwoOrders": "PT0.0000002S"
+            },
+            {
+              "@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":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  23.1,
+                                  32.1
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers":
+                      [
+                        "111-111-1111",
+                        "012",
+                        "310",
+                        "bca",
+                        "ayz"
+                      ],
+              "Emails":
+                      [
+                        "abc@abc.com"
+                      ],
+              "City": "London",
+              "Birthday": "1957-04-03T00:00:00Z",
+              "TimeBetweenLastTwoOrders": "PT0.0000001S"
+            }
+          ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/fit/src/main/resources/V40/People/orderby/PersonID desc/filter/(PersonID lt 3).xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/People/orderby/PersonID desc/filter/(PersonID lt 3).xml b/fit/src/main/resources/V40/People/orderby/PersonID desc/filter/(PersonID lt 3).xml
new file mode 100644
index 0000000..692d7e5
--- /dev/null
+++ b/fit/src/main/resources/V40/People/orderby/PersonID desc/filter/(PersonID lt 3).xml	
@@ -0,0 +1,103 @@
+<?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-04-24T11:35:03Z</updated>
+  <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-04-24T11:35:03Z</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(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-04-24T11:35:03Z</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>
+          <m:element>012</m:element>
+          <m:element>310</m:element>
+          <m:element>bca</m:element>
+          <m:element>ayz</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>
+</feed>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/fit/src/main/resources/V40/People/skiptoken/5.full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/People/skiptoken/5.full.json b/fit/src/main/resources/V40/People/skiptoken/5.full.json
new file mode 100644
index 0000000..a26a5c4
--- /dev/null
+++ b/fit/src/main/resources/V40/People/skiptoken/5.full.json
@@ -0,0 +1,56 @@
+{
+  "@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#People",
+  "value":
+          [
+            {
+              "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Person",
+              "@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(6)",
+              "@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(6)",
+              "PersonID": 6,
+              "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/olingo-odata4/blob/149c51c7/fit/src/main/resources/V40/People/skiptoken/5.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/People/skiptoken/5.xml b/fit/src/main/resources/V40/People/skiptoken/5.xml
new file mode 100644
index 0000000..9147608
--- /dev/null
+++ b/fit/src/main/resources/V40/People/skiptoken/5.xml
@@ -0,0 +1,62 @@
+<?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(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(6)" />
+    <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(6)/Parent" />
+    <title />
+    <updated>2014-03-20T14:31:00Z</updated>
+    <author>
+      <name />
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PersonID m:type="Int32">6</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/olingo-odata4/blob/149c51c7/fit/src/main/resources/V40/crossjoin.full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/crossjoin.full.json b/fit/src/main/resources/V40/crossjoin.full.json
new file mode 100644
index 0000000..6ba10f0
--- /dev/null
+++ b/fit/src/main/resources/V40/crossjoin.full.json
@@ -0,0 +1,18 @@
+{
+  "@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Customers",
+  "value":
+          [
+            {
+              "Products@odata.navigationLink": "Products(0)",
+              "Sales@odata.navigationLink": "Sales(42)"
+            },
+            {
+              "Products@odata.navigationLink": "Products(0)",
+              "Sales@odata.navigationLink": "Sales(57)"
+            },
+            {
+              "Products@odata.navigationLink": "Products(99)",
+              "Sales@odata.navigationLink": "Sales(21)"
+            }
+          ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v4/URIBuilder.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v4/URIBuilder.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v4/URIBuilder.java
index 9985ce8..a393ea4 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v4/URIBuilder.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v4/URIBuilder.java
@@ -119,4 +119,16 @@ public interface URIBuilder extends CommonURIBuilder<URIBuilder> {
    * @see org.apache.olingo.client.api.uri.QueryOption#EXPAND
    */
   URIBuilder expandWithOptions(String expandItem, Map<String, Object> options);
+  
+  /**
+   * Properties of related entities can be specified by including the $select query option within the $expand.
+   * <br />
+   * <tt>http://host/service/Products?$expand=Category($select=Name)</tt>
+   * @param expandItem related entity name.
+   * @param selectItems properties to be selected.
+   * @return current URIBuilder instance.
+   * @see org.apache.olingo.client.api.uri.QueryOption#EXPAND
+   * @see org.apache.olingo.client.api.uri.QueryOption#SELECT
+   */
+  URIBuilder expandWithSelect(String expandItem, String... selectItems);
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java
index f3c8cdf..1029173 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java
@@ -23,7 +23,6 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URLDecoder;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -104,7 +103,12 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
 
   @Override
   public UB addQueryOption(final String option, final String value) {
-    queryOptions.put(option, value);
+    final StringBuilder builder = new StringBuilder();
+    if (queryOptions.containsKey(option)) {
+      builder.append(queryOptions.get(option)).append(',');
+    }
+    builder.append(value);
+    queryOptions.put(option, builder.toString());
     return getThis();
   }
 
@@ -199,14 +203,7 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
 
   @Override
   public UB expand(final String... expandItems) {
-    final List<String> values = new ArrayList<String>();
-    if (queryOptions.containsKey(QueryOption.EXPAND.toString())) {
-      values.add(queryOptions.get(QueryOption.EXPAND.toString()));
-    }
-
-    values.addAll(Arrays.asList(expandItems));
-
-    return addQueryOption(QueryOption.EXPAND, StringUtils.join(values, ","));
+    return addQueryOption(QueryOption.EXPAND, StringUtils.join(expandItems, ","));
   }
 
   @Override
@@ -231,14 +228,7 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
 
   @Override
   public UB select(final String... selectItems) {
-    final List<String> values = new ArrayList<String>();
-    if (queryOptions.containsKey(QueryOption.SELECT.toString())) {
-      values.add(queryOptions.get(QueryOption.SELECT.toString()));
-    }
-
-    values.addAll(Arrays.asList(selectItems));
-
-    return addQueryOption(QueryOption.SELECT, StringUtils.join(values, ","));
+    return addQueryOption(QueryOption.SELECT, StringUtils.join(selectItems, ","));
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java
index a59c760..cd32192 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java
@@ -134,4 +134,9 @@ public class URIBuilderImpl extends AbstractURIBuilder<URIBuilder> implements UR
   public URIBuilder expandWithOptions(final String expandItem, final Map<String, Object> options) {
     return expand(expandItem + buildMultiKeySegment(options, false));
   }
+
+  @Override
+  public URIBuilder expandWithSelect(final String expandItem, final String... selectItems) {
+    return expand(expandItem + "($select=" + StringUtils.join(selectItems, ",") + ")");
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/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 68702e5..03884df 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
@@ -47,7 +47,7 @@ public class QueryOptionsTestITCase extends AbstractTestITCase {
   /**
    * Test <tt>$expand</tt>.
    *
-   * @see EntityRetrieveTest#readODataEntityWithInline(com.msopentech.odatajclient.engine.types.ODataPubFormat)
+   * @see EntityRetrieveTest#readODataEntityWithInline(org.apache.olingo.commons.api.format.ODataPubFormat)
    */
   public void expand() {
     // empty
@@ -115,7 +115,7 @@ public class QueryOptionsTestITCase extends AbstractTestITCase {
   /**
    * Test <tt>$skip</tt>.
    *
-   * @see FeedTest#readFeedWithNextLink(com.msopentech.odatajclient.engine.types.ODataPubFormat)
+   * @see FeedTest#readFeedWithNextLink(org.apache.olingo.commons.api.format.ODataPubFormat)
    */
   public void skip() {
     // empty
@@ -124,7 +124,7 @@ public class QueryOptionsTestITCase extends AbstractTestITCase {
   /**
    * Test <tt>$top</tt>.
    *
-   * @see FeedTest#readFeed(com.msopentech.odatajclient.engine.types.ODataPubFormat)
+   * @see FeedTest#readFeed(org.apache.olingo.commons.api.format.ODataPubFormat)
    */
   public void top() {
     // empty

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/FilterFactoryTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/FilterFactoryTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/FilterFactoryTestITCase.java
new file mode 100644
index 0000000..595c6c6
--- /dev/null
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/FilterFactoryTestITCase.java
@@ -0,0 +1,64 @@
+/*
+ * 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 org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.olingo.client.api.uri.URIFilter;
+import org.apache.olingo.client.api.uri.v4.FilterArgFactory;
+import org.apache.olingo.client.api.uri.v4.FilterFactory;
+import org.apache.olingo.client.api.uri.v4.URIBuilder;
+import static org.apache.olingo.client.core.it.v4.AbstractTestITCase.client;
+import org.apache.olingo.commons.api.domain.v4.ODataEntity;
+import org.apache.olingo.commons.api.domain.v4.ODataEntitySet;
+import org.apache.olingo.commons.api.format.ODataPubFormat;
+import org.junit.Test;
+
+public class FilterFactoryTestITCase extends AbstractTestITCase {
+
+  private FilterFactory getFilterFactory() {
+    return getClient().getFilterFactory();
+  }
+
+  private FilterArgFactory getFilterArgFactory() {
+    return getFilterFactory().getArgFactory();
+  }
+
+  @Test
+  public void crossjoin() {
+
+    final URIFilter filter = getFilterFactory().eq(
+            getFilterArgFactory().property("Orders/OrderID"), getFilterArgFactory().property("Customers/Order"));
+
+    final URIBuilder uriBuilder =
+            client.getURIBuilder(testStaticServiceRootURL).appendCrossjoinSegment("Customers", "Orders").filter(filter);
+
+    final ODataEntitySetRequest<ODataEntitySet> req =
+            client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.build());
+    req.setFormat(ODataPubFormat.JSON_FULL_METADATA);
+
+    final ODataEntitySet feed = req.execute().getBody();
+    assertEquals(3, feed.getEntities().size());
+
+    for (ODataEntity entity : feed.getEntities()) {
+      assertEquals(2, entity.getNavigationLinks().size());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/KeyAsSegmentTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/KeyAsSegmentTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/KeyAsSegmentTestITCase.java
index 2beb518..4a0c369 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/KeyAsSegmentTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/KeyAsSegmentTestITCase.java
@@ -27,7 +27,6 @@ import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRe
 import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
 import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
 import org.apache.olingo.client.api.uri.v4.URIBuilder;
-import static org.apache.olingo.client.core.it.v4.AbstractTestITCase.testStaticServiceRootURL;
 import org.apache.olingo.commons.api.domain.v4.ODataEntity;
 import org.apache.olingo.commons.api.domain.v4.ODataProperty;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/QueryOptionsTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/QueryOptionsTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/QueryOptionsTestITCase.java
new file mode 100644
index 0000000..51580f8
--- /dev/null
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/QueryOptionsTestITCase.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.client.core.it.v4;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.uri.v4.URIBuilder;
+import static org.apache.olingo.client.core.it.v4.AbstractTestITCase.client;
+import org.apache.olingo.commons.api.domain.ODataInlineEntitySet;
+import org.apache.olingo.commons.api.domain.v4.ODataEntity;
+import org.apache.olingo.commons.api.domain.v4.ODataEntitySet;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.format.ODataPubFormat;
+import org.junit.Test;
+
+/**
+ * This is the unit test class to check for query options.
+ */
+public class QueryOptionsTestITCase extends AbstractTestITCase {
+
+  /**
+   * Test <tt>$expand</tt>.
+   */
+  public void expand() {
+    final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+            appendEntitySetSegment("Customers").appendKeySegment(1).expand("Orders");
+
+    final ODataEntityRequest<ODataEntity> req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
+    req.setFormat(ODataPubFormat.JSON_FULL_METADATA);
+
+    final ODataEntity customer = req.execute().getBody();
+    assertTrue(customer.getNavigationLink("Orders") instanceof ODataInlineEntitySet);
+  }
+
+  /**
+   * Test <tt>$filter</tt> and <tt>$orderby</tt>.
+   *
+   * @see org.apache.olingo.client.core.v3.FilterFactoryTest for more tests.
+   */
+  @Test
+  public void filterOrderby() throws EdmPrimitiveTypeException {
+    final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+            appendEntitySetSegment("People").filter("(PersonID lt 3)");
+
+    // 1. check that filtered entity set looks as expected
+    ODataEntitySetRequest<ODataEntitySet> req =
+            client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.build());
+    req.setFormat(ODataPubFormat.JSON);
+
+    ODataEntitySet feed = req.execute().getBody();
+    assertNotNull(feed);
+    assertEquals(2, feed.getEntities().size());
+
+    // 2. extract PersonID values - sorted ASC by default
+    final List<Integer> former = new ArrayList<Integer>(2);
+    for (ODataEntity entity : feed.getEntities()) {
+      final Integer personID = entity.getProperty("PersonID").getPrimitiveValue().toCastValue(Integer.class);
+      assertTrue(personID < 3);
+      former.add(personID);
+    }
+
+    // 3. add orderby clause to filter above
+    req = client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.orderBy("PersonID desc").build());
+    req.setFormat(ODataPubFormat.JSON);
+    feed = req.execute().getBody();
+    assertNotNull(feed);
+    assertEquals(2, feed.getEntities().size());
+
+    // 4. extract again VIN value - now they were required to be sorted DESC
+    final List<Integer> latter = new ArrayList<Integer>(2);
+    for (ODataEntity entity : feed.getEntities()) {
+      final Integer personID = entity.getProperty("PersonID").getPrimitiveValue().toCastValue(Integer.class);
+      assertTrue(personID < 3);
+      latter.add(personID);
+    }
+
+    // 5. reverse latter and expect to be equal to former
+    Collections.reverse(latter);
+    assertEquals(former, latter);
+  }
+
+  /**
+   * Test <tt>$format</tt>.
+   */
+  @Test
+  public void format() {
+    final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+            appendEntitySetSegment("Customers").appendKeySegment(1).format("json");
+
+    final ODataEntityRequest<ODataEntity> req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
+    req.setFormat(ODataPubFormat.ATOM);
+
+    final ODataRetrieveResponse<ODataEntity> res = req.execute();
+    assertNotNull(res);
+    assertTrue(res.getContentType().replaceAll(" ", "").
+            startsWith(ODataPubFormat.JSON.toString(client.getServiceVersion())));
+  }
+
+  /**
+   * Test <tt>$skip</tt>.
+   */
+  public void skip() {
+    final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("People");
+
+    // 1. check that filtered entity set looks as expected
+    ODataEntitySetRequest<ODataEntitySet> req =
+            client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.skip(2).build());
+    ODataEntitySet feed = req.execute().getBody();
+    assertEquals(3, feed.getEntities().size());
+  }
+
+  /**
+   * Test <tt>$top</tt>.
+   */
+  public void top() {
+    final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("People");
+
+    // 1. check that filtered entity set looks as expected
+    ODataEntitySetRequest<ODataEntitySet> req = client.getRetrieveRequestFactory().
+            getEntitySetRequest(uriBuilder.top(2).build());
+    ODataEntitySet feed = req.execute().getBody();
+    assertEquals(2, feed.getEntities().size());
+  }
+
+  /**
+   * Test <tt>$skiptoken</tt>.
+   */
+  @Test
+  public void skiptoken() throws EdmPrimitiveTypeException {
+    final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL);
+    uriBuilder.appendEntitySetSegment("People").skipToken("5");
+
+    final ODataEntitySetRequest<ODataEntitySet> req =
+            client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.build());
+    req.setFormat(ODataPubFormat.JSON);
+
+    final ODataEntitySet feed = req.execute().getBody();
+    assertNotNull(feed);
+    assertEquals(1, feed.getEntities().size());
+
+    for (ODataEntity entity : feed.getEntities()) {
+      assertTrue(entity.getProperty("PersonID").getPrimitiveValue().toCastValue(Integer.class) > 5);
+    }
+  }
+
+  /**
+   * Test <tt>$inlinecount</tt>.
+   */
+  @Test
+  public void inlinecount() {
+    final URIBuilder uriBuilder =
+            client.getURIBuilder(testStaticServiceRootURL).appendEntitySetSegment("Customers").count(true);
+
+    final ODataEntitySetRequest<ODataEntitySet> req =
+            client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.build());
+    req.setFormat(ODataPubFormat.JSON);
+    final ODataEntitySet feed = req.execute().getBody();
+    assertNotNull(feed);
+    assertEquals(feed.getEntities().size(), feed.getCount());
+  }
+
+  /**
+   * Test <tt>$select</tt>.
+   */
+  @Test
+  public void select() {
+    final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+            appendEntitySetSegment("Customers").appendKeySegment(1).select("PersonID,Orders").expand("Orders");
+
+    final ODataEntityRequest<ODataEntity> req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
+    req.setFormat(ODataPubFormat.JSON_FULL_METADATA);
+
+    final ODataEntity customer = req.execute().getBody();
+    assertEquals(1, customer.getProperties().size());
+    assertEquals(1, customer.getNavigationLinks().size());
+    assertTrue((customer.getNavigationLinks().get(0) instanceof ODataInlineEntitySet));
+  }
+
+  @Test
+  public void issue253() {
+    final URIBuilder uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+            appendEntitySetSegment("relatedEntitySelect").appendEntitySetSegment("Customers").appendKeySegment(1).
+            expandWithSelect("Orders", "OrderID", "OrderDetails");
+
+    final ODataEntityRequest<ODataEntity> req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
+    req.setFormat(ODataPubFormat.JSON_FULL_METADATA);
+
+    final ODataRetrieveResponse<ODataEntity> res = req.execute();
+    assertEquals(200, res.getStatusCode());
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java
index 619734b..c2add62 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java
@@ -85,15 +85,15 @@ public class JSONTest extends AbstractTest {
 
       if (field.getKey().charAt(0) == '#'
               || field.getKey().endsWith(
-                      getClient().getServiceVersion().getJSONMap().get(ODataServiceVersion.JSON_TYPE))
+              getClient().getServiceVersion().getJSONMap().get(ODataServiceVersion.JSON_TYPE))
               || field.getKey().endsWith(
-                      getClient().getServiceVersion().getJSONMap().get(ODataServiceVersion.JSON_MEDIAEDIT_LINK))
+              getClient().getServiceVersion().getJSONMap().get(ODataServiceVersion.JSON_MEDIAEDIT_LINK))
               || field.getKey().endsWith(
-                      getClient().getServiceVersion().getJSONMap().get(ODataServiceVersion.JSON_MEDIA_CONTENT_TYPE))
+              getClient().getServiceVersion().getJSONMap().get(ODataServiceVersion.JSON_MEDIA_CONTENT_TYPE))
               || field.getKey().endsWith(
-                      getClient().getServiceVersion().getJSONMap().get(ODataServiceVersion.JSON_ASSOCIATION_LINK))
+              getClient().getServiceVersion().getJSONMap().get(ODataServiceVersion.JSON_ASSOCIATION_LINK))
               || field.getKey().endsWith(
-                      getClient().getServiceVersion().getJSONMap().get(ODataServiceVersion.JSON_MEDIA_ETAG))) {
+              getClient().getServiceVersion().getJSONMap().get(ODataServiceVersion.JSON_MEDIA_ETAG))) {
 
         toRemove.add(field.getKey());
       } else if (field.getValue().isObject()) {
@@ -113,7 +113,7 @@ public class JSONTest extends AbstractTest {
   protected void assertSimilar(final String filename, final String actual) throws Exception {
     final JsonNode expected = OBJECT_MAPPER.readTree(IOUtils.toString(getClass().getResourceAsStream(filename)).
             replace(getClient().getServiceVersion().getJSONMap().get(ODataServiceVersion.JSON_NAVIGATION_LINK),
-                    Constants.JSON_BIND_LINK_SUFFIX));
+            Constants.JSON_BIND_LINK_SUFFIX));
     cleanup((ObjectNode) expected);
     final ObjectNode actualNode = (ObjectNode) OBJECT_MAPPER.readTree(new ByteArrayInputStream(actual.getBytes()));
     cleanup(actualNode);
@@ -175,4 +175,10 @@ public class JSONTest extends AbstractTest {
     property("Employees_3_HomeAddress", getODataFormat());
     property("Employees_3_HomeAddress", getODataFormat());
   }
+
+  @Test
+  public void crossjoin() throws Exception {
+    getClient().getDeserializer().toFeed(
+            getClass().getResourceAsStream("crossjoin.json"), ODataPubFormat.JSON_FULL_METADATA);
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/149c51c7/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/crossjoin.json
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/crossjoin.json b/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/crossjoin.json
new file mode 100644
index 0000000..248ae34
--- /dev/null
+++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/crossjoin.json
@@ -0,0 +1,18 @@
+{
+  "@odata.context": "http://host/service/$metadata#Collection(Edm.ComplexType)",
+  "value":
+          [
+            {
+              "Products@odata.navigationLink": "Products(0)",
+              "Sales@odata.navigationLink": "Sales(42)"
+            },
+            {
+              "Products@odata.navigationLink": "Products(0)",
+              "Sales@odata.navigationLink": "Sales(57)"
+            },
+            {
+              "Products@odata.navigationLink": "Products(99)",
+              "Sales@odata.navigationLink": "Sales(21)"
+            }
+          ]
+}
\ No newline at end of file