You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by il...@apache.org on 2014/03/07 15:27:27 UTC

[1/4] [OLINGO-190] V3 service document deserializer merged, V4 implemented

Repository: incubator-olingo-odata4
Updated Branches:
  refs/heads/master 744a37136 -> e62481554


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/AbstractODataBinder.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/AbstractODataBinder.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/AbstractODataBinder.java
new file mode 100644
index 0000000..8483df3
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/AbstractODataBinder.java
@@ -0,0 +1,581 @@
+/*
+ * 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.odata4.client.core.op.impl;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.odata4.client.api.ODataClient;
+import org.apache.olingo.odata4.client.api.ODataConstants;
+import org.apache.olingo.odata4.client.api.data.ServiceDocument;
+import org.apache.olingo.odata4.client.api.data.ServiceDocumentItem;
+import org.apache.olingo.odata4.client.api.domain.ODataServiceDocument;
+import org.apache.olingo.odata4.client.api.op.ODataBinder;
+import org.apache.olingo.odata4.client.api.utils.XMLUtils;
+import org.apache.olingo.odata4.client.core.uri.URIUtils;
+import org.apache.olingo.odata4.commons.api.edm.constants.ODataServiceVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public abstract class AbstractODataBinder implements ODataBinder {
+
+  private static final long serialVersionUID = 454285889193689536L;
+
+  /**
+   * Logger.
+   */
+  protected final Logger LOG = LoggerFactory.getLogger(AbstractODataBinder.class);
+
+  protected final ODataClient client;
+
+  protected AbstractODataBinder(final ODataClient client) {
+    this.client = client;
+  }
+
+  protected Element newEntryContent() {
+    Element properties = null;
+    try {
+      final DocumentBuilder builder = XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder();
+      final Document doc = builder.newDocument();
+      properties = doc.createElement(ODataConstants.ELEM_PROPERTIES);
+      properties.setAttribute(ODataConstants.XMLNS_METADATA,
+              client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA));
+      properties.setAttribute(ODataConstants.XMLNS_DATASERVICES,
+              client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES));
+      properties.setAttribute(ODataConstants.XMLNS_GML, ODataConstants.NS_GML);
+      properties.setAttribute(ODataConstants.XMLNS_GEORSS, ODataConstants.NS_GEORSS);
+    } catch (ParserConfigurationException e) {
+      LOG.error("Failure building entry content", e);
+    }
+
+    return properties;
+  }
+
+  @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 <T extends Feed> T getFeed(final ODataEntitySet feed, final Class<T> reference) {
+//    final T feedResource = ResourceFactory.newFeed(reference);
+//
+//    final List<Entry> entries = new ArrayList<Entry>();
+//    feedResource.setEntries(entries);
+//
+//    final URI next = feed.getNext();
+//    if (next != null) {
+//      feedResource.setNext(next);
+//    }
+//
+//    for (ODataEntity entity : feed.getEntities()) {
+//      entries.add(getEntry(entity, ResourceFactory.entryClassForFeed(reference)));
+//    }
+//
+//    feedResource.setEntries(entries);
+//
+//    return feedResource;
+//  }
+//
+//  @Override
+//  public <T extends Entry> T getEntry(final ODataEntity entity, final Class<T> reference) {
+//    return getEntry(entity, reference, true);
+//  }
+//
+//  @Override
+//  @SuppressWarnings("unchecked")
+//  public <T extends Entry> T getEntry(final ODataEntity entity, final Class<T> reference,
+//          final boolean setType) {
+//
+//    final T entry = ResourceFactory.newEntry(reference);
+//    entry.setType(entity.getName());
+//
+//        // -------------------------------------------------------------
+//    // Add edit and self link
+//    // -------------------------------------------------------------
+//    final URI editLink = entity.getEditLink();
+//    if (editLink != null) {
+//      final Link entryEditLink = ResourceFactory.newLinkForEntry(reference);
+//      entryEditLink.setTitle(entity.getName());
+//      entryEditLink.setHref(editLink.toASCIIString());
+//      entryEditLink.setRel(ODataConstants.EDIT_LINK_REL);
+//      entry.setEditLink(entryEditLink);
+//    }
+//
+//    if (entity.isReadOnly()) {
+//      final Link entrySelfLink = ResourceFactory.newLinkForEntry(reference);
+//      entrySelfLink.setTitle(entity.getName());
+//      entrySelfLink.setHref(entity.getLink().toASCIIString());
+//      entrySelfLink.setRel(ODataConstants.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.addNavigationLink(getLinkResource(link, ResourceFactory.linkClassForEntry(reference)));
+//    }
+//        // -------------------------------------------------------------
+//
+//        // -------------------------------------------------------------
+//    // Append edit-media links
+//    // -------------------------------------------------------------
+//    for (ODataLink link : entity.getEditMediaLinks()) {
+//      LOG.debug("Append edit-media link\n{}", link);
+//      entry.addMediaEditLink(getLinkResource(link, ResourceFactory.linkClassForEntry(reference)));
+//    }
+//        // -------------------------------------------------------------
+//
+//        // -------------------------------------------------------------
+//    // Append association links
+//    // -------------------------------------------------------------
+//    for (ODataLink link : entity.getAssociationLinks()) {
+//      LOG.debug("Append association link\n{}", link);
+//      entry.addAssociationLink(getLinkResource(link, ResourceFactory.linkClassForEntry(reference)));
+//    }
+//    // -------------------------------------------------------------
+//
+//    final Element content = newEntryContent();
+//    if (entity.isMediaEntity()) {
+//      entry.setMediaEntryProperties(content);
+//      entry.setMediaContentSource(entity.getMediaContentSource());
+//      entry.setMediaContentType(entity.getMediaContentType());
+//    } else {
+//      entry.setContent(content);
+//    }
+//
+//    for (ODataProperty prop : entity.getProperties()) {
+//      content.appendChild(toDOMElement(prop, content.getOwnerDocument(), setType));
+//    }
+//
+//    return entry;
+//  }
+//
+//  @Override
+//  public Element toDOMElement(final ODataProperty prop) {
+//    try {
+//      return toDOMElement(prop, XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder().newDocument(), true);
+//    } catch (ParserConfigurationException e) {
+//      LOG.error("Error retrieving property DOM", e);
+//      throw new IllegalArgumentException(e);
+//    }
+//  }
+//
+//  @Override
+//  public ODataLinkCollection getLinkCollection(final LinkCollection linkCollection) {
+//    final ODataLinkCollection collection = new ODataLinkCollection(linkCollection.getNext());
+//    collection.setLinks(linkCollection.getLinks());
+//    return collection;
+//  }
+//
+//  @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("FeedResource -> 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.addOperation(operation);
+//    }
+//
+//    final Element content;
+//    if (resource.isMediaEntry()) {
+//      entity.setMediaEntity(true);
+//      entity.setMediaContentSource(resource.getMediaContentSource());
+//      entity.setMediaContentType(resource.getMediaContentType());
+//      content = resource.getMediaEntryProperties();
+//    } else {
+//      content = resource.getContent();
+//    }
+//    if (content != null) {
+//      for (Node property : XMLUtils.getChildNodes(content, Node.ELEMENT_NODE)) {
+//        try {
+//          entity.addProperty(getProperty((Element) property));
+//        } catch (IllegalArgumentException e) {
+//          LOG.warn("Failure retrieving EdmType for {}", property.getTextContent(), e);
+//        }
+//      }
+//    }
+//
+//    return entity;
+//  }
+//
+//  @Override
+//  public <T extends Link> T getLinkResource(final ODataLink link, final Class<T> reference) {
+//    final T linkResource = ResourceFactory.newLink(reference);
+//    linkResource.setRel(link.getRel());
+//    linkResource.setTitle(link.getName());
+//    linkResource.setHref(link.getLink() == null ? null : link.getLink().toASCIIString());
+//    linkResource.setType(link.getType().toString());
+//
+//    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.entryClassForLink(reference)));
+//    } 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.feedClassForLink(reference)));
+//    }
+//
+//    return linkResource;
+//  }
+//
+//  @Override
+//  public ODataProperty getProperty(final Element property) {
+//    final ODataProperty res;
+//
+//    final Node nullNode = property.getAttributes().getNamedItem(ODataConstants.ATTR_NULL);
+//
+//    if (nullNode == null) {
+//      final EdmType edmType = StringUtils.isBlank(property.getAttribute(ODataConstants.ATTR_M_TYPE))
+//              ? null
+//              : newEdmType(property.getAttribute(ODataConstants.ATTR_M_TYPE));
+//
+//      final PropertyType propType = edmType == null
+//              ? guessPropertyType(property)
+//              : edmType.isCollection()
+//              ? PropertyType.COLLECTION
+//              : edmType.isSimpleType()
+//              ? PropertyType.PRIMITIVE
+//              : PropertyType.COMPLEX;
+//
+//      switch (propType) {
+//        case COLLECTION:
+//          res = fromCollectionPropertyElement(property, edmType);
+//          break;
+//
+//        case COMPLEX:
+//          res = fromComplexPropertyElement(property, edmType);
+//          break;
+//
+//        case PRIMITIVE:
+//          res = fromPrimitivePropertyElement(property, edmType);
+//          break;
+//
+//        case EMPTY:
+//        default:
+//          res = client.getObjectFactory().newPrimitiveProperty(XMLUtils.getSimpleName(property), null);
+//      }
+//    } else {
+//      res = client.getObjectFactory().newPrimitiveProperty(XMLUtils.getSimpleName(property), null);
+//    }
+//
+//    return res;
+//  }
+//
+//  protected PropertyType guessPropertyType(final Element property) {
+//    PropertyType res = null;
+//
+//    if (property.hasChildNodes()) {
+//      final NodeList children = property.getChildNodes();
+//
+//      for (int i = 0; res == null && i < children.getLength(); i++) {
+//        final Node child = children.item(i);
+//
+//        if (child.getNodeType() == Node.ELEMENT_NODE
+//                && !child.getNodeName().startsWith(ODataConstants.PREFIX_GML)) {
+//
+//          res = ODataConstants.ELEM_ELEMENT.equals(XMLUtils.getSimpleName(child))
+//                  ? PropertyType.COLLECTION
+//                  : PropertyType.COMPLEX;
+//        }
+//      }
+//    } else {
+//      res = PropertyType.EMPTY;
+//    }
+//
+//    if (res == null) {
+//      res = PropertyType.PRIMITIVE;
+//    }
+//
+//    return res;
+//  }
+//
+//  protected Element toDOMElement(final ODataProperty prop, final Document doc, final boolean setType) {
+//    final Element element;
+//
+//    if (prop.hasNullValue()) {
+//      // null property handling
+//      element = toNullPropertyElement(prop, doc);
+//    } else if (prop.hasPrimitiveValue()) {
+//      // primitive property handling
+//      element = toPrimitivePropertyElement(prop, doc, setType);
+//    } else if (prop.hasCollectionValue()) {
+//      // collection property handling
+//      element = toCollectionPropertyElement(prop, doc, setType);
+//    } else {
+//      // complex property handling
+//      element = toComplexPropertyElement(prop, doc, setType);
+//    }
+//
+//    element.setAttribute(ODataConstants.XMLNS_METADATA,
+//            client.getWorkingVersion().getNamespaceMap().get(ODataVersion.NS_METADATA));
+//    element.setAttribute(ODataConstants.XMLNS_DATASERVICES,
+//            client.getWorkingVersion().getNamespaceMap().get(ODataVersion.NS_DATASERVICES));
+//    element.setAttribute(ODataConstants.XMLNS_GML, ODataConstants.NS_GML);
+//    element.setAttribute(ODataConstants.XMLNS_GEORSS, ODataConstants.NS_GEORSS);
+//
+//    return element;
+//  }
+//
+//  protected Element toNullPropertyElement(final ODataProperty prop, final Document doc) {
+//    final Element element = doc.createElement(ODataConstants.PREFIX_DATASERVICES + prop.getName());
+//    element.setAttribute(ODataConstants.ATTR_NULL, Boolean.toString(true));
+//    return element;
+//  }
+//
+//  protected Element toPrimitivePropertyElement(
+//          final ODataProperty prop, final Document doc, final boolean setType) {
+//
+//    return toPrimitivePropertyElement(prop.getName(), prop.getPrimitiveValue(), doc, setType);
+//  }
+//
+//  protected Element toPrimitivePropertyElement(
+//          final String name, final ODataPrimitiveValue value, final Document doc, final boolean setType) {
+//
+//    final Element element = doc.createElement(ODataConstants.PREFIX_DATASERVICES + name);
+//    if (setType) {
+//      element.setAttribute(ODataConstants.ATTR_M_TYPE, value.getTypeName());
+//    }
+//
+//    if (value instanceof ODataGeospatialValue) {
+//      element.appendChild(doc.importNode(((ODataGeospatialValue) value).toTree(), true));
+//    } else {
+//      element.setTextContent(value.toString());
+//    }
+//
+//    return element;
+//  }
+//
+//  protected Element toCollectionPropertyElement(
+//          final ODataProperty prop, final Document doc, final boolean setType) {
+//
+//    if (!prop.hasCollectionValue()) {
+//      throw new IllegalArgumentException("Invalid property value type "
+//              + prop.getValue().getClass().getSimpleName());
+//    }
+//
+//    final ODataCollectionValue value = prop.getCollectionValue();
+//
+//    final Element element = doc.createElement(ODataConstants.PREFIX_DATASERVICES + prop.getName());
+//    if (value.getTypeName() != null && setType) {
+//      element.setAttribute(ODataConstants.ATTR_M_TYPE, value.getTypeName());
+//    }
+//
+//    for (ODataValue el : value) {
+//      if (el.isPrimitive()) {
+//        element.appendChild(
+//                toPrimitivePropertyElement(ODataConstants.ELEM_ELEMENT, el.asPrimitive(), doc, setType));
+//      } else {
+//        element.appendChild(
+//                toComplexPropertyElement(ODataConstants.ELEM_ELEMENT, el.asComplex(), doc, setType));
+//      }
+//    }
+//
+//    return element;
+//  }
+//
+//  protected Element toComplexPropertyElement(
+//          final ODataProperty prop, final Document doc, final boolean setType) {
+//
+//    return toComplexPropertyElement(prop.getName(), prop.getComplexValue(), doc, setType);
+//  }
+//
+//  protected Element toComplexPropertyElement(
+//          final String name, final ODataComplexValue value, final Document doc, final boolean setType) {
+//
+//    final Element element = doc.createElement(ODataConstants.PREFIX_DATASERVICES + name);
+//    if (value.getTypeName() != null && setType) {
+//      element.setAttribute(ODataConstants.ATTR_M_TYPE, value.getTypeName());
+//    }
+//
+//    for (ODataProperty field : value) {
+//      element.appendChild(toDOMElement(field, doc, true));
+//    }
+//    return element;
+//  }
+//
+//  protected ODataPrimitiveValue fromPrimitiveValueElement(final Element prop, final EdmType edmType) {
+//    final ODataPrimitiveValue value;
+//    if (edmType != null && edmType.getSimpleType().isGeospatial()) {
+//      final Element geoProp = ODataConstants.PREFIX_GML.equals(prop.getPrefix())
+//              ? prop : (Element) XMLUtils.getChildNodes(prop, Node.ELEMENT_NODE).get(0);
+//      value = client.getGeospatialValueBuilder().
+//              setType(edmType.getSimpleType()).setTree(geoProp).build();
+//    } else {
+//      value = client.getPrimitiveValueBuilder().
+//              setType(edmType == null ? null : edmType.getSimpleType()).setText(prop.getTextContent()).build();
+//    }
+//    return value;
+//  }
+//
+//  protected ODataProperty fromPrimitivePropertyElement(final Element prop, final EdmType edmType) {
+//    return client.getObjectFactory().newPrimitiveProperty(
+//            XMLUtils.getSimpleName(prop), fromPrimitiveValueElement(prop, edmType));
+//  }
+//
+//  protected ODataComplexValue fromComplexValueElement(final Element prop, final EdmType edmType) {
+//    final ODataComplexValue value = new ODataComplexValue(edmType == null ? null : edmType.getTypeExpression());
+//
+//    for (Node child : XMLUtils.getChildNodes(prop, Node.ELEMENT_NODE)) {
+//      value.add(getProperty((Element) child));
+//    }
+//
+//    return value;
+//  }
+//
+//  protected ODataProperty fromComplexPropertyElement(final Element prop, final EdmType edmType) {
+//    return client.getObjectFactory().newComplexProperty(XMLUtils.getSimpleName(prop),
+//            fromComplexValueElement(prop, edmType));
+//  }
+//
+//  protected ODataProperty fromCollectionPropertyElement(final Element prop, final EdmType edmType) {
+//    final ODataCollectionValue value
+//            = new ODataCollectionValue(edmType == null ? null : edmType.getTypeExpression());
+//
+//    final EdmType type = edmType == null ? null : newEdmType(edmType.getBaseType());
+//    final NodeList elements = prop.getChildNodes();
+//
+//    for (int i = 0; i < elements.getLength(); i++) {
+//      if (elements.item(i).getNodeType() != Node.TEXT_NODE) {
+//        final Element child = (Element) elements.item(i);
+//
+//        switch (guessPropertyType(child)) {
+//          case COMPLEX:
+//            value.add(fromComplexValueElement(child, type));
+//            break;
+//          case PRIMITIVE:
+//            value.add(fromPrimitiveValueElement(child, type));
+//            break;
+//          default:
+//          // do not add null or empty values
+//        }
+//      }
+//    }
+//
+//    return client.getObjectFactory().newCollectionProperty(XMLUtils.getSimpleName(prop), value);
+//  }
+//  protected abstract EdmType newEdmType(String expression);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataBinderImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataBinderImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataBinderImpl.java
new file mode 100644
index 0000000..b935254
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataBinderImpl.java
@@ -0,0 +1,37 @@
+/*
+ * 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.odata4.client.core.op.impl.v3;
+
+import org.apache.olingo.odata4.client.core.ODataV3Client;
+import org.apache.olingo.odata4.client.core.op.impl.AbstractODataBinder;
+
+public class ODataBinderImpl extends AbstractODataBinder {
+
+    private static final long serialVersionUID = 8970843539708952308L;
+
+    public ODataBinderImpl(final ODataV3Client client) {
+        super(client);
+    }
+
+//    @Override
+//    protected EdmType newEdmType(final String expression) {
+//        return new EdmV3Type(expression);
+//    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataDeserializerImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataDeserializerImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataDeserializerImpl.java
index 9096099..63cd9b2 100644
--- a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataDeserializerImpl.java
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataDeserializerImpl.java
@@ -18,8 +18,13 @@
  */
 package org.apache.olingo.odata4.client.core.op.impl.v3;
 
+import java.io.IOException;
 import java.io.InputStream;
 import org.apache.olingo.odata4.client.api.ODataClient;
+import org.apache.olingo.odata4.client.api.data.ServiceDocument;
+import org.apache.olingo.odata4.client.api.format.ODataFormat;
+import org.apache.olingo.odata4.client.core.data.v3.JSONServiceDocumentImpl;
+import org.apache.olingo.odata4.client.core.data.v4.XMLServiceDocumentImpl;
 import org.apache.olingo.odata4.client.core.op.impl.AbstractODataDeserializer;
 import org.apache.olingo.odata4.client.core.edm.xml.v3.EdmxImpl;
 import org.apache.olingo.odata4.client.core.edm.xml.v3.XMLMetadataImpl;
@@ -41,17 +46,17 @@ public class ODataDeserializerImpl extends AbstractODataDeserializer {
     }
   }
 
-//    @Override
-//    public AbstractServiceDocument toServiceDocument(final InputStream input, final ODataFormat format) {
-//        try {
-//            return format == ODataFormat.XML
-//                    ? getXmlMapper().readValue(input, XMLServiceDocument.class)
-//                    : getObjectMapper().readValue(input, JSONServiceDocument.class);
-//        } catch (IOException e) {
-//            throw new IllegalArgumentException("Could not parse Service Document", e);
-//        }
-//    }
-//
+  @Override
+  public ServiceDocument toServiceDocument(final InputStream input, final ODataFormat format) {
+    try {
+      return format == ODataFormat.XML
+              ? getXmlMapper().readValue(input, XMLServiceDocumentImpl.class)
+              : getObjectMapper().readValue(input, JSONServiceDocumentImpl.class);
+    } catch (IOException e) {
+      throw new IllegalArgumentException("Could not parse Service Document", e);
+    }
+  }
+
 //    @Override
 //    protected JSONEntry toJSONEntry(final InputStream input) {
 //        try {

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataReaderImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataReaderImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataReaderImpl.java
index 5b1c6cc..841987f 100644
--- a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataReaderImpl.java
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v3/ODataReaderImpl.java
@@ -19,6 +19,8 @@
 package org.apache.olingo.odata4.client.core.op.impl.v3;
 
 import java.io.InputStream;
+import org.apache.olingo.odata4.client.api.domain.ODataServiceDocument;
+import org.apache.olingo.odata4.client.api.format.ODataFormat;
 import org.apache.olingo.odata4.client.core.ODataV3Client;
 import org.apache.olingo.odata4.client.core.edm.EdmClientImpl;
 import org.apache.olingo.odata4.client.core.op.impl.AbstractODataReader;
@@ -37,9 +39,9 @@ public class ODataReaderImpl extends AbstractODataReader {
     return new EdmClientImpl(client.getDeserializer().toMetadata(input));
   }
 
