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 10:09:07 UTC

[18/57] [abbrv] git commit: [OLINGO-169] Introducing V3 and V4 metadata parsing tests - still using dummy Edm interfaces

[OLINGO-169] Introducing V3 and V4 metadata parsing tests - still using dummy Edm interfaces


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

Branch: refs/heads/master
Commit: e7135610cf6b59806a89973c92dad6127b6d8896
Parents: 7f76d8a
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Feb 24 11:51:47 2014 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Feb 24 11:51:47 2014 +0100

----------------------------------------------------------------------
 odata4-lib/odata4-client-api/pom.xml            |   4 +
 .../olingo/odata4/client/api/ODataClient.java   |   6 +-
 .../odata4/client/api/data/EdmSimpleType.java   | 288 +++++++++++
 .../client/api/data/ODataCollectionValue.java   |  98 ++++
 .../client/api/data/ODataComplexValue.java      |  97 ++++
 .../client/api/data/ODataDeserializer.java      |  90 ----
 .../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/ODataReader.java     | 102 ----
 .../odata4/client/api/data/ODataSerializer.java | 120 -----
 .../odata4/client/api/data/ODataTimestamp.java  | 141 ++++++
 .../odata4/client/api/data/ODataValue.java      | 111 +++++
 .../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 +++
 .../olingo/odata4/client/api/edm/EdmType.java   | 108 ++++
 .../api/edm/EdmTypeNotFoundException.java       |  37 ++
 .../odata4/client/api/op/ODataDeserializer.java |  90 ++++
 .../odata4/client/api/op/ODataReader.java       | 102 ++++
 .../odata4/client/api/op/ODataSerializer.java   | 120 +++++
 .../odata4/client/api/utils/XMLUtils.java       | 176 +++++++
 .../odata4/client/core/AbstractODataClient.java |   4 +-
 .../odata4/client/core/data/EdmSimpleType.java  | 288 -----------
 .../client/core/data/ODataCollectionValue.java  |  98 ----
 .../client/core/data/ODataComplexValue.java     |  97 ----
 .../odata4/client/core/data/ODataDuration.java  |  80 ---
 .../client/core/data/ODataGeospatialValue.java  | 488 -------------------
 .../client/core/data/ODataInvokeResult.java     |  30 --
 .../client/core/data/ODataPrimitiveValue.java   | 376 --------------
 .../odata4/client/core/data/ODataProperty.java  | 192 --------
 .../odata4/client/core/data/ODataTimestamp.java | 141 ------
 .../odata4/client/core/data/ODataValue.java     | 111 -----
 .../data/geospatial/ComposedGeospatial.java     |  75 ---
 .../client/core/data/geospatial/Geospatial.java | 156 ------
 .../data/geospatial/GeospatialCollection.java   |  47 --
 .../client/core/data/geospatial/LineString.java |  38 --
 .../core/data/geospatial/MultiLineString.java   |  38 --
 .../client/core/data/geospatial/MultiPoint.java |  38 --
 .../core/data/geospatial/MultiPolygon.java      |  38 --
 .../client/core/data/geospatial/Point.java      |  77 ---
 .../client/core/data/geospatial/Polygon.java    |  72 ---
 .../core/data/impl/AbstractEdmDeserializer.java |  69 ---
 .../core/data/impl/AbstractJacksonTool.java     |  83 ----
 .../data/impl/AbstractODataDeserializer.java    | 177 -------
 .../core/data/impl/AbstractODataReader.java     | 138 ------
 .../core/data/impl/AbstractODataSerializer.java | 160 ------
 .../core/data/impl/ComplexTypeDeserializer.java |  81 ---
 .../data/impl/EntityContainerDeserializer.java  | 100 ----
 .../core/data/impl/EntityKeyDeserializer.java   |  48 --
 .../core/data/impl/EntitySetDeserializer.java   |  68 ---
 .../core/data/impl/EntityTypeDeserializer.java  |  90 ----
 .../core/data/impl/EnumTypeDeserializer.java    |  71 ---
 .../data/impl/InjectableSerializerProvider.java |  43 --
 .../core/data/impl/SchemaDeserializer.java      | 147 ------
 .../data/impl/v3/ODataDeserializerImpl.java     |   2 +-
 .../core/data/impl/v3/ODataReaderImpl.java      |   2 +-
 .../core/data/impl/v3/ODataSerializerImpl.java  |   2 +-
 .../data/impl/v4/ODataDeserializerImpl.java     |   2 +-
 .../core/data/impl/v4/ODataReaderImpl.java      |   2 +-
 .../core/data/impl/v4/ODataSerializerImpl.java  |   2 +-
 .../client/core/edm/AbstractComplexType.java    |   2 +-
 .../odata4/client/core/edm/AbstractEdmType.java | 261 ++++++++++
 .../core/edm/AbstractEntityContainer.java       |   2 +-
 .../client/core/edm/AbstractEntitySet.java      |   2 +-
 .../client/core/edm/AbstractEntityType.java     |   2 +-
 .../client/core/edm/AbstractEnumType.java       |   2 +-
 .../client/core/edm/AbstractProperty.java       |   1 +
 .../odata4/client/core/edm/AbstractSchema.java  |   2 +-
 .../core/edm/DataServicesDeserializer.java      |   6 +-
 .../client/core/edm/EdmxDeserializer.java       |   8 +-
 .../odata4/client/core/edm/EntityKeyImpl.java   |   2 +-
 .../core/edm/v3/AnnotationsDeserializer.java    |   6 +-
 .../core/edm/v3/AssociationDeserializer.java    |   6 +-
 .../core/edm/v3/AssociationSetDeserializer.java |   4 +-
 .../odata4/client/core/edm/v3/EdmTypeImpl.java  |  35 ++
 .../core/edm/v3/FunctionImportDeserializer.java |   4 +-
 .../ReferentialConstraintRoleDeserializer.java  |   4 +-
 .../core/edm/v3/TypeAnnotationDeserializer.java |   4 +-
 .../client/core/edm/v4/ActionDeserializer.java  |   6 +-
 .../core/edm/v4/AnnotationDeserializer.java     |   4 +-
 .../client/core/edm/v4/AnnotationImpl.java      |  60 +--
 .../core/edm/v4/AnnotationsDeserializer.java    |   4 +-
 .../client/core/edm/v4/ComplexTypeImpl.java     |  11 +-
 .../odata4/client/core/edm/v4/EdmTypeImpl.java  |  35 ++
 .../core/edm/v4/FunctionDeserializer.java       |   6 +-
 .../edm/v4/NavigationPropertyDeserializer.java  |   8 +-
 .../core/edm/v4/NavigationPropertyImpl.java     |   5 +-
 .../odata4/client/core/edm/v4/PropertyImpl.java |   8 +-
 .../core/edm/v4/ReferenceDeserializer.java      |   8 +-
 .../core/edm/v4/SingletonDeserializer.java      |   6 +-
 .../client/core/edm/v4/SingletonImpl.java       |   7 +-
 .../client/core/edm/v4/TermDeserializer.java    |   4 +-
 .../core/edm/v4/TypeDefinitionDeserializer.java |   4 +-
 .../edm/v4/annotation/ApplyDeserializer.java    |   6 +-
 .../edm/v4/annotation/CastDeserializer.java     |   6 +-
 .../v4/annotation/CollectionDeserializer.java   |   4 +-
 .../DynExprConstructDeserializer.java           |  26 +-
 .../edm/v4/annotation/IsOfDeserializer.java     |   6 +-
 .../annotation/LabeledElementDeserializer.java  |   6 +-
 .../edm/v4/annotation/NullDeserializer.java     |   4 +-
 .../annotation/PropertyValueDeserializer.java   |   6 +-
 .../edm/v4/annotation/RecordDeserializer.java   |   6 +-
 .../edm/v4/annotation/UrlRefDeserializer.java   |   4 +-
 .../core/op/impl/AbstractEdmDeserializer.java   |  69 +++
 .../core/op/impl/AbstractJacksonTool.java       |  83 ++++
 .../core/op/impl/AbstractODataDeserializer.java | 177 +++++++
 .../core/op/impl/AbstractODataReader.java       | 138 ++++++
 .../core/op/impl/AbstractODataSerializer.java   | 160 ++++++
 .../core/op/impl/ComplexTypeDeserializer.java   |  81 +++
 .../op/impl/EntityContainerDeserializer.java    | 100 ++++
 .../core/op/impl/EntityKeyDeserializer.java     |  48 ++
 .../core/op/impl/EntitySetDeserializer.java     |  68 +++
 .../core/op/impl/EntityTypeDeserializer.java    |  90 ++++
 .../core/op/impl/EnumTypeDeserializer.java      |  71 +++
 .../op/impl/InjectableSerializerProvider.java   |  43 ++
 .../client/core/op/impl/SchemaDeserializer.java | 147 ++++++
 .../client/core/utils/AbstractDOMParser.java    |  46 --
 .../client/core/utils/AndroidDOMParserImpl.java |  49 --
 .../client/core/utils/DefaultDOMParserImpl.java |  78 ---
 .../odata4/client/core/utils/XMLUtils.java      | 186 -------
 .../client/core/xml/AbstractDOMParser.java      |  46 ++
 .../client/core/xml/AndroidDOMParserImpl.java   |  50 ++
 .../client/core/xml/DefaultDOMParserImpl.java   |  78 +++
 .../odata4/client/core/xml/XMLParser.java       |  37 ++
 .../olingo/odata4/client/core/AbstractTest.java |  56 +++
 .../odata4/client/core/v3/MetadataTest.java     | 162 ++++++
 .../odata4/client/core/v4/MetadataTest.java     | 261 ++++++++++
 .../olingo/odata4/client/core/v3/metadata.xml   |  22 +
 .../client/core/v3/northwind-metadata.xml       |  22 +
 .../odata4/client/core/v4/demo-metadata.xml     |  22 +
 .../odata4/client/core/v4/fromdoc1-metadata.xml | 116 +++++
 .../odata4/client/core/v4/fromdoc2-metadata.xml |  54 ++
 .../odata4/client/core/v4/fromdoc3-metadata.xml | 131 +++++
 .../olingo/odata4/client/core/v4/metadata.xml   | 232 +++++++++
 .../client/core/v4/northwind-metadata.xml       |  22 +
 144 files changed, 6179 insertions(+), 4573 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-api/pom.xml
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/pom.xml b/odata4-lib/odata4-client-api/pom.xml
index 5d56f03..130d014 100644
--- a/odata4-lib/odata4-client-api/pom.xml
+++ b/odata4-lib/odata4-client-api/pom.xml
@@ -42,6 +42,10 @@
     </dependency>
 
     <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpclient</artifactId>
     </dependency>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/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 b5a8dec..353d2d3 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,9 +18,9 @@
  */
 package org.apache.olingo.odata4.client.api;
 