-//    @Override
-//    public ODataServiceDocument readServiceDocument(final InputStream input, final ODataFormat format) {
-//        return ((ODataV3Client) client).getBinder().getODataServiceDocument(
-//                ((ODataV3Client) client).getDeserializer().toServiceDocument(input, format));
-//    }
+  @Override
+  public ODataServiceDocument readServiceDocument(final InputStream input, final ODataFormat format) {
+    return ((ODataV3Client) client).getBinder().getODataServiceDocument(
+            ((ODataV3Client) client).getDeserializer().toServiceDocument(input, format));
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataBinderImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataBinderImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataBinderImpl.java
new file mode 100644
index 0000000..d018436
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataBinderImpl.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.odata4.client.core.op.impl.v4;
+
+import org.apache.olingo.odata4.client.api.data.ServiceDocument;
+import org.apache.olingo.odata4.client.api.data.ServiceDocumentItem;
+import org.apache.olingo.odata4.client.api.domain.ODataServiceDocument;
+import org.apache.olingo.odata4.client.core.ODataV4Client;
+import org.apache.olingo.odata4.client.core.op.impl.AbstractODataBinder;
+import org.apache.olingo.odata4.client.core.uri.URIUtils;
+
+public class ODataBinderImpl extends AbstractODataBinder {
+
+  private static final long serialVersionUID = -6371110655960799393L;
+
+  public ODataBinderImpl(final ODataV4Client client) {
+    super(client);
+  }
+
+//    @Override
+//    protected EdmType newEdmType(final String expression) {
+//        return new EdmV4Type(expression);
+//    }
+  @Override
+  public ODataServiceDocument getODataServiceDocument(final ServiceDocument resource) {
+    final ODataServiceDocument serviceDocument = super.getODataServiceDocument(resource);
+
+    serviceDocument.setMetadataContext(URIUtils.getURI(resource.getBaseURI(), resource.getMetadataContext()));
+    serviceDocument.setMetadataETag(resource.getMetadataETag());
+
+    for (ServiceDocumentItem functionImport : resource.getFunctionImports()) {
+      serviceDocument.getFunctionImports().put(functionImport.getTitle(),
+              URIUtils.getURI(resource.getBaseURI(), functionImport.getHref()));
+    }
+    for (ServiceDocumentItem singleton : resource.getSingletons()) {
+      serviceDocument.getSingletons().put(singleton.getTitle(),
+              URIUtils.getURI(resource.getBaseURI(), singleton.getHref()));
+    }
+    for (ServiceDocumentItem sdoc : resource.getRelatedServiceDocuments()) {
+      serviceDocument.getRelatedServiceDocuments().put(sdoc.getTitle(),
+              URIUtils.getURI(resource.getBaseURI(), sdoc.getHref()));
+    }
+
+    return serviceDocument;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataDeserializerImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataDeserializerImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataDeserializerImpl.java
index 83c1aea..039d163 100644
--- a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataDeserializerImpl.java
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataDeserializerImpl.java
@@ -18,8 +18,13 @@
  */
 package org.apache.olingo.odata4.client.core.op.impl.v4;
 
+import java.io.IOException;
 import java.io.InputStream;
 import org.apache.olingo.odata4.client.api.ODataClient;
+import org.apache.olingo.odata4.client.api.data.ServiceDocument;
+import org.apache.olingo.odata4.client.api.format.ODataFormat;
+import org.apache.olingo.odata4.client.core.data.v4.JSONServiceDocumentImpl;
+import org.apache.olingo.odata4.client.core.data.v4.XMLServiceDocumentImpl;
 import org.apache.olingo.odata4.client.core.op.impl.AbstractODataDeserializer;
 import org.apache.olingo.odata4.client.core.edm.xml.v4.EdmxImpl;
 import org.apache.olingo.odata4.client.core.edm.xml.v4.XMLMetadataImpl;
@@ -41,18 +46,17 @@ public class ODataDeserializerImpl extends AbstractODataDeserializer {
     }
   }
 
-//    @Override
-//    public AbstractServiceDocument toServiceDocument(final InputStream input, final ODataFormat format) {
-//        try {
-//            return format == ODataFormat.XML
-//                    ? getXmlMapper().readValue(input, XMLServiceDocument.class)
-//                    : null;
-////                    : getObjectMapper().readValue(input, JSONServiceDocument.class);
-//        } catch (IOException e) {
-//            throw new IllegalArgumentException("Could not parse Service Document", e);
-//        }
-//    }
-//
+  @Override
+  public ServiceDocument toServiceDocument(final InputStream input, final ODataFormat format) {
+    try {
+      return format == ODataFormat.XML
+              ? getXmlMapper().readValue(input, XMLServiceDocumentImpl.class)
+              : getObjectMapper().readValue(input, JSONServiceDocumentImpl.class);
+    } catch (IOException e) {
+      throw new IllegalArgumentException("Could not parse Service Document", e);
+    }
+  }
+
 //    @Override
 //    protected JSONEntry toJSONEntry(final InputStream input) {
 //        try {

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataReaderImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataReaderImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataReaderImpl.java
index 35209c2..96ea552 100644
--- a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataReaderImpl.java
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/v4/ODataReaderImpl.java
@@ -19,6 +19,8 @@
 package org.apache.olingo.odata4.client.core.op.impl.v4;
 
 import java.io.InputStream;
+import org.apache.olingo.odata4.client.api.domain.ODataServiceDocument;
+import org.apache.olingo.odata4.client.api.format.ODataFormat;
 import org.apache.olingo.odata4.client.core.ODataV4Client;
 import org.apache.olingo.odata4.client.core.edm.EdmClientImpl;
 import org.apache.olingo.odata4.client.core.op.impl.AbstractODataReader;
@@ -37,9 +39,9 @@ public class ODataReaderImpl extends AbstractODataReader {
     return new EdmClientImpl(client.getDeserializer().toMetadata(input));
   }
 
-//    @Override
-//    public ODataServiceDocument readServiceDocument(final InputStream input, final ODataFormat format) {
-//        return ((ODataV4Client) client).getBinder().getODataServiceDocument(
-//                ((ODataV4Client) client).getDeserializer().toServiceDocument(input, format));
-//    }
+  @Override
+  public ODataServiceDocument readServiceDocument(final InputStream input, final ODataFormat format) {
+    return ((ODataV4Client) client).getBinder().getODataServiceDocument(
+            ((ODataV4Client) client).getDeserializer().toServiceDocument(input, format));
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/URIUtils.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/URIUtils.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/URIUtils.java
new file mode 100644
index 0000000..cd3a913
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/URIUtils.java
@@ -0,0 +1,195 @@
+/*
+ * 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.odata4.client.core.uri;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.text.DecimalFormat;
+import java.util.UUID;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.entity.InputStreamEntity;
+import org.apache.olingo.odata4.client.api.ODataClient;
+import org.apache.olingo.odata4.client.api.ODataConstants;
+import org.apache.olingo.odata4.client.api.domain.EdmSimpleType;
+import org.apache.olingo.odata4.client.api.domain.ODataDuration;
+import org.apache.olingo.odata4.client.api.domain.ODataTimestamp;
+import org.apache.olingo.odata4.client.api.edm.xml.CommonFunctionImport;
+import org.apache.olingo.odata4.client.api.edm.xml.EntityContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * URI utilities.
+ */
+public final class URIUtils {
+
+  /**
+   * Logger.
+   */
+  private static final Logger LOG = LoggerFactory.getLogger(URIUtils.class);
+
+  private URIUtils() {
+    // Empty private constructor for static utility classes
+  }
+
+  /**
+   * Build URI starting from the given base and href.
+   * <br/>
+   * If href is absolute or base is null then base will be ignored.
+   *
+   * @param base URI prefix.
+   * @param href URI suffix.
+   * @return built URI.
+   */
+  public static URI getURI(final String base, final String href) {
+    if (href == null) {
+      throw new IllegalArgumentException("Null link provided");
+    }
+
+    URI uri = URI.create(href);
+
+    if (!uri.isAbsolute() && base != null) {
+      uri = URI.create(base + "/" + href);
+    }
+
+    return uri.normalize();
+  }
+
+  /**
+   * Build URI starting from the given base and href.
+   * <br/>
+   * If href is absolute or base is null then base will be ignored.
+   *
+   * @param base URI prefix.
+   * @param href URI suffix.
+   * @return built URI.
+   */
+  public static URI getURI(final URI base, final URI href) {
+    if (href == null) {
+      throw new IllegalArgumentException("Null link provided");
+    }
+    return getURI(base, href.toASCIIString());
+  }
+
+  /**
+   * Build URI starting from the given base and href.
+   * <br/>
+   * If href is absolute or base is null then base will be ignored.
+   *
+   * @param base URI prefix.
+   * @param href URI suffix.
+   * @return built URI.
+   */
+  public static URI getURI(final URI base, final String href) {
+    if (href == null) {
+      throw new IllegalArgumentException("Null link provided");
+    }
+
+    URI uri = URI.create(href);
+
+    if (!uri.isAbsolute() && base != null) {
+      uri = URI.create(base.toASCIIString() + "/" + href);
+    }
+
+    return uri.normalize();
+  }
+
+  /**
+   * Gets function import URI segment.
+   *
+   * @param entityContainer entity container.
+   * @param functionImport function import.
+   * @return URI segment.
+   */
+  public static String rootFunctionImportURISegment(
+          final EntityContainer entityContainer, final CommonFunctionImport functionImport) {
+
+    final StringBuilder result = new StringBuilder();
+    if (!entityContainer.isDefaultEntityContainer()) {
+      result.append(entityContainer.getName()).append('.');
+    }
+    result.append(functionImport.getName());
+
+    return result.toString();
+  }
+
+  /**
+   * Turns primitive values into their respective URI representation.
+   *
+   * @param obj primitive value
+   * @return URI representation
+   */
+  public static String escape(final Object obj) {
+    String value;
+
+    try {
+      value = (obj instanceof UUID)
+              ? "guid'" + obj.toString() + "'"
+              : (obj instanceof byte[])
+              ? "X'" + Hex.encodeHexString((byte[]) obj) + "'"
+              : ((obj instanceof ODataTimestamp) && ((ODataTimestamp) obj).getTimezone() == null)
+              ? "datetime'" + URLEncoder.encode(((ODataTimestamp) obj).toString(), ODataConstants.UTF8) + "'"
+              : ((obj instanceof ODataTimestamp) && ((ODataTimestamp) obj).getTimezone() != null)
+              ? "datetimeoffset'" + URLEncoder.encode(((ODataTimestamp) obj).toString(), ODataConstants.UTF8)
+              + "'"
+              : (obj instanceof ODataDuration)
+              ? "time'" + ((ODataDuration) obj).toString() + "'"
+              : (obj instanceof BigDecimal)
+              ? new DecimalFormat(EdmSimpleType.Decimal.pattern()).format((BigDecimal) obj) + "M"
+              : (obj instanceof Double)
+              ? new DecimalFormat(EdmSimpleType.Double.pattern()).format((Double) obj) + "D"
+              : (obj instanceof Float)
+              ? new DecimalFormat(EdmSimpleType.Single.pattern()).format((Float) obj) + "f"
+              : (obj instanceof Long)
+              ? ((Long) obj).toString() + "L"
+              : (obj instanceof String)
+              ? "'" + URLEncoder.encode((String) obj, ODataConstants.UTF8) + "'"
+              : obj.toString();
+    } catch (Exception e) {
+      LOG.warn("While generating key segment for '{}', using toString()", obj, e);
+      value = obj.toString();
+    }
+
+    return value;
+  }
+
+  public static InputStreamEntity buildInputStreamEntity(final ODataClient client, final InputStream input) {
+    InputStreamEntity entity;
+    if (client.getConfiguration().isUseChuncked()) {
+      entity = new InputStreamEntity(input, -1);
+    } else {
+      byte[] bytes = new byte[0];
+      try {
+        bytes = IOUtils.toByteArray(input);
+      } catch (IOException e) {
+        LOG.error("While reading input for not chunked encoding", e);
+      }
+
+      entity = new InputStreamEntity(new ByteArrayInputStream(bytes), bytes.length);
+    }
+    entity.setChunked(client.getConfiguration().isUseChuncked());
+
+    return entity;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/MetadataTest.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/MetadataTest.java b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/MetadataTest.java
index 0d4eb2f..70f7aa2 100644
--- a/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/MetadataTest.java
+++ b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/MetadataTest.java
@@ -18,14 +18,14 @@
  */
 package org.apache.olingo.odata4.client.core.v3;
 
-import java.util.Arrays;
-import java.util.HashSet;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import org.apache.olingo.odata4.client.api.edm.xml.EntityContainer;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/ServiceDocumentTest.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/ServiceDocumentTest.java b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/ServiceDocumentTest.java
new file mode 100644
index 0000000..3f7a027
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/ServiceDocumentTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.odata4.client.core.v3;
+
+import org.apache.olingo.odata4.client.api.domain.ODataServiceDocument;
+import org.apache.olingo.odata4.client.api.format.ODataFormat;
+import org.apache.olingo.odata4.client.core.AbstractTest;
+import org.apache.olingo.odata4.client.core.ODataV3Client;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class ServiceDocumentTest extends AbstractTest {
+
+  @Override
+  protected ODataV3Client getClient() {
+    return v3Client;
+  }
+
+  private String getFileExtension(final ODataFormat format) {
+    return format == ODataFormat.XML ? "xml" : "json";
+  }
+
+  private void parse(final ODataFormat format) {
+    final ODataServiceDocument serviceDocument = getClient().getReader().readServiceDocument(
+            getClass().getResourceAsStream("serviceDocument." + getFileExtension(format)), format);
+    assertNotNull(serviceDocument);
+    assertTrue(serviceDocument.getEntitySetTitles().contains("Persons"));
+  }
+
+  @Test
+  public void json() {
+    parse(ODataFormat.JSON);
+  }
+
+  @Test
+  public void xml() {
+    parse(ODataFormat.XML);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v4/ServiceDocumentTest.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v4/ServiceDocumentTest.java b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v4/ServiceDocumentTest.java
new file mode 100644
index 0000000..0fc96ca
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v4/ServiceDocumentTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.odata4.client.core.v4;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.net.URI;
+import org.apache.olingo.odata4.client.api.domain.ODataServiceDocument;
+import org.apache.olingo.odata4.client.api.format.ODataFormat;
+import org.apache.olingo.odata4.client.core.AbstractTest;
+import org.apache.olingo.odata4.client.core.ODataV4Client;
+import org.junit.Test;
+
+public class ServiceDocumentTest extends AbstractTest {
+
+  @Override
+  protected ODataV4Client getClient() {
+    return v4Client;
+  }
+
+  private String getFileExtension(final ODataFormat format) {
+    return format == ODataFormat.XML ? "xml" : "json";
+  }
+
+  private ODataServiceDocument parse(final ODataFormat format) {
+    final ODataServiceDocument serviceDocument = getClient().getReader().readServiceDocument(
+            getClass().getResourceAsStream("serviceDocument." + getFileExtension(format)), format);
+    assertNotNull(serviceDocument);
+    assertEquals(URI.create("http://host/service/$metadata"), serviceDocument.getMetadataContext());
+    assertTrue(serviceDocument.getEntitySetTitles().contains("Order Details"));
+    assertEquals(URI.create("http://host/service/TopProducts"),
+            serviceDocument.getFunctionImportURI("Best-Selling Products"));
+    assertEquals(URI.create("http://host/HR/"),
+            serviceDocument.getRelatedServiceDocumentsURIs().iterator().next());
+
+    return serviceDocument;
+  }
+
+  @Test
+  public void json() {
+    parse(ODataFormat.JSON);
+  }
+
+  @Test
+  public void xml() {
+    final ODataServiceDocument serviceDocument = parse(ODataFormat.XML);
+    assertEquals("W/\"MjAxMy0wNS0xM1QxNDo1NFo=\"", serviceDocument.getMetadataETag());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v3/serviceDocument.json
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v3/serviceDocument.json b/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v3/serviceDocument.json
new file mode 100644
index 0000000..791f961
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v3/serviceDocument.json
@@ -0,0 +1,33 @@
+{
+  "odata.metadata": "http://services.odata.org/V3/OData/OData.svc/$metadata",
+  "value": [
+    {
+      "name": "Products",
+      "url": "Products"
+    },
+    {
+      "name": "ProductDetails",
+      "url": "ProductDetails"
+    },
+    {
+      "name": "Categories",
+      "url": "Categories"
+    },
+    {
+      "name": "Suppliers",
+      "url": "Suppliers"
+    },
+    {
+      "name": "Persons",
+      "url": "Persons"
+    },
+    {
+      "name": "PersonDetails",
+      "url": "PersonDetails"
+    },
+    {
+      "name": "Advertisements",
+      "url": "Advertisements"
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v3/serviceDocument.xml
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v3/serviceDocument.xml b/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v3/serviceDocument.xml
new file mode 100644
index 0000000..0981814
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v3/serviceDocument.xml
@@ -0,0 +1,49 @@
+<?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.
+
+-->
+<service xml:base="http://services.odata.org/V3/OData/OData.svc/" 
+         xmlns="http://www.w3.org/2007/app" 
+         xmlns:atom="http://www.w3.org/2005/Atom">
+  <workspace>
+    <atom:title>Default</atom:title>
+    <collection href="Products">
+      <atom:title>Products</atom:title>
+    </collection>
+    <collection href="ProductDetails">
+      <atom:title>ProductDetails</atom:title>
+    </collection>
+    <collection href="Categories">
+      <atom:title>Categories</atom:title>
+    </collection>
+    <collection href="Suppliers">
+      <atom:title>Suppliers</atom:title>
+    </collection>
+    <collection href="Persons">
+      <atom:title>Persons</atom:title>
+    </collection>
+    <collection href="PersonDetails">
+      <atom:title>PersonDetails</atom:title>
+    </collection>
+    <collection href="Advertisements">
+      <atom:title>Advertisements</atom:title>
+    </collection>
+  </workspace>
+</service>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v4/serviceDocument.json
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v4/serviceDocument.json b/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v4/serviceDocument.json
new file mode 100644
index 0000000..2e7f066
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v4/serviceDocument.json
@@ -0,0 +1,32 @@
+{
+  "@odata.context": "http://host/service/$metadata",
+  "value": [
+    {
+      "name": "Orders",
+      "kind": "EntitySet",
+      "url": "Orders"
+    },
+    {
+      "name": "OrderItems",
+      "title": "Order Details",
+      "url": "OrderItems"
+    },
+    {
+      "name": "TopProducts",
+      "title": "Best-Selling Products",
+      "kind": "FunctionImport",
+      "url": "TopProducts"
+    },
+    {
+      "name": "Contoso",
+      "title": "Contoso Ltd.",
+      "kind": "Singleton",
+      "url": "Contoso"
+    },
+    {
+      "name": "Human Resources",
+      "kind": "ServiceDocument",
+      "url": "http://host/HR/"
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v4/serviceDocument.xml
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v4/serviceDocument.xml b/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v4/serviceDocument.xml
new file mode 100644
index 0000000..faddf9c
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/test/resources/org/apache/olingo/odata4/client/core/v4/serviceDocument.xml
@@ -0,0 +1,46 @@
+<?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.
+
+-->
+<app:service xmlns:app="http://www.w3.org/2007/app"
+             xmlns:atom="http://www.w3.org/2005/Atom"
+             xmlns:metadata="http://docs.oasis-open.org/odata/ns/metadata"
+             xml:base="http://host/service/"
+             metadata:context="$metadata"
+             metadata:metadata-etag="W/&quot;MjAxMy0wNS0xM1QxNDo1NFo=&quot;">
+  <app:workspace>
+    <atom:title type="text">Data</atom:title>
+    <app:collection href="Orders">
+      <atom:title type="text">Orders</atom:title>
+    </app:collection>
+    <app:collection href="OrderItems">
+      <atom:title type="text">Order Details</atom:title>
+    </app:collection>
+    <metadata:function-import href="TopProducts">
+      <atom:title>Best-Selling Products</atom:title>
+    </metadata:function-import>
+    <metadata:singleton href="Contoso">
+      <atom:title>Contoso Ltd.</atom:title>
+    </metadata:singleton>
+    <metadata:service-document href="http://host/HR/">
+      <atom:title>Human Resources</atom:title>
+    </metadata:service-document>
+  </app:workspace>
+</app:service>


[2/4] [OLINGO-190] V3 service document deserializer merged, V4 implemented

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/ComposedGeospatial.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/ComposedGeospatial.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/ComposedGeospatial.java
new file mode 100644
index 0000000..bdff17c
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/ComposedGeospatial.java
@@ -0,0 +1,75 @@
+/*
+ * 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.odata4.client.api.domain.geospatial;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Abstract base class for all Geometries that are composed out of other geospatial elements.
+ */
+public abstract class ComposedGeospatial<T extends Geospatial> extends Geospatial implements Iterable<T> {
+
+  private static final long serialVersionUID = 8796254901098541307L;
+
+  protected final List<T> geospatials;
+
+  /**
+   * Constructor.
+   *
+   * @param dimension dimension.
+   * @param type type.
+   * @param geospatials geospatials info.
+   */
+  protected ComposedGeospatial(final Dimension dimension, final Type type, final List<T> geospatials) {
+    super(dimension, type);
+    this.geospatials = new ArrayList<T>();
+    if (geospatials != null) {
+      this.geospatials.addAll(geospatials);
+    }
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public Iterator<T> iterator() {
+    return this.geospatials.iterator();
+  }
+
+  /**
+   * Checks if is empty.
+   *
+   * @return 'TRUE' if is empty; 'FALSE' otherwise.
+   */
+  public boolean isEmpty() {
+    return geospatials.isEmpty();
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public void setSrid(final Integer srid) {
+    for (Geospatial geospatial : this.geospatials) {
+      geospatial.setSrid(srid);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/Geospatial.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/Geospatial.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/Geospatial.java
new file mode 100644
index 0000000..47f830b
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/Geospatial.java
@@ -0,0 +1,156 @@
+/*
+ * 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.odata4.client.api.domain.geospatial;
+
+import java.io.Serializable;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.olingo.odata4.client.api.domain.EdmSimpleType;
+
+/**
+ * Base class for all geospatial info.
+ */
+public abstract class Geospatial implements Serializable {
+
+    public enum Dimension {
+
+        GEOMETRY,
+        GEOGRAPHY;
+
+    }
+
+    public enum Type {
+
+        /**
+         * The OGIS geometry type number for points.
+         */
+        POINT,
+        /**
+         * The OGIS geometry type number for lines.
+         */
+        LINESTRING,
+        /**
+         * The OGIS geometry type number for polygons.
+         */
+        POLYGON,
+        /**
+         * The OGIS geometry type number for aggregate points.
+         */
+        MULTIPOINT,
+        /**
+         * The OGIS geometry type number for aggregate lines.
+         */
+        MULTILINESTRING,
+        /**
+         * The OGIS geometry type number for aggregate polygons.
+         */
+        MULTIPOLYGON,
+        /**
+         * The OGIS geometry type number for feature collections.
+         */
+        GEOSPATIALCOLLECTION;
+
+    }
+
+    protected final Dimension dimension;
+
+    protected final Type type;
+
+    /**
+     * Null value means it is expected to vary per instance.
+     */
+    protected Integer srid;
+
+    /**
+     * Constructor.
+     *
+     * @param dimension dimension.
+     * @param type type.
+     */
+    protected Geospatial(final Dimension dimension, final Type type) {
+        this.dimension = dimension;
+        this.type = type;
+    }
+
+    /**
+     * Gets dimension.
+     *
+     * @return dimension.
+     * @see Dimension
+     */
+    public Dimension getDimension() {
+        return dimension;
+    }
+
+    /**
+     * Gets type.
+     *
+     * @return type.
+     * @see Type
+     */
+    public Type getType() {
+        return type;
+    }
+
+    /**
+     * Gets s-rid.
+     *
+     * @return s-rid.
+     */
+    public Integer getSrid() {
+        return srid;
+    }
+
+    /**
+     * Sets s-rid.
+     *
+     * @param srid s-rid.
+     */
+    public void setSrid(final Integer srid) {
+        this.srid = srid;
+    }
+
+    public abstract EdmSimpleType getEdmSimpleType();
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public boolean equals(final Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public String toString() {
+        return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/GeospatialCollection.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/GeospatialCollection.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/GeospatialCollection.java
new file mode 100644
index 0000000..732d5a2
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/GeospatialCollection.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.odata4.client.api.domain.geospatial;
+
+import java.util.List;
+import org.apache.olingo.odata4.client.api.domain.EdmSimpleType;
+
+/**
+ * Wrapper for a collection of geospatials info.
+ */
+public class GeospatialCollection extends ComposedGeospatial<Geospatial> {
+
+    private static final long serialVersionUID = -9181547636133878977L;
+
+    /**
+     * Constructor.
+     *
+     * @param dimension dimension.
+     * @param geospatials geospatials info.
+     */
+    public GeospatialCollection(final Dimension dimension, final List<Geospatial> geospatials) {
+        super(dimension, Type.GEOSPATIALCOLLECTION, geospatials);
+    }
+
+    @Override
+    public EdmSimpleType getEdmSimpleType() {
+        return dimension == Dimension.GEOGRAPHY
+                ? EdmSimpleType.GeographyCollection
+                : EdmSimpleType.GeometryCollection;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/LineString.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/LineString.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/LineString.java
new file mode 100644
index 0000000..8b8c6ac
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/LineString.java
@@ -0,0 +1,38 @@
+/*
+ * 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.odata4.client.api.domain.geospatial;
+
+import java.util.List;
+import org.apache.olingo.odata4.client.api.domain.EdmSimpleType;
+
+public class LineString extends ComposedGeospatial<Point> {
+
+    private static final long serialVersionUID = 3207958185407535907L;
+
+    public LineString(final Dimension dimension, final List<Point> points) {
+        super(dimension, Type.LINESTRING, points);
+    }
+
+    @Override
+    public EdmSimpleType getEdmSimpleType() {
+        return dimension == Dimension.GEOGRAPHY
+                ? EdmSimpleType.GeographyLineString
+                : EdmSimpleType.GeometryLineString;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/MultiLineString.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/MultiLineString.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/MultiLineString.java
new file mode 100644
index 0000000..b849ecb
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/MultiLineString.java
@@ -0,0 +1,38 @@
+/*
+ * 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.odata4.client.api.domain.geospatial;
+
+import java.util.List;
+import org.apache.olingo.odata4.client.api.domain.EdmSimpleType;
+
+public class MultiLineString extends ComposedGeospatial<LineString> {
+
+  private static final long serialVersionUID = -5042414471218124125L;
+
+  public MultiLineString(final Dimension dimension, final List<LineString> lineStrings) {
+    super(dimension, Type.MULTILINESTRING, lineStrings);
+  }
+
+  @Override
+  public EdmSimpleType getEdmSimpleType() {
+    return dimension == Dimension.GEOGRAPHY
+            ? EdmSimpleType.GeographyMultiLineString
+            : EdmSimpleType.GeometryMultiLineString;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/MultiPoint.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/MultiPoint.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/MultiPoint.java
new file mode 100644
index 0000000..6b68aea
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/MultiPoint.java
@@ -0,0 +1,38 @@
+/*
+ * 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.odata4.client.api.domain.geospatial;
+
+import java.util.List;
+import org.apache.olingo.odata4.client.api.domain.EdmSimpleType;
+
+public class MultiPoint extends ComposedGeospatial<Point> {
+
+  private static final long serialVersionUID = 4951011255142116129L;
+
+  public MultiPoint(final Dimension dimension, final List<Point> points) {
+    super(dimension, Type.MULTIPOINT, points);
+  }
+
+  @Override
+  public EdmSimpleType getEdmSimpleType() {
+    return dimension == Dimension.GEOGRAPHY
+            ? EdmSimpleType.GeographyMultiPoint
+            : EdmSimpleType.GeometryMultiPoint;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/MultiPolygon.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/MultiPolygon.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/MultiPolygon.java
new file mode 100644
index 0000000..a20286b
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/MultiPolygon.java
@@ -0,0 +1,38 @@
+/*
+ * 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.odata4.client.api.domain.geospatial;
+
+import java.util.List;
+import org.apache.olingo.odata4.client.api.domain.EdmSimpleType;
+
+public class MultiPolygon extends ComposedGeospatial<Polygon> {
+
+  private static final long serialVersionUID = -160184788048512883L;
+
+  public MultiPolygon(final Dimension dimension, final List<Polygon> polygons) {
+    super(dimension, Type.MULTIPOLYGON, polygons);
+  }
+
+  @Override
+  public EdmSimpleType getEdmSimpleType() {
+    return dimension == Dimension.GEOGRAPHY
+            ? EdmSimpleType.GeographyMultiPolygon
+            : EdmSimpleType.GeometryMultiPolygon;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/Point.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/Point.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/Point.java
new file mode 100644
index 0000000..13948fb
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/Point.java
@@ -0,0 +1,77 @@
+/*
+ * 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.odata4.client.api.domain.geospatial;
+
+import org.apache.olingo.odata4.client.api.domain.EdmSimpleType;
+
+public class Point extends Geospatial {
+
+  private static final long serialVersionUID = 4917380107331557828L;
+
+  /**
+   * The X coordinate of the point. In most long/lat systems, this is the longitude.
+   */
+  private double x;
+
+  /**
+   * The Y coordinate of the point. In most long/lat systems, this is the latitude.
+   */
+  private double y;
+
+  /**
+   * The Z coordinate of the point. In most long/lat systems, this is a radius from the center of the earth, or the
+   * height / elevation over the ground.
+   */
+  private double z;
+
+  public Point(final Dimension dimension) {
+    super(dimension, Type.POINT);
+  }
+
+  public double getX() {
+    return x;
+  }
+
+  public void setX(double x) {
+    this.x = x;
+  }
+
+  public double getY() {
+    return y;
+  }
+
+  public void setY(double y) {
+    this.y = y;
+  }
+
+  public double getZ() {
+    return z;
+  }
+
+  public void setZ(double z) {
+    this.z = z;
+  }
+
+  @Override
+  public EdmSimpleType getEdmSimpleType() {
+    return dimension == Dimension.GEOGRAPHY
+            ? EdmSimpleType.GeographyPoint
+            : EdmSimpleType.GeometryPoint;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/Polygon.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/Polygon.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/Polygon.java
new file mode 100644
index 0000000..87159cb
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/geospatial/Polygon.java
@@ -0,0 +1,72 @@
+/*
+ * 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.odata4.client.api.domain.geospatial;
+
+import java.util.List;
+import org.apache.olingo.odata4.client.api.domain.EdmSimpleType;
+
+/**
+ * Polygon.
+ */
+public class Polygon extends Geospatial {
+
+  private static final long serialVersionUID = 7797602503445391678L;
+
+  final ComposedGeospatial<Point> interior;
+
+  final ComposedGeospatial<Point> exterior;
+
+  /**
+   * Constructor.
+   *
+   * @param dimension dimension.
+   * @param interior interior points.
+   * @param exterior exterior points.
+   */
+  public Polygon(final Dimension dimension, final List<Point> interior, final List<Point> exterior) {
+    super(dimension, Type.POLYGON);
+    this.interior = new MultiPoint(dimension, interior);
+    this.exterior = new MultiPoint(dimension, exterior);
+  }
+
+  /**
+   * Gest interior points.
+   *
+   * @return interior points.
+   */
+  public ComposedGeospatial<Point> getInterior() {
+    return interior;
+  }
+
+  /**
+   * Gets exterior points.
+   *
+   * @return exterior points.I
+   */
+  public ComposedGeospatial<Point> getExterior() {
+    return exterior;
+  }
+
+  @Override
+  public EdmSimpleType getEdmSimpleType() {
+    return dimension == Dimension.GEOGRAPHY
+            ? EdmSimpleType.GeographyPolygon
+            : EdmSimpleType.GeometryPolygon;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataBinder.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataBinder.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataBinder.java
new file mode 100644
index 0000000..6468650
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataBinder.java
@@ -0,0 +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.odata4.client.api.op;
+
+import java.io.Serializable;
+import org.apache.olingo.odata4.client.api.data.ServiceDocument;
+import org.apache.olingo.odata4.client.api.domain.ODataServiceDocument;
+
+public interface ODataBinder extends Serializable {
+
+  /**
+   * Gets <tt>ODataServiceDocument</tt> from the given service document resource.
+   *
+   * @param resource service document resource.
+   * @return <tt>ODataServiceDocument</tt> object.
+   */
+  ODataServiceDocument getODataServiceDocument(ServiceDocument resource);
+
+  /**
+   * Gets a <tt>FeedResource</tt> from the given OData entity set.
+   *
+   * @param <T> feed resource type.
+   * @param feed OData entity set.
+   * @param reference reference class.
+   * @return <tt>FeedResource</tt> object.
+   */
+//    <T extends Feed> T getFeed(ODataEntitySet feed, Class<T> reference);
+  /**
+   * Gets an <tt>EntryResource</tt> from the given OData entity.
+   *
+   * @param <T> entry resource type.
+   * @param entity OData entity.
+   * @param reference reference class.
+   * @return <tt>EntryResource</tt> object.
+   */
+//    <T extends Entry> T getEntry(ODataEntity entity, Class<T> reference);
+  /**
+   * Gets an <tt>EntryResource</tt> from the given OData entity.
+   *
+   * @param <T> entry resource type.
+   * @param entity OData entity.
+   * @param reference reference class.
+   * @param setType whether to explicitly output type information.
+   * @return <tt>EntryResource</tt> object.
+   */
+//    <T extends Entry> T getEntry(ODataEntity entity, Class<T> reference, boolean setType);
+  /**
+   * Gets the given OData property as DOM element.
+   *
+   * @param prop OData property.
+   * @return <tt>Element</tt> object.
+   */
+//    Element toDOMElement(ODataProperty prop);
+//    ODataLinkCollection getLinkCollection(LinkCollection linkCollection);
+  /**
+   * Gets <tt>ODataEntitySet</tt> from the given feed resource.
+   *
+   * @param resource feed resource.
+   * @return <tt>ODataEntitySet</tt> object.
+   */
+//    ODataEntitySet getODataEntitySet(Feed resource);
+  /**
+   * Gets <tt>ODataEntitySet</tt> from the given feed resource.
+   *
+   * @param resource feed resource.
+   * @param defaultBaseURI default base URI.
+   * @return <tt>ODataEntitySet</tt> object.
+   */
+//    ODataEntitySet getODataEntitySet(Feed resource, URI defaultBaseURI);
+  /**
+   * Gets <tt>ODataEntity</tt> from the given entry resource.
+   *
+   * @param resource entry resource.
+   * @return <tt>ODataEntity</tt> object.
+   */
+//    ODataEntity getODataEntity(Entry resource);
+  /**
+   * Gets <tt>ODataEntity</tt> from the given entry resource.
+   *
+   * @param resource entry resource.
+   * @param defaultBaseURI default base URI.
+   * @return <tt>ODataEntity</tt> object.
+   */
+//    ODataEntity getODataEntity(Entry resource, URI defaultBaseURI);
+  /**
+   * Gets a <tt>LinkResource</tt> from the given OData link.
+   *
+   * @param <T> link resource type.
+   * @param link OData link.
+   * @param reference reference class.
+   * @return <tt>LinkResource</tt> object.
+   */
+//  @SuppressWarnings("unchecked")
+//    <T extends Link> T getLinkResource(ODataLink link, Class<T> reference);
+
+  /**
+   * Gets an <tt>ODataProperty</tt> from the given DOM element.
+   *
+   * @param property content.
+   * @return <tt>ODataProperty</tt> object.
+   */
+//    ODataProperty getProperty(Element property);
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataDeserializer.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataDeserializer.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataDeserializer.java
index 8d6fc62..047983d 100644
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataDeserializer.java
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataDeserializer.java
@@ -20,7 +20,9 @@ package org.apache.olingo.odata4.client.api.op;
 
 import java.io.InputStream;
 import java.io.Serializable;
+import org.apache.olingo.odata4.client.api.data.ServiceDocument;
 import org.apache.olingo.odata4.client.api.edm.xml.XMLMetadata;
+import org.apache.olingo.odata4.client.api.format.ODataFormat;
 import org.w3c.dom.Element;
 
 /**
@@ -37,7 +39,8 @@ public interface ODataDeserializer extends Serializable {
    * @param format OData service document format.
    * @return ServiceDocumentResource object.
    */
-//    ServiceDocument toServiceDocument(InputStream input, ODataFormat format);
+  ServiceDocument toServiceDocument(InputStream input, ODataFormat format);
+
   /**
    * Gets a feed object from the given InputStream.
    *

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataReader.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataReader.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataReader.java
index a933919..1686c91 100644
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataReader.java
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/op/ODataReader.java
@@ -20,6 +20,8 @@ package org.apache.olingo.odata4.client.api.op;
 
 import java.io.InputStream;
 import java.io.Serializable;
+import org.apache.olingo.odata4.client.api.domain.ODataServiceDocument;
+import org.apache.olingo.odata4.client.api.format.ODataFormat;
 import org.apache.olingo.odata4.commons.api.edm.Edm;
 
 /**
@@ -46,7 +48,8 @@ public interface ODataReader extends Serializable {
    * @param format de-serialize as XML or JSON
    * @return List of URIs.
    */
-  //ODataServiceDocument readServiceDocument(InputStream input, ODataFormat format);
+  ODataServiceDocument readServiceDocument(InputStream input, ODataFormat format);
+
   /**
    * De-Serializes a stream into an OData entity set.
    *

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/SegmentType.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/SegmentType.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/SegmentType.java
new file mode 100644
index 0000000..a029c0d
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/SegmentType.java
@@ -0,0 +1,55 @@
+/*
+ * 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.odata4.client.api.uri;
+
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * URI Segment types.
+ */
+public enum SegmentType {
+
+  ENTITYSET,
+  ENTITYTYPE,
+  KEY,
+  KEY_AS_SEGMENT,
+  NAVIGATION,
+  STRUCTURAL,
+  VALUE("$value"),
+  FUNCTIONIMPORT,
+  METADATA("$metadata"),
+  BATCH("$batch"),
+  LINKS("$links"),
+  COUNT("$count"),
+  SERVICEROOT;
+
+  private String value;
+
+  private SegmentType() {
+    this.value = StringUtils.EMPTY;
+  }
+
+  private SegmentType(final String value) {
+    this.value = value;
+  }
+
+  public String getValue() {
+    return value;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/utils/XMLUtils.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/utils/XMLUtils.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/utils/XMLUtils.java
index b717d87..e1d580a 100644
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/utils/XMLUtils.java
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/utils/XMLUtils.java
@@ -23,8 +23,8 @@ import java.util.List;
 import javax.xml.parsers.DocumentBuilderFactory;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.odata4.client.api.Constants;
-import org.apache.olingo.odata4.client.api.data.EdmSimpleType;
-import org.apache.olingo.odata4.client.api.data.geospatial.Geospatial;
+import org.apache.olingo.odata4.client.api.domain.EdmSimpleType;
+import org.apache.olingo.odata4.client.api.domain.geospatial.Geospatial;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/AbstractODataClient.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/AbstractODataClient.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/AbstractODataClient.java
index 337a40d..47adcaa 100644
--- a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/AbstractODataClient.java
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/AbstractODataClient.java
@@ -19,8 +19,8 @@
 package org.apache.olingo.odata4.client.core;
 
 import org.apache.olingo.odata4.client.api.ODataClient;
-import org.apache.olingo.odata4.client.api.data.ODataGeospatialValue;
-import org.apache.olingo.odata4.client.api.data.ODataPrimitiveValue;
+import org.apache.olingo.odata4.client.api.domain.ODataGeospatialValue;
+import org.apache.olingo.odata4.client.api.domain.ODataPrimitiveValue;
 
 abstract class AbstractODataClient implements ODataClient {
 

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV3Client.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV3Client.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV3Client.java
index 4555c8c..77b9617 100644
--- a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV3Client.java
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV3Client.java
@@ -18,6 +18,7 @@
  */
 package org.apache.olingo.odata4.client.core;
 
+import org.apache.olingo.odata4.client.core.op.impl.v3.ODataBinderImpl;
 import org.apache.olingo.odata4.client.core.op.impl.v3.ODataDeserializerImpl;
 import org.apache.olingo.odata4.client.core.op.impl.v3.ODataReaderImpl;
 import org.apache.olingo.odata4.client.core.op.impl.v3.ODataSerializerImpl;
@@ -30,18 +31,15 @@ public class ODataV3Client extends AbstractODataClient {
   private final V3Configuration configuration = new V3Configuration();
 
 //  private final V3FilterFactory filterFactory = new V3FilterFactory();
-//
   private final ODataDeserializerImpl deserializer = new ODataDeserializerImpl(this);
-//
 
   private final ODataSerializerImpl serializer = new ODataSerializerImpl(this);
 
   private final ODataReaderImpl reader = new ODataReaderImpl(this);
 
 //  private final ODataWriterImpl writer = new ODataWriterImpl(this);
-//
-//  private final ODataBinderImpl binder = new ODataBinderImpl(this);
-//
+  private final ODataBinderImpl binder = new ODataBinderImpl(this);
+
 //  private final ODataObjectFactoryImpl objectFactory = new ODataObjectFactoryImpl(this);
 //
 //  private final V3RetrieveRequestFactory retrieveReqFact = new V3RetrieveRequestFactory(this);
@@ -100,12 +98,11 @@ public class ODataV3Client extends AbstractODataClient {
 //  public ODataWriterImpl getWriter() {
 //    return writer;
 //  }
-//
-//  @Override
-//  public ODataBinderImpl getBinder() {
-//    return binder;
-//  }
-//
+  @Override
+  public ODataBinderImpl getBinder() {
+    return binder;
+  }
+
 //  @Override
 //  public ODataObjectFactoryImpl getObjectFactory() {
 //    return objectFactory;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV4Client.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV4Client.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV4Client.java
index 6fdc8b0..06195d8 100644
--- a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV4Client.java
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV4Client.java
@@ -18,6 +18,7 @@
  */
 package org.apache.olingo.odata4.client.core;
 
+import org.apache.olingo.odata4.client.core.op.impl.v4.ODataBinderImpl;
 import org.apache.olingo.odata4.client.core.op.impl.v4.ODataDeserializerImpl;
 import org.apache.olingo.odata4.client.core.op.impl.v4.ODataReaderImpl;
 import org.apache.olingo.odata4.client.core.op.impl.v4.ODataSerializerImpl;
@@ -30,18 +31,15 @@ public class ODataV4Client extends AbstractODataClient {
   private final V4Configuration configuration = new V4Configuration();
 
 //    private final V4FilterFactory filterFactory = new V4FilterFactory();
-//
   private final ODataDeserializerImpl deserializer = new ODataDeserializerImpl(this);
-//
 
   private final ODataSerializerImpl serializer = new ODataSerializerImpl(this);
 
   private final ODataReaderImpl reader = new ODataReaderImpl(this);
 
 //    private final ODataWriterImpl writer = new ODataWriterImpl(this);
-//
-//    private final ODataBinderImpl binder = new ODataBinderImpl(this);
-//
+  private final ODataBinderImpl binder = new ODataBinderImpl(this);
+
 //    private final ODataObjectFactoryImpl objectFactory = new ODataObjectFactoryImpl(this);
 //
 //    private final V4RetrieveRequestFactory retrieveReqFact = new V4RetrieveRequestFactory(this);
@@ -99,12 +97,11 @@ public class ODataV4Client extends AbstractODataClient {
 //    public ODataWriterImpl getWriter() {
 //        return writer;
 //    }
-//
-//    @Override
-//    public ODataBinderImpl getBinder() {
-//        return binder;
-//    }
-//
+  @Override
+  public ODataBinderImpl getBinder() {
+    return binder;
+  }
+
 //    @Override
 //    public ODataObjectFactoryImpl getObjectFactory() {
 //        return objectFactory;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/AbstractServiceDocument.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/AbstractServiceDocument.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/AbstractServiceDocument.java
new file mode 100644
index 0000000..c841b40
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/AbstractServiceDocument.java
@@ -0,0 +1,145 @@
+/*
+ * 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.odata4.client.core.data;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.olingo.odata4.client.api.data.ServiceDocument;
+import org.apache.olingo.odata4.client.api.data.ServiceDocumentItem;
+
+public abstract class AbstractServiceDocument implements ServiceDocument {
+
+  private String title;
+
+  private final List<ServiceDocumentItem> entitySets = new ArrayList<ServiceDocumentItem>();
+
+  @Override
+  public String getMetadataContext() {
+    return null;
+  }
+
+  @Override
+  public String getMetadataETag() {
+    return null;
+  }
+
+  @Override
+  public String getTitle() {
+    return title;
+  }
+
+  public void setTitle(final String title) {
+    this.title = title;
+  }
+
+  protected ServiceDocumentItem getByName(final List<ServiceDocumentItem> elements, final String name) {
+    ServiceDocumentItem result = null;
+    for (ServiceDocumentItem element : elements) {
+      if (name.equals(element.getName())) {
+        result = element;
+      }
+    }
+    return result;
+  }
+
+  protected ServiceDocumentItem getByTitle(final List<ServiceDocumentItem> elements, final String title) {
+    ServiceDocumentItem result = null;
+    for (ServiceDocumentItem element : elements) {
+      if (title.equals(element.getTitle())) {
+        result = element;
+      }
+    }
+    return result;
+  }
+
+  @Override
+  public List<ServiceDocumentItem> getEntitySets() {
+    return entitySets;
+  }
+
+  @Override
+  public ServiceDocumentItem getEntitySetByName(final String name) {
+    return getByName(getEntitySets(), name);
+  }
+
+  @Override
+  public ServiceDocumentItem getEntitySetByTitle(final String title) {
+    return getByTitle(getEntitySets(), title);
+  }
+
+  @Override
+  public List<ServiceDocumentItem> getFunctionImports() {
+    return Collections.<ServiceDocumentItem>emptyList();
+  }
+
+  @Override
+  public ServiceDocumentItem getFunctionImportByName(final String name) {
+    return getByName(getFunctionImports(), name);
+  }
+
+  @Override
+  public ServiceDocumentItem getFunctionImportByTitle(final String title) {
+    return getByTitle(getFunctionImports(), title);
+  }
+
+  @Override
+  public List<ServiceDocumentItem> getSingletons() {
+    return Collections.<ServiceDocumentItem>emptyList();
+  }
+
+  @Override
+  public ServiceDocumentItem getSingletonByName(final String name) {
+    return getByName(getSingletons(), name);
+  }
+
+  @Override
+  public ServiceDocumentItem getSingletonByTitle(final String title) {
+    return getByTitle(getSingletons(), title);
+  }
+
+  @Override
+  public List<ServiceDocumentItem> getRelatedServiceDocuments() {
+    return Collections.<ServiceDocumentItem>emptyList();
+  }
+
+  @Override
+  public ServiceDocumentItem getRelatedServiceDocumentByTitle(final String title) {
+    return getByTitle(getRelatedServiceDocuments(), title);
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return EqualsBuilder.reflectionEquals(this, obj);
+  }
+
+  @Override
+  public int hashCode() {
+    return HashCodeBuilder.reflectionHashCode(this);
+  }
+
+  @Override
+  public String toString() {
+    return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/JSONServiceDocumentDeserializer.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/JSONServiceDocumentDeserializer.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/JSONServiceDocumentDeserializer.java
new file mode 100644
index 0000000..33b4bdf
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/JSONServiceDocumentDeserializer.java
@@ -0,0 +1,82 @@
+/*
+ * 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.odata4.client.core.data;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.IOException;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.odata4.client.api.ODataConstants;
+import org.apache.olingo.odata4.commons.api.edm.constants.ODataServiceVersion;
+
+public class JSONServiceDocumentDeserializer extends ODataJacksonDeserializer<AbstractServiceDocument> {
+
+  @Override
+  protected AbstractServiceDocument doDeserialize(final JsonParser parser, final DeserializationContext ctxt)
+          throws IOException, JsonProcessingException {
+
+    final ObjectNode tree = (ObjectNode) parser.getCodec().readTree(parser);
+
+    final AbstractServiceDocument serviceDocument = ODataServiceVersion.V30 == client.getServiceVersion()
+            ? new org.apache.olingo.odata4.client.core.data.v3.JSONServiceDocumentImpl()
+            : new org.apache.olingo.odata4.client.core.data.v4.JSONServiceDocumentImpl();
+
+    if (tree.hasNonNull(ODataConstants.JSON_METADATA)
+            && serviceDocument instanceof org.apache.olingo.odata4.client.core.data.v3.JSONServiceDocumentImpl) {
+
+      ((org.apache.olingo.odata4.client.core.data.v3.JSONServiceDocumentImpl) serviceDocument).
+              setMetadata(tree.get(ODataConstants.JSON_METADATA).textValue());
+    }
+    if (tree.hasNonNull(ODataConstants.JSON_CONTEXT)
+            && serviceDocument instanceof org.apache.olingo.odata4.client.core.data.v4.JSONServiceDocumentImpl) {
+
+      ((org.apache.olingo.odata4.client.core.data.v4.JSONServiceDocumentImpl) serviceDocument).
+              setMetadataContext(tree.get(ODataConstants.JSON_CONTEXT).textValue());
+    }
+
+    for (final Iterator<JsonNode> itor = tree.get(ODataConstants.JSON_VALUE).elements(); itor.hasNext();) {
+      final JsonNode node = itor.next();
+
+      final ServiceDocumentItemImpl item = new ServiceDocumentItemImpl();
+      item.setName(node.get("name").asText());
+      if (node.has("title")) {
+        item.setTitle(node.get("title").asText());
+      }
+      item.setHref(node.get("url").asText());
+
+      final String kind = node.has("kind") ? node.get("kind").asText() : null;
+      if (StringUtils.isBlank(kind) || "EntitySet".equals(kind)) {
+        serviceDocument.getEntitySets().add(item);
+      } else if ("Singleton".equals(kind)) {
+        serviceDocument.getSingletons().add(item);
+      } else if ("FunctionImport".equals(kind)) {
+        serviceDocument.getFunctionImports().add(item);
+      } else if ("ServiceDocument".equals(kind)) {
+        serviceDocument.getRelatedServiceDocuments().add(item);
+      }
+    }
+
+    return serviceDocument;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/ODataJacksonDeserializer.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/ODataJacksonDeserializer.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/ODataJacksonDeserializer.java
new file mode 100644
index 0000000..c5864f2
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/ODataJacksonDeserializer.java
@@ -0,0 +1,43 @@
+/*
+ * 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.odata4.client.core.data;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import java.io.IOException;
+import org.apache.olingo.odata4.client.api.ODataClient;
+
+abstract class ODataJacksonDeserializer<T> extends JsonDeserializer<T> {
+
+  protected ODataClient client;
+
+  protected abstract T doDeserialize(JsonParser jp, DeserializationContext ctxt)
+          throws IOException, JsonProcessingException;
+
+  @Override
+  public T deserialize(final JsonParser jp, final DeserializationContext ctxt)
+          throws IOException, JsonProcessingException {
+
+    client = (ODataClient) ctxt.findInjectableValue(ODataClient.class.getName(), null, null);
+    return doDeserialize(jp, ctxt);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/ODataJacksonSerializer.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/ODataJacksonSerializer.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/ODataJacksonSerializer.java
new file mode 100644
index 0000000..4e44277
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/ODataJacksonSerializer.java
@@ -0,0 +1,43 @@
+/*
+ * 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.odata4.client.core.data;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import java.io.IOException;
+import org.apache.olingo.odata4.client.api.ODataClient;
+
+abstract class ODataJacksonSerializer<T> extends JsonSerializer<T> {
+
+  protected ODataClient client;
+
+  protected abstract void doSerialize(T value, JsonGenerator jgen, SerializerProvider provider)
+          throws IOException, JsonProcessingException;
+
+  @Override
+  public void serialize(final T value, final JsonGenerator jgen, final SerializerProvider provider)
+          throws IOException, JsonProcessingException {
+
+    client = (ODataClient) provider.getAttribute(ODataClient.class);
+    doSerialize(value, jgen, provider);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/ServiceDocumentItemImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/ServiceDocumentItemImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/ServiceDocumentItemImpl.java
new file mode 100644
index 0000000..3d4610a
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/ServiceDocumentItemImpl.java
@@ -0,0 +1,78 @@
+/*
+ * 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.odata4.client.core.data;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.olingo.odata4.client.api.data.ServiceDocumentItem;
+
+public class ServiceDocumentItemImpl implements ServiceDocumentItem {
+
+  private String name;
+
+  private String title;
+
+  @JsonProperty("url")
+  private String href;
+
+  @Override
+  public String getName() {
+    return name;
+  }
+
+  public void setName(final String name) {
+    this.name = name;
+  }
+
+  @Override
+  public String getTitle() {
+    return title;
+  }
+
+  public void setTitle(final String title) {
+    this.title = title;
+  }
+
+  @Override
+  public String getHref() {
+    return href;
+  }
+
+  public void setHref(final String href) {
+    this.href = href;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return EqualsBuilder.reflectionEquals(this, obj);
+  }
+
+  @Override
+  public int hashCode() {
+    return HashCodeBuilder.reflectionHashCode(this);
+  }
+
+  @Override
+  public String toString() {
+    return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/XMLServiceDocumentDeserializer.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/XMLServiceDocumentDeserializer.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/XMLServiceDocumentDeserializer.java
new file mode 100644
index 0000000..749a420
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/XMLServiceDocumentDeserializer.java
@@ -0,0 +1,118 @@
+/*
+ * 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.odata4.client.core.data;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser;
+import java.io.IOException;
+import java.net.URI;
+import org.apache.olingo.odata4.client.api.data.ServiceDocument;
+import org.apache.olingo.odata4.commons.api.edm.constants.ODataServiceVersion;
+
+public class XMLServiceDocumentDeserializer extends ODataJacksonDeserializer<ServiceDocument> {
+
+  private String getTitle(final JsonParser jp) throws IOException {
+    String title = jp.nextTextValue();
+    if (title == null) {
+      jp.nextToken();
+      jp.nextToken();
+      jp.nextToken();
+      title = jp.nextTextValue();
+    }
+    return title;
+  }
+
+  private ServiceDocumentItemImpl deserializeElement(final JsonParser jp, final String elementName)
+          throws IOException {
+
+    final ServiceDocumentItemImpl element = new ServiceDocumentItemImpl();
+    for (; jp.getCurrentToken() != JsonToken.END_OBJECT
+            || !elementName.equals(((FromXmlParser) jp).getStaxReader().getLocalName()); jp.nextToken()) {
+
+      final JsonToken token = jp.getCurrentToken();
+      if (token == JsonToken.FIELD_NAME) {
+        if ("href".equals(jp.getCurrentName())) {
+          element.setHref(jp.nextTextValue());
+        } else if ("name".equals(jp.getCurrentName())) {
+          element.setName(jp.nextTextValue());
+        } else if ("title".equals(jp.getCurrentName())) {
+          element.setTitle(getTitle(jp));
+        }
+      }
+    }
+
+    return element;
+  }
+
+  @Override
+  protected ServiceDocument doDeserialize(final JsonParser jp, final DeserializationContext ctxt)
+          throws IOException, JsonProcessingException {
+
+    final AbstractServiceDocument sdoc = ODataServiceVersion.V30 == client.getServiceVersion()
+            ? new org.apache.olingo.odata4.client.core.data.v3.XMLServiceDocumentImpl()
+            : new org.apache.olingo.odata4.client.core.data.v4.XMLServiceDocumentImpl();
+
+    for (; jp.getCurrentToken() != JsonToken.END_OBJECT
+            || !"service".equals(((FromXmlParser) jp).getStaxReader().getLocalName()); jp.nextToken()) {
+
+      final JsonToken token = jp.getCurrentToken();
+      if (token == JsonToken.FIELD_NAME) {
+        if ("base".equals(jp.getCurrentName())) {
+          if (sdoc instanceof org.apache.olingo.odata4.client.core.data.v3.XMLServiceDocumentImpl) {
+            ((org.apache.olingo.odata4.client.core.data.v3.XMLServiceDocumentImpl) sdoc).
+                    setBaseURI(URI.create(jp.nextTextValue()));
+          } else {
+            ((org.apache.olingo.odata4.client.core.data.v4.XMLServiceDocumentImpl) sdoc).
+                    setBaseURI(URI.create(jp.nextTextValue()));
+          }
+        } else if ("context".equals(jp.getCurrentName())) {
+          ((org.apache.olingo.odata4.client.core.data.v4.XMLServiceDocumentImpl) sdoc).
+                  setMetadataContext(jp.nextTextValue());
+        } else if ("metadata-etag".equals(jp.getCurrentName())) {
+          ((org.apache.olingo.odata4.client.core.data.v4.XMLServiceDocumentImpl) sdoc).
+                  setMetadataETag(jp.nextTextValue());
+        } else if ("workspace".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          jp.nextToken();
+          if ("title".equals(jp.getCurrentName())) {
+            sdoc.setTitle(getTitle(jp));
+          }
+        } else if ("collection".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          sdoc.getEntitySets().add(deserializeElement(jp, "collection"));
+        } else if ("function-import".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          sdoc.getFunctionImports().add(deserializeElement(jp, "function-import"));
+        } else if ("singleton".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          sdoc.getSingletons().add(deserializeElement(jp, "singleton"));
+        } else if ("service-document".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          sdoc.getRelatedServiceDocuments().add(deserializeElement(jp, "service-document"));
+        }
+      }
+    }
+
+    return sdoc;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v3/JSONServiceDocumentImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v3/JSONServiceDocumentImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v3/JSONServiceDocumentImpl.java
new file mode 100644
index 0000000..28db339
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v3/JSONServiceDocumentImpl.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.odata4.client.core.data.v3;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import java.net.URI;
+import org.apache.olingo.odata4.client.api.uri.SegmentType;
+import org.apache.olingo.odata4.client.core.data.AbstractServiceDocument;
+import org.apache.olingo.odata4.client.core.data.JSONServiceDocumentDeserializer;
+
+/**
+ * Service document, represented via JSON.
+ */
+@JsonDeserialize(using = JSONServiceDocumentDeserializer.class)
+public class JSONServiceDocumentImpl extends AbstractServiceDocument {
+
+  private static final long serialVersionUID = 4195734928526398830L;
+
+  private String metadata;
+
+  @Override
+  public URI getBaseURI() {
+    URI baseURI = null;
+    if (metadata != null) {
+      final String metadataURI = getMetadata();
+      baseURI = URI.create(metadataURI.substring(0, metadataURI.indexOf(SegmentType.METADATA.getValue())));
+    }
+
+    return baseURI;
+  }
+
+  /**
+   * Gets the metadata URI.
+   *
+   * @return the metadata URI
+   */
+  public String getMetadata() {
+    return metadata;
+  }
+
+  /**
+   * Sets the metadata URI.
+   *
+   * @param metadata metadata URI.
+   */
+  public void setMetadata(final String metadata) {
+    this.metadata = metadata;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v3/XMLServiceDocumentImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v3/XMLServiceDocumentImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v3/XMLServiceDocumentImpl.java
new file mode 100644
index 0000000..caed09c
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v3/XMLServiceDocumentImpl.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.odata4.client.core.data.v3;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import java.net.URI;
+import org.apache.olingo.odata4.client.api.data.ServiceDocument;
+import org.apache.olingo.odata4.client.core.data.AbstractServiceDocument;
+import org.apache.olingo.odata4.client.core.data.XMLServiceDocumentDeserializer;
+
+@JsonDeserialize(using = XMLServiceDocumentDeserializer.class)
+public class XMLServiceDocumentImpl extends AbstractServiceDocument implements ServiceDocument {
+
+  private URI baseURI;
+
+  @Override
+  public URI getBaseURI() {
+    return this.baseURI;
+  }
+
+  /**
+   * Sets base URI.
+   *
+   * @param baseURI base URI.
+   */
+  public void setBaseURI(final URI baseURI) {
+    this.baseURI = baseURI;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v4/AbstractServiceDocument.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v4/AbstractServiceDocument.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v4/AbstractServiceDocument.java
new file mode 100644
index 0000000..152c058
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v4/AbstractServiceDocument.java
@@ -0,0 +1,88 @@
+/*
+ * 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.odata4.client.core.data.v4;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.olingo.odata4.client.api.data.ServiceDocumentItem;
+
+public abstract class AbstractServiceDocument
+        extends org.apache.olingo.odata4.client.core.data.AbstractServiceDocument {
+
+  private URI baseURI;
+
+  private String metadataContext;
+
+  private String metadataETag;
+
+  private List<ServiceDocumentItem> functionImports = new ArrayList<ServiceDocumentItem>();
+
+  private List<ServiceDocumentItem> singletons = new ArrayList<ServiceDocumentItem>();
+
+  private List<ServiceDocumentItem> relatedServiceDocuments = new ArrayList<ServiceDocumentItem>();
+
+  @Override
+  public URI getBaseURI() {
+    return this.baseURI;
+  }
+
+  /**
+   * Sets base URI.
+   *
+   * @param baseURI base URI.
+   */
+  public void setBaseURI(final URI baseURI) {
+    this.baseURI = baseURI;
+  }
+
+  @Override
+  public String getMetadataContext() {
+    return metadataContext;
+  }
+
+  public void setMetadataContext(final String metadataContext) {
+    this.metadataContext = metadataContext;
+  }
+
+  @Override
+  public String getMetadataETag() {
+    return metadataETag;
+  }
+
+  public void setMetadataETag(final String metadataETag) {
+    this.metadataETag = metadataETag;
+  }
+
+  @Override
+  public List<ServiceDocumentItem> getFunctionImports() {
+    return functionImports;
+  }
+
+  @Override
+  public List<ServiceDocumentItem> getSingletons() {
+    return singletons;
+  }
+
+  @Override
+  public List<ServiceDocumentItem> getRelatedServiceDocuments() {
+    return relatedServiceDocuments;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v4/JSONServiceDocumentImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v4/JSONServiceDocumentImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v4/JSONServiceDocumentImpl.java
new file mode 100644
index 0000000..82dfb9c
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v4/JSONServiceDocumentImpl.java
@@ -0,0 +1,41 @@
+/*
+ * 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.odata4.client.core.data.v4;
+
+import org.apache.olingo.odata4.client.core.data.JSONServiceDocumentDeserializer;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import java.net.URI;
+import org.apache.olingo.odata4.client.api.data.ServiceDocument;
+import org.apache.olingo.odata4.client.api.uri.SegmentType;
+
+@JsonDeserialize(using = JSONServiceDocumentDeserializer.class)
+public class JSONServiceDocumentImpl extends AbstractServiceDocument implements ServiceDocument {
+
+  @Override
+  public URI getBaseURI() {
+    URI baseURI = null;
+    if (getMetadataContext() != null) {
+      final String metadataURI = getMetadataContext();
+      baseURI = URI.create(metadataURI.substring(0, metadataURI.indexOf(SegmentType.METADATA.getValue())));
+    }
+
+    return baseURI;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v4/XMLServiceDocumentImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v4/XMLServiceDocumentImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v4/XMLServiceDocumentImpl.java
new file mode 100644
index 0000000..7142df2
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/data/v4/XMLServiceDocumentImpl.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.odata4.client.core.data.v4;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import org.apache.olingo.odata4.client.api.data.ServiceDocument;
+import org.apache.olingo.odata4.client.core.data.XMLServiceDocumentDeserializer;
+
+@JsonDeserialize(using = XMLServiceDocumentDeserializer.class)
+public class XMLServiceDocumentImpl extends AbstractServiceDocument implements ServiceDocument {
+
+}


[3/4] [OLINGO-190] V3 service document deserializer merged, V4 implemented

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/Geospatial.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/Geospatial.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/Geospatial.java
deleted file mode 100644
index 858cf5e..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/Geospatial.java
+++ /dev/null
@@ -1,156 +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.odata4.client.api.data.geospatial;
-
-import java.io.Serializable;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-import org.apache.olingo.odata4.client.api.data.EdmSimpleType;
-
-/**
- * Base class for all geospatial info.
- */
-public abstract class Geospatial implements Serializable {
-
-    public enum Dimension {
-
-        GEOMETRY,
-        GEOGRAPHY;
-
-    }
-
-    public enum Type {
-
-        /**
-         * The OGIS geometry type number for points.
-         */
-        POINT,
-        /**
-         * The OGIS geometry type number for lines.
-         */
-        LINESTRING,
-        /**
-         * The OGIS geometry type number for polygons.
-         */
-        POLYGON,
-        /**
-         * The OGIS geometry type number for aggregate points.
-         */
-        MULTIPOINT,
-        /**
-         * The OGIS geometry type number for aggregate lines.
-         */
-        MULTILINESTRING,
-        /**
-         * The OGIS geometry type number for aggregate polygons.
-         */
-        MULTIPOLYGON,
-        /**
-         * The OGIS geometry type number for feature collections.
-         */
-        GEOSPATIALCOLLECTION;
-
-    }
-
-    protected final Dimension dimension;
-
-    protected final Type type;
-
-    /**
-     * Null value means it is expected to vary per instance.
-     */
-    protected Integer srid;
-
-    /**
-     * Constructor.
-     *
-     * @param dimension dimension.
-     * @param type type.
-     */
-    protected Geospatial(final Dimension dimension, final Type type) {
-        this.dimension = dimension;
-        this.type = type;
-    }
-
-    /**
-     * Gets dimension.
-     *
-     * @return dimension.
-     * @see Dimension
-     */
-    public Dimension getDimension() {
-        return dimension;
-    }
-
-    /**
-     * Gets type.
-     *
-     * @return type.
-     * @see Type
-     */
-    public Type getType() {
-        return type;
-    }
-
-    /**
-     * Gets s-rid.
-     *
-     * @return s-rid.
-     */
-    public Integer getSrid() {
-        return srid;
-    }
-
-    /**
-     * Sets s-rid.
-     *
-     * @param srid s-rid.
-     */
-    public void setSrid(final Integer srid) {
-        this.srid = srid;
-    }
-
-    public abstract EdmSimpleType getEdmSimpleType();
-
-    /**
-     * {@inheritDoc }
-     */
-    @Override
-    public boolean equals(final Object obj) {
-        return EqualsBuilder.reflectionEquals(this, obj);
-    }
-
-    /**
-     * {@inheritDoc }
-     */
-    @Override
-    public int hashCode() {
-        return HashCodeBuilder.reflectionHashCode(this);
-    }
-
-    /**
-     * {@inheritDoc }
-     */
-    @Override
-    public String toString() {
-        return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/GeospatialCollection.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/GeospatialCollection.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/GeospatialCollection.java
deleted file mode 100644
index 509c6e1..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/GeospatialCollection.java
+++ /dev/null
@@ -1,47 +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.odata4.client.api.data.geospatial;
-
-import java.util.List;
-import org.apache.olingo.odata4.client.api.data.EdmSimpleType;
-
-/**
- * Wrapper for a collection of geospatials info.
- */
-public class GeospatialCollection extends ComposedGeospatial<Geospatial> {
-
-    private static final long serialVersionUID = -9181547636133878977L;
-
-    /**
-     * Constructor.
-     *
-     * @param dimension dimension.
-     * @param geospatials geospatials info.
-     */
-    public GeospatialCollection(final Dimension dimension, final List<Geospatial> geospatials) {
-        super(dimension, Type.GEOSPATIALCOLLECTION, geospatials);
-    }
-
-    @Override
-    public EdmSimpleType getEdmSimpleType() {
-        return dimension == Dimension.GEOGRAPHY
-                ? EdmSimpleType.GeographyCollection
-                : EdmSimpleType.GeometryCollection;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/LineString.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/LineString.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/LineString.java
deleted file mode 100644
index de8b9f1..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/LineString.java
+++ /dev/null
@@ -1,38 +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.odata4.client.api.data.geospatial;
-
-import java.util.List;
-import org.apache.olingo.odata4.client.api.data.EdmSimpleType;
-
-public class LineString extends ComposedGeospatial<Point> {
-
-    private static final long serialVersionUID = 3207958185407535907L;
-
-    public LineString(final Dimension dimension, final List<Point> points) {
-        super(dimension, Type.LINESTRING, points);
-    }
-
-    @Override
-    public EdmSimpleType getEdmSimpleType() {
-        return dimension == Dimension.GEOGRAPHY
-                ? EdmSimpleType.GeographyLineString
-                : EdmSimpleType.GeometryLineString;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/MultiLineString.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/MultiLineString.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/MultiLineString.java
deleted file mode 100644
index 426f108..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/MultiLineString.java
+++ /dev/null
@@ -1,38 +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.odata4.client.api.data.geospatial;
-
-import java.util.List;
-import org.apache.olingo.odata4.client.api.data.EdmSimpleType;
-
-public class MultiLineString extends ComposedGeospatial<LineString> {
-
-  private static final long serialVersionUID = -5042414471218124125L;
-
-  public MultiLineString(final Dimension dimension, final List<LineString> lineStrings) {
-    super(dimension, Type.MULTILINESTRING, lineStrings);
-  }
-
-  @Override
-  public EdmSimpleType getEdmSimpleType() {
-    return dimension == Dimension.GEOGRAPHY
-            ? EdmSimpleType.GeographyMultiLineString
-            : EdmSimpleType.GeometryMultiLineString;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/MultiPoint.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/MultiPoint.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/MultiPoint.java
deleted file mode 100644
index 6488598..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/MultiPoint.java
+++ /dev/null
@@ -1,38 +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.odata4.client.api.data.geospatial;
-
-import java.util.List;
-import org.apache.olingo.odata4.client.api.data.EdmSimpleType;
-
-public class MultiPoint extends ComposedGeospatial<Point> {
-
-  private static final long serialVersionUID = 4951011255142116129L;
-
-  public MultiPoint(final Dimension dimension, final List<Point> points) {
-    super(dimension, Type.MULTIPOINT, points);
-  }
-
-  @Override
-  public EdmSimpleType getEdmSimpleType() {
-    return dimension == Dimension.GEOGRAPHY
-            ? EdmSimpleType.GeographyMultiPoint
-            : EdmSimpleType.GeometryMultiPoint;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/MultiPolygon.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/MultiPolygon.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/MultiPolygon.java
deleted file mode 100644
index 8b7137d..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/MultiPolygon.java
+++ /dev/null
@@ -1,38 +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.odata4.client.api.data.geospatial;
-
-import java.util.List;
-import org.apache.olingo.odata4.client.api.data.EdmSimpleType;
-
-public class MultiPolygon extends ComposedGeospatial<Polygon> {
-
-  private static final long serialVersionUID = -160184788048512883L;
-
-  public MultiPolygon(final Dimension dimension, final List<Polygon> polygons) {
-    super(dimension, Type.MULTIPOLYGON, polygons);
-  }
-
-  @Override
-  public EdmSimpleType getEdmSimpleType() {
-    return dimension == Dimension.GEOGRAPHY
-            ? EdmSimpleType.GeographyMultiPolygon
-            : EdmSimpleType.GeometryMultiPolygon;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/Point.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/Point.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/Point.java
deleted file mode 100644
index 8e96d57..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/Point.java
+++ /dev/null
@@ -1,77 +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.odata4.client.api.data.geospatial;
-
-import org.apache.olingo.odata4.client.api.data.EdmSimpleType;
-
-public class Point extends Geospatial {
-
-  private static final long serialVersionUID = 4917380107331557828L;
-
-  /**
-   * The X coordinate of the point. In most long/lat systems, this is the longitude.
-   */
-  private double x;
-
-  /**
-   * The Y coordinate of the point. In most long/lat systems, this is the latitude.
-   */
-  private double y;
-
-  /**
-   * The Z coordinate of the point. In most long/lat systems, this is a radius from the center of the earth, or the
-   * height / elevation over the ground.
-   */
-  private double z;
-
-  public Point(final Dimension dimension) {
-    super(dimension, Type.POINT);
-  }
-
-  public double getX() {
-    return x;
-  }
-
-  public void setX(double x) {
-    this.x = x;
-  }
-
-  public double getY() {
-    return y;
-  }
-
-  public void setY(double y) {
-    this.y = y;
-  }
-
-  public double getZ() {
-    return z;
-  }
-
-  public void setZ(double z) {
-    this.z = z;
-  }
-
-  @Override
-  public EdmSimpleType getEdmSimpleType() {
-    return dimension == Dimension.GEOGRAPHY
-            ? EdmSimpleType.GeographyPoint
-            : EdmSimpleType.GeometryPoint;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/Polygon.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/Polygon.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/Polygon.java
deleted file mode 100644
index a6166ed..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/Polygon.java
+++ /dev/null
@@ -1,72 +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.odata4.client.api.data.geospatial;
-
-import java.util.List;
-import org.apache.olingo.odata4.client.api.data.EdmSimpleType;
-
-/**
- * Polygon.
- */
-public class Polygon extends Geospatial {
-
-  private static final long serialVersionUID = 7797602503445391678L;
-
-  final ComposedGeospatial<Point> interior;
-
-  final ComposedGeospatial<Point> exterior;
-
-  /**
-   * Constructor.
-   *
-   * @param dimension dimension.
-   * @param interior interior points.
-   * @param exterior exterior points.
-   */
-  public Polygon(final Dimension dimension, final List<Point> interior, final List<Point> exterior) {
-    super(dimension, Type.POLYGON);
-    this.interior = new MultiPoint(dimension, interior);
-    this.exterior = new MultiPoint(dimension, exterior);
-  }
-
-  /**
-   * Gest interior points.
-   *
-   * @return interior points.
-   */
-  public ComposedGeospatial<Point> getInterior() {
-    return interior;
-  }
-
-  /**
-   * Gets exterior points.
-   *
-   * @return exterior points.I
-   */
-  public ComposedGeospatial<Point> getExterior() {
-    return exterior;
-  }
-
-  @Override
-  public EdmSimpleType getEdmSimpleType() {
-    return dimension == Dimension.GEOGRAPHY
-            ? EdmSimpleType.GeographyPolygon
-            : EdmSimpleType.GeometryPolygon;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/EdmSimpleType.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/EdmSimpleType.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/EdmSimpleType.java
new file mode 100644
index 0000000..f99df2b
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/EdmSimpleType.java
@@ -0,0 +1,288 @@
+/*
+ * 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.odata4.client.api.domain;
+
+import java.math.BigDecimal;
+import java.net.URI;
+import java.util.UUID;
+import org.apache.olingo.odata4.client.api.domain.geospatial.Geospatial;
+import org.apache.olingo.odata4.client.api.domain.geospatial.GeospatialCollection;
+import org.apache.olingo.odata4.client.api.domain.geospatial.LineString;
+import org.apache.olingo.odata4.client.api.domain.geospatial.MultiLineString;
+import org.apache.olingo.odata4.client.api.domain.geospatial.MultiPoint;
+import org.apache.olingo.odata4.client.api.domain.geospatial.MultiPolygon;
+import org.apache.olingo.odata4.client.api.domain.geospatial.Point;
+import org.apache.olingo.odata4.client.api.domain.geospatial.Polygon;
+import org.apache.olingo.odata4.commons.api.edm.constants.ODataServiceVersion;
+
+/**
+ * Represent the primitive types of the Entity Data Model (EDM).
+ *
+ * @see http://dl.windowsazure.com/javadoc/com/microsoft/windowsazure/services/table/models/EdmType.html
+ * <p>
+ * For an overview of the available EDM primitive data types and names, see the <a
+ * href="http://www.odata.org/developers/protocols/overview#AbstractTypeSystem">Primitive Data Types</a> section of the
+ * <a href="http://www.odata.org/developers/protocols/overview">OData Protocol Overview</a>.
+ * </p>
+ * <p>
+ * The Abstract Type System used to define the primitive types supported by OData is defined in detail in <a
+ * href="http://msdn.microsoft.com/en-us/library/dd541474.aspx">[MC-CSDL] (section 2.2.1).</a>
+ * </p>
+ */
+public enum EdmSimpleType {
+
+  /**
+   * The absence of a value.
+   */
+  Null(Void.class),
+  /**
+   * An array of bytes.
+   */
+  Binary(byte[].class),
+  /**
+   * A Boolean value.
+   */
+  Boolean(Boolean.class),
+  /**
+   * Unsigned 8-bit integer value.
+   */
+  Byte(Integer.class),
+  /**
+   * A signed 8-bit integer value.
+   */
+  SByte(Byte.class),
+  /**
+   * A 64-bit value expressed as Coordinated Universal Time (UTC).
+   */
+  DateTime(new ODataServiceVersion[]{ODataServiceVersion.V30}, ODataTimestamp.class, "yyyy-MM-dd'T'HH:mm:ss"),
+  /**
+   * Date without a time-zone offset.
+   */
+  Date(new ODataServiceVersion[]{ODataServiceVersion.V40}, ODataTimestamp.class, "yyyy-MM-dd"),
+  /**
+   * Date and time as an Offset in minutes from GMT.
+   */
+  DateTimeOffset(ODataTimestamp.class, "yyyy-MM-dd'T'HH:mm:ss"),
+  /**
+   * The time of day with values ranging from 0:00:00.x to 23:59:59.y, where x and y depend upon the precision.
+   */
+  Time(new ODataServiceVersion[]{ODataServiceVersion.V30}, ODataDuration.class),
+  /**
+   * The time of day with values ranging from 0:00:00.x to 23:59:59.y, where x and y depend upon the precision.
+   */
+  TimeOfDay(new ODataServiceVersion[]{ODataServiceVersion.V40}, ODataDuration.class),
+  /**
+   * Signed duration in days, hours, minutes, and (sub)seconds.
+   */
+  Duration(new ODataServiceVersion[]{ODataServiceVersion.V40}, ODataDuration.class),
+  /**
+   * Numeric values with fixed precision and scale.
+   */
+  Decimal(BigDecimal.class, "#.#######################"),
+  /**
+   * A floating point number with 7 digits precision.
+   */
+  Single(Float.class, "#.#######E0"),
+  /**
+   * A 64-bit double-precision floating point value.
+   */
+  Double(Double.class, "#.#######################E0"),
+  // --- Geospatial ---
+  Geography(Geospatial.class),
+  GeographyPoint(Point.class),
+  GeographyLineString(LineString.class),
+  GeographyPolygon(Polygon.class),
+  GeographyMultiPoint(MultiPoint.class),
+  GeographyMultiLineString(MultiLineString.class),
+  GeographyMultiPolygon(MultiPolygon.class),
+  GeographyCollection(GeospatialCollection.class),
+  Geometry(Geospatial.class),
+  GeometryPoint(Point.class),
+  GeometryLineString(LineString.class),
+  GeometryPolygon(Polygon.class),
+  GeometryMultiPoint(MultiPoint.class),
+  GeometryMultiLineString(MultiLineString.class),
+  GeometryMultiPolygon(MultiPolygon.class),
+  GeometryCollection(GeospatialCollection.class),
+  /**
+   * A 128-bit globally unique identifier.
+   */
+  Guid(UUID.class),
+  /**
+   * A 16-bit integer value.
+   */
+  Int16(Short.class),
+  /**
+   * A 32-bit integer value.
+   */
+  Int32(Integer.class),
+  /**
+   * A 64-bit integer value.
+   */
+  Int64(Long.class),
+  /**
+   * A UTF-16-encoded value. String values may be up to 64 KB in size.
+   */
+  String(String.class),
+  /**
+   * Resource stream (for media entities).
+   */
+  Stream(URI.class);
+
+  private final Class<?> clazz;
+
+  private final String pattern;
+
+  private final ODataServiceVersion[] versions;
+
+  /**
+   * Constructor (all OData versions).
+   *
+   * @param clazz type.
+   */
+  EdmSimpleType(final Class<?> clazz) {
+    this(ODataServiceVersion.values(), clazz, null);
+  }
+
+  /**
+   * Constructor.
+   *
+   * @param versions supported OData versions.
+   * @param clazz type.
+   */
+  EdmSimpleType(final ODataServiceVersion[] versions, final Class<?> clazz) {
+    this(versions, clazz, null);
+  }
+
+  /**
+   * Constructor (all OData versions).
+   *
+   * @param clazz type.
+   * @param pattern pattern.
+   */
+  EdmSimpleType(final Class<?> clazz, final String pattern) {
+    this(ODataServiceVersion.values(), clazz, pattern);
+  }
+
+  /**
+   * Constructor.
+   *
+   * @param versions supported OData versions.
+   * @param clazz type.
+   * @param pattern pattern.
+   */
+  EdmSimpleType(final ODataServiceVersion[] versions, final Class<?> clazz, final String pattern) {
+    this.clazz = clazz;
+    this.pattern = pattern;
+    this.versions = versions.clone();
+  }
+
+  /**
+   * Gets pattern.
+   *
+   * @return pattern.
+   */
+  public String pattern() {
+    return pattern;
+  }
+
+  /**
+   * Gets corresponding java type.
+   *
+   * @return java type.
+   */
+  public Class<?> javaType() {
+    return this.clazz;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public String toString() {
+    return namespace() + "." + name();
+  }
+
+  /**
+   * Checks if is a geospatial type.
+   *
+   * @return <tt>true</tt> if is geospatial type; <tt>false</tt> otherwise.
+   */
+  public boolean isGeospatial() {
+    return name().startsWith("Geo");
+  }
+
+  /**
+   * Checks if the given type is a geospatial type.
+   *
+   * @param type type.
+   * @return <tt>true</tt> if is geospatial type; <tt>false</tt> otherwise.
+   */
+  public static boolean isGeospatial(final String type) {
+    return type != null && type.startsWith(namespace() + ".Geo");
+  }
+
+  /**
+   * Gets <tt>EdmSimpleType</tt> from string.
+   *
+   * @param value string value type.
+   * @return <tt>EdmSimpleType</tt> object.
+   */
+  public static EdmSimpleType fromValue(final String value) {
+    final String noNsValue = value.substring(4);
+    for (EdmSimpleType edmSimpleType : EdmSimpleType.values()) {
+      if (edmSimpleType.name().equals(noNsValue)) {
+        return edmSimpleType;
+      }
+    }
+    throw new IllegalArgumentException(value);
+  }
+
+  /**
+   * Gets <tt>EdmSimpleType</tt> from object instance.
+   *
+   * @param workingVersion OData version.
+   * @param obj object.
+   * @return <tt>EdmSimpleType</tt> object.
+   */
+  public static EdmSimpleType fromObject(final ODataServiceVersion workingVersion, final Object obj) {
+    for (EdmSimpleType edmSimpleType : EdmSimpleType.values()) {
+      if (edmSimpleType.javaType().equals(obj.getClass())) {
+        return edmSimpleType == DateTimeOffset || edmSimpleType == DateTime || edmSimpleType == Date
+                ? ((ODataTimestamp) obj).isOffset()
+                ? DateTimeOffset : workingVersion == ODataServiceVersion.V30 ? DateTime : Date
+                : edmSimpleType;
+      }
+    }
+    throw new IllegalArgumentException(obj.getClass().getSimpleName() + " is not a simple type");
+  }
+
+  /**
+   * Gets namespace.
+   *
+   * @return namespace.
+   */
+  public static String namespace() {
+    return "Edm";
+  }
+
+  public ODataServiceVersion[] getSupportedVersions() {
+    return versions.clone();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataCollectionValue.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataCollectionValue.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataCollectionValue.java
new file mode 100644
index 0000000..253083b
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataCollectionValue.java
@@ -0,0 +1,98 @@
+/*
+ * 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.odata4.client.api.domain;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * OData collection property value.
+ */
+public class ODataCollectionValue extends ODataValue implements Iterable<ODataValue> {
+
+  private static final long serialVersionUID = -3665659846001987187L;
+
+  /**
+   * Type name;
+   */
+  private final String typeName;
+
+  /**
+   * Values.
+   */
+  private final List<ODataValue> values = new ArrayList<ODataValue>();
+
+  /**
+   * Constructor.
+   *
+   * @param typeName type name.
+   */
+  public ODataCollectionValue(final String typeName) {
+    this.typeName = typeName;
+  }
+
+  /**
+   * Adds a value to the collection.
+   *
+   * @param value value to be added.
+   */
+  public void add(final ODataValue value) {
+    if (value.isPrimitive() || value.isComplex()) {
+      values.add(value);
+    }
+  }
+
+  /**
+   * Value iterator.
+   *
+   * @return value iterator.
+   */
+  @Override
+  public Iterator<ODataValue> iterator() {
+    return values.iterator();
+  }
+
+  /**
+   * Gets value type name.
+   *
+   * @return value type name.
+   */
+  public String getTypeName() {
+    return typeName;
+  }
+
+  /**
+   * Gets collection size.
+   *
+   * @return collection size.
+   */
+  public int size() {
+    return values.size();
+  }
+
+  /**
+   * Checks if collection is empty.
+   *
+   * @return 'TRUE' if empty; 'FALSE' otherwise.
+   */
+  public boolean isEmpty() {
+    return values.isEmpty();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataComplexValue.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataComplexValue.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataComplexValue.java
new file mode 100644
index 0000000..6bca821
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataComplexValue.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.odata4.client.api.domain;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * OData complex property value.
+ */
+public class ODataComplexValue extends ODataValue implements Iterable<ODataProperty> {
+
+  private static final long serialVersionUID = -1878555027714020431L;
+
+  /**
+   * Type name.
+   */
+  private final String typeName;
+
+  /**
+   * Complex type fields.
+   */
+  private final Map<String, ODataProperty> fields = new LinkedHashMap<String, ODataProperty>();
+
+  /**
+   * Constructor.
+   *
+   * @param typeName type name.
+   */
+  public ODataComplexValue(final String typeName) {
+    this.typeName = typeName;
+  }
+
+  /**
+   * Adds field to the complex type.
+   *
+   * @param field field to be added.
+   */
+  public void add(final ODataProperty field) {
+    fields.put(field.getName(), field);
+  }
+
+  /**
+   * Gets field.
+   *
+   * @param name name of the field to be retrieved.
+   * @return requested field.
+   */
+  public ODataProperty get(final String name) {
+    return fields.get(name);
+  }
+
+  /**
+   * Complex property fields iterator.
+   *
+   * @return fields iterator.
+   */
+  @Override
+  public Iterator<ODataProperty> iterator() {
+    return fields.values().iterator();
+  }
+
+  /**
+   * Gest value type name.
+   *
+   * @return value type name.
+   */
+  public String getTypeName() {
+    return typeName;
+  }
+
+  /**
+   * Gets number of fields.
+   *
+   * @return number of fields.
+   */
+  public int size() {
+    return fields.size();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataDuration.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataDuration.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataDuration.java
new file mode 100644
index 0000000..ba6ff17
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataDuration.java
@@ -0,0 +1,80 @@
+/*
+ * 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.odata4.client.api.domain;
+
+import java.io.Serializable;
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.Duration;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * Helper class for handling time (as duration) primitive values.
+ *
+ * @see com.msopentech.odatajclient.engine.data.metadata.edm.EdmSimpleType#TIME
+ * @see Duration
+ */
+public final class ODataDuration implements Serializable {
+
+  private static final long serialVersionUID = 778404231943967899L;
+
+  private final Duration duration;
+
+  public ODataDuration(final String input) {
+    try {
+      final DatatypeFactory dtFactory = DatatypeFactory.newInstance();
+      this.duration = dtFactory.newDuration(input);
+    } catch (DatatypeConfigurationException e) {
+      throw new IllegalArgumentException("Could not parse '" + input + "' as Duration", e);
+    }
+  }
+
+  public ODataDuration(final Duration duration) {
+    this.duration = duration;
+  }
+
+  public Duration getDuration() {
+    return duration;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public boolean equals(final Object obj) {
+    return EqualsBuilder.reflectionEquals(this, obj);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public int hashCode() {
+    return HashCodeBuilder.reflectionHashCode(this);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public String toString() {
+    return this.duration.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataGeospatialValue.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataGeospatialValue.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataGeospatialValue.java
new file mode 100644
index 0000000..2115b8a
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataGeospatialValue.java
@@ -0,0 +1,486 @@
+/*
+ * 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.odata4.client.api.domain;
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+import org.apache.olingo.odata4.client.api.Constants;
+import org.apache.olingo.odata4.client.api.ODataClient;
+import org.apache.olingo.odata4.client.api.domain.geospatial.Geospatial;
+import org.apache.olingo.odata4.client.api.domain.geospatial.GeospatialCollection;
+import org.apache.olingo.odata4.client.api.domain.geospatial.LineString;
+import org.apache.olingo.odata4.client.api.domain.geospatial.MultiLineString;
+import org.apache.olingo.odata4.client.api.domain.geospatial.MultiPoint;
+import org.apache.olingo.odata4.client.api.domain.geospatial.MultiPolygon;
+import org.apache.olingo.odata4.client.api.domain.geospatial.Point;
+import org.apache.olingo.odata4.client.api.domain.geospatial.Polygon;
+import org.apache.olingo.odata4.client.api.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class ODataGeospatialValue extends ODataPrimitiveValue {
+
+  private static final long serialVersionUID = -3984105137562291082L;
+
+  /**
+   * Geospatial value builder.
+   */
+  public static class Builder extends AbstractBuilder {
+
+    private final ODataGeospatialValue ogv;
+
+    /**
+     * Constructor.
+     */
+    public Builder(final ODataClient client) {
+      super(client);
+      this.ogv = new ODataGeospatialValue(client);
+    }
+
+    /**
+     * Sets the given value provided as a DOM tree.
+     *
+     * @param tree value.
+     * @return the current builder.
+     */
+    public Builder setTree(final Element tree) {
+      this.ogv.tree = tree;
+      return this;
+    }
+
+    /**
+     * Sets the actual object value.
+     *
+     * @param value value.
+     * @return the current builder.
+     */
+    public <T extends Geospatial> Builder setValue(final T value) {
+      this.ogv.value = value;
+      return this;
+    }
+
+    /**
+     * Sets actual value type.
+     *
+     * @param type type.
+     * @return the current builder.
+     */
+    public Builder setType(final EdmSimpleType type) {
+      isSupported(type);
+
+      if (!type.isGeospatial()) {
+        throw new IllegalArgumentException(
+                "Use " + ODataPrimitiveValue.class.getSimpleName() + " for non-geospatial types");
+      }
+
+      if (type == EdmSimpleType.Geography || type == EdmSimpleType.Geometry) {
+        throw new IllegalArgumentException(
+                type + "is not an instantiable type. "
+                + "An entity can declare a property to be of type Geometry. "
+                + "An instance of an entity MUST NOT have a value of type Geometry. "
+                + "Each value MUST be of some subtype.");
+      }
+      this.ogv.type = type;
+      return this;
+    }
+
+    /**
+     * Builds the geospatial value.
+     *
+     * @return <tt>ODataGeospatialValue</tt> object.
+     */
+    public ODataGeospatialValue build() {
+      if (this.ogv.tree == null && this.ogv.value == null) {
+        throw new IllegalArgumentException("Must provide either tree or value");
+      }
+      if (this.ogv.tree != null && this.ogv.value != null) {
+        throw new IllegalArgumentException("Cannot provide both tree and value");
+      }
+
+      if (this.ogv.type == null) {
+        throw new IllegalArgumentException("Must provide geospatial type");
+      }
+
+      if (this.ogv.tree != null) {
+        this.ogv.value = this.ogv.parseTree(this.ogv.tree, this.ogv.type);
+      }
+      if (this.ogv.value != null) {
+        this.ogv.tree = this.ogv.parseGeospatial((Geospatial) this.ogv.value);
+      }
+
+      return this.ogv;
+    }
+  }
+
+  /**
+   * DOM tree.
+   */
+  private Element tree;
+
+  /**
+   * Protected constructor, need to use the builder to instantiate this class.
+   *
+   * @see Builder
+   */
+  protected ODataGeospatialValue(final ODataClient client) {
+    super(client);
+  }
+
+  private Geospatial.Dimension getDimension() {
+    Geospatial.Dimension dimension;
+
+    switch (this.type) {
+      case Geography:
+      case GeographyCollection:
+      case GeographyLineString:
+      case GeographyMultiLineString:
+      case GeographyPoint:
+      case GeographyMultiPoint:
+      case GeographyPolygon:
+      case GeographyMultiPolygon:
+        dimension = Geospatial.Dimension.GEOGRAPHY;
+        break;
+
+      default:
+        dimension = Geospatial.Dimension.GEOMETRY;
+    }
+
+    return dimension;
+  }
+
+  private List<Point> parsePoints(final NodeList posList) {
+    final List<Point> result = new ArrayList<Point>();
+    for (int i = 0; i < posList.getLength(); i++) {
+      final String[] pointInfo = posList.item(i).getTextContent().split(" ");
+      final Point point = new Point(getDimension());
+      point.setX(Double.valueOf(pointInfo[0]));
+      point.setY(Double.valueOf(pointInfo[1]));
+
+      result.add(point);
+    }
+    return result;
+  }
+
+  private LineString parseLineString(final Element element) {
+    return new LineString(getDimension(),
+            parsePoints(element.getElementsByTagName(Constants.ELEM_POS)));
+  }
+
+  private Polygon parsePolygon(final Element element) {
+    List<Point> extPoints = null;
+    final Element exterior
+            = (Element) element.getElementsByTagName(Constants.ELEM_POLYGON_EXTERIOR).item(0);
+    if (exterior != null) {
+      extPoints = parsePoints(
+              ((Element) exterior.getElementsByTagName(Constants.ELEM_POLYGON_LINEARRING).item(0)).
+              getElementsByTagName(Constants.ELEM_POS));
+    }
+    List<Point> intPoints = null;
+    final Element interior
+            = (Element) element.getElementsByTagName(Constants.ELEM_POLYGON_INTERIOR).item(0);
+    if (interior != null) {
+      intPoints = parsePoints(
+              ((Element) interior.getElementsByTagName(Constants.ELEM_POLYGON_LINEARRING).item(0)).
+              getElementsByTagName(Constants.ELEM_POS));
+    }
+
+    return new Polygon(getDimension(), intPoints, extPoints);
+  }
+
+  /**
+   * Parses given tree as geospatial value.
+   */
+  private Geospatial parseTree(final Element tree, final EdmSimpleType type) {
+    Geospatial value;
+
+    switch (type) {
+      case GeographyPoint:
+      case GeometryPoint:
+        value = parsePoints(tree.getElementsByTagName(Constants.ELEM_POS)).get(0);
+        break;
+
+      case GeographyMultiPoint:
+      case GeometryMultiPoint:
+        final Element pMembs
+                = (Element) tree.getElementsByTagName(Constants.ELEM_POINTMEMBERS).item(0);
+        final List<Point> points = pMembs == null
+                ? Collections.<Point>emptyList()
+                : parsePoints(pMembs.getElementsByTagName(Constants.ELEM_POS));
+        value = new MultiPoint(getDimension(), points);
+        break;
+
+      case GeographyLineString:
+      case GeometryLineString:
+        value = parseLineString(tree);
+        break;
+
+      case GeographyMultiLineString:
+      case GeometryMultiLineString:
+        final Element mlMembs
+                = (Element) tree.getElementsByTagName(Constants.ELEM_LINESTRINGMEMBERS).item(0);
+        final List<LineString> lineStrings;
+        if (mlMembs == null) {
+          lineStrings = Collections.<LineString>emptyList();
+        } else {
+          lineStrings = new ArrayList<LineString>();
+          final NodeList lineStringNodes = mlMembs.getElementsByTagName(Constants.ELEM_LINESTRING);
+          for (int i = 0; i < lineStringNodes.getLength(); i++) {
+            lineStrings.add(parseLineString((Element) lineStringNodes.item(i)));
+          }
+        }
+        value = new MultiLineString(getDimension(), lineStrings);
+        break;
+
+      case GeographyPolygon:
+      case GeometryPolygon:
+        value = parsePolygon(tree);
+        break;
+
+      case GeographyMultiPolygon:
+      case GeometryMultiPolygon:
+        final Element mpMembs
+                = (Element) tree.getElementsByTagName(Constants.ELEM_SURFACEMEMBERS).item(0);
+        final List<Polygon> polygons;
+        if (mpMembs == null) {
+          polygons = Collections.<Polygon>emptyList();
+        } else {
+          polygons = new ArrayList<Polygon>();
+          final NodeList polygonNodes = mpMembs.getElementsByTagName(Constants.ELEM_POLYGON);
+          for (int i = 0; i < polygonNodes.getLength(); i++) {
+            polygons.add(parsePolygon((Element) polygonNodes.item(i)));
+          }
+        }
+        value = new MultiPolygon(getDimension(), polygons);
+        break;
+
+      case GeographyCollection:
+      case GeometryCollection:
+        final Element cMembs
+                = (Element) tree.getElementsByTagName(Constants.ELEM_GEOMEMBERS).item(0);
+        final List<Geospatial> geospatials;
+        if (cMembs == null) {
+          geospatials = Collections.<Geospatial>emptyList();
+        } else {
+          geospatials = new ArrayList<Geospatial>();
+          for (Node geom : XMLUtils.getChildNodes(cMembs, Node.ELEMENT_NODE)) {
+            geospatials.add(parseTree((Element) geom, XMLUtils.simpleTypeForNode(getDimension(), geom)));
+          }
+        }
+        value = new GeospatialCollection(getDimension(), geospatials);
+        break;
+
+      default:
+        value = null;
+    }
+
+    return value;
+  }
+
+  private void parsePoints(final Element parent, final Iterator<Point> itor, final boolean wrap) {
+    while (itor.hasNext()) {
+      final Point point = itor.next();
+
+      final Element pos = parent.getOwnerDocument().
+              createElementNS(Constants.NS_GML, Constants.ELEM_POS);
+      pos.appendChild(parent.getOwnerDocument().createTextNode(
+              Double.toString(point.getX()) + " " + point.getY()));
+
+      final Element appendable;
+      if (wrap) {
+        final Element epoint = parent.getOwnerDocument().
+                createElementNS(Constants.NS_GML, Constants.ELEM_POINT);
+        parent.appendChild(epoint);
+        appendable = epoint;
+      } else {
+        appendable = parent;
+      }
+      appendable.appendChild(pos);
+    }
+  }
+
+  private void parseLineStrings(final Element parent, final Iterator<LineString> itor, final boolean wrap) {
+    while (itor.hasNext()) {
+      final LineString lineString = itor.next();
+
+      final Element appendable;
+      if (wrap) {
+        final Element eLineString = parent.getOwnerDocument().
+                createElementNS(Constants.NS_GML, Constants.ELEM_LINESTRING);
+        parent.appendChild(eLineString);
+        appendable = eLineString;
+      } else {
+        appendable = parent;
+      }
+      parsePoints(appendable, lineString.iterator(), false);
+    }
+  }
+
+  private void parsePolygons(final Element parent, final Iterator<Polygon> itor, final boolean wrap) {
+    while (itor.hasNext()) {
+      final Polygon polygon = itor.next();
+
+      final Element appendable;
+      if (wrap) {
+        final Element ePolygon = parent.getOwnerDocument().createElementNS(
+                Constants.NS_GML, Constants.ELEM_POLYGON);
+        parent.appendChild(ePolygon);
+        appendable = ePolygon;
+      } else {
+        appendable = parent;
+      }
+
+      if (!polygon.getExterior().isEmpty()) {
+        final Element exterior = parent.getOwnerDocument().createElementNS(
+                Constants.NS_GML, Constants.ELEM_POLYGON_EXTERIOR);
+        appendable.appendChild(exterior);
+        final Element linearRing = parent.getOwnerDocument().createElementNS(
+                Constants.NS_GML, Constants.ELEM_POLYGON_LINEARRING);
+        exterior.appendChild(linearRing);
+
+        parsePoints(linearRing, polygon.getExterior().iterator(), false);
+      }
+      if (!polygon.getInterior().isEmpty()) {
+        final Element interior = parent.getOwnerDocument().createElementNS(
+                Constants.NS_GML, Constants.ELEM_POLYGON_INTERIOR);
+        appendable.appendChild(interior);
+        final Element linearRing = parent.getOwnerDocument().createElementNS(
+                Constants.NS_GML, Constants.ELEM_POLYGON_LINEARRING);
+        interior.appendChild(linearRing);
+
+        parsePoints(linearRing, polygon.getInterior().iterator(), false);
+      }
+    }
+  }
+
+  private Element parseGeospatial(final Geospatial value) {
+    final DocumentBuilder builder;
+    try {
+      builder = XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder();
+    } catch (ParserConfigurationException e) {
+      throw new IllegalStateException("Failure initializing Geospatial DOM tree", e);
+    }
+    final Document doc = builder.newDocument();
+
+    final Element tree;
+
+    switch (value.getEdmSimpleType()) {
+      case GeographyPoint:
+      case GeometryPoint:
+        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_POINT);
+
+        parsePoints(tree, Collections.singleton((Point) value).iterator(), false);
+        break;
+
+      case GeometryMultiPoint:
+      case GeographyMultiPoint:
+        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_MULTIPOINT);
+
+        final Element pMembs = doc.createElementNS(Constants.NS_GML, Constants.ELEM_POINTMEMBERS);
+        tree.appendChild(pMembs);
+
+        parsePoints(pMembs, ((MultiPoint) value).iterator(), true);
+        break;
+
+      case GeometryLineString:
+      case GeographyLineString:
+        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_LINESTRING);
+
+        parseLineStrings(tree, Collections.singleton((LineString) value).iterator(), false);
+        break;
+
+      case GeometryMultiLineString:
+      case GeographyMultiLineString:
+        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_MULTILINESTRING);
+
+        final Element mlMembs
+                = doc.createElementNS(Constants.NS_GML, Constants.ELEM_LINESTRINGMEMBERS);
+        tree.appendChild(mlMembs);
+
+        parseLineStrings(mlMembs, ((MultiLineString) value).iterator(), true);
+        break;
+
+      case GeographyPolygon:
+      case GeometryPolygon:
+        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_POLYGON);
+        parsePolygons(tree, Collections.singleton(((Polygon) value)).iterator(), false);
+        break;
+
+      case GeographyMultiPolygon:
+      case GeometryMultiPolygon:
+        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_MULTIPOLYGON);
+
+        final Element mpMembs
+                = doc.createElementNS(Constants.NS_GML, Constants.ELEM_SURFACEMEMBERS);
+        tree.appendChild(mpMembs);
+
+        parsePolygons(mpMembs, ((MultiPolygon) value).iterator(), true);
+        break;
+
+      case GeographyCollection:
+      case GeometryCollection:
+        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_GEOCOLLECTION);
+
+        final Element gMembs
+                = doc.createElementNS(Constants.NS_GML, Constants.ELEM_GEOMEMBERS);
+        tree.appendChild(gMembs);
+
+        final Iterator<Geospatial> itor = ((GeospatialCollection) value).iterator();
+        while (itor.hasNext()) {
+          final Geospatial geospatial = itor.next();
+          gMembs.appendChild(doc.importNode(parseGeospatial(geospatial), true));
+        }
+        break;
+
+      default:
+        tree = null;
+    }
+
+    return tree;
+  }
+
+  public Element toTree() {
+    return this.tree;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    final ODataGeospatialValue other = (ODataGeospatialValue) obj;
+    return this.tree.isEqualNode(other.tree);
+  }
+
+  @Override
+  public String toString() {
+    final StringWriter writer = new StringWriter();
+    client.getSerializer().dom(this.tree, writer);
+    return writer.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataInvokeResult.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataInvokeResult.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataInvokeResult.java
new file mode 100644
index 0000000..f28e5dd
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataInvokeResult.java
@@ -0,0 +1,30 @@
+/*
+ * 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.odata4.client.api.domain;
+
+/**
+ * Marker interface for any OData domain object that can be returned by an operation invocation.
+ *
+ * @see ODataEntitySet
+ * @see ODataEntity
+ * @see ODataProperty
+ * @see ODataNoContent
+ */
+public interface ODataInvokeResult {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataPrimitiveValue.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataPrimitiveValue.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataPrimitiveValue.java
new file mode 100644
index 0000000..05da80a
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataPrimitiveValue.java
@@ -0,0 +1,376 @@
+/*
+ * 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.odata4.client.api.domain;
+
+import java.math.BigDecimal;
+import java.net.URI;
+import java.sql.Timestamp;
+import java.text.DecimalFormat;
+import java.util.Date;
+import java.util.UUID;
+import javax.xml.datatype.Duration;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.odata4.client.api.ODataClient;
+import org.apache.olingo.odata4.client.api.domain.EdmSimpleType;
+import org.apache.olingo.odata4.client.api.domain.ODataDuration;
+import org.apache.olingo.odata4.client.api.domain.ODataTimestamp;
+import org.apache.olingo.odata4.client.api.domain.ODataValue;
+
+/**
+ * OData primitive property value.
+ */
+public class ODataPrimitiveValue extends ODataValue {
+
+  private static final long serialVersionUID = 2841837627899878223L;
+
+  protected abstract static class AbstractBuilder {
+
+    private final ODataClient client;
+
+    /**
+     * Constructor.
+     */
+    public AbstractBuilder(final ODataClient client) {
+      this.client = client;
+    }
+
+    public AbstractBuilder isSupported(final EdmSimpleType type) {
+      if (type != null && !ArrayUtils.contains(type.getSupportedVersions(), client.getServiceVersion())) {
+        throw new IllegalArgumentException(String.format(
+                "Type %s not supported by the current OData working version", type.toString()));
+      }
+
+      return this;
+    }
+  }
+
+  /**
+   * Primitive value builder.
+   */
+  public static class Builder extends AbstractBuilder {
+
+    private final ODataPrimitiveValue opv;
+
+    /**
+     * Constructor.
+     */
+    public Builder(final ODataClient client) {
+      super(client);
+      this.opv = new ODataPrimitiveValue(client);
+    }
+
+    /**
+     * Sets the given value provided as a text.
+     *
+     * @param text value.
+     * @return the current builder.
+     */
+    public Builder setText(final String text) {
+      this.opv.text = text;
+      return this;
+    }
+
+    /**
+     * Sets the actual object value.
+     *
+     * @param value value.
+     * @return the current builder.
+     */
+    public Builder setValue(final Object value) {
+      this.opv.value = value;
+      return this;
+    }
+
+    /**
+     * Sets actual value type.
+     *
+     * @param type type.
+     * @return the current builder.
+     */
+    public Builder setType(final EdmSimpleType type) {
+      isSupported(type);
+
+      if (type == EdmSimpleType.Stream) {
+        throw new IllegalArgumentException(String.format(
+                "Cannot build a primitive value for %s", EdmSimpleType.Stream.toString()));
+      }
+
+      this.opv.type = type;
+      return this;
+    }
+
+    /**
+     * Builds the primitive value.
+     *
+     * @return <code>ODataPrimitiveValue</code> object.
+     */
+    public ODataPrimitiveValue build() {
+      if (this.opv.text == null && this.opv.value == null) {
+        throw new IllegalArgumentException("Must provide either text or value");
+      }
+      if (this.opv.text != null && this.opv.value != null) {
+        throw new IllegalArgumentException("Cannot provide both text and value");
+      }
+
+      if (this.opv.type == null) {
+        this.opv.type = EdmSimpleType.String;
+      }
+
+      if (this.opv.type.isGeospatial()) {
+        throw new IllegalArgumentException(
+                "Use " + ODataGeospatialValue.class.getSimpleName() + " for geospatial types");
+      }
+
+      if (this.opv.value instanceof Timestamp) {
+        this.opv.value = ODataTimestamp.getInstance(this.opv.type, (Timestamp) this.opv.value);
+      } else if (this.opv.value instanceof Date) {
+        this.opv.value = ODataTimestamp.getInstance(this.opv.type,
+                new Timestamp(((Date) this.opv.value).getTime()));
+      }
+      if (this.opv.value instanceof Duration) {
+        this.opv.value = new ODataDuration((Duration) this.opv.value);
+      }
+
+      if (this.opv.value != null && !this.opv.type.javaType().isAssignableFrom(this.opv.value.getClass())) {
+        throw new IllegalArgumentException("Provided value is not compatible with " + this.opv.type.toString());
+      }
+
+      if (this.opv.text != null) {
+        this.opv.parseText();
+      }
+      if (this.opv.value != null) {
+        this.opv.formatValue();
+      }
+
+      return this.opv;
+    }
+  }
+
+  protected ODataClient client;
+
+  /**
+   * Text value.
+   */
+  private String text;
+
+  /**
+   * Actual value.
+   */
+  protected Object value;
+
+  /**
+   * Value type.
+   */
+  protected EdmSimpleType type;
+
+  /**
+   * Protected constructor, need to use the builder to instantiate this class.
+   *
+   * @see Builder
+   */
+  protected ODataPrimitiveValue(final ODataClient client) {
+    super();
+    this.client = client;
+  }
+
+  /**
+   * Parses given text as object value.
+   */
+  private void parseText() {
+    switch (this.type) {
+      case Null:
+        this.value = null;
+        break;
+
+      case Binary:
+        this.value = Base64.decodeBase64(this.toString());
+        break;
+
+      case SByte:
+        this.value = Byte.parseByte(this.toString());
+        break;
+
+      case Boolean:
+        this.value = Boolean.parseBoolean(this.toString());
+        break;
+
+      case Date:
+      case DateTime:
+      case DateTimeOffset:
+        this.value = ODataTimestamp.parse(this.type, this.toString());
+        break;
+
+      case Time:
+      case TimeOfDay:
+        this.value = new ODataDuration(this.toString());
+        break;
+
+      case Decimal:
+        this.value = new BigDecimal(this.toString());
+        break;
+
+      case Single:
+        this.value = Float.parseFloat(this.toString());
+        break;
+
+      case Double:
+        this.value = Double.parseDouble(this.toString());
+        break;
+
+      case Guid:
+        this.value = UUID.fromString(this.toString());
+        break;
+
+      case Int16:
+        this.value = Short.parseShort(this.toString());
+        break;
+
+      case Byte:
+      case Int32:
+        this.value = Integer.parseInt(this.toString());
+        break;
+
+      case Int64:
+        this.value = Long.parseLong(this.toString());
+        break;
+
+      case Stream:
+        this.value = URI.create(this.toString());
+        break;
+
+      case String:
+        this.value = this.toString();
+        break;
+
+      default:
+    }
+  }
+
+  /**
+   * Format given value as text.
+   */
+  private void formatValue() {
+    switch (this.type) {
+      case Null:
+        this.text = StringUtils.EMPTY;
+        break;
+
+      case Binary:
+        this.text = Base64.encodeBase64String(this.<byte[]>toCastValue());
+        break;
+
+      case SByte:
+        this.text = this.<Byte>toCastValue().toString();
+        break;
+
+      case Boolean:
+        this.text = this.<Boolean>toCastValue().toString();
+        break;
+
+      case Date:
+      case DateTime:
+      case DateTimeOffset:
+        this.text = this.<ODataTimestamp>toCastValue().toString();
+        break;
+
+      case Time:
+      case TimeOfDay:
+        this.text = this.<ODataDuration>toCastValue().toString();
+        break;
+
+      case Decimal:
+        this.text = new DecimalFormat(this.type.pattern()).format(this.<BigDecimal>toCastValue());
+        break;
+
+      case Single:
+        this.text = new DecimalFormat(this.type.pattern()).format(this.<Float>toCastValue());
+        break;
+
+      case Double:
+        this.text = new DecimalFormat(this.type.pattern()).format(this.<Double>toCastValue());
+        break;
+
+      case Guid:
+        this.text = this.<UUID>toCastValue().toString();
+        break;
+
+      case Int16:
+        this.text = this.<Short>toCastValue().toString();
+        break;
+
+      case Byte:
+      case Int32:
+        this.text = this.<Integer>toCastValue().toString();
+        break;
+
+      case Int64:
+        this.text = this.<Long>toCastValue().toString();
+        break;
+
+      case Stream:
+        this.text = this.<URI>toCastValue().toASCIIString();
+        break;
+
+      case String:
+        this.text = this.<String>toCastValue();
+        break;
+
+      default:
+    }
+  }
+
+  /**
+   * Gets type name.
+   *
+   * @return type name.
+   */
+  public String getTypeName() {
+    return type.toString();
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public String toString() {
+    return this.text;
+  }
+
+  /**
+   * Gets actual primitive value.
+   *
+   * @return
+   */
+  public Object toValue() {
+    return this.value;
+  }
+
+  /**
+   * Casts primitive value.
+   *
+   * @param <T> cast.
+   * @return casted value.
+   */
+  @SuppressWarnings("unchecked")
+  public <T> T toCastValue() {
+    return (T) type.javaType().cast(toValue());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataProperty.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataProperty.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataProperty.java
new file mode 100644
index 0000000..5aa9acd
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataProperty.java
@@ -0,0 +1,192 @@
+/*
+ * 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.odata4.client.api.domain;
+
+import java.io.Serializable;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * OData entity property.
+ */
+public class ODataProperty implements Serializable, ODataInvokeResult {
+
+  /**
+   * Property type.
+   */
+  public enum PropertyType {
+
+    /**
+     * Primitive.
+     */
+    PRIMITIVE,
+    /**
+     * Collection
+     */
+    COLLECTION,
+    /**
+     * Complex.
+     */
+    COMPLEX,
+    /**
+     * Empty type (possibly, no type information could be retrieved).
+     */
+    EMPTY
+
+  }
+
+  private static final long serialVersionUID = 926939448778950450L;
+
+  /**
+   * Property name.
+   */
+  private final String name;
+
+  /**
+   * Property value.
+   */
+  private ODataValue value;
+
+  /**
+   * Constructor.
+   *
+   * @param name property name.
+   * @param value property value.
+   */
+  ODataProperty(final String name, final ODataValue value) {
+    this.name = name;
+    this.value = value;
+  }
+
+  /**
+   * Returns property name.
+   *
+   * @return property name.
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * Returns property value.
+   *
+   * @return property value.
+   */
+  public ODataValue getValue() {
+    return value;
+  }
+
+  /**
+   * Updates property value.
+   *
+   * @param value property value that replaces current.
+   */
+  public void setValue(final ODataValue value) {
+    this.value = value;
+  }
+
+  /**
+   * Checks if has null value.
+   *
+   * @return 'TRUE' if has null value; 'FALSE' otherwise.
+   */
+  public boolean hasNullValue() {
+    return this.value == null;
+  }
+
+  /**
+   * Checks if has primitive value.
+   *
+   * @return 'TRUE' if has primitive value; 'FALSE' otherwise.
+   */
+  public boolean hasPrimitiveValue() {
+    return !hasNullValue() && this.value.isPrimitive();
+  }
+
+  /**
+   * Gets primitive value.
+   *
+   * @return primitive value if exists; null otherwise.
+   */
+  public ODataPrimitiveValue getPrimitiveValue() {
+    return hasPrimitiveValue() ? this.value.asPrimitive() : null;
+  }
+
+  /**
+   * Checks if has complex value.
+   *
+   * @return 'TRUE' if has complex value; 'FALSE' otherwise.
+   */
+  public boolean hasComplexValue() {
+    return !hasNullValue() && this.value.isComplex();
+  }
+
+  /**
+   * Gets complex value.
+   *
+   * @return complex value if exists; null otherwise.
+   */
+  public ODataComplexValue getComplexValue() {
+    return hasComplexValue() ? this.value.asComplex() : null;
+  }
+
+  /**
+   * Checks if has collection value.
+   *
+   * @return 'TRUE' if has collection value; 'FALSE' otherwise.
+   */
+  public boolean hasCollectionValue() {
+    return !hasNullValue() && this.value.isCollection();
+  }
+
+  /**
+   * Gets collection value.
+   *
+   * @return collection value if exists; null otherwise.
+   */
+  public ODataCollectionValue getCollectionValue() {
+    return hasCollectionValue() ? this.value.asCollection() : null;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public boolean equals(final Object obj) {
+    return EqualsBuilder.reflectionEquals(this, obj);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public int hashCode() {
+    return HashCodeBuilder.reflectionHashCode(this);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public String toString() {
+    return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataServiceDocument.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataServiceDocument.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataServiceDocument.java
new file mode 100644
index 0000000..f16852b
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataServiceDocument.java
@@ -0,0 +1,183 @@
+/*
+ * 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.odata4.client.api.domain;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ODataServiceDocument {
+
+  private URI metadataContext;
+
+  private String metadataETag;
+
+  private final Map<String, URI> entitySets = new HashMap<String, URI>();
+
+  private final Map<String, URI> functionImports = new HashMap<String, URI>();
+
+  private final Map<String, URI> singletons = new HashMap<String, URI>();
+
+  private final Map<String, URI> relatedServiceDocuments = new HashMap<String, URI>();
+
+  public URI getMetadataContext() {
+    return metadataContext;
+  }
+
+  public void setMetadataContext(final URI metadataContext) {
+    this.metadataContext = metadataContext;
+  }
+
+  public String getMetadataETag() {
+    return metadataETag;
+  }
+
+  public void setMetadataETag(final String metadataETag) {
+    this.metadataETag = metadataETag;
+  }
+
+  public Map<String, URI> getEntitySets() {
+    return entitySets;
+  }
+
+  /**
+   * Gets entity set titles.
+   *
+   * @return entity set titles.
+   */
+  public Collection<String> getEntitySetTitles() {
+    return entitySets.keySet();
+  }
+
+  /**
+   * Gets entity set URIs.
+   *
+   * @return entity set URIs.
+   */
+  public Collection<URI> getEntitySetURIs() {
+    return entitySets.values();
+  }
+
+  /**
+   * Gets URI about the given entity set.
+   *
+   * @param title title.
+   * @return URI.
+   */
+  public URI getEntitySetURI(final String title) {
+    return entitySets.get(title);
+  }
+
+  public Map<String, URI> getFunctionImports() {
+    return functionImports;
+  }
+
+  /**
+   * Gets function import titles.
+   *
+   * @return function import titles.
+   */
+  public Collection<String> getFunctionImportTitles() {
+    return functionImports.keySet();
+  }
+
+  /**
+   * Gets function import URIs.
+   *
+   * @return function import URIs.
+   */
+  public Collection<URI> getFunctionImportURIs() {
+    return functionImports.values();
+  }
+
+  /**
+   * Gets URI of the given function import.
+   *
+   * @param title title.
+   * @return URI.
+   */
+  public URI getFunctionImportURI(final String title) {
+    return functionImports.get(title);
+  }
+
+  public Map<String, URI> getSingletons() {
+    return singletons;
+  }
+
+  /**
+   * Gets singleton titles.
+   *
+   * @return singleton titles.
+   */
+  public Collection<String> getSingletonTitles() {
+    return singletons.keySet();
+  }
+
+  /**
+   * Gets singleton URIs.
+   *
+   * @return singleton URIs.
+   */
+  public Collection<URI> getSingletonURIs() {
+    return singletons.values();
+  }
+
+  /**
+   * Gets URI of the given singleton.
+   *
+   * @param title title.
+   * @return URI.
+   */
+  public URI getSingletonURI(final String title) {
+    return singletons.get(title);
+  }
+
+  public Map<String, URI> getRelatedServiceDocuments() {
+    return relatedServiceDocuments;
+  }
+
+  /**
+   * Gets related service documents titles.
+   *
+   * @return related service documents titles.
+   */
+  public Collection<String> getRelatedServiceDocumentsTitles() {
+    return relatedServiceDocuments.keySet();
+  }
+
+  /**
+   * Gets related service documents URIs.
+   *
+   * @return related service documents URIs.
+   */
+  public Collection<URI> getRelatedServiceDocumentsURIs() {
+    return relatedServiceDocuments.values();
+  }
+
+  /**
+   * Gets URI of the given related service documents.
+   *
+   * @param title title.
+   * @return URI.
+   */
+  public URI getRelatedServiceDocumentURI(final String title) {
+    return relatedServiceDocuments.get(title);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataTimestamp.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataTimestamp.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataTimestamp.java
new file mode 100644
index 0000000..b2a4077
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataTimestamp.java
@@ -0,0 +1,141 @@
+/*
+ * 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.odata4.client.api.domain;
+
+import java.io.Serializable;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * Helper class for handling datetime and datetime-offset primitive values.
+ *
+ * @see com.msopentech.odatajclient.engine.data.metadata.edm.EdmSimpleType#DATE_TIME
+ * @see com.msopentech.odatajclient.engine.data.metadata.edm.EdmSimpleType#DATE_TIME_OFFSET
+ */
+public final class ODataTimestamp implements Serializable {
+
+    private static final long serialVersionUID = 4053990618660356004L;
+
+    private final SimpleDateFormat sdf;
+
+    private final Timestamp timestamp;
+
+    private String timezone;
+
+    private final boolean offset;
+
+    public static ODataTimestamp getInstance(final EdmSimpleType type, final Timestamp timestamp) {
+        return new ODataTimestamp(new SimpleDateFormat(type.pattern()),
+                new Date(timestamp.getTime()), timestamp.getNanos(), type == EdmSimpleType.DateTimeOffset);
+    }
+
+    public static ODataTimestamp parse(final EdmSimpleType type, final String input) {
+        final ODataTimestamp instance;
+
+        final String[] dateParts = input.split("\\.");
+        final SimpleDateFormat sdf = new SimpleDateFormat(type.pattern());
+        final boolean isOffset = type == EdmSimpleType.DateTimeOffset;
+
+        try {
+            final Date date = sdf.parse(dateParts[0]);
+            if (dateParts.length > 1) {
+                int idx = dateParts[1].indexOf('+');
+                if (idx == -1) {
+                    idx = dateParts[1].indexOf('-');
+                }
+                if (idx == -1) {
+                    instance = new ODataTimestamp(sdf, date, Integer.parseInt(dateParts[1]), isOffset);
+                } else {
+                    instance = new ODataTimestamp(sdf, date,
+                            Integer.parseInt(dateParts[1].substring(0, idx)), dateParts[1].substring(idx), isOffset);
+                }
+            } else {
+                instance = new ODataTimestamp(sdf, date, isOffset);
+            }
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Cannot parse " + type.pattern(), e);
+        }
+
+        return instance;
+    }
+
+    private ODataTimestamp(final SimpleDateFormat sdf, final Date date, final boolean offset) {
+        this.sdf = sdf;
+        this.timestamp = new Timestamp(date.getTime());
+        this.offset = offset;
+    }
+
+    private ODataTimestamp(final SimpleDateFormat sdf, final Date date, final int nanos, final boolean offset) {
+        this(sdf, date, offset);
+        this.timestamp.setNanos(nanos);
+    }
+
+    private ODataTimestamp(
+            final SimpleDateFormat sdf, final Date date, final int nanos, final String timezone, final boolean offset) {
+        this(sdf, date, nanos, offset);
+        this.timezone = timezone;
+    }
+
+    public Timestamp getTimestamp() {
+        return timestamp;
+    }
+
+    public String getTimezone() {
+        return timezone;
+    }
+
+    public boolean isOffset() {
+        return offset;
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public boolean equals(final Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj, "sdf");
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this, "sdf");
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public String toString() {
+        final StringBuilder formatted = new StringBuilder().append(sdf.format(timestamp));
+        if (timestamp.getNanos() > 0) {
+            formatted.append('.').append(String.valueOf(timestamp.getNanos()));
+        }
+        if (StringUtils.isNotBlank(timezone)) {
+            formatted.append(timezone);
+        }
+        return formatted.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataValue.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataValue.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataValue.java
new file mode 100644
index 0000000..2978ffa
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataValue.java
@@ -0,0 +1,111 @@
+/*
+ * 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.odata4.client.api.domain;
+
+import java.io.Serializable;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * Abstract representation of an OData entity property value.
+ */
+public abstract class ODataValue implements Serializable {
+
+  private static final long serialVersionUID = 7445422004232581877L;
+
+  /**
+   * Check is is a primitive value.
+   *
+   * @return 'TRUE' if primitive; 'FALSE' otherwise.
+   */
+  public boolean isPrimitive() {
+    return (this instanceof ODataPrimitiveValue);
+  }
+
+  /**
+   * Casts to primitive value.
+   *
+   * @return primitive value.
+   */
+  public ODataPrimitiveValue asPrimitive() {
+    return isPrimitive() ? (ODataPrimitiveValue) this : null;
+  }
+
+  /**
+   * Check is is a complex value.
+   *
+   * @return 'TRUE' if complex; 'FALSE' otherwise.
+   */
+  public boolean isComplex() {
+    return (this instanceof ODataComplexValue);
+  }
+
+  /**
+   * Casts to complex value.
+   *
+   * @return complex value.
+   */
+  public ODataComplexValue asComplex() {
+    return isComplex() ? (ODataComplexValue) this : null;
+  }
+
+  /**
+   * Check is is a collection value.
+   *
+   * @return 'TRUE' if collection; 'FALSE' otherwise.
+   */
+  public boolean isCollection() {
+    return (this instanceof ODataCollectionValue);
+  }
+
+  /**
+   * Casts to collection value.
+   *
+   * @return collection value.
+   */
+  public ODataCollectionValue asCollection() {
+    return isCollection() ? (ODataCollectionValue) this : null;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public boolean equals(final Object obj) {
+    return EqualsBuilder.reflectionEquals(this, obj);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public int hashCode() {
+    return HashCodeBuilder.reflectionHashCode(this);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public String toString() {
+    return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+  }
+}


[4/4] git commit: [OLINGO-190] V3 service document deserializer merged, V4 implemented

Posted by il...@apache.org.
[OLINGO-190] V3 service document deserializer merged, V4 implemented


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

Branch: refs/heads/master
Commit: e624815544784ef9f1aa71b453bf1ca8cf901c24
Parents: 744a371
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Mar 7 15:27:15 2014 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Mar 7 15:27:15 2014 +0100

----------------------------------------------------------------------
 .../olingo/odata4/client/api/ODataClient.java   |  14 +-
 .../odata4/client/api/ODataConstants.java       | 219 +++++++
 .../odata4/client/api/data/EdmSimpleType.java   | 288 ---------
 .../client/api/data/ODataCollectionValue.java   |  98 ----
 .../client/api/data/ODataComplexValue.java      |  97 ----
 .../odata4/client/api/data/ODataDuration.java   |  80 ---
 .../client/api/data/ODataGeospatialValue.java   | 486 ----------------
 .../client/api/data/ODataInvokeResult.java      |  30 -
 .../client/api/data/ODataPrimitiveValue.java    | 376 ------------
 .../odata4/client/api/data/ODataProperty.java   | 192 ------
 .../odata4/client/api/data/ODataTimestamp.java  | 141 -----
 .../odata4/client/api/data/ODataValue.java      | 111 ----
 .../odata4/client/api/data/ServiceDocument.java | 139 +++++
 .../client/api/data/ServiceDocumentItem.java    |  30 +
 .../api/data/geospatial/ComposedGeospatial.java |  75 ---
 .../client/api/data/geospatial/Geospatial.java  | 156 -----
 .../data/geospatial/GeospatialCollection.java   |  47 --
 .../client/api/data/geospatial/LineString.java  |  38 --
 .../api/data/geospatial/MultiLineString.java    |  38 --
 .../client/api/data/geospatial/MultiPoint.java  |  38 --
 .../api/data/geospatial/MultiPolygon.java       |  38 --
 .../client/api/data/geospatial/Point.java       |  77 ---
 .../client/api/data/geospatial/Polygon.java     |  72 ---
 .../odata4/client/api/domain/EdmSimpleType.java | 288 +++++++++
 .../client/api/domain/ODataCollectionValue.java |  98 ++++
 .../client/api/domain/ODataComplexValue.java    |  97 ++++
 .../odata4/client/api/domain/ODataDuration.java |  80 +++
 .../client/api/domain/ODataGeospatialValue.java | 486 ++++++++++++++++
 .../client/api/domain/ODataInvokeResult.java    |  30 +
 .../client/api/domain/ODataPrimitiveValue.java  | 376 ++++++++++++
 .../odata4/client/api/domain/ODataProperty.java | 192 ++++++
 .../client/api/domain/ODataServiceDocument.java | 183 ++++++
 .../client/api/domain/ODataTimestamp.java       | 141 +++++
 .../odata4/client/api/domain/ODataValue.java    | 111 ++++
 .../domain/geospatial/ComposedGeospatial.java   |  75 +++
 .../api/domain/geospatial/Geospatial.java       | 156 +++++
 .../domain/geospatial/GeospatialCollection.java |  47 ++
 .../api/domain/geospatial/LineString.java       |  38 ++
 .../api/domain/geospatial/MultiLineString.java  |  38 ++
 .../api/domain/geospatial/MultiPoint.java       |  38 ++
 .../api/domain/geospatial/MultiPolygon.java     |  38 ++
 .../client/api/domain/geospatial/Point.java     |  77 +++
 .../client/api/domain/geospatial/Polygon.java   |  72 +++
 .../odata4/client/api/op/ODataBinder.java       | 121 ++++
 .../odata4/client/api/op/ODataDeserializer.java |   5 +-
 .../odata4/client/api/op/ODataReader.java       |   5 +-
 .../odata4/client/api/uri/SegmentType.java      |  55 ++
 .../odata4/client/api/utils/XMLUtils.java       |   4 +-
 .../odata4/client/core/AbstractODataClient.java |   4 +-
 .../odata4/client/core/ODataV3Client.java       |  19 +-
 .../odata4/client/core/ODataV4Client.java       |  19 +-
 .../core/data/AbstractServiceDocument.java      | 145 +++++
 .../data/JSONServiceDocumentDeserializer.java   |  82 +++
 .../core/data/ODataJacksonDeserializer.java     |  43 ++
 .../core/data/ODataJacksonSerializer.java       |  43 ++
 .../core/data/ServiceDocumentItemImpl.java      |  78 +++
 .../data/XMLServiceDocumentDeserializer.java    | 118 ++++
 .../core/data/v3/JSONServiceDocumentImpl.java   |  65 +++
 .../core/data/v3/XMLServiceDocumentImpl.java    |  46 ++
 .../core/data/v4/AbstractServiceDocument.java   |  88 +++
 .../core/data/v4/JSONServiceDocumentImpl.java   |  41 ++
 .../core/data/v4/XMLServiceDocumentImpl.java    |  28 +
 .../core/op/impl/AbstractODataBinder.java       | 581 +++++++++++++++++++
 .../client/core/op/impl/v3/ODataBinderImpl.java |  37 ++
 .../core/op/impl/v3/ODataDeserializerImpl.java  |  27 +-
 .../client/core/op/impl/v3/ODataReaderImpl.java |  12 +-
 .../client/core/op/impl/v4/ODataBinderImpl.java |  62 ++
 .../core/op/impl/v4/ODataDeserializerImpl.java  |  28 +-
 .../client/core/op/impl/v4/ODataReaderImpl.java |  12 +-
 .../olingo/odata4/client/core/uri/URIUtils.java | 195 +++++++
 .../odata4/client/core/v3/MetadataTest.java     |   4 +-
 .../client/core/v3/ServiceDocumentTest.java     |  57 ++
 .../client/core/v4/ServiceDocumentTest.java     |  67 +++
 .../odata4/client/core/v3/serviceDocument.json  |  33 ++
 .../odata4/client/core/v3/serviceDocument.xml   |  49 ++
 .../odata4/client/core/v4/serviceDocument.json  |  32 +
 .../odata4/client/core/v4/serviceDocument.xml   |  46 ++
 77 files changed, 5241 insertions(+), 2551 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/ODataClient.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/ODataClient.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/ODataClient.java
index 353d2d3..b101a8d 100644
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/ODataClient.java
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/ODataClient.java
@@ -18,6 +18,7 @@
  */
 package org.apache.olingo.odata4.client.api;
 
+import org.apache.olingo.odata4.client.api.op.ODataBinder;
 import org.apache.olingo.odata4.client.api.op.ODataDeserializer;
 import org.apache.olingo.odata4.client.api.op.ODataReader;
 import org.apache.olingo.odata4.client.api.op.ODataSerializer;
@@ -31,28 +32,21 @@ public interface ODataClient {
   Configuration getConfiguration();
 
 //  URIBuilder getURIBuilder(String serviceRoot);
-//
 //  FilterFactory getFilterFactory();
-//
   ODataSerializer getSerializer();
 //
+
   ODataDeserializer getDeserializer();
 
   ODataReader getReader();
 
 //  ODataWriter getWriter();
-//
-//  ODataBinder getBinder();
-//
+  ODataBinder getBinder();
+
 //  ODataObjectFactory getObjectFactory();
-//
 //  RetrieveRequestFactory getRetrieveRequestFactory();
-//
 //  CUDRequestFactory getCUDRequestFactory();
-//
 //  StreamedRequestFactory getStreamedRequestFactory();
-//
 //  InvokeRequestFactory<?, ?, ?, ?, ?, ?, ?, ?> getInvokeRequestFactory();
-//
 //  BatchRequestFactory getBatchRequestFactory();
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/ODataConstants.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/ODataConstants.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/ODataConstants.java
new file mode 100644
index 0000000..9c4b3ed
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/ODataConstants.java
@@ -0,0 +1,219 @@
+/*
+ * 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.odata4.client.api;
+
+import javax.xml.XMLConstants;
+
+/**
+ * Constant values related to the OData protocol.
+ */
+public class ODataConstants {
+
+  // Other stuff
+  public final static String UTF8 = "UTF-8";
+
+  public final static String NAME = "name";
+
+  public final static String PROPERTIES = "properties";
+
+  // XML namespaces and prefixes
+  public final static String NS_ATOM = "http://www.w3.org/2005/Atom";
+
+  public static final String NS_GEORSS = "http://www.georss.org/georss";
+
+  public static final String NS_GML = "http://www.opengis.net/gml";
+
+  public static final String XMLNS_DATASERVICES = XMLConstants.XMLNS_ATTRIBUTE + ":d";
+
+  public static final String PREFIX_DATASERVICES = "d:";
+
+  public static final String XMLNS_METADATA = XMLConstants.XMLNS_ATTRIBUTE + ":m";
+
+  public static final String PREFIX_METADATA = "m:";
+
+  public static final String XMLNS_GEORSS = XMLConstants.XMLNS_ATTRIBUTE + ":georss";
+
+  public static final String PREFIX_GEORSS = "georss:";
+
+  public static final String XMLNS_GML = XMLConstants.XMLNS_ATTRIBUTE + ":gml";
+
+  public static final String PREFIX_GML = "gml:";
+
+  /**
+   * Edit link rel value.
+   */
+  public static final String EDIT_LINK_REL = "edit";
+
+  /**
+   * Self link rel value.
+   */
+  public static final String SELF_LINK_REL = "self";
+
+  public static final String NEXT_LINK_REL = "next";
+
+  // XML elements and attributes
+  public static final String ELEM_PROPERTIES = PREFIX_METADATA + PROPERTIES;
+
+  public static final String ELEM_ELEMENT = "element";
+
+  public final static String ATTR_TYPE = "type";
+
+  public static final String ATTR_M_TYPE = PREFIX_METADATA + ATTR_TYPE;
+
+  public static final String ATTR_NULL = PREFIX_METADATA + "null";
+
+  public static final String ATTR_XMLBASE = "xml:base";
+
+  public static final String ATTR_REL = "rel";
+
+  public static final String ATTR_HREF = "href";
+
+  public static final String ATTR_METADATA = "metadata";
+
+  public static final String ATTR_TITLE = "title";
+
+  public static final String ATTR_TARGET = "target";
+
+  public static final String ELEM_COLLECTION = "collection";
+
+  public static final String ATTR_SRSNAME = PREFIX_GML + "srsName";
+
+  public static final String ELEM_POINT = PREFIX_GML + "Point";
+
+  public static final String ELEM_MULTIPOINT = PREFIX_GML + "MultiPoint";
+
+  public static final String ELEM_POINTMEMBERS = PREFIX_GML + "pointMembers";
+
+  public static final String ELEM_LINESTRING = PREFIX_GML + "LineString";
+
+  public static final String ELEM_MULTILINESTRING = PREFIX_GML + "MultiCurve";
+
+  public static final String ELEM_LINESTRINGMEMBERS = PREFIX_GML + "curveMembers";
+
+  public static final String ELEM_POLYGON = PREFIX_GML + "Polygon";
+
+  public static final String ELEM_POLYGON_EXTERIOR = PREFIX_GML + "exterior";
+
+  public static final String ELEM_POLYGON_INTERIOR = PREFIX_GML + "interior";
+
+  public static final String ELEM_POLYGON_LINEARRING = PREFIX_GML + "LinearRing";
+
+  public static final String ELEM_MULTIPOLYGON = PREFIX_GML + "MultiSurface";
+
+  public static final String ELEM_SURFACEMEMBERS = PREFIX_GML + "surfaceMembers";
+
+  public static final String ELEM_GEOCOLLECTION = PREFIX_GML + "MultiGeometry";
+
+  public static final String ELEM_GEOMEMBERS = PREFIX_GML + "geometryMembers";
+
+  public static final String ELEM_POS = PREFIX_GML + "pos";
+
+  public static final String ELEM_POSLIST = PREFIX_GML + "posList";
+
+  public static final String ELEM_PROPERTY = "property";
+
+  public static final String ELEM_URI = "uri";
+
+  // JSON stuff
+  public final static String JSON_CONTEXT = "@odata.context";
+
+  public final static String JSON_METADATA = "odata.metadata";
+
+  public final static String JSON_TYPE = "odata.type";
+
+  public final static String JSON_ETAG = "odata.etag";
+
+  public final static String JSON_MEDIA_ETAG = "odata.mediaETag";
+
+  public final static String JSON_ID = "odata.id";
+
+  public final static String JSON_READ_LINK = "odata.readLink";
+
+  public final static String JSON_EDIT_LINK = "odata.editLink";
+
+  public final static String JSON_MEDIAREAD_LINK = "odata.mediaReadLink";
+
+  public final static String JSON_MEDIAEDIT_LINK = "odata.mediaEditLink";
+
+  public final static String JSON_MEDIA_CONTENT_TYPE = "odata.mediaContentType";
+
+  public final static String JSON_NAVIGATION_LINK_SUFFIX = "@odata.navigationLinkUrl";
+
+  public final static String JSON_BIND_LINK_SUFFIX = "@odata.bind";
+
+  public final static String JSON_ASSOCIATION_LINK_SUFFIX = "@odata.associationLinkUrl";
+
+  public final static String JSON_MEDIAEDIT_LINK_SUFFIX = "@odata.mediaEditLink";
+
+  public final static String JSON_VALUE = "value";
+
+  public final static String JSON_URL = "url";
+
+  public final static String JSON_COORDINATES = "coordinates";
+
+  public final static String JSON_GEOMETRIES = "geometries";
+
+  public final static String JSON_CRS = "crs";
+
+  public final static String JSON_GIS_URLPREFIX = "http://www.opengis.net/def/crs/EPSG/0/";
+
+  // Atom stuff
+  public final static String ATOM_ELEM_ENTRY = "entry";
+
+  public final static String ATOM_ELEM_FEED = "feed";
+
+  public final static String ATOM_ELEM_CATEGORY = "category";
+
+  public final static String ATOM_ELEM_ID = "id";
+
+  public final static String ATOM_ELEM_LINK = "link";
+
+  public final static String ATOM_ELEM_CONTENT = "content";
+
+  public static final String ATOM_ELEM_TITLE = "title";
+
+  public static final String ATOM_ELEM_SUMMARY = "summary";
+
+  public static final String ATOM_ELEM_UPDATED = "updated";
+
+  public static final String ATOM_ELEM_AUTHOR = "author";
+
+  public static final String ATOM_ELEM_AUTHOR_NAME = "name";
+
+  public static final String ATOM_ELEM_AUTHOR_URI = "uri";
+
+  public static final String ATOM_ELEM_AUTHOR_EMAIL = "email";
+
+  public static final String ATOM_ELEM_ACTION = PREFIX_METADATA + "action";
+
+  public static final String ATOM_ELEM_INLINE = PREFIX_METADATA + "inline";
+
+  public static final String ATOM_ATTR_TITLE = "atom:title";
+
+  public static final String ATOM_ATTR_TERM = "term";
+
+  public static final String ATOM_ATTR_SCHEME = "scheme";
+
+  public static final String ATOM_ATTR_SRC = "src";
+
+  public static final String ATOM_ATTR_ETAG = PREFIX_METADATA + "etag";
+
+  public static final String ATOM_ATTR_COUNT = PREFIX_METADATA + "count";
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/EdmSimpleType.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/EdmSimpleType.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/EdmSimpleType.java
deleted file mode 100644
index 7d44c37..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/EdmSimpleType.java
+++ /dev/null
@@ -1,288 +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.odata4.client.api.data;
-
-import java.math.BigDecimal;
-import java.net.URI;
-import java.util.UUID;
-import org.apache.olingo.odata4.client.api.data.geospatial.Geospatial;
-import org.apache.olingo.odata4.client.api.data.geospatial.GeospatialCollection;
-import org.apache.olingo.odata4.client.api.data.geospatial.LineString;
-import org.apache.olingo.odata4.client.api.data.geospatial.MultiLineString;
-import org.apache.olingo.odata4.client.api.data.geospatial.MultiPoint;
-import org.apache.olingo.odata4.client.api.data.geospatial.MultiPolygon;
-import org.apache.olingo.odata4.client.api.data.geospatial.Point;
-import org.apache.olingo.odata4.client.api.data.geospatial.Polygon;
-import org.apache.olingo.odata4.commons.api.edm.constants.ODataServiceVersion;
-
-/**
- * Represent the primitive types of the Entity Data Model (EDM).
- *
- * @see http://dl.windowsazure.com/javadoc/com/microsoft/windowsazure/services/table/models/EdmType.html
- * <p>
- * For an overview of the available EDM primitive data types and names, see the <a
- * href="http://www.odata.org/developers/protocols/overview#AbstractTypeSystem">Primitive Data Types</a> section of the
- * <a href="http://www.odata.org/developers/protocols/overview">OData Protocol Overview</a>.
- * </p>
- * <p>
- * The Abstract Type System used to define the primitive types supported by OData is defined in detail in <a
- * href="http://msdn.microsoft.com/en-us/library/dd541474.aspx">[MC-CSDL] (section 2.2.1).</a>
- * </p>
- */
-public enum EdmSimpleType {
-
-  /**
-   * The absence of a value.
-   */
-  Null(Void.class),
-  /**
-   * An array of bytes.
-   */
-  Binary(byte[].class),
-  /**
-   * A Boolean value.
-   */
-  Boolean(Boolean.class),
-  /**
-   * Unsigned 8-bit integer value.
-   */
-  Byte(Integer.class),
-  /**
-   * A signed 8-bit integer value.
-   */
-  SByte(Byte.class),
-  /**
-   * A 64-bit value expressed as Coordinated Universal Time (UTC).
-   */
-  DateTime(new ODataServiceVersion[]{ODataServiceVersion.V30}, ODataTimestamp.class, "yyyy-MM-dd'T'HH:mm:ss"),
-  /**
-   * Date without a time-zone offset.
-   */
-  Date(new ODataServiceVersion[]{ODataServiceVersion.V40}, ODataTimestamp.class, "yyyy-MM-dd"),
-  /**
-   * Date and time as an Offset in minutes from GMT.
-   */
-  DateTimeOffset(ODataTimestamp.class, "yyyy-MM-dd'T'HH:mm:ss"),
-  /**
-   * The time of day with values ranging from 0:00:00.x to 23:59:59.y, where x and y depend upon the precision.
-   */
-  Time(new ODataServiceVersion[]{ODataServiceVersion.V30}, ODataDuration.class),
-  /**
-   * The time of day with values ranging from 0:00:00.x to 23:59:59.y, where x and y depend upon the precision.
-   */
-  TimeOfDay(new ODataServiceVersion[]{ODataServiceVersion.V40}, ODataDuration.class),
-  /**
-   * Signed duration in days, hours, minutes, and (sub)seconds.
-   */
-  Duration(new ODataServiceVersion[]{ODataServiceVersion.V40}, ODataDuration.class),
-  /**
-   * Numeric values with fixed precision and scale.
-   */
-  Decimal(BigDecimal.class, "#.#######################"),
-  /**
-   * A floating point number with 7 digits precision.
-   */
-  Single(Float.class, "#.#######E0"),
-  /**
-   * A 64-bit double-precision floating point value.
-   */
-  Double(Double.class, "#.#######################E0"),
-  // --- Geospatial ---
-  Geography(Geospatial.class),
-  GeographyPoint(Point.class),
-  GeographyLineString(LineString.class),
-  GeographyPolygon(Polygon.class),
-  GeographyMultiPoint(MultiPoint.class),
-  GeographyMultiLineString(MultiLineString.class),
-  GeographyMultiPolygon(MultiPolygon.class),
-  GeographyCollection(GeospatialCollection.class),
-  Geometry(Geospatial.class),
-  GeometryPoint(Point.class),
-  GeometryLineString(LineString.class),
-  GeometryPolygon(Polygon.class),
-  GeometryMultiPoint(MultiPoint.class),
-  GeometryMultiLineString(MultiLineString.class),
-  GeometryMultiPolygon(MultiPolygon.class),
-  GeometryCollection(GeospatialCollection.class),
-  /**
-   * A 128-bit globally unique identifier.
-   */
-  Guid(UUID.class),
-  /**
-   * A 16-bit integer value.
-   */
-  Int16(Short.class),
-  /**
-   * A 32-bit integer value.
-   */
-  Int32(Integer.class),
-  /**
-   * A 64-bit integer value.
-   */
-  Int64(Long.class),
-  /**
-   * A UTF-16-encoded value. String values may be up to 64 KB in size.
-   */
-  String(String.class),
-  /**
-   * Resource stream (for media entities).
-   */
-  Stream(URI.class);
-
-  private final Class<?> clazz;
-
-  private final String pattern;
-
-  private final ODataServiceVersion[] versions;
-
-  /**
-   * Constructor (all OData versions).
-   *
-   * @param clazz type.
-   */
-  EdmSimpleType(final Class<?> clazz) {
-    this(ODataServiceVersion.values(), clazz, null);
-  }
-
-  /**
-   * Constructor.
-   *
-   * @param versions supported OData versions.
-   * @param clazz type.
-   */
-  EdmSimpleType(final ODataServiceVersion[] versions, final Class<?> clazz) {
-    this(versions, clazz, null);
-  }
-
-  /**
-   * Constructor (all OData versions).
-   *
-   * @param clazz type.
-   * @param pattern pattern.
-   */
-  EdmSimpleType(final Class<?> clazz, final String pattern) {
-    this(ODataServiceVersion.values(), clazz, pattern);
-  }
-
-  /**
-   * Constructor.
-   *
-   * @param versions supported OData versions.
-   * @param clazz type.
-   * @param pattern pattern.
-   */
-  EdmSimpleType(final ODataServiceVersion[] versions, final Class<?> clazz, final String pattern) {
-    this.clazz = clazz;
-    this.pattern = pattern;
-    this.versions = versions.clone();
-  }
-
-  /**
-   * Gets pattern.
-   *
-   * @return pattern.
-   */
-  public String pattern() {
-    return pattern;
-  }
-
-  /**
-   * Gets corresponding java type.
-   *
-   * @return java type.
-   */
-  public Class<?> javaType() {
-    return this.clazz;
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public String toString() {
-    return namespace() + "." + name();
-  }
-
-  /**
-   * Checks if is a geospatial type.
-   *
-   * @return <tt>true</tt> if is geospatial type; <tt>false</tt> otherwise.
-   */
-  public boolean isGeospatial() {
-    return name().startsWith("Geo");
-  }
-
-  /**
-   * Checks if the given type is a geospatial type.
-   *
-   * @param type type.
-   * @return <tt>true</tt> if is geospatial type; <tt>false</tt> otherwise.
-   */
-  public static boolean isGeospatial(final String type) {
-    return type != null && type.startsWith(namespace() + ".Geo");
-  }
-
-  /**
-   * Gets <tt>EdmSimpleType</tt> from string.
-   *
-   * @param value string value type.
-   * @return <tt>EdmSimpleType</tt> object.
-   */
-  public static EdmSimpleType fromValue(final String value) {
-    final String noNsValue = value.substring(4);
-    for (EdmSimpleType edmSimpleType : EdmSimpleType.values()) {
-      if (edmSimpleType.name().equals(noNsValue)) {
-        return edmSimpleType;
-      }
-    }
-    throw new IllegalArgumentException(value);
-  }
-
-  /**
-   * Gets <tt>EdmSimpleType</tt> from object instance.
-   *
-   * @param workingVersion OData version.
-   * @param obj object.
-   * @return <tt>EdmSimpleType</tt> object.
-   */
-  public static EdmSimpleType fromObject(final ODataServiceVersion workingVersion, final Object obj) {
-    for (EdmSimpleType edmSimpleType : EdmSimpleType.values()) {
-      if (edmSimpleType.javaType().equals(obj.getClass())) {
-        return edmSimpleType == DateTimeOffset || edmSimpleType == DateTime || edmSimpleType == Date
-                ? ((ODataTimestamp) obj).isOffset()
-                ? DateTimeOffset : workingVersion == ODataServiceVersion.V30 ? DateTime : Date
-                : edmSimpleType;
-      }
-    }
-    throw new IllegalArgumentException(obj.getClass().getSimpleName() + " is not a simple type");
-  }
-
-  /**
-   * Gets namespace.
-   *
-   * @return namespace.
-   */
-  public static String namespace() {
-    return "Edm";
-  }
-
-  public ODataServiceVersion[] getSupportedVersions() {
-    return versions.clone();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataCollectionValue.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataCollectionValue.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataCollectionValue.java
deleted file mode 100644
index 2d94b2e..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataCollectionValue.java
+++ /dev/null
@@ -1,98 +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.odata4.client.api.data;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * OData collection property value.
- */
-public class ODataCollectionValue extends ODataValue implements Iterable<ODataValue> {
-
-  private static final long serialVersionUID = -3665659846001987187L;
-
-  /**
-   * Type name;
-   */
-  private final String typeName;
-
-  /**
-   * Values.
-   */
-  private final List<ODataValue> values = new ArrayList<ODataValue>();
-
-  /**
-   * Constructor.
-   *
-   * @param typeName type name.
-   */
-  public ODataCollectionValue(final String typeName) {
-    this.typeName = typeName;
-  }
-
-  /**
-   * Adds a value to the collection.
-   *
-   * @param value value to be added.
-   */
-  public void add(final ODataValue value) {
-    if (value.isPrimitive() || value.isComplex()) {
-      values.add(value);
-    }
-  }
-
-  /**
-   * Value iterator.
-   *
-   * @return value iterator.
-   */
-  @Override
-  public Iterator<ODataValue> iterator() {
-    return values.iterator();
-  }
-
-  /**
-   * Gets value type name.
-   *
-   * @return value type name.
-   */
-  public String getTypeName() {
-    return typeName;
-  }
-
-  /**
-   * Gets collection size.
-   *
-   * @return collection size.
-   */
-  public int size() {
-    return values.size();
-  }
-
-  /**
-   * Checks if collection is empty.
-   *
-   * @return 'TRUE' if empty; 'FALSE' otherwise.
-   */
-  public boolean isEmpty() {
-    return values.isEmpty();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataComplexValue.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataComplexValue.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataComplexValue.java
deleted file mode 100644
index 3633e34..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataComplexValue.java
+++ /dev/null
@@ -1,97 +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.odata4.client.api.data;
-
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * OData complex property value.
- */
-public class ODataComplexValue extends ODataValue implements Iterable<ODataProperty> {
-
-  private static final long serialVersionUID = -1878555027714020431L;
-
-  /**
-   * Type name.
-   */
-  private final String typeName;
-
-  /**
-   * Complex type fields.
-   */
-  private final Map<String, ODataProperty> fields = new LinkedHashMap<String, ODataProperty>();
-
-  /**
-   * Constructor.
-   *
-   * @param typeName type name.
-   */
-  public ODataComplexValue(final String typeName) {
-    this.typeName = typeName;
-  }
-
-  /**
-   * Adds field to the complex type.
-   *
-   * @param field field to be added.
-   */
-  public void add(final ODataProperty field) {
-    fields.put(field.getName(), field);
-  }
-
-  /**
-   * Gets field.
-   *
-   * @param name name of the field to be retrieved.
-   * @return requested field.
-   */
-  public ODataProperty get(final String name) {
-    return fields.get(name);
-  }
-
-  /**
-   * Complex property fields iterator.
-   *
-   * @return fields iterator.
-   */
-  @Override
-  public Iterator<ODataProperty> iterator() {
-    return fields.values().iterator();
-  }
-
-  /**
-   * Gest value type name.
-   *
-   * @return value type name.
-   */
-  public String getTypeName() {
-    return typeName;
-  }
-
-  /**
-   * Gets number of fields.
-   *
-   * @return number of fields.
-   */
-  public int size() {
-    return fields.size();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataDuration.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataDuration.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataDuration.java
deleted file mode 100644
index a04171b..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataDuration.java
+++ /dev/null
@@ -1,80 +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.odata4.client.api.data;
-
-import java.io.Serializable;
-import javax.xml.datatype.DatatypeConfigurationException;
-import javax.xml.datatype.DatatypeFactory;
-import javax.xml.datatype.Duration;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-
-/**
- * Helper class for handling time (as duration) primitive values.
- *
- * @see com.msopentech.odatajclient.engine.data.metadata.edm.EdmSimpleType#TIME
- * @see Duration
- */
-public final class ODataDuration implements Serializable {
-
-  private static final long serialVersionUID = 778404231943967899L;
-
-  private final Duration duration;
-
-  public ODataDuration(final String input) {
-    try {
-      final DatatypeFactory dtFactory = DatatypeFactory.newInstance();
-      this.duration = dtFactory.newDuration(input);
-    } catch (DatatypeConfigurationException e) {
-      throw new IllegalArgumentException("Could not parse '" + input + "' as Duration", e);
-    }
-  }
-
-  public ODataDuration(final Duration duration) {
-    this.duration = duration;
-  }
-
-  public Duration getDuration() {
-    return duration;
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public boolean equals(final Object obj) {
-    return EqualsBuilder.reflectionEquals(this, obj);
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public int hashCode() {
-    return HashCodeBuilder.reflectionHashCode(this);
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public String toString() {
-    return this.duration.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataGeospatialValue.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataGeospatialValue.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataGeospatialValue.java
deleted file mode 100644
index 116c307..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataGeospatialValue.java
+++ /dev/null
@@ -1,486 +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.odata4.client.api.data;
-
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.ParserConfigurationException;
-import org.apache.olingo.odata4.client.api.Constants;
-import org.apache.olingo.odata4.client.api.ODataClient;
-import org.apache.olingo.odata4.client.api.data.geospatial.Geospatial;
-import org.apache.olingo.odata4.client.api.data.geospatial.GeospatialCollection;
-import org.apache.olingo.odata4.client.api.data.geospatial.LineString;
-import org.apache.olingo.odata4.client.api.data.geospatial.MultiLineString;
-import org.apache.olingo.odata4.client.api.data.geospatial.MultiPoint;
-import org.apache.olingo.odata4.client.api.data.geospatial.MultiPolygon;
-import org.apache.olingo.odata4.client.api.data.geospatial.Point;
-import org.apache.olingo.odata4.client.api.data.geospatial.Polygon;
-import org.apache.olingo.odata4.client.api.utils.XMLUtils;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-public class ODataGeospatialValue extends ODataPrimitiveValue {
-
-  private static final long serialVersionUID = -3984105137562291082L;
-
-  /**
-   * Geospatial value builder.
-   */
-  public static class Builder extends AbstractBuilder {
-
-    private final ODataGeospatialValue ogv;
-
-    /**
-     * Constructor.
-     */
-    public Builder(final ODataClient client) {
-      super(client);
-      this.ogv = new ODataGeospatialValue(client);
-    }
-
-    /**
-     * Sets the given value provided as a DOM tree.
-     *
-     * @param tree value.
-     * @return the current builder.
-     */
-    public Builder setTree(final Element tree) {
-      this.ogv.tree = tree;
-      return this;
-    }
-
-    /**
-     * Sets the actual object value.
-     *
-     * @param value value.
-     * @return the current builder.
-     */
-    public <T extends Geospatial> Builder setValue(final T value) {
-      this.ogv.value = value;
-      return this;
-    }
-
-    /**
-     * Sets actual value type.
-     *
-     * @param type type.
-     * @return the current builder.
-     */
-    public Builder setType(final EdmSimpleType type) {
-      isSupported(type);
-
-      if (!type.isGeospatial()) {
-        throw new IllegalArgumentException(
-                "Use " + ODataPrimitiveValue.class.getSimpleName() + " for non-geospatial types");
-      }
-
-      if (type == EdmSimpleType.Geography || type == EdmSimpleType.Geometry) {
-        throw new IllegalArgumentException(
-                type + "is not an instantiable type. "
-                + "An entity can declare a property to be of type Geometry. "
-                + "An instance of an entity MUST NOT have a value of type Geometry. "
-                + "Each value MUST be of some subtype.");
-      }
-      this.ogv.type = type;
-      return this;
-    }
-
-    /**
-     * Builds the geospatial value.
-     *
-     * @return <tt>ODataGeospatialValue</tt> object.
-     */
-    public ODataGeospatialValue build() {
-      if (this.ogv.tree == null && this.ogv.value == null) {
-        throw new IllegalArgumentException("Must provide either tree or value");
-      }
-      if (this.ogv.tree != null && this.ogv.value != null) {
-        throw new IllegalArgumentException("Cannot provide both tree and value");
-      }
-
-      if (this.ogv.type == null) {
-        throw new IllegalArgumentException("Must provide geospatial type");
-      }
-
-      if (this.ogv.tree != null) {
-        this.ogv.value = this.ogv.parseTree(this.ogv.tree, this.ogv.type);
-      }
-      if (this.ogv.value != null) {
-        this.ogv.tree = this.ogv.parseGeospatial((Geospatial) this.ogv.value);
-      }
-
-      return this.ogv;
-    }
-  }
-
-  /**
-   * DOM tree.
-   */
-  private Element tree;
-
-  /**
-   * Protected constructor, need to use the builder to instantiate this class.
-   *
-   * @see Builder
-   */
-  protected ODataGeospatialValue(final ODataClient client) {
-    super(client);
-  }
-
-  private Geospatial.Dimension getDimension() {
-    Geospatial.Dimension dimension;
-
-    switch (this.type) {
-      case Geography:
-      case GeographyCollection:
-      case GeographyLineString:
-      case GeographyMultiLineString:
-      case GeographyPoint:
-      case GeographyMultiPoint:
-      case GeographyPolygon:
-      case GeographyMultiPolygon:
-        dimension = Geospatial.Dimension.GEOGRAPHY;
-        break;
-
-      default:
-        dimension = Geospatial.Dimension.GEOMETRY;
-    }
-
-    return dimension;
-  }
-
-  private List<Point> parsePoints(final NodeList posList) {
-    final List<Point> result = new ArrayList<Point>();
-    for (int i = 0; i < posList.getLength(); i++) {
-      final String[] pointInfo = posList.item(i).getTextContent().split(" ");
-      final Point point = new Point(getDimension());
-      point.setX(Double.valueOf(pointInfo[0]));
-      point.setY(Double.valueOf(pointInfo[1]));
-
-      result.add(point);
-    }
-    return result;
-  }
-
-  private LineString parseLineString(final Element element) {
-    return new LineString(getDimension(),
-            parsePoints(element.getElementsByTagName(Constants.ELEM_POS)));
-  }
-
-  private Polygon parsePolygon(final Element element) {
-    List<Point> extPoints = null;
-    final Element exterior
-            = (Element) element.getElementsByTagName(Constants.ELEM_POLYGON_EXTERIOR).item(0);
-    if (exterior != null) {
-      extPoints = parsePoints(
-              ((Element) exterior.getElementsByTagName(Constants.ELEM_POLYGON_LINEARRING).item(0)).
-              getElementsByTagName(Constants.ELEM_POS));
-    }
-    List<Point> intPoints = null;
-    final Element interior
-            = (Element) element.getElementsByTagName(Constants.ELEM_POLYGON_INTERIOR).item(0);
-    if (interior != null) {
-      intPoints = parsePoints(
-              ((Element) interior.getElementsByTagName(Constants.ELEM_POLYGON_LINEARRING).item(0)).
-              getElementsByTagName(Constants.ELEM_POS));
-    }
-
-    return new Polygon(getDimension(), intPoints, extPoints);
-  }
-
-  /**
-   * Parses given tree as geospatial value.
-   */
-  private Geospatial parseTree(final Element tree, final EdmSimpleType type) {
-    Geospatial value;
-
-    switch (type) {
-      case GeographyPoint:
-      case GeometryPoint:
-        value = parsePoints(tree.getElementsByTagName(Constants.ELEM_POS)).get(0);
-        break;
-
-      case GeographyMultiPoint:
-      case GeometryMultiPoint:
-        final Element pMembs
-                = (Element) tree.getElementsByTagName(Constants.ELEM_POINTMEMBERS).item(0);
-        final List<Point> points = pMembs == null
-                ? Collections.<Point>emptyList()
-                : parsePoints(pMembs.getElementsByTagName(Constants.ELEM_POS));
-        value = new MultiPoint(getDimension(), points);
-        break;
-
-      case GeographyLineString:
-      case GeometryLineString:
-        value = parseLineString(tree);
-        break;
-
-      case GeographyMultiLineString:
-      case GeometryMultiLineString:
-        final Element mlMembs
-                = (Element) tree.getElementsByTagName(Constants.ELEM_LINESTRINGMEMBERS).item(0);
-        final List<LineString> lineStrings;
-        if (mlMembs == null) {
-          lineStrings = Collections.<LineString>emptyList();
-        } else {
-          lineStrings = new ArrayList<LineString>();
-          final NodeList lineStringNodes = mlMembs.getElementsByTagName(Constants.ELEM_LINESTRING);
-          for (int i = 0; i < lineStringNodes.getLength(); i++) {
-            lineStrings.add(parseLineString((Element) lineStringNodes.item(i)));
-          }
-        }
-        value = new MultiLineString(getDimension(), lineStrings);
-        break;
-
-      case GeographyPolygon:
-      case GeometryPolygon:
-        value = parsePolygon(tree);
-        break;
-
-      case GeographyMultiPolygon:
-      case GeometryMultiPolygon:
-        final Element mpMembs
-                = (Element) tree.getElementsByTagName(Constants.ELEM_SURFACEMEMBERS).item(0);
-        final List<Polygon> polygons;
-        if (mpMembs == null) {
-          polygons = Collections.<Polygon>emptyList();
-        } else {
-          polygons = new ArrayList<Polygon>();
-          final NodeList polygonNodes = mpMembs.getElementsByTagName(Constants.ELEM_POLYGON);
-          for (int i = 0; i < polygonNodes.getLength(); i++) {
-            polygons.add(parsePolygon((Element) polygonNodes.item(i)));
-          }
-        }
-        value = new MultiPolygon(getDimension(), polygons);
-        break;
-
-      case GeographyCollection:
-      case GeometryCollection:
-        final Element cMembs
-                = (Element) tree.getElementsByTagName(Constants.ELEM_GEOMEMBERS).item(0);
-        final List<Geospatial> geospatials;
-        if (cMembs == null) {
-          geospatials = Collections.<Geospatial>emptyList();
-        } else {
-          geospatials = new ArrayList<Geospatial>();
-          for (Node geom : XMLUtils.getChildNodes(cMembs, Node.ELEMENT_NODE)) {
-            geospatials.add(parseTree((Element) geom, XMLUtils.simpleTypeForNode(getDimension(), geom)));
-          }
-        }
-        value = new GeospatialCollection(getDimension(), geospatials);
-        break;
-
-      default:
-        value = null;
-    }
-
-    return value;
-  }
-
-  private void parsePoints(final Element parent, final Iterator<Point> itor, final boolean wrap) {
-    while (itor.hasNext()) {
-      final Point point = itor.next();
-
-      final Element pos = parent.getOwnerDocument().
-              createElementNS(Constants.NS_GML, Constants.ELEM_POS);
-      pos.appendChild(parent.getOwnerDocument().createTextNode(
-              Double.toString(point.getX()) + " " + point.getY()));
-
-      final Element appendable;
-      if (wrap) {
-        final Element epoint = parent.getOwnerDocument().
-                createElementNS(Constants.NS_GML, Constants.ELEM_POINT);
-        parent.appendChild(epoint);
-        appendable = epoint;
-      } else {
-        appendable = parent;
-      }
-      appendable.appendChild(pos);
-    }
-  }
-
-  private void parseLineStrings(final Element parent, final Iterator<LineString> itor, final boolean wrap) {
-    while (itor.hasNext()) {
-      final LineString lineString = itor.next();
-
-      final Element appendable;
-      if (wrap) {
-        final Element eLineString = parent.getOwnerDocument().
-                createElementNS(Constants.NS_GML, Constants.ELEM_LINESTRING);
-        parent.appendChild(eLineString);
-        appendable = eLineString;
-      } else {
-        appendable = parent;
-      }
-      parsePoints(appendable, lineString.iterator(), false);
-    }
-  }
-
-  private void parsePolygons(final Element parent, final Iterator<Polygon> itor, final boolean wrap) {
-    while (itor.hasNext()) {
-      final Polygon polygon = itor.next();
-
-      final Element appendable;
-      if (wrap) {
-        final Element ePolygon = parent.getOwnerDocument().createElementNS(
-                Constants.NS_GML, Constants.ELEM_POLYGON);
-        parent.appendChild(ePolygon);
-        appendable = ePolygon;
-      } else {
-        appendable = parent;
-      }
-
-      if (!polygon.getExterior().isEmpty()) {
-        final Element exterior = parent.getOwnerDocument().createElementNS(
-                Constants.NS_GML, Constants.ELEM_POLYGON_EXTERIOR);
-        appendable.appendChild(exterior);
-        final Element linearRing = parent.getOwnerDocument().createElementNS(
-                Constants.NS_GML, Constants.ELEM_POLYGON_LINEARRING);
-        exterior.appendChild(linearRing);
-
-        parsePoints(linearRing, polygon.getExterior().iterator(), false);
-      }
-      if (!polygon.getInterior().isEmpty()) {
-        final Element interior = parent.getOwnerDocument().createElementNS(
-                Constants.NS_GML, Constants.ELEM_POLYGON_INTERIOR);
-        appendable.appendChild(interior);
-        final Element linearRing = parent.getOwnerDocument().createElementNS(
-                Constants.NS_GML, Constants.ELEM_POLYGON_LINEARRING);
-        interior.appendChild(linearRing);
-
-        parsePoints(linearRing, polygon.getInterior().iterator(), false);
-      }
-    }
-  }
-
-  private Element parseGeospatial(final Geospatial value) {
-    final DocumentBuilder builder;
-    try {
-      builder = XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder();
-    } catch (ParserConfigurationException e) {
-      throw new IllegalStateException("Failure initializing Geospatial DOM tree", e);
-    }
-    final Document doc = builder.newDocument();
-
-    final Element tree;
-
-    switch (value.getEdmSimpleType()) {
-      case GeographyPoint:
-      case GeometryPoint:
-        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_POINT);
-
-        parsePoints(tree, Collections.singleton((Point) value).iterator(), false);
-        break;
-
-      case GeometryMultiPoint:
-      case GeographyMultiPoint:
-        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_MULTIPOINT);
-
-        final Element pMembs = doc.createElementNS(Constants.NS_GML, Constants.ELEM_POINTMEMBERS);
-        tree.appendChild(pMembs);
-
-        parsePoints(pMembs, ((MultiPoint) value).iterator(), true);
-        break;
-
-      case GeometryLineString:
-      case GeographyLineString:
-        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_LINESTRING);
-
-        parseLineStrings(tree, Collections.singleton((LineString) value).iterator(), false);
-        break;
-
-      case GeometryMultiLineString:
-      case GeographyMultiLineString:
-        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_MULTILINESTRING);
-
-        final Element mlMembs
-                = doc.createElementNS(Constants.NS_GML, Constants.ELEM_LINESTRINGMEMBERS);
-        tree.appendChild(mlMembs);
-
-        parseLineStrings(mlMembs, ((MultiLineString) value).iterator(), true);
-        break;
-
-      case GeographyPolygon:
-      case GeometryPolygon:
-        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_POLYGON);
-        parsePolygons(tree, Collections.singleton(((Polygon) value)).iterator(), false);
-        break;
-
-      case GeographyMultiPolygon:
-      case GeometryMultiPolygon:
-        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_MULTIPOLYGON);
-
-        final Element mpMembs
-                = doc.createElementNS(Constants.NS_GML, Constants.ELEM_SURFACEMEMBERS);
-        tree.appendChild(mpMembs);
-
-        parsePolygons(mpMembs, ((MultiPolygon) value).iterator(), true);
-        break;
-
-      case GeographyCollection:
-      case GeometryCollection:
-        tree = doc.createElementNS(Constants.NS_GML, Constants.ELEM_GEOCOLLECTION);
-
-        final Element gMembs
-                = doc.createElementNS(Constants.NS_GML, Constants.ELEM_GEOMEMBERS);
-        tree.appendChild(gMembs);
-
-        final Iterator<Geospatial> itor = ((GeospatialCollection) value).iterator();
-        while (itor.hasNext()) {
-          final Geospatial geospatial = itor.next();
-          gMembs.appendChild(doc.importNode(parseGeospatial(geospatial), true));
-        }
-        break;
-
-      default:
-        tree = null;
-    }
-
-    return tree;
-  }
-
-  public Element toTree() {
-    return this.tree;
-  }
-
-  @Override
-  public boolean equals(final Object obj) {
-    if (obj == null) {
-      return false;
-    }
-    if (getClass() != obj.getClass()) {
-      return false;
-    }
-    final ODataGeospatialValue other = (ODataGeospatialValue) obj;
-    return this.tree.isEqualNode(other.tree);
-  }
-
-  @Override
-  public String toString() {
-    final StringWriter writer = new StringWriter();
-    client.getSerializer().dom(this.tree, writer);
-    return writer.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataInvokeResult.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataInvokeResult.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataInvokeResult.java
deleted file mode 100644
index af429f8..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataInvokeResult.java
+++ /dev/null
@@ -1,30 +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.odata4.client.api.data;
-
-/**
- * Marker interface for any OData domain object that can be returned by an operation invocation.
- *
- * @see ODataEntitySet
- * @see ODataEntity
- * @see ODataProperty
- * @see ODataNoContent
- */
-public interface ODataInvokeResult {
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataPrimitiveValue.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataPrimitiveValue.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataPrimitiveValue.java
deleted file mode 100644
index 4f7c674..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataPrimitiveValue.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.olingo.odata4.client.api.data;
-
-import java.math.BigDecimal;
-import java.net.URI;
-import java.sql.Timestamp;
-import java.text.DecimalFormat;
-import java.util.Date;
-import java.util.UUID;
-import javax.xml.datatype.Duration;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.odata4.client.api.ODataClient;
-import org.apache.olingo.odata4.client.api.data.EdmSimpleType;
-import org.apache.olingo.odata4.client.api.data.ODataDuration;
-import org.apache.olingo.odata4.client.api.data.ODataTimestamp;
-import org.apache.olingo.odata4.client.api.data.ODataValue;
-
-/**
- * OData primitive property value.
- */
-public class ODataPrimitiveValue extends ODataValue {
-
-  private static final long serialVersionUID = 2841837627899878223L;
-
-  protected abstract static class AbstractBuilder {
-
-    private final ODataClient client;
-
-    /**
-     * Constructor.
-     */
-    public AbstractBuilder(final ODataClient client) {
-      this.client = client;
-    }
-
-    public AbstractBuilder isSupported(final EdmSimpleType type) {
-      if (type != null && !ArrayUtils.contains(type.getSupportedVersions(), client.getServiceVersion())) {
-        throw new IllegalArgumentException(String.format(
-                "Type %s not supported by the current OData working version", type.toString()));
-      }
-
-      return this;
-    }
-  }
-
-  /**
-   * Primitive value builder.
-   */
-  public static class Builder extends AbstractBuilder {
-
-    private final ODataPrimitiveValue opv;
-
-    /**
-     * Constructor.
-     */
-    public Builder(final ODataClient client) {
-      super(client);
-      this.opv = new ODataPrimitiveValue(client);
-    }
-
-    /**
-     * Sets the given value provided as a text.
-     *
-     * @param text value.
-     * @return the current builder.
-     */
-    public Builder setText(final String text) {
-      this.opv.text = text;
-      return this;
-    }
-
-    /**
-     * Sets the actual object value.
-     *
-     * @param value value.
-     * @return the current builder.
-     */
-    public Builder setValue(final Object value) {
-      this.opv.value = value;
-      return this;
-    }
-
-    /**
-     * Sets actual value type.
-     *
-     * @param type type.
-     * @return the current builder.
-     */
-    public Builder setType(final EdmSimpleType type) {
-      isSupported(type);
-
-      if (type == EdmSimpleType.Stream) {
-        throw new IllegalArgumentException(String.format(
-                "Cannot build a primitive value for %s", EdmSimpleType.Stream.toString()));
-      }
-
-      this.opv.type = type;
-      return this;
-    }
-
-    /**
-     * Builds the primitive value.
-     *
-     * @return <code>ODataPrimitiveValue</code> object.
-     */
-    public ODataPrimitiveValue build() {
-      if (this.opv.text == null && this.opv.value == null) {
-        throw new IllegalArgumentException("Must provide either text or value");
-      }
-      if (this.opv.text != null && this.opv.value != null) {
-        throw new IllegalArgumentException("Cannot provide both text and value");
-      }
-
-      if (this.opv.type == null) {
-        this.opv.type = EdmSimpleType.String;
-      }
-
-      if (this.opv.type.isGeospatial()) {
-        throw new IllegalArgumentException(
-                "Use " + ODataGeospatialValue.class.getSimpleName() + " for geospatial types");
-      }
-
-      if (this.opv.value instanceof Timestamp) {
-        this.opv.value = ODataTimestamp.getInstance(this.opv.type, (Timestamp) this.opv.value);
-      } else if (this.opv.value instanceof Date) {
-        this.opv.value = ODataTimestamp.getInstance(this.opv.type,
-                new Timestamp(((Date) this.opv.value).getTime()));
-      }
-      if (this.opv.value instanceof Duration) {
-        this.opv.value = new ODataDuration((Duration) this.opv.value);
-      }
-
-      if (this.opv.value != null && !this.opv.type.javaType().isAssignableFrom(this.opv.value.getClass())) {
-        throw new IllegalArgumentException("Provided value is not compatible with " + this.opv.type.toString());
-      }
-
-      if (this.opv.text != null) {
-        this.opv.parseText();
-      }
-      if (this.opv.value != null) {
-        this.opv.formatValue();
-      }
-
-      return this.opv;
-    }
-  }
-
-  protected ODataClient client;
-
-  /**
-   * Text value.
-   */
-  private String text;
-
-  /**
-   * Actual value.
-   */
-  protected Object value;
-
-  /**
-   * Value type.
-   */
-  protected EdmSimpleType type;
-
-  /**
-   * Protected constructor, need to use the builder to instantiate this class.
-   *
-   * @see Builder
-   */
-  protected ODataPrimitiveValue(final ODataClient client) {
-    super();
-    this.client = client;
-  }
-
-  /**
-   * Parses given text as object value.
-   */
-  private void parseText() {
-    switch (this.type) {
-      case Null:
-        this.value = null;
-        break;
-
-      case Binary:
-        this.value = Base64.decodeBase64(this.toString());
-        break;
-
-      case SByte:
-        this.value = Byte.parseByte(this.toString());
-        break;
-
-      case Boolean:
-        this.value = Boolean.parseBoolean(this.toString());
-        break;
-
-      case Date:
-      case DateTime:
-      case DateTimeOffset:
-        this.value = ODataTimestamp.parse(this.type, this.toString());
-        break;
-
-      case Time:
-      case TimeOfDay:
-        this.value = new ODataDuration(this.toString());
-        break;
-
-      case Decimal:
-        this.value = new BigDecimal(this.toString());
-        break;
-
-      case Single:
-        this.value = Float.parseFloat(this.toString());
-        break;
-
-      case Double:
-        this.value = Double.parseDouble(this.toString());
-        break;
-
-      case Guid:
-        this.value = UUID.fromString(this.toString());
-        break;
-
-      case Int16:
-        this.value = Short.parseShort(this.toString());
-        break;
-
-      case Byte:
-      case Int32:
-        this.value = Integer.parseInt(this.toString());
-        break;
-
-      case Int64:
-        this.value = Long.parseLong(this.toString());
-        break;
-
-      case Stream:
-        this.value = URI.create(this.toString());
-        break;
-
-      case String:
-        this.value = this.toString();
-        break;
-
-      default:
-    }
-  }
-
-  /**
-   * Format given value as text.
-   */
-  private void formatValue() {
-    switch (this.type) {
-      case Null:
-        this.text = StringUtils.EMPTY;
-        break;
-
-      case Binary:
-        this.text = Base64.encodeBase64String(this.<byte[]>toCastValue());
-        break;
-
-      case SByte:
-        this.text = this.<Byte>toCastValue().toString();
-        break;
-
-      case Boolean:
-        this.text = this.<Boolean>toCastValue().toString();
-        break;
-
-      case Date:
-      case DateTime:
-      case DateTimeOffset:
-        this.text = this.<ODataTimestamp>toCastValue().toString();
-        break;
-
-      case Time:
-      case TimeOfDay:
-        this.text = this.<ODataDuration>toCastValue().toString();
-        break;
-
-      case Decimal:
-        this.text = new DecimalFormat(this.type.pattern()).format(this.<BigDecimal>toCastValue());
-        break;
-
-      case Single:
-        this.text = new DecimalFormat(this.type.pattern()).format(this.<Float>toCastValue());
-        break;
-
-      case Double:
-        this.text = new DecimalFormat(this.type.pattern()).format(this.<Double>toCastValue());
-        break;
-
-      case Guid:
-        this.text = this.<UUID>toCastValue().toString();
-        break;
-
-      case Int16:
-        this.text = this.<Short>toCastValue().toString();
-        break;
-
-      case Byte:
-      case Int32:
-        this.text = this.<Integer>toCastValue().toString();
-        break;
-
-      case Int64:
-        this.text = this.<Long>toCastValue().toString();
-        break;
-
-      case Stream:
-        this.text = this.<URI>toCastValue().toASCIIString();
-        break;
-
-      case String:
-        this.text = this.<String>toCastValue();
-        break;
-
-      default:
-    }
-  }
-
-  /**
-   * Gets type name.
-   *
-   * @return type name.
-   */
-  public String getTypeName() {
-    return type.toString();
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public String toString() {
-    return this.text;
-  }
-
-  /**
-   * Gets actual primitive value.
-   *
-   * @return
-   */
-  public Object toValue() {
-    return this.value;
-  }
-
-  /**
-   * Casts primitive value.
-   *
-   * @param <T> cast.
-   * @return casted value.
-   */
-  @SuppressWarnings("unchecked")
-  public <T> T toCastValue() {
-    return (T) type.javaType().cast(toValue());
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataProperty.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataProperty.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataProperty.java
deleted file mode 100644
index c9582fc..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataProperty.java
+++ /dev/null
@@ -1,192 +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.odata4.client.api.data;
-
-import java.io.Serializable;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
-/**
- * OData entity property.
- */
-public class ODataProperty implements Serializable, ODataInvokeResult {
-
-  /**
-   * Property type.
-   */
-  public enum PropertyType {
-
-    /**
-     * Primitive.
-     */
-    PRIMITIVE,
-    /**
-     * Collection
-     */
-    COLLECTION,
-    /**
-     * Complex.
-     */
-    COMPLEX,
-    /**
-     * Empty type (possibly, no type information could be retrieved).
-     */
-    EMPTY
-
-  }
-
-  private static final long serialVersionUID = 926939448778950450L;
-
-  /**
-   * Property name.
-   */
-  private final String name;
-
-  /**
-   * Property value.
-   */
-  private ODataValue value;
-
-  /**
-   * Constructor.
-   *
-   * @param name property name.
-   * @param value property value.
-   */
-  ODataProperty(final String name, final ODataValue value) {
-    this.name = name;
-    this.value = value;
-  }
-
-  /**
-   * Returns property name.
-   *
-   * @return property name.
-   */
-  public String getName() {
-    return name;
-  }
-
-  /**
-   * Returns property value.
-   *
-   * @return property value.
-   */
-  public ODataValue getValue() {
-    return value;
-  }
-
-  /**
-   * Updates property value.
-   *
-   * @param value property value that replaces current.
-   */
-  public void setValue(final ODataValue value) {
-    this.value = value;
-  }
-
-  /**
-   * Checks if has null value.
-   *
-   * @return 'TRUE' if has null value; 'FALSE' otherwise.
-   */
-  public boolean hasNullValue() {
-    return this.value == null;
-  }
-
-  /**
-   * Checks if has primitive value.
-   *
-   * @return 'TRUE' if has primitive value; 'FALSE' otherwise.
-   */
-  public boolean hasPrimitiveValue() {
-    return !hasNullValue() && this.value.isPrimitive();
-  }
-
-  /**
-   * Gets primitive value.
-   *
-   * @return primitive value if exists; null otherwise.
-   */
-  public ODataPrimitiveValue getPrimitiveValue() {
-    return hasPrimitiveValue() ? this.value.asPrimitive() : null;
-  }
-
-  /**
-   * Checks if has complex value.
-   *
-   * @return 'TRUE' if has complex value; 'FALSE' otherwise.
-   */
-  public boolean hasComplexValue() {
-    return !hasNullValue() && this.value.isComplex();
-  }
-
-  /**
-   * Gets complex value.
-   *
-   * @return complex value if exists; null otherwise.
-   */
-  public ODataComplexValue getComplexValue() {
-    return hasComplexValue() ? this.value.asComplex() : null;
-  }
-
-  /**
-   * Checks if has collection value.
-   *
-   * @return 'TRUE' if has collection value; 'FALSE' otherwise.
-   */
-  public boolean hasCollectionValue() {
-    return !hasNullValue() && this.value.isCollection();
-  }
-
-  /**
-   * Gets collection value.
-   *
-   * @return collection value if exists; null otherwise.
-   */
-  public ODataCollectionValue getCollectionValue() {
-    return hasCollectionValue() ? this.value.asCollection() : null;
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public boolean equals(final Object obj) {
-    return EqualsBuilder.reflectionEquals(this, obj);
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public int hashCode() {
-    return HashCodeBuilder.reflectionHashCode(this);
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public String toString() {
-    return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataTimestamp.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataTimestamp.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataTimestamp.java
deleted file mode 100644
index f7f7266..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataTimestamp.java
+++ /dev/null
@@ -1,141 +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.odata4.client.api.data;
-
-import java.io.Serializable;
-import java.sql.Timestamp;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-
-/**
- * Helper class for handling datetime and datetime-offset primitive values.
- *
- * @see com.msopentech.odatajclient.engine.data.metadata.edm.EdmSimpleType#DATE_TIME
- * @see com.msopentech.odatajclient.engine.data.metadata.edm.EdmSimpleType#DATE_TIME_OFFSET
- */
-public final class ODataTimestamp implements Serializable {
-
-    private static final long serialVersionUID = 4053990618660356004L;
-
-    private final SimpleDateFormat sdf;
-
-    private final Timestamp timestamp;
-
-    private String timezone;
-
-    private final boolean offset;
-
-    public static ODataTimestamp getInstance(final EdmSimpleType type, final Timestamp timestamp) {
-        return new ODataTimestamp(new SimpleDateFormat(type.pattern()),
-                new Date(timestamp.getTime()), timestamp.getNanos(), type == EdmSimpleType.DateTimeOffset);
-    }
-
-    public static ODataTimestamp parse(final EdmSimpleType type, final String input) {
-        final ODataTimestamp instance;
-
-        final String[] dateParts = input.split("\\.");
-        final SimpleDateFormat sdf = new SimpleDateFormat(type.pattern());
-        final boolean isOffset = type == EdmSimpleType.DateTimeOffset;
-
-        try {
-            final Date date = sdf.parse(dateParts[0]);
-            if (dateParts.length > 1) {
-                int idx = dateParts[1].indexOf('+');
-                if (idx == -1) {
-                    idx = dateParts[1].indexOf('-');
-                }
-                if (idx == -1) {
-                    instance = new ODataTimestamp(sdf, date, Integer.parseInt(dateParts[1]), isOffset);
-                } else {
-                    instance = new ODataTimestamp(sdf, date,
-                            Integer.parseInt(dateParts[1].substring(0, idx)), dateParts[1].substring(idx), isOffset);
-                }
-            } else {
-                instance = new ODataTimestamp(sdf, date, isOffset);
-            }
-        } catch (Exception e) {
-            throw new IllegalArgumentException("Cannot parse " + type.pattern(), e);
-        }
-
-        return instance;
-    }
-
-    private ODataTimestamp(final SimpleDateFormat sdf, final Date date, final boolean offset) {
-        this.sdf = sdf;
-        this.timestamp = new Timestamp(date.getTime());
-        this.offset = offset;
-    }
-
-    private ODataTimestamp(final SimpleDateFormat sdf, final Date date, final int nanos, final boolean offset) {
-        this(sdf, date, offset);
-        this.timestamp.setNanos(nanos);
-    }
-
-    private ODataTimestamp(
-            final SimpleDateFormat sdf, final Date date, final int nanos, final String timezone, final boolean offset) {
-        this(sdf, date, nanos, offset);
-        this.timezone = timezone;
-    }
-
-    public Timestamp getTimestamp() {
-        return timestamp;
-    }
-
-    public String getTimezone() {
-        return timezone;
-    }
-
-    public boolean isOffset() {
-        return offset;
-    }
-
-    /**
-     * {@inheritDoc }
-     */
-    @Override
-    public boolean equals(final Object obj) {
-        return EqualsBuilder.reflectionEquals(this, obj, "sdf");
-    }
-
-    /**
-     * {@inheritDoc }
-     */
-    @Override
-    public int hashCode() {
-        return HashCodeBuilder.reflectionHashCode(this, "sdf");
-    }
-
-    /**
-     * {@inheritDoc }
-     */
-    @Override
-    public String toString() {
-        final StringBuilder formatted = new StringBuilder().append(sdf.format(timestamp));
-        if (timestamp.getNanos() > 0) {
-            formatted.append('.').append(String.valueOf(timestamp.getNanos()));
-        }
-        if (StringUtils.isNotBlank(timezone)) {
-            formatted.append(timezone);
-        }
-        return formatted.toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataValue.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataValue.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataValue.java
deleted file mode 100644
index 3d8f8e8..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataValue.java
+++ /dev/null
@@ -1,111 +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.odata4.client.api.data;
-
-import java.io.Serializable;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
-/**
- * Abstract representation of an OData entity property value.
- */
-public abstract class ODataValue implements Serializable {
-
-  private static final long serialVersionUID = 7445422004232581877L;
-
-  /**
-   * Check is is a primitive value.
-   *
-   * @return 'TRUE' if primitive; 'FALSE' otherwise.
-   */
-  public boolean isPrimitive() {
-    return (this instanceof ODataPrimitiveValue);
-  }
-
-  /**
-   * Casts to primitive value.
-   *
-   * @return primitive value.
-   */
-  public ODataPrimitiveValue asPrimitive() {
-    return isPrimitive() ? (ODataPrimitiveValue) this : null;
-  }
-
-  /**
-   * Check is is a complex value.
-   *
-   * @return 'TRUE' if complex; 'FALSE' otherwise.
-   */
-  public boolean isComplex() {
-    return (this instanceof ODataComplexValue);
-  }
-
-  /**
-   * Casts to complex value.
-   *
-   * @return complex value.
-   */
-  public ODataComplexValue asComplex() {
-    return isComplex() ? (ODataComplexValue) this : null;
-  }
-
-  /**
-   * Check is is a collection value.
-   *
-   * @return 'TRUE' if collection; 'FALSE' otherwise.
-   */
-  public boolean isCollection() {
-    return (this instanceof ODataCollectionValue);
-  }
-
-  /**
-   * Casts to collection value.
-   *
-   * @return collection value.
-   */
-  public ODataCollectionValue asCollection() {
-    return isCollection() ? (ODataCollectionValue) this : null;
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public boolean equals(final Object obj) {
-    return EqualsBuilder.reflectionEquals(this, obj);
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public int hashCode() {
-    return HashCodeBuilder.reflectionHashCode(this);
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public String toString() {
-    return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ServiceDocument.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ServiceDocument.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ServiceDocument.java
new file mode 100644
index 0000000..b36e1c5
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ServiceDocument.java
@@ -0,0 +1,139 @@
+/*
+ * 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.odata4.client.api.data;
+
+import java.net.URI;
+import java.util.List;
+import org.apache.olingo.odata4.client.api.domain.ODataServiceDocument;
+
+/**
+ * REST resource for an <tt>ODataServiceDocument</tt>.
+ *
+ * @see ODataServiceDocument
+ */
+public interface ServiceDocument {
+
+  String getTitle();
+
+  /**
+   * Gets base URI.
+   *
+   * @return base URI.
+   */
+  URI getBaseURI();
+
+  /**
+   * Returns metadata context.
+   *
+   * @return metadata context
+   */
+  String getMetadataContext();
+
+  /**
+   * Returns metadata ETag.
+   *
+   * @return metadata ETag
+   */
+  String getMetadataETag();
+
+  /**
+   * Gets top level entity sets.
+   *
+   * @return top level entity sets.
+   */
+  List<ServiceDocumentItem> getEntitySets();
+
+  /**
+   * Gets top level entity set with given name.
+   *
+   * @param name entity set name
+   * @return entity set with given name if found, otherwise null
+   */
+  ServiceDocumentItem getEntitySetByName(String name);
+
+  /**
+   * Gets top level entity set with given title.
+   *
+   * @param title entity set title
+   * @return entity set with given title if found, otherwise null
+   */
+  ServiceDocumentItem getEntitySetByTitle(String title);
+
+  /**
+   * Gets top level function imports.
+   *
+   * @return top level function imports.
+   */
+  List<ServiceDocumentItem> getFunctionImports();
+
+  /**
+   * Gets top level function import set with given name.
+   *
+   * @param name function import name
+   * @return function import with given name if found, otherwise null
+   */
+  ServiceDocumentItem getFunctionImportByName(String name);
+
+  /**
+   * Gets top level function import with given title.
+   *
+   * @param title function import title
+   * @return function import with given title if found, otherwise null
+   */
+  ServiceDocumentItem getFunctionImportByTitle(String title);
+
+  /**
+   * Gets top level singletons.
+   *
+   * @return top level singletons.
+   */
+  List<ServiceDocumentItem> getSingletons();
+
+  /**
+   * Gets top level singleton with given name.
+   *
+   * @param name singleton name
+   * @return singleton with given name if found, otherwise null
+   */
+  ServiceDocumentItem getSingletonByName(String name);
+
+  /**
+   * Gets top level singleton with given title.
+   *
+   * @param title singleton title
+   * @return singleton with given title if found, otherwise null
+   */
+  ServiceDocumentItem getSingletonByTitle(String title);
+
+  /**
+   * Gets related service documents.
+   *
+   * @return related service documents.
+   */
+  List<ServiceDocumentItem> getRelatedServiceDocuments();
+
+  /**
+   * Gets related service document with given title.
+   *
+   * @param title related service document title
+   * @return related service document with given title if found, otherwise null
+   */
+  ServiceDocumentItem getRelatedServiceDocumentByTitle(String title);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ServiceDocumentItem.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ServiceDocumentItem.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ServiceDocumentItem.java
new file mode 100644
index 0000000..4f4bd77
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ServiceDocumentItem.java
@@ -0,0 +1,30 @@
+/*
+ * 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.odata4.client.api.data;
+
+public interface ServiceDocumentItem {
+
+  String getHref();
+
+  String getName();
+
+  String getTitle();
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e6248155/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/ComposedGeospatial.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/ComposedGeospatial.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/ComposedGeospatial.java
deleted file mode 100644
index 64b4fa8..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/geospatial/ComposedGeospatial.java
+++ /dev/null
@@ -1,75 +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.odata4.client.api.data.geospatial;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Abstract base class for all Geometries that are composed out of other geospatial elements.
- */
-public abstract class ComposedGeospatial<T extends Geospatial> extends Geospatial implements Iterable<T> {
-
-  private static final long serialVersionUID = 8796254901098541307L;
-
-  protected final List<T> geospatials;
-
-  /**
-   * Constructor.
-   *
-   * @param dimension dimension.
-   * @param type type.
-   * @param geospatials geospatials info.
-   */
-  protected ComposedGeospatial(final Dimension dimension, final Type type, final List<T> geospatials) {
-    super(dimension, type);
-    this.geospatials = new ArrayList<T>();
-    if (geospatials != null) {
-      this.geospatials.addAll(geospatials);
-    }
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public Iterator<T> iterator() {
-    return this.geospatials.iterator();
-  }
-
-  /**
-   * Checks if is empty.
-   *
-   * @return 'TRUE' if is empty; 'FALSE' otherwise.
-   */
-  public boolean isEmpty() {
-    return geospatials.isEmpty();
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public void setSrid(final Integer srid) {
-    for (Geospatial geospatial : this.geospatials) {
-      geospatial.setSrid(srid);
-    }
-  }
-}