-import org.apache.olingo.odata4.client.api.data.ODataDeserializer;
-import org.apache.olingo.odata4.client.api.data.ODataReader;
-import org.apache.olingo.odata4.client.api.data.ODataSerializer;
+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;
 import org.apache.olingo.odata4.commons.api.edm.constants.ODataServiceVersion;
 
 public interface ODataClient {

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/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
new file mode 100644
index 0000000..7d44c37
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/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.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/e7135610/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
new file mode 100644
index 0000000..2d94b2e
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/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.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/e7135610/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
new file mode 100644
index 0000000..3633e34
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/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.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/e7135610/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataDeserializer.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataDeserializer.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataDeserializer.java
deleted file mode 100644
index 8884a58..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataDeserializer.java
+++ /dev/null
@@ -1,90 +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.InputStream;
-import java.io.Serializable;
-import org.apache.olingo.odata4.client.api.edm.Edmx;
-import org.w3c.dom.Element;
-
-/**
- * Utility class for serialization.
- */
-public interface ODataDeserializer extends Serializable {
-
-  Edmx toMetadata(InputStream input);
-
-  /**
-   * Gets the ServiceDocumentResource object represented by the given InputStream.
-   *
-   * @param input stream to be de-serialized.
-   * @param format OData service document format.
-   * @return ServiceDocumentResource object.
-   */
-//    ServiceDocument toServiceDocument(InputStream input, ODataFormat format);
-  /**
-   * Gets a feed object from the given InputStream.
-   *
-   * @param <T> reference class type
-   * @param input stream to be de-serialized.
-   * @param reference reference class (AtomFeed.class, JSONFeed.class).
-   * @return FeedResource instance.
-   */
-//    <T extends Feed> T toFeed(InputStream input, Class<T> reference);
-  /**
-   * Gets an entry object from the given InputStream.
-   *
-   * @param <T> reference class type
-   * @param input stream to be de-serialized.
-   * @param reference reference class (AtomEntry.class, JSONV3Entry.class).
-   * @return EntryResource instance.
-   */
-//    <T extends Entry> T toEntry(InputStream input, Class<T> reference);
-  /**
-   * Gets a DOM representation of the given InputStream.
-   *
-   * @param input stream to be de-serialized.
-   * @param format OData format.
-   * @return DOM.
-   */
-//  Element toPropertyDOM(InputStream input, ODataFormat format);
-  /**
-   * Gets a list of links from the given InputStream.
-   *
-   * @param input stream to be de-serialized.
-   * @param format OData format.
-   * @return de-serialized links.
-   */
-//    LinkCollection toLinkCollection(InputStream input, ODataFormat format);
-  /**
-   * Gets the ODataError object represented by the given InputStream.
-   *
-   * @param input stream to be parsed and de-serialized.
-   * @param isXML 'TRUE' if the error is represented by XML; 'FALSE' otherwise.
-   * @return
-   */
-//  ODataError toODataError(InputStream input, boolean isXML);
-  /**
-   * Parses the given input into a DOM tree.
-   *
-   * @param input stream to be parsed and de-serialized.
-   * @return DOM tree
-   */
-  Element toDOM(InputStream input);
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/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
new file mode 100644
index 0000000..a04171b
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/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.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/e7135610/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
new file mode 100644
index 0000000..116c307
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/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.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/e7135610/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
new file mode 100644
index 0000000..af429f8
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/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.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/e7135610/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
new file mode 100644
index 0000000..4f7c674
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/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.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/e7135610/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
new file mode 100644
index 0000000..c9582fc
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/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.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/e7135610/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataReader.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataReader.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataReader.java
deleted file mode 100644
index df0ec9a..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataReader.java
+++ /dev/null
@@ -1,102 +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.InputStream;
-import java.io.Serializable;
-import org.apache.olingo.odata4.client.api.ODataError;
-import org.apache.olingo.odata4.client.api.edm.EdmMetadata;
-
-/**
- * OData reader.
- * <br/>
- * Use this class to de-serialize an OData response body.
- * <br/>
- * This class provides method helpers to de-serialize an entire feed, a set of entities and a single entity as well.
- */
-public interface ODataReader extends Serializable {
-
-  /**
-   * Parses a stream into metadata representation.
-   *
-   * @param input stream to de-serialize.
-   * @return metadata representation.
-   */
-  EdmMetadata readMetadata(InputStream input);
-
-  /**
-   * Parses an OData service document.
-   *
-   * @param input stream to de-serialize.
-   * @param format de-serialize as XML or JSON
-   * @return List of URIs.
-   */
-  //ODataServiceDocument readServiceDocument(InputStream input, ODataFormat format);
-  /**
-   * De-Serializes a stream into an OData entity set.
-   *
-   * @param input stream to de-serialize.
-   * @param format de-serialize as AtomFeed or JSONFeed
-   * @return de-serialized entity set.
-   */
-  //ODataEntitySet readEntitySet(InputStream input, ODataPubFormat format);
-  /**
-   * Parses a stream taking care to de-serializes the first OData entity found.
-   *
-   * @param input stream to de-serialize.
-   * @param format de-serialize as AtomEntry or JSONEntry
-   * @return entity de-serialized.
-   */
-  //ODataEntity readEntity(InputStream input, ODataPubFormat format);
-  /**
-   * Parses a stream taking care to de-serialize the first OData entity property found.
-   *
-   * @param input stream to de-serialize.
-   * @param format de-serialize as XML or JSON
-   * @return OData entity property de-serialized.
-   */
-  //ODataProperty readProperty(InputStream input, ODataFormat format);
-  /**
-   * Parses a $links request response.
-   *
-   * @param input stream to de-serialize.
-   * @param format de-serialize as XML or JSON
-   * @return List of URIs.
-   */
-  //ODataLinkCollection readLinks(InputStream input, ODataFormat format);
-  /**
-   * Parses a stream into an OData error.
-   *
-   * @param inputStream stream to de-serialize.
-   * @param isXML 'TRUE' if the error is in XML format.
-   * @return OData error.
-   */
-//  ODataError readError(InputStream inputStream, boolean isXML);
-
-  /**
-   * Parses a stream into the object type specified by the given reference.
-   *
-   * @param <T> expected object type.
-   * @param src input stream.
-   * @param format format
-   * @param reference reference.
-   * @return read object.
-   */
-  //<T> T read(InputStream src, String format, Class<T> reference);
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataSerializer.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataSerializer.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataSerializer.java
deleted file mode 100644
index 8553371..0000000
--- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/ODataSerializer.java
+++ /dev/null
@@ -1,120 +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.OutputStream;
-import java.io.Serializable;
-import java.io.Writer;
-import org.apache.olingo.odata4.client.api.format.ODataFormat;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * Utility class for serialization.
- */
-public interface ODataSerializer extends Serializable {
-
-    /**
-     * Writes <tt>FeedResource</tt> object onto the given stream.
-     *
-     * @param <T> feed resource type.
-     * @param obj object to be streamed.
-     * @param out output stream.
-     */
-//    <T extends Feed> void feed(T obj, OutputStream out);
-
-    /**
-     * Writes <tt>FeedResource</tt> object by the given writer.
-     *
-     * @param <T> feed resource type.
-     * @param obj object to be streamed.
-     * @param writer writer.
-     */
-//    <T extends Feed> void feed(T obj, Writer writer);
-
-    /**
-     * Writes <tt>EntryResource</tt> object onto the given stream.
-     *
-     * @param <T> entry resource type.
-     * @param obj object to be streamed.
-     * @param out output stream.
-     */
-//    <T extends Entry> void entry(T obj, OutputStream out);
-
-    /**
-     * Writes <tt>EntryResource</tt> object by the given writer.
-     *
-     * @param <T> entry resource type.
-     * @param obj object to be streamed.
-     * @param writer writer.
-     */
-//    <T extends Entry> void entry(T obj, Writer writer);
-
-    /**
-     * Writes entry content onto the given stream.
-     *
-     * @param element element to be streamed.
-     * @param format streaming format.
-     * @param out output stream.
-     */
-//    void property(Element element, ODataFormat format, OutputStream out);
-
-    /**
-     * Writes entry content by the given writer.
-     *
-     * @param element element to be streamed.
-     * @param format streaming format.
-     * @param writer writer.
-     */
-//    void property(Element element, ODataFormat format, Writer writer);
-
-    /**
-     * Writes OData link onto the given stream.
-     *
-     * @param link OData link to be streamed.
-     * @param format streaming format.
-     * @param out output stream.
-     */
-//    void link(ODataLink link, ODataFormat format, OutputStream out);
-
-    /**
-     * Writes OData link by the given writer.
-     *
-     * @param link OData link to be streamed.
-     * @param format streaming format.
-     * @param writer writer.
-     */
-//    void link(ODataLink link, ODataFormat format, Writer writer);
-
-    /**
-     * Writes DOM object onto the given stream.
-     *
-     * @param content DOM to be streamed.
-     * @param out output stream.
-     */
-    void dom(Node content, OutputStream out);
-
-    /**
-     * Writes DOM object by the given writer.
-     *
-     * @param content DOM to be streamed.
-     * @param writer writer.
-     */
-    void dom(Node content, Writer writer);
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/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
new file mode 100644
index 0000000..f7f7266
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/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.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/e7135610/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
new file mode 100644
index 0000000..3d8f8e8
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/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.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/e7135610/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
new file mode 100644
index 0000000..64b4fa8
--- /dev/null
+++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/data/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.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);
+    }
+  }
+}