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/20 11:27:08 UTC

[14/21] [OLINGO-200] New StAX (replacing DOM) (de)serializers in place - still IT to check

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedImpl.java
index ced3d09..271ef3d 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedImpl.java
@@ -19,6 +19,7 @@
 package org.apache.olingo.client.core.data;
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
@@ -32,10 +33,13 @@ import org.apache.olingo.client.api.uri.SegmentType;
  * @see JSONEntry
  */
 @JsonDeserialize(using = JSONFeedDeserializer.class)
+@JsonSerialize(using = JSONFeedSerializer.class)
 public class JSONFeedImpl extends AbstractPayloadObject implements Feed {
 
   private static final long serialVersionUID = -3576372289800799417L;
 
+  private String id;
+
   private URI metadata;
 
   private Integer count;
@@ -74,10 +78,20 @@ public class JSONFeedImpl extends AbstractPayloadObject implements Feed {
   }
 
   @Override
+  public String getId() {
+    return id;
+  }
+
+  public void setId(final String id) {
+    this.id = id;
+  }
+
+  @Override
   public Integer getCount() {
     return count;
   }
 
+  @Override
   public void setCount(final Integer count) {
     this.count = count;
   }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedSerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedSerializer.java
new file mode 100644
index 0000000..f89303e
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedSerializer.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.client.core.data;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import java.io.IOException;
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.data.Entry;
+
+public class JSONFeedSerializer extends AbstractJsonSerializer<JSONFeedImpl> {
+
+  @Override
+  protected void doSerialize(final JSONFeedImpl feed, final JsonGenerator jgen, final SerializerProvider provider)
+          throws IOException, JsonProcessingException {
+
+    jgen.writeStartObject();
+
+    if (feed.getMetadata() != null) {
+      jgen.writeStringField(Constants.JSON_METADATA, feed.getMetadata().toASCIIString());
+    }
+    if (feed.getId() != null) {
+      jgen.writeStringField(Constants.JSON_ID, feed.getId());
+    }
+    if (feed.getCount() != null) {
+      jgen.writeNumberField(Constants.JSON_COUNT, feed.getCount());
+    }
+    if (feed.getNext() != null) {
+      jgen.writeStringField(Constants.JSON_NEXT_LINK, feed.getNext().toASCIIString());
+    }
+
+    jgen.writeArrayFieldStart(Constants.JSON_VALUE);
+    for (Entry entry : feed.getEntries()) {
+      jgen.writeObject(entry);
+    }
+
+    jgen.writeEndArray();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java
new file mode 100644
index 0000000..1e92bab
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueDeserializer.java
@@ -0,0 +1,256 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.client.core.data;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
+import org.apache.olingo.client.api.domain.geospatial.Geospatial;
+import org.apache.olingo.client.api.domain.geospatial.GeospatialCollection;
+import org.apache.olingo.client.api.domain.geospatial.LineString;
+import org.apache.olingo.client.api.domain.geospatial.MultiLineString;
+import org.apache.olingo.client.api.domain.geospatial.MultiPoint;
+import org.apache.olingo.client.api.domain.geospatial.MultiPolygon;
+import org.apache.olingo.client.api.domain.geospatial.Point;
+import org.apache.olingo.client.api.domain.geospatial.Polygon;
+
+class JSONGeoValueDeserializer {
+
+  private Point point(final Iterator<JsonNode> itor, final ODataJClientEdmPrimitiveType type, final String crs) {
+    Point point = null;
+
+    if (itor.hasNext()) {
+      point = new Point(GeoUtils.getDimension(type), crs);
+      point.setX(Double.valueOf(itor.next().asText()));
+      point.setY(Double.valueOf(itor.next().asText()));
+    }
+
+    return point;
+  }
+
+  private MultiPoint multipoint(final Iterator<JsonNode> itor, final ODataJClientEdmPrimitiveType type,
+          final String crs) {
+
+    MultiPoint multiPoint = null;
+
+    if (itor.hasNext()) {
+      final List<Point> points = new ArrayList<Point>();
+      while (itor.hasNext()) {
+        final Iterator<JsonNode> mpItor = itor.next().elements();
+        points.add(point(mpItor, type, crs));
+      }
+      multiPoint = new MultiPoint(GeoUtils.getDimension(type), crs, points);
+    } else {
+      multiPoint = new MultiPoint(GeoUtils.getDimension(type), crs, Collections.<Point>emptyList());
+    }
+
+    return multiPoint;
+  }
+
+  private LineString lineString(final Iterator<JsonNode> itor, final ODataJClientEdmPrimitiveType type,
+          final String crs) {
+
+    LineString lineString = null;
+
+    if (itor.hasNext()) {
+      final List<Point> points = new ArrayList<Point>();
+      while (itor.hasNext()) {
+        final Iterator<JsonNode> mpItor = itor.next().elements();
+        points.add(point(mpItor, type, crs));
+      }
+      lineString = new LineString(GeoUtils.getDimension(type), crs, points);
+    } else {
+      lineString = new LineString(GeoUtils.getDimension(type), crs, Collections.<Point>emptyList());
+    }
+
+    return lineString;
+  }
+
+  private MultiLineString multiLineString(final Iterator<JsonNode> itor, final ODataJClientEdmPrimitiveType type,
+          final String crs) {
+
+    MultiLineString multiLineString = null;
+
+    if (itor.hasNext()) {
+      final List<LineString> lineStrings = new ArrayList<LineString>();
+      while (itor.hasNext()) {
+        final Iterator<JsonNode> mlsItor = itor.next().elements();
+        lineStrings.add(lineString(mlsItor, type, crs));
+      }
+      multiLineString = new MultiLineString(GeoUtils.getDimension(type), crs, lineStrings);
+    } else {
+      multiLineString = new MultiLineString(GeoUtils.getDimension(type), crs, Collections.<LineString>emptyList());
+    }
+
+    return multiLineString;
+  }
+
+  private Polygon polygon(final Iterator<JsonNode> itor, final ODataJClientEdmPrimitiveType type,
+          final String crs) {
+
+    List<Point> extPoints = null;
+    if (itor.hasNext()) {
+      final Iterator<JsonNode> extItor = itor.next().elements();
+      if (extItor.hasNext()) {
+        extPoints = new ArrayList<Point>();
+        while (extItor.hasNext()) {
+          final Iterator<JsonNode> mpItor = extItor.next().elements();
+          extPoints.add(point(mpItor, type, crs));
+        }
+      }
+    }
+
+    List<Point> intPoints = null;
+    if (itor.hasNext()) {
+      final Iterator<JsonNode> intItor = itor.next().elements();
+      if (intItor.hasNext()) {
+        intPoints = new ArrayList<Point>();
+        while (intItor.hasNext()) {
+          final Iterator<JsonNode> mpItor = intItor.next().elements();
+          intPoints.add(point(mpItor, type, crs));
+        }
+      }
+    }
+
+    return new Polygon(GeoUtils.getDimension(type), crs, intPoints, extPoints);
+  }
+
+  private MultiPolygon multiPolygon(final Iterator<JsonNode> itor, final ODataJClientEdmPrimitiveType type,
+          final String crs) {
+
+    MultiPolygon multiPolygon = null;
+
+    if (itor.hasNext()) {
+      final List<Polygon> polygons = new ArrayList<Polygon>();
+      while (itor.hasNext()) {
+        final Iterator<JsonNode> mpItor = itor.next().elements();
+        polygons.add(polygon(mpItor, type, crs));
+      }
+      multiPolygon = new MultiPolygon(GeoUtils.getDimension(type), crs, polygons);
+    } else {
+      multiPolygon = new MultiPolygon(GeoUtils.getDimension(type), crs, Collections.<Polygon>emptyList());
+    }
+
+    return multiPolygon;
+  }
+
+  private GeospatialCollection collection(final Iterator<JsonNode> itor, final ODataJClientEdmPrimitiveType type,
+          final String crs) {
+
+    GeospatialCollection collection = null;
+
+    if (itor.hasNext()) {
+      final List<Geospatial> geospatials = new ArrayList<Geospatial>();
+
+      while (itor.hasNext()) {
+        final JsonNode geo = itor.next();
+        final String collItemType = geo.get(Constants.ATTR_TYPE).asText();
+        final String callAsType;
+        if (ODataJClientEdmPrimitiveType.GeographyCollection.name().equals(collItemType)
+                || ODataJClientEdmPrimitiveType.GeometryCollection.name().equals(collItemType)) {
+
+          callAsType = collItemType;
+        } else {
+          callAsType = (type == ODataJClientEdmPrimitiveType.GeographyCollection ? "Geography" : "Geometry")
+                  + collItemType;
+        }
+
+        geospatials.add(deserialize(geo, ODataJClientEdmPrimitiveType.valueOf(callAsType)));
+      }
+
+      collection = new GeospatialCollection(GeoUtils.getDimension(type), crs, geospatials);
+    } else {
+      collection = new GeospatialCollection(GeoUtils.getDimension(type), crs, Collections.<Geospatial>emptyList());
+    }
+
+    return collection;
+  }
+
+  public Geospatial deserialize(final JsonNode node, final ODataJClientEdmPrimitiveType type) {
+    final ODataJClientEdmPrimitiveType actualType;
+    if ((type == ODataJClientEdmPrimitiveType.Geography || type == ODataJClientEdmPrimitiveType.Geometry)
+            && node.has(Constants.ATTR_TYPE)) {
+
+      String nodeType = node.get(Constants.ATTR_TYPE).asText();
+      if (nodeType.startsWith("Geo")) {
+        final int yIdx = nodeType.indexOf('y');
+        nodeType = nodeType.substring(yIdx + 1);
+      }
+      actualType = ODataJClientEdmPrimitiveType.fromValue(type.toString() + nodeType);
+    } else {
+      actualType = type;
+    }
+
+    final Iterator<JsonNode> cooItor = node.has(Constants.JSON_COORDINATES)
+            ? node.get(Constants.JSON_COORDINATES).elements()
+            : Collections.<JsonNode>emptyList().iterator();
+
+    String crs = null;
+    if (node.has(Constants.JSON_CRS)) {
+      crs = node.get(Constants.JSON_CRS).get(Constants.PROPERTIES).get(Constants.NAME).asText().split(":")[1];
+    }
+
+    Geospatial value = null;
+    switch (actualType) {
+      case GeographyPoint:
+      case GeometryPoint:
+        value = point(cooItor, type, crs);
+        break;
+
+      case GeographyMultiPoint:
+      case GeometryMultiPoint:
+        value = multipoint(cooItor, type, crs);
+        break;
+
+      case GeographyLineString:
+      case GeometryLineString:
+        value = lineString(cooItor, type, crs);
+        break;
+
+      case GeographyMultiLineString:
+      case GeometryMultiLineString:
+        value = multiLineString(cooItor, type, crs);
+        break;
+
+      case GeographyPolygon:
+      case GeometryPolygon:
+        value = polygon(cooItor, type, crs);
+        break;
+
+      case GeographyMultiPolygon:
+      case GeometryMultiPolygon:
+        value = multiPolygon(cooItor, type, crs);
+        break;
+
+      case GeographyCollection:
+      case GeometryCollection:
+        value = collection(node.get(Constants.JSON_GEOMETRIES).elements(), type, crs);
+        break;
+
+      default:
+    }
+
+    return value;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueSerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueSerializer.java
new file mode 100644
index 0000000..207ded6
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONGeoValueSerializer.java
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.client.core.data;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+import java.util.Iterator;
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
+import org.apache.olingo.client.api.domain.geospatial.ComposedGeospatial;
+import org.apache.olingo.client.api.domain.geospatial.Geospatial;
+import org.apache.olingo.client.api.domain.geospatial.GeospatialCollection;
+import org.apache.olingo.client.api.domain.geospatial.LineString;
+import org.apache.olingo.client.api.domain.geospatial.MultiLineString;
+import org.apache.olingo.client.api.domain.geospatial.MultiPoint;
+import org.apache.olingo.client.api.domain.geospatial.MultiPolygon;
+import org.apache.olingo.client.api.domain.geospatial.Point;
+import org.apache.olingo.client.api.domain.geospatial.Polygon;
+
+class JSONGeoValueSerializer {
+
+  private void crs(final JsonGenerator jgen, final String crs) throws IOException {
+    jgen.writeObjectFieldStart(Constants.JSON_CRS);
+    jgen.writeStringField(Constants.ATTR_TYPE, Constants.NAME);
+    jgen.writeObjectFieldStart(Constants.PROPERTIES);
+    jgen.writeStringField(Constants.NAME, "EPSG:" + crs);
+    jgen.writeEndObject();
+    jgen.writeEndObject();
+  }
+
+  private void point(final JsonGenerator jgen, final Point point) throws IOException {
+    jgen.writeNumber(point.getX());
+    jgen.writeNumber(point.getY());
+  }
+
+  private void multipoint(final JsonGenerator jgen, final MultiPoint multiPoint) throws IOException {
+    for (final Iterator<Point> itor = multiPoint.iterator(); itor.hasNext();) {
+      jgen.writeStartArray();
+      point(jgen, itor.next());
+      jgen.writeEndArray();
+    }
+  }
+
+  private void lineString(final JsonGenerator jgen, final ComposedGeospatial<Point> lineString) throws IOException {
+    for (final Iterator<Point> itor = lineString.iterator(); itor.hasNext();) {
+      jgen.writeStartArray();
+      point(jgen, itor.next());
+      jgen.writeEndArray();
+    }
+  }
+
+  private void multiLineString(final JsonGenerator jgen, final MultiLineString multiLineString) throws IOException {
+    for (final Iterator<LineString> itor = multiLineString.iterator(); itor.hasNext();) {
+      jgen.writeStartArray();
+      lineString(jgen, itor.next());
+      jgen.writeEndArray();
+    }
+  }
+
+  private void polygon(final JsonGenerator jgen, final Polygon polygon) throws IOException {
+    if (!polygon.getExterior().isEmpty()) {
+      jgen.writeStartArray();
+      lineString(jgen, polygon.getExterior());
+      jgen.writeEndArray();
+    }
+    if (!polygon.getInterior().isEmpty()) {
+      jgen.writeStartArray();
+      lineString(jgen, polygon.getInterior());
+      jgen.writeEndArray();
+    }
+  }
+
+  private void multiPolygon(final JsonGenerator jgen, final MultiPolygon multiPolygon) throws IOException {
+    for (final Iterator<Polygon> itor = multiPolygon.iterator(); itor.hasNext();) {
+      final Polygon polygon = itor.next();
+      jgen.writeStartArray();
+      polygon(jgen, polygon);
+      jgen.writeEndArray();
+    }
+  }
+
+  private void collection(final JsonGenerator jgen, final GeospatialCollection collection) throws IOException {
+    jgen.writeArrayFieldStart(Constants.JSON_GEOMETRIES);
+    for (final Iterator<Geospatial> itor = collection.iterator(); itor.hasNext();) {
+      jgen.writeStartObject();
+      serialize(jgen, itor.next());
+      jgen.writeEndObject();
+    }
+    jgen.writeEndArray();
+  }
+
+  public void serialize(final JsonGenerator jgen, final Geospatial value) throws IOException {
+    if (value.getEdmSimpleType().equals(ODataJClientEdmPrimitiveType.GeographyCollection)
+            || value.getEdmSimpleType().equals(ODataJClientEdmPrimitiveType.GeometryCollection)) {
+
+      jgen.writeStringField(Constants.ATTR_TYPE, ODataJClientEdmPrimitiveType.GeometryCollection.name());
+    } else {
+      final int yIdx = value.getEdmSimpleType().name().indexOf('y');
+      final String itemType = value.getEdmSimpleType().name().substring(yIdx + 1);
+      jgen.writeStringField(Constants.ATTR_TYPE, itemType);
+    }
+
+    switch (value.getEdmSimpleType()) {
+      case GeographyPoint:
+      case GeometryPoint:
+        jgen.writeArrayFieldStart(Constants.JSON_COORDINATES);
+        point(jgen, (Point) value);
+        jgen.writeEndArray();
+        break;
+
+      case GeographyMultiPoint:
+      case GeometryMultiPoint:
+        jgen.writeArrayFieldStart(Constants.JSON_COORDINATES);
+        multipoint(jgen, (MultiPoint) value);
+        jgen.writeEndArray();
+        break;
+
+      case GeographyLineString:
+      case GeometryLineString:
+        jgen.writeArrayFieldStart(Constants.JSON_COORDINATES);
+        lineString(jgen, (LineString) value);
+        jgen.writeEndArray();
+        break;
+
+      case GeographyMultiLineString:
+      case GeometryMultiLineString:
+        jgen.writeArrayFieldStart(Constants.JSON_COORDINATES);
+        multiLineString(jgen, (MultiLineString) value);
+        jgen.writeEndArray();
+        break;
+
+      case GeographyPolygon:
+      case GeometryPolygon:
+        jgen.writeArrayFieldStart(Constants.JSON_COORDINATES);
+        polygon(jgen, (Polygon) value);
+        jgen.writeEndArray();
+        break;
+
+      case GeographyMultiPolygon:
+      case GeometryMultiPolygon:
+        jgen.writeArrayFieldStart(Constants.JSON_COORDINATES);
+        multiPolygon(jgen, (MultiPolygon) value);
+        jgen.writeEndArray();
+        break;
+
+      case GeographyCollection:
+      case GeometryCollection:
+        collection(jgen, (GeospatialCollection) value);
+        break;
+
+      default:
+    }
+
+    if (value.getCrs() != null) {
+      crs(jgen, value.getCrs());
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyDeserializer.java
index 5800c83..998296b 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyDeserializer.java
@@ -18,7 +18,6 @@
  */
 package org.apache.olingo.client.core.data;
 
-import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.DeserializationContext;
@@ -26,23 +25,14 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import java.io.IOException;
 import java.net.URI;
-import java.util.List;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.ParserConfigurationException;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.client.api.Constants;
-import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
-import org.apache.olingo.client.api.utils.XMLUtils;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
 
 /**
- * Parse JSON string into <tt>JSONProperty</tt>.
+ * Parse JSON string into <tt>JSONPropertyImpl</tt>.
  *
- * @see JSONProperty
+ * @see JSONPropertyImpl
  */
-public class JSONPropertyDeserializer extends ODataJacksonDeserializer<JSONPropertyImpl> {
+public class JSONPropertyDeserializer extends AbstractJsonDeserializer<JSONPropertyImpl> {
 
   @Override
   protected JSONPropertyImpl doDeserialize(final JsonParser parser, final DeserializationContext ctxt)
@@ -57,64 +47,36 @@ public class JSONPropertyDeserializer extends ODataJacksonDeserializer<JSONPrope
       tree.remove(Constants.JSON_METADATA);
     }
 
-    try {
-      final DocumentBuilder builder = XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder();
-      final Document document = builder.newDocument();
-
-      Element content = document.createElement(Constants.ELEM_PROPERTY);
-
-      if (property.getMetadata() != null) {
-        final String metadataURI = property.getMetadata().toASCIIString();
-        final int dashIdx = metadataURI.lastIndexOf('#');
-        if (dashIdx != -1) {
-          content.setAttribute(Constants.ATTR_M_TYPE, metadataURI.substring(dashIdx + 1));
-        }
+    if (property.getMetadata() != null) {
+      final String metadataURI = property.getMetadata().toASCIIString();
+      final int dashIdx = metadataURI.lastIndexOf('#');
+      if (dashIdx != -1) {
+        property.setType(metadataURI.substring(dashIdx + 1));
       }
+    }
 
-      JsonNode subtree = null;
-      if (tree.has(Constants.JSON_VALUE)) {
-        if (tree.has(Constants.JSON_TYPE)
-                && StringUtils.isBlank(content.getAttribute(Constants.ATTR_M_TYPE))) {
+    if (tree.has(Constants.JSON_TYPE) && property.getType() == null) {
+      property.setType(tree.get(Constants.JSON_TYPE).asText());
+    }
 
-          content.setAttribute(Constants.ATTR_M_TYPE, tree.get(Constants.JSON_TYPE).asText());
-        }
+    if (tree.has(Constants.JSON_NULL) && tree.get(Constants.JSON_NULL).asBoolean()) {
+      property.setValue(new NullValueImpl());
+    }
 
-        final JsonNode value = tree.get(Constants.JSON_VALUE);
-        if (value.isValueNode()) {
-          content.appendChild(document.createTextNode(value.asText()));
-        } else if (ODataJClientEdmPrimitiveType.isGeospatial(content.getAttribute(Constants.ATTR_M_TYPE))) {
-          subtree = tree.objectNode();
-          ((ObjectNode) subtree).put(Constants.JSON_VALUE, tree.get(Constants.JSON_VALUE));
-          if (StringUtils.isNotBlank(content.getAttribute(Constants.ATTR_M_TYPE))) {
-            ((ObjectNode) subtree).put(
-                    Constants.JSON_VALUE + "@" + Constants.JSON_TYPE,
-                    content.getAttribute(Constants.ATTR_M_TYPE));
-          }
-        } else {
-          subtree = tree.get(Constants.JSON_VALUE);
-        }
+    JsonNode subtree = null;
+    if (tree.has(Constants.JSON_VALUE)) {
+      final JsonNode value = tree.get(Constants.JSON_VALUE);
+      if (value.isValueNode()) {
+        property.setValue(new PrimitiveValueImpl(value.asText()));
       } else {
-        subtree = tree;
-      }
-
-      if (subtree != null) {
-        JSONDOMTreeUtils.buildSubtree(client, content, subtree);
-      }
-
-      final List<Node> children = XMLUtils.getChildNodes(content, Node.ELEMENT_NODE);
-      if (children.size() == 1) {
-        final Element value = (Element) children.iterator().next();
-        if (Constants.JSON_VALUE.equals(XMLUtils.getSimpleName(value))) {
-          if (StringUtils.isNotBlank(content.getAttribute(Constants.ATTR_M_TYPE))) {
-            value.setAttribute(Constants.ATTR_M_TYPE, content.getAttribute(Constants.ATTR_M_TYPE));
-          }
-          content = value;
-        }
+        subtree = tree.get(Constants.JSON_VALUE);
       }
+    } else {
+      subtree = tree;
+    }
 
-      property.setContent(content);
-    } catch (ParserConfigurationException e) {
-      throw new JsonParseException("Cannot build property", parser.getCurrentLocation(), e);
+    if (property.getValue() == null && subtree != null) {
+      value(property, subtree);
     }
 
     return property;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyImpl.java
index 66b889a..1002d3b 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyImpl.java
@@ -21,21 +21,18 @@ package org.apache.olingo.client.core.data;
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import java.net.URI;
-import org.w3c.dom.Element;
 
 /**
  * A single property (primitive, complex or collection) represented via JSON.
  */
 @JsonSerialize(using = JSONPropertySerializer.class)
 @JsonDeserialize(using = JSONPropertyDeserializer.class)
-public class JSONPropertyImpl extends AbstractPayloadObject {
+public class JSONPropertyImpl extends AbstractPropertyImpl {
 
   private static final long serialVersionUID = 553414431536637434L;
 
   private URI metadata;
 
-  private Element content;
-
   /**
    * Gets metadata URI.
    *
@@ -53,22 +50,4 @@ public class JSONPropertyImpl extends AbstractPayloadObject {
   public void setMetadata(final URI metadata) {
     this.metadata = metadata;
   }
-
-  /**
-   * Gets content.
-   *
-   * @return content as DOM element.
-   */
-  public Element getContent() {
-    return content;
-  }
-
-  /**
-   * Sets content.
-   *
-   * @param content content as DOM element.
-   */
-  public void setContent(final Element content) {
-    this.content = content;
-  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertySerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertySerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertySerializer.java
index 1752e46..21e017b 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertySerializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertySerializer.java
@@ -19,28 +19,22 @@
 package org.apache.olingo.client.core.data;
 
 import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.core.JsonLocation;
-import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.SerializerProvider;
 import java.io.IOException;
-import javax.xml.parsers.DocumentBuilder;
 import org.apache.olingo.client.api.Constants;
-import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
-import org.apache.olingo.client.api.utils.XMLUtils;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
+import org.apache.olingo.client.api.data.Property;
 
 /**
- * Writes out JSON string from <tt>JSONProperty</tt>.
+ * Writes out JSON string from <tt>JSONPropertyImpl</tt>.
  *
- * @see JSONProperty
+ * @see JSONPropertyImpl
  */
-public class JSONPropertySerializer extends ODataJacksonSerializer<JSONPropertyImpl> {
+public class JSONPropertySerializer extends AbstractJsonSerializer<JSONPropertyImpl> {
 
   @Override
-  public void doSerialize(final JSONPropertyImpl property, final JsonGenerator jgen, final SerializerProvider provider)
-          throws IOException, JsonProcessingException {
+  protected void doSerialize(final JSONPropertyImpl property, final JsonGenerator jgen,
+          final SerializerProvider provider) throws IOException, JsonProcessingException {
 
     jgen.writeStartObject();
 
@@ -48,30 +42,15 @@ public class JSONPropertySerializer extends ODataJacksonSerializer<JSONPropertyI
       jgen.writeStringField(Constants.JSON_METADATA, property.getMetadata().toASCIIString());
     }
 
-    final Element content = property.getContent();
-    if (XMLUtils.hasOnlyTextChildNodes(content)) {
-      jgen.writeStringField(Constants.JSON_VALUE, content.getTextContent());
-    } else {
-      try {
-        final DocumentBuilder builder = XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder();
-        final Document document = builder.newDocument();
-        final Element wrapper = document.createElement(Constants.ELEM_PROPERTY);
-
-        if (XMLUtils.hasElementsChildNode(content)) {
-          wrapper.appendChild(document.renameNode(
-                  document.importNode(content, true), null, Constants.JSON_VALUE));
-
-          JSONDOMTreeUtils.writeSubtree(client, jgen, wrapper);
-        } else if (ODataJClientEdmPrimitiveType.isGeospatial(content.getAttribute(Constants.ATTR_M_TYPE))) {
-          wrapper.appendChild(document.renameNode(
-                  document.importNode(content, true), null, Constants.JSON_VALUE));
-
-          JSONDOMTreeUtils.writeSubtree(client, jgen, wrapper, true);
-        } else {
-          JSONDOMTreeUtils.writeSubtree(client, jgen, content);
-        }
-      } catch (Exception e) {
-        throw new JsonParseException("Cannot serialize property", JsonLocation.NA, e);
+    if (property.getValue().isNull()) {
+      jgen.writeBooleanField(Constants.JSON_NULL, true);
+    } else if (property.getValue().isSimple()) {
+      jgen.writeStringField(Constants.JSON_VALUE, property.getValue().asSimple().get());
+    } else if (property.getValue().isGeospatial() || property.getValue().isCollection()) {
+      property(jgen, property, Constants.JSON_VALUE);
+    } else if (property.getValue().isComplex()) {
+      for (Property cproperty : property.getValue().asComplex().get()) {
+        property(jgen, cproperty, cproperty.getName());
       }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/LinkImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/LinkImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/LinkImpl.java
index 9ba76dc..2bba504 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/LinkImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/LinkImpl.java
@@ -34,6 +34,8 @@ public class LinkImpl extends AbstractPayloadObject implements Link {
 
   private String type;
 
+  private String mediaETag;
+
   private Entry entry;
 
   private Feed feed;
@@ -79,6 +81,16 @@ public class LinkImpl extends AbstractPayloadObject implements Link {
   }
 
   @Override
+  public String getMediaETag() {
+    return mediaETag;
+  }
+
+  @Override
+  public void setMediaETag(final String mediaETag) {
+    this.mediaETag = mediaETag;
+  }
+
+  @Override
   public Entry getInlineEntry() {
     return entry;
   }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/NullValueImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/NullValueImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/NullValueImpl.java
new file mode 100644
index 0000000..83e6785
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/NullValueImpl.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.client.core.data;
+
+import org.apache.olingo.client.api.data.NullValue;
+
+public class NullValueImpl extends AbstractValue implements NullValue {
+
+  @Override
+  public boolean isNull() {
+    return true;
+  }
+
+  @Override
+  public Void get() {
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/PrimitiveValueImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/PrimitiveValueImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/PrimitiveValueImpl.java
new file mode 100644
index 0000000..6d61cf4
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/PrimitiveValueImpl.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.client.core.data;
+
+import org.apache.olingo.client.api.data.PrimitiveValue;
+
+public class PrimitiveValueImpl extends AbstractValue implements PrimitiveValue {
+
+  private final String value;
+
+  public PrimitiveValueImpl(final String value) {
+    this.value = value;
+  }
+
+  @Override
+  public boolean isSimple() {
+    return true;
+  }
+
+  @Override
+  public String get() {
+    return value;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java
index 2cfb2cb..3ed86dc 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmTypeInfo.java
@@ -119,7 +119,7 @@ public class EdmTypeInfo {
     } catch (IllegalArgumentException e) {
       LOG.debug("{} does not appear to refer to an Edm primitive type", this.fullQualifiedName);
     }
-    // TODO: implement Geospatial types!
+    // TODO - OLINGO-65 implement Geospatial types!
     this.geospatialType = this.fullQualifiedName.getNamespace().equals(EdmPrimitiveType.EDM_NAMESPACE)
             && this.fullQualifiedName.getName().startsWith("Geo");
     if (this.primitiveType == null && this.edm != null) {

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/xml/EdmxDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/xml/EdmxDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/xml/EdmxDeserializer.java
index 0f4b451..796624b 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/xml/EdmxDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/xml/EdmxDeserializer.java
@@ -29,7 +29,6 @@ import com.fasterxml.jackson.databind.DeserializationContext;
 
 import java.io.IOException;
 
-@SuppressWarnings("rawtypes")
 public class EdmxDeserializer extends AbstractEdmDeserializer<AbstractEdmx> {
 
   @Override
@@ -59,7 +58,7 @@ public class EdmxDeserializer extends AbstractEdmDeserializer<AbstractEdmx> {
         } else if ("Reference".equals(jp.getCurrentName())) {
           jp.nextToken();
           ((org.apache.olingo.client.core.edm.xml.v4.EdmxImpl) edmx).getReferences().
-                  add(jp.readValueAs( ReferenceImpl.class));
+                  add(jp.readValueAs(ReferenceImpl.class));
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/xml/v4/AnnotationDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/xml/v4/AnnotationDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/xml/v4/AnnotationDeserializer.java
index c5c3bb6..7de7a3e 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/xml/v4/AnnotationDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/xml/v4/AnnotationDeserializer.java
@@ -48,7 +48,7 @@ public class AnnotationDeserializer extends AbstractEdmDeserializer<AnnotationIm
           annotation.setConstExpr(parseAnnotationConstExprConstruct(jp));
         } else {
           // Dynamic Expressions
-          annotation.setDynExpr(jp.readValueAs( DynExprConstructImpl.class));
+          annotation.setDynExpr(jp.readValueAs(DynExprConstructImpl.class));
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
index bdb968c..990a942 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
@@ -20,19 +20,18 @@ package org.apache.olingo.client.core.op.impl;
 
 import java.io.StringWriter;
 import java.net.URI;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.ParserConfigurationException;
-
+import java.util.Iterator;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.data.Entry;
 import org.apache.olingo.client.api.data.Feed;
 import org.apache.olingo.client.api.data.Link;
 import org.apache.olingo.client.api.data.LinkCollection;
-import org.apache.olingo.client.api.domain.ODataOperation;
+import org.apache.olingo.client.api.data.Property;
 import org.apache.olingo.client.api.data.ServiceDocument;
 import org.apache.olingo.client.api.data.ServiceDocumentItem;
+import org.apache.olingo.client.api.data.Value;
 import org.apache.olingo.client.api.domain.ODataCollectionValue;
 import org.apache.olingo.client.api.domain.ODataComplexValue;
 import org.apache.olingo.client.api.domain.ODataEntity;
@@ -40,26 +39,26 @@ import org.apache.olingo.client.api.domain.ODataEntitySet;
 import org.apache.olingo.client.api.domain.ODataGeospatialValue;
 import org.apache.olingo.client.api.domain.ODataInlineEntity;
 import org.apache.olingo.client.api.domain.ODataInlineEntitySet;
-import org.apache.olingo.client.api.domain.ODataJClientEdmType;
+import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
 import org.apache.olingo.client.api.domain.ODataLink;
 import org.apache.olingo.client.api.domain.ODataLinkCollection;
+import org.apache.olingo.client.api.domain.ODataOperation;
 import org.apache.olingo.client.api.domain.ODataPrimitiveValue;
 import org.apache.olingo.client.api.domain.ODataProperty;
-import org.apache.olingo.client.api.domain.ODataProperty.PropertyType;
 import org.apache.olingo.client.api.domain.ODataServiceDocument;
 import org.apache.olingo.client.api.domain.ODataValue;
 import org.apache.olingo.client.api.format.ODataPubFormat;
 import org.apache.olingo.client.api.op.ODataBinder;
-import org.apache.olingo.client.api.utils.XMLUtils;
 import org.apache.olingo.client.api.utils.URIUtils;
+import org.apache.olingo.client.core.data.CollectionValueImpl;
+import org.apache.olingo.client.core.data.ComplexValueImpl;
+import org.apache.olingo.client.core.data.GeospatialValueImpl;
+import org.apache.olingo.client.core.data.JSONPropertyImpl;
 import org.apache.olingo.client.core.data.LinkImpl;
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.client.core.data.NullValueImpl;
+import org.apache.olingo.client.core.data.PrimitiveValueImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 
 public abstract class AbstractODataBinder implements ODataBinder {
 
@@ -76,25 +75,6 @@ public abstract class AbstractODataBinder implements ODataBinder {
     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(Constants.ELEM_PROPERTIES);
-      properties.setAttribute(Constants.XMLNS_METADATA,
-              client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA));
-      properties.setAttribute(Constants.XMLNS_DATASERVICES,
-              client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES));
-      properties.setAttribute(Constants.XMLNS_GML, Constants.NS_GML);
-      properties.setAttribute(Constants.XMLNS_GEORSS, Constants.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();
@@ -113,6 +93,8 @@ public abstract class AbstractODataBinder implements ODataBinder {
   public Feed getFeed(final ODataEntitySet feed, final Class<? extends Feed> reference) {
     final Feed feedResource = ResourceFactory.newFeed(reference);
 
+    feedResource.setCount(feed.getCount());
+
     final URI next = feed.getNext();
     if (next != null) {
       feedResource.setNext(next);
@@ -188,30 +170,94 @@ public abstract class AbstractODataBinder implements ODataBinder {
     }
     // -------------------------------------------------------------
 
-    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));
+    for (ODataProperty property : entity.getProperties()) {
+      entry.getProperties().add(getProperty(property, reference, 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);
+  public Link getLink(final ODataLink link, boolean isXML) {
+    final Link linkResource = new LinkImpl();
+    linkResource.setRel(link.getRel());
+    linkResource.setTitle(link.getName());
+    linkResource.setHref(link.getLink() == null ? null : link.getLink().toASCIIString());
+    linkResource.setType(link.getType().toString());
+    linkResource.setMediaETag(link.getMediaETag());
+
+    if (link instanceof ODataInlineEntity) {
+      // append inline entity
+      final ODataEntity inlineEntity = ((ODataInlineEntity) link).getEntity();
+      LOG.debug("Append in-line entity\n{}", inlineEntity);
+
+      linkResource.setInlineEntry(getEntry(inlineEntity, ResourceFactory.entryClassForFormat(isXML)));
+    } else if (link instanceof ODataInlineEntitySet) {
+      // append inline feed
+      final ODataEntitySet InlineFeed = ((ODataInlineEntitySet) link).getEntitySet();
+      LOG.debug("Append in-line feed\n{}", InlineFeed);
+
+      linkResource.setInlineFeed(getFeed(InlineFeed, ResourceFactory.feedClassForFormat(isXML)));
+    }
+
+    return linkResource;
+  }
+
+  @Override
+  public Property getProperty(final ODataProperty property, final Class<? extends Entry> reference,
+          final boolean setType) {
+
+    final Property propertyResource = ResourceFactory.newProperty(reference);
+    propertyResource.setName(property.getName());
+    propertyResource.setValue(getValue(property.getValue(), reference, setType));
+
+    if (setType) {
+      if (property.hasPrimitiveValue()) {
+        propertyResource.setType(property.getPrimitiveValue().getTypeName());
+      } else if (property.hasComplexValue()) {
+        propertyResource.setType(property.getComplexValue().getTypeName());
+      } else if (property.hasCollectionValue()) {
+        propertyResource.setType(property.getCollectionValue().getTypeName());
+      }
+    }
+
+    return propertyResource;
+  }
+
+  private Value getValue(final ODataValue value, final Class<? extends Entry> reference, final boolean setType) {
+    Value valueResource = null;
+
+    if (value == null) {
+      valueResource = new NullValueImpl();
+    } else if (value.isPrimitive()) {
+      final ODataPrimitiveValue _value = value.asPrimitive();
+      if (_value instanceof ODataGeospatialValue) {
+        valueResource = new GeospatialValueImpl(((ODataGeospatialValue) _value).getGeospatial());
+      } else {
+        valueResource = new PrimitiveValueImpl(_value.toString());
+      }
+    } else if (value.isComplex()) {
+      final ODataComplexValue _value = value.asComplex();
+      valueResource = new ComplexValueImpl();
+
+      for (final Iterator<ODataProperty> itor = _value.iterator(); itor.hasNext();) {
+        valueResource.asComplex().get().add(getProperty(itor.next(), reference, setType));
+      }
+    } else if (value.isCollection()) {
+      final ODataCollectionValue _value = value.asCollection();
+      valueResource = new CollectionValueImpl();
+
+      for (final Iterator<ODataValue> itor = _value.iterator(); itor.hasNext();) {
+        valueResource.asCollection().get().add(getValue(itor.next(), reference, setType));
+      }
     }
+
+    return valueResource;
   }
 
   @Override
@@ -316,287 +362,55 @@ public abstract class AbstractODataBinder implements ODataBinder {
       entity.getOperations().add(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.getProperties().add(getODataProperty((Element) property));
-        } catch (IllegalArgumentException e) {
-          LOG.warn("Failure retrieving EdmType for {}", property.getTextContent(), e);
-        }
-      }
     }
 
-    return entity;
-  }
-
-  @Override
-  public Link getLink(final ODataLink link, boolean isXML) {
-    final Link linkResource = new LinkImpl();
-    linkResource.setRel(link.getRel());
-    linkResource.setTitle(link.getName());
-    linkResource.setHref(link.getLink() == null ? null : link.getLink().toASCIIString());
-    linkResource.setType(link.getType().toString());
-
-    if (link instanceof ODataInlineEntity) {
-      // append inline entity
-      final ODataEntity inlineEntity = ((ODataInlineEntity) link).getEntity();
-      LOG.debug("Append in-line entity\n{}", inlineEntity);
-
-      linkResource.setInlineEntry(getEntry(inlineEntity, ResourceFactory.entryClassForFormat(isXML)));
-    } else if (link instanceof ODataInlineEntitySet) {
-      // append inline feed
-      final ODataEntitySet InlineFeed = ((ODataInlineEntitySet) link).getEntitySet();
-      LOG.debug("Append in-line feed\n{}", InlineFeed);
-
-      linkResource.setInlineFeed(getFeed(InlineFeed, ResourceFactory.feedClassForFormat(isXML)));
+    for (Property property : resource.getProperties()) {
+      entity.getProperties().add(getODataProperty(property));
     }
 
-    return linkResource;
+    return entity;
   }
 
   @Override
-  public ODataProperty getODataProperty(final Element property) {
-    final ODataProperty res;
-
-    final Node nullNode = property.getAttributes().getNamedItem(Constants.ATTR_M_NULL);
-
-    if (nullNode == null) {
-      final ODataJClientEdmType edmType = StringUtils.isBlank(property.getAttribute(Constants.ATTR_M_TYPE))
-              ? null
-              : new ODataJClientEdmType(property.getAttribute(Constants.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;
+  public ODataProperty getODataProperty(final Property property) {
+    return new ODataProperty(property.getName(), getODataValue(property));
   }
 
-  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(Constants.PREFIX_GML)) {
-
-          res = Constants.ELEM_ELEMENT.equals(XMLUtils.getSimpleName(child))
-                  ? PropertyType.COLLECTION
-                  : PropertyType.COMPLEX;
-        }
+  private ODataValue getODataValue(final Property resource) {
+    ODataValue value = null;
+
+    if (resource.getValue().isSimple()) {
+      value = new ODataPrimitiveValue.Builder(client).setText(resource.getValue().asSimple().get()).
+              setType(resource.getType() == null
+                      ? null
+                      : ODataJClientEdmPrimitiveType.fromValue(resource.getType())).build();
+    } else if (resource.getValue().isGeospatial()) {
+      value = new ODataGeospatialValue.Builder(client).setValue(resource.getValue().asGeospatial().get()).
+              setType(resource.getType() == null
+                      || ODataJClientEdmPrimitiveType.Geography.toString().equals(resource.getType())
+                      || ODataJClientEdmPrimitiveType.Geometry.toString().equals(resource.getType())
+                      ? null
+                      : ODataJClientEdmPrimitiveType.fromValue(resource.getType())).build();
+    } else if (resource.getValue().isComplex()) {
+      value = new ODataComplexValue(resource.getType());
+
+      for (Property property : resource.getValue().asComplex().get()) {
+        value.asComplex().add(getODataProperty(property));
       }
-    } else {
-      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(Constants.XMLNS_METADATA,
-            client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA));
-    element.setAttribute(Constants.XMLNS_DATASERVICES,
-            client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES));
-    element.setAttribute(Constants.XMLNS_GML, Constants.NS_GML);
-    element.setAttribute(Constants.XMLNS_GEORSS, Constants.NS_GEORSS);
-
-    return element;
-  }
-
-  protected Element toNullPropertyElement(final ODataProperty prop, final Document doc) {
-    final Element element = doc.createElement(Constants.PREFIX_DATASERVICES + prop.getName());
-    element.setAttribute(Constants.ATTR_M_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(Constants.PREFIX_DATASERVICES + name);
-    if (setType) {
-      element.setAttribute(Constants.ATTR_M_TYPE, value.getTypeName());
-    }
-
-    if (value instanceof ODataGeospatialValue) {
-      element.appendChild(doc.importNode(((ODataGeospatialValue) value).toTree(), true));
-    } else {
-      element.setTextContent(value.toString());
-    }
-
-    return element;
-  }
+    } else if (resource.getValue().isCollection()) {
+      value = new ODataCollectionValue(resource.getType());
 
-  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(Constants.PREFIX_DATASERVICES + prop.getName());
-    if (value.getTypeName() != null && setType) {
-      element.setAttribute(Constants.ATTR_M_TYPE, value.getTypeName());
-    }
-
-    for (ODataValue el : value) {
-      if (el.isPrimitive()) {
-        element.appendChild(
-                toPrimitivePropertyElement(Constants.ELEM_ELEMENT, el.asPrimitive(), doc, setType));
-      } else {
-        element.appendChild(
-                toComplexPropertyElement(Constants.ELEM_ELEMENT, el.asComplex(), doc, setType));
+      for (Value _value : resource.getValue().asCollection().get()) {
+        final JSONPropertyImpl fake = new JSONPropertyImpl();
+        fake.setValue(_value);
+        value.asCollection().add(getODataValue(fake));
       }
     }
 
-    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(Constants.PREFIX_DATASERVICES + name);
-    if (value.getTypeName() != null && setType) {
-      element.setAttribute(Constants.ATTR_M_TYPE, value.getTypeName());
-    }
-
-    for (ODataProperty field : value) {
-      element.appendChild(toDOMElement(field, doc, true));
-    }
-    return element;
-  }
-
-  protected ODataPrimitiveValue fromPrimitiveValueElement(final Element prop, final ODataJClientEdmType edmType) {
-    final ODataPrimitiveValue value;
-    if (edmType != null && edmType.getSimpleType().isGeospatial()) {
-      final Element geoProp = Constants.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 ODataJClientEdmType edmType) {
-    return client.getObjectFactory().newPrimitiveProperty(
-            XMLUtils.getSimpleName(prop), fromPrimitiveValueElement(prop, edmType));
-  }
-
-  protected ODataComplexValue fromComplexValueElement(final Element prop, final ODataJClientEdmType edmType) {
-    final ODataComplexValue value = new ODataComplexValue(edmType == null ? null : edmType.getTypeExpression());
-
-    for (Node child : XMLUtils.getChildNodes(prop, Node.ELEMENT_NODE)) {
-      value.add(getODataProperty((Element) child));
-    }
-
     return value;
   }
-
-  protected ODataProperty fromComplexPropertyElement(final Element prop, final ODataJClientEdmType edmType) {
-    return client.getObjectFactory().newComplexProperty(XMLUtils.getSimpleName(prop),
-            fromComplexValueElement(prop, edmType));
-  }
-
-  protected ODataProperty fromCollectionPropertyElement(final Element prop, final ODataJClientEdmType edmType) {
-    final ODataCollectionValue value =
-            new ODataCollectionValue(edmType == null ? null : edmType.getTypeExpression());
-
-    final ODataJClientEdmType type = edmType == null ? null : new ODataJClientEdmType(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);
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
index c3c5fb0..14357cb 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
@@ -18,26 +18,20 @@
  */
 package org.apache.olingo.client.core.op.impl;
 
-import com.fasterxml.aalto.stax.InputFactoryImpl;
-import com.fasterxml.aalto.stax.OutputFactoryImpl;
-import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
-import com.fasterxml.jackson.dataformat.xml.XmlFactory;
-import com.fasterxml.jackson.dataformat.xml.XmlMapper;
-
-import java.io.IOException;
 import java.io.InputStream;
-import java.net.URI;
-
 import org.apache.olingo.client.api.ODataClient;
-import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.data.Entry;
 import org.apache.olingo.client.api.data.Error;
 import org.apache.olingo.client.api.data.Feed;
 import org.apache.olingo.client.api.data.LinkCollection;
+import org.apache.olingo.client.api.data.Property;
 import org.apache.olingo.client.api.format.ODataFormat;
 import org.apache.olingo.client.api.format.ODataPubFormat;
 import org.apache.olingo.client.api.op.ODataDeserializer;
 import org.apache.olingo.client.core.data.AtomDeserializer;
+import org.apache.olingo.client.core.data.AtomEntryImpl;
+import org.apache.olingo.client.core.data.AtomFeedImpl;
+import org.apache.olingo.client.core.data.AtomPropertyImpl;
 import org.apache.olingo.client.core.data.JSONEntryImpl;
 import org.apache.olingo.client.core.data.JSONErrorBundle;
 import org.apache.olingo.client.core.data.JSONFeedImpl;
@@ -45,9 +39,6 @@ import org.apache.olingo.client.core.data.JSONLinkCollectionImpl;
 import org.apache.olingo.client.core.data.JSONPropertyImpl;
 import org.apache.olingo.client.core.data.XMLErrorImpl;
 import org.apache.olingo.client.core.data.XMLLinkCollectionImpl;
-import org.apache.olingo.client.core.xml.XMLParser;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
 
 public abstract class AbstractODataDeserializer extends AbstractJacksonTool implements ODataDeserializer {
 
@@ -57,135 +48,70 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl
 
   public AbstractODataDeserializer(final ODataClient client) {
     super(client);
-    this.atomDeserializer = new AtomDeserializer(client);
+
+    this.atomDeserializer = new AtomDeserializer(client.getServiceVersion());
   }
 
   @Override
   public Feed toFeed(final InputStream input, final ODataPubFormat format) {
     return format == ODataPubFormat.ATOM
-            ? toAtomFeed(input)
-            : toJSONFeed(input);
+            ? atom(input, AtomFeedImpl.class)
+            : json(input, JSONFeedImpl.class);
   }
 
   @Override
   public Entry toEntry(final InputStream input, final ODataPubFormat format) {
     return format == ODataPubFormat.ATOM
-            ? toAtomEntry(input)
-            : toJSONEntry(input);
+            ? atom(input, AtomEntryImpl.class)
+            : json(input, JSONEntryImpl.class);
   }
 
   @Override
-  public Element toPropertyDOM(final InputStream input, final ODataFormat format) {
+  public Property toProperty(final InputStream input, final ODataFormat format) {
     return format == ODataFormat.XML
-            ? toPropertyDOMFromXML(input)
-            : toPropertyDOMFromJSON(input);
+            ? atom(input, AtomPropertyImpl.class)
+            : json(input, JSONPropertyImpl.class);
   }
 
   @Override
   public LinkCollection toLinkCollection(final InputStream input, final ODataFormat format) {
     return format == ODataFormat.XML
-            ? toLinkCollectionFromXML(input)
-            : toLinkCollectionFromJSON(input);
+            ? xml(input, XMLLinkCollectionImpl.class)
+            : json(input, JSONLinkCollectionImpl.class);
   }
 
   @Override
   public Error toError(final InputStream input, final boolean isXML) {
     return isXML
-            ? toErrorFromXML(input)
-            : toErrorFromJSON(input);
-  }
-
-  @Override
-  public Element toDOM(final InputStream input) {
-    return XMLParser.PARSER.deserialize(input);
+            ? xml(input, XMLErrorImpl.class)
+            : json(input, JSONErrorBundle.class).getError();
   }
 
   /*
    * ------------------ Protected methods ------------------
    */
-  protected Feed toAtomFeed(final InputStream input) {
+  protected <T> T xml(final InputStream input, final Class<T> reference) {
     try {
-      return atomDeserializer.feed(toDOM(input));
+      return getXmlMapper().readValue(input, reference);
     } catch (Exception e) {
-      throw new IllegalArgumentException("While deserializing Atom feed", e);
+      throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
     }
   }
 
-  protected Entry toAtomEntry(final InputStream input) {
+  protected <T> T atom(final InputStream input, final Class<T> reference) {
     try {
-      return atomDeserializer.entry(toDOM(input));
+      return atomDeserializer.read(input, reference);
     } catch (Exception e) {
-      throw new IllegalArgumentException("While deserializing Atom entry", e);
+      throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
     }
   }
 
-  protected Feed toJSONFeed(final InputStream input) {
+  protected <T> T json(final InputStream input, final Class<T> reference) {
     try {
-      return getObjectMapper().readValue(input, JSONFeedImpl.class);
-    } catch (IOException e) {
-      throw new IllegalArgumentException("While deserializing JSON feed", e);
-    }
-  }
-
-  protected Entry toJSONEntry(final InputStream input) {
-    try {
-      return getObjectMapper().readValue(input, JSONEntryImpl.class);
-    } catch (IOException e) {
-      throw new IllegalArgumentException("While deserializing JSON entry", e);
-    }
-  }
-
-  protected Element toPropertyDOMFromXML(final InputStream input) {
-    return toDOM(input);
-  }
-
-  protected Element toPropertyDOMFromJSON(final InputStream input) {
-    try {
-      return getObjectMapper().readValue(input, JSONPropertyImpl.class).getContent();
-    } catch (IOException e) {
-      throw new IllegalArgumentException("While deserializing JSON property", e);
-    }
-  }
-
-  protected XMLLinkCollectionImpl toLinkCollectionFromXML(final InputStream input) {
-    final Element root = toDOM(input);
-
-    final NodeList uris = root.getOwnerDocument().getElementsByTagName(Constants.ELEM_URI);
-
-    final NodeList next = root.getElementsByTagName(Constants.NEXT_LINK_REL);
-    final XMLLinkCollectionImpl linkCollection = next.getLength() > 0
-            ? new XMLLinkCollectionImpl(URI.create(next.item(0).getTextContent()))
-            : new XMLLinkCollectionImpl();
-    for (int i = 0; i < uris.getLength(); i++) {
-      linkCollection.getLinks().add(URI.create(uris.item(i).getTextContent()));
-    }
-
-    return linkCollection;
-  }
-
-  protected JSONLinkCollectionImpl toLinkCollectionFromJSON(final InputStream input) {
-    try {
-      return getObjectMapper().readValue(input, JSONLinkCollectionImpl.class);
-    } catch (IOException e) {
-      throw new IllegalArgumentException("While deserializing JSON $links", e);
-    }
-  }
-
-  protected Error toErrorFromXML(final InputStream input) {
-    try {
-      final XmlMapper xmlMapper = new XmlMapper(
-              new XmlFactory(new InputFactoryImpl(), new OutputFactoryImpl()), new JacksonXmlModule());
-      return xmlMapper.readValue(input, XMLErrorImpl.class);
+      return getObjectMapper().readValue(input, reference);
     } catch (Exception e) {
-      throw new IllegalArgumentException("While deserializing XML error", e);
+      throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
     }
   }
 
-  protected Error toErrorFromJSON(final InputStream input) {
-    try {
-      return getObjectMapper().readValue(input, JSONErrorBundle.class).getError();
-    } catch (IOException e) {
-      throw new IllegalArgumentException("While deserializing JSON error", e);
-    }
-  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataReader.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataReader.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataReader.java
index dad3707..9cc3c74 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataReader.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataReader.java
@@ -20,10 +20,9 @@ package org.apache.olingo.client.core.op.impl;
 
 import java.io.InputStream;
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.client.api.ODataClient;
-import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.data.Error;
+import org.apache.olingo.client.api.data.Property;
 import org.apache.olingo.client.api.domain.ODataEntity;
 import org.apache.olingo.client.api.domain.ODataEntitySet;
 import org.apache.olingo.client.api.domain.ODataEntitySetIterator;
@@ -39,9 +38,6 @@ import org.apache.olingo.client.api.format.ODataValueFormat;
 import org.apache.olingo.client.api.op.ODataReader;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 
 public abstract class AbstractODataReader implements ODataReader {
 
@@ -70,33 +66,7 @@ public abstract class AbstractODataReader implements ODataReader {
 
   @Override
   public ODataProperty readProperty(final InputStream input, final ODataFormat format) {
-    final Element property = client.getDeserializer().toPropertyDOM(input, format);
-
-    // The ODataProperty object is used either for actual entity properties and for invoke result 
-    // (when return type is neither an entity nor a collection of entities).
-    // Such formats are mostly the same except for collections: an entity property looks like
-    //     <aproperty m:type="Collection(AType)">
-    //       <element>....</element>
-    //     </aproperty>
-    //
-    // while an invoke result with returnType="Collection(AnotherType)" looks like
-    //     <functionImportName>
-    //       <element m:type="AnotherType">...</element>
-    //     <functionImportName>
-    //
-    // The code below is meant for "normalizing" the latter into
-    //     <functionImportName m:type="Collection(AnotherType)">
-    //       <element m:type="AnotherType">...</element>
-    //     <functionImportName>
-    final String type = property.getAttribute(Constants.ATTR_M_TYPE);
-    final NodeList elements = property.getElementsByTagName(Constants.ELEM_ELEMENT);
-    if (StringUtils.isBlank(type) && elements != null && elements.getLength() > 0) {
-      final Node elementType = elements.item(0).getAttributes().getNamedItem(Constants.ATTR_M_TYPE);
-      if (elementType != null) {
-        property.setAttribute(Constants.ATTR_M_TYPE, "Collection(" + elementType.getTextContent() + ")");
-      }
-    }
-
+    final Property property = client.getDeserializer().toProperty(input, format);
     return client.getBinder().getODataProperty(property);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataSerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataSerializer.java
index 8be014c..b847354 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataSerializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataSerializer.java
@@ -20,33 +20,25 @@ package org.apache.olingo.client.core.op.impl;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
-
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
-import javax.xml.parsers.DocumentBuilder;
-
-import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.data.Entry;
 import org.apache.olingo.client.api.data.Feed;
 import org.apache.olingo.client.api.data.Link;
+import org.apache.olingo.client.api.data.Property;
 import org.apache.olingo.client.api.format.ODataFormat;
 import org.apache.olingo.client.api.op.ODataSerializer;
-import org.apache.olingo.client.api.utils.XMLUtils;
-import org.apache.olingo.client.core.data.AbstractPayloadObject;
 import org.apache.olingo.client.core.data.AtomEntryImpl;
 import org.apache.olingo.client.core.data.AtomFeedImpl;
+import org.apache.olingo.client.core.data.AtomPropertyImpl;
 import org.apache.olingo.client.core.data.AtomSerializer;
 import org.apache.olingo.client.core.data.JSONEntryImpl;
 import org.apache.olingo.client.core.data.JSONFeedImpl;
 import org.apache.olingo.client.core.data.JSONPropertyImpl;
-import org.apache.olingo.client.core.xml.XMLParser;
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
 
 public abstract class AbstractODataSerializer extends AbstractJacksonTool implements ODataSerializer {
 
@@ -56,7 +48,8 @@ public abstract class AbstractODataSerializer extends AbstractJacksonTool implem
 
   public AbstractODataSerializer(final ODataClient client) {
     super(client);
-    this.atomSerializer = new AtomSerializer(client);
+
+    this.atomSerializer = new AtomSerializer(client.getServiceVersion());
   }
 
   @Override
@@ -88,16 +81,16 @@ public abstract class AbstractODataSerializer extends AbstractJacksonTool implem
   }
 
   @Override
-  public void property(final Element element, final ODataFormat format, final OutputStream out) {
-    property(element, format, new OutputStreamWriter(out));
+  public void property(final Property obj, final OutputStream out) {
+    property(obj, new OutputStreamWriter(out));
   }
 
   @Override
-  public void property(final Element element, final ODataFormat format, final Writer writer) {
-    if (format == ODataFormat.XML) {
-      dom(element, writer);
+  public void property(final Property obj, final Writer writer) {
+    if (obj instanceof AtomPropertyImpl) {
+      atom((AtomPropertyImpl) obj, writer);
     } else {
-      json(element, writer);
+      json((JSONPropertyImpl) obj, writer);
     }
   }
 
@@ -109,34 +102,24 @@ public abstract class AbstractODataSerializer extends AbstractJacksonTool implem
   @Override
   public void link(final Link link, final ODataFormat format, final Writer writer) {
     if (format == ODataFormat.XML) {
-      xmlLink(link, writer);
+      atom(link, writer);
     } else {
       jsonLink(link, writer);
     }
   }
 
-  @Override
-  public void dom(final Node content, final OutputStream out) {
-    dom(content, new OutputStreamWriter(out));
-  }
-
-  @Override
-  public void dom(final Node content, final Writer writer) {
-    XMLParser.PARSER.serialize(content, writer);
-  }
-
   /*
    * ------------------ Protected methods ------------------
    */
-  protected <T extends AbstractPayloadObject> void atom(final T obj, final Writer writer) {
+  protected <T> void atom(final T obj, final Writer writer) {
     try {
-      dom(atomSerializer.serialize(obj), writer);
+      atomSerializer.write(writer, obj);
     } catch (Exception e) {
       throw new IllegalArgumentException("While serializing Atom object", e);
     }
   }
 
-  protected <T extends AbstractPayloadObject> void json(final T obj, final Writer writer) {
+  protected <T> void json(final T obj, final Writer writer) {
     try {
       getObjectMapper().writeValue(writer, obj);
     } catch (IOException e) {
@@ -144,31 +127,6 @@ public abstract class AbstractODataSerializer extends AbstractJacksonTool implem
     }
   }
 
-  protected void json(final Element element, final Writer writer) {
-    try {
-      final JSONPropertyImpl property = new JSONPropertyImpl();
-      property.setContent(element);
-      getObjectMapper().writeValue(writer, property);
-    } catch (IOException e) {
-      throw new IllegalArgumentException("While serializing JSON property", e);
-    }
-  }
-
-  protected void xmlLink(final Link link, final Writer writer) {
-    try {
-      final DocumentBuilder builder = XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder();
-      final Document doc = builder.newDocument();
-      final Element uri = doc.createElementNS(
-              client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES),
-              Constants.ELEM_URI);
-      uri.appendChild(doc.createTextNode(link.getHref()));
-
-      dom(uri, writer);
-    } catch (Exception e) {
-      throw new IllegalArgumentException("While serializing XML link", e);
-    }
-  }
-
   protected void jsonLink(final Link link, final Writer writer) {
     final ObjectMapper mapper = getObjectMapper();
     final ObjectNode uri = mapper.createObjectNode();

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataObjectFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataObjectFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataObjectFactoryImpl.java
index 56767a6..023ac9e 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataObjectFactoryImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataObjectFactoryImpl.java
@@ -160,7 +160,8 @@ public class ODataObjectFactoryImpl implements ODataObjectFactory {
    */
   @Override
   public ODataLink newEntityNavigationLink(final String name, final URI link) {
-    return new ODataLink(client.getServiceVersion(), link, ODataLinkType.ENTITY_NAVIGATION, name);
+    return new ODataLink.Builder().setVersion(client.getServiceVersion()).setURI(link).
+            setType(ODataLinkType.ENTITY_NAVIGATION).setTitle(name).build();
   }
 
   /**
@@ -173,7 +174,8 @@ public class ODataObjectFactoryImpl implements ODataObjectFactory {
    */
   @Override
   public ODataLink newEntityNavigationLink(final String name, final URI baseURI, final String href) {
-    return new ODataLink(client.getServiceVersion(), baseURI, href, ODataLinkType.ENTITY_NAVIGATION, name);
+    return new ODataLink.Builder().setVersion(client.getServiceVersion()).setURI(baseURI, href).
+            setType(ODataLinkType.ENTITY_NAVIGATION).setTitle(name).build();
   }
 
   /**
@@ -185,7 +187,8 @@ public class ODataObjectFactoryImpl implements ODataObjectFactory {
    */
   @Override
   public ODataLink newFeedNavigationLink(final String name, final URI link) {
-    return new ODataLink(client.getServiceVersion(), link, ODataLinkType.ENTITY_SET_NAVIGATION, name);
+    return new ODataLink.Builder().setVersion(client.getServiceVersion()).setURI(link).
+            setType(ODataLinkType.ENTITY_SET_NAVIGATION).setTitle(name).build();
   }
 
   /**
@@ -198,7 +201,8 @@ public class ODataObjectFactoryImpl implements ODataObjectFactory {
    */
   @Override
   public ODataLink newFeedNavigationLink(final String name, final URI baseURI, final String href) {
-    return new ODataLink(client.getServiceVersion(), baseURI, href, ODataLinkType.ENTITY_SET_NAVIGATION, name);
+    return new ODataLink.Builder().setVersion(client.getServiceVersion()).setURI(baseURI, href).
+            setType(ODataLinkType.ENTITY_SET_NAVIGATION).setTitle(name).build();
   }
 
   /**
@@ -210,7 +214,8 @@ public class ODataObjectFactoryImpl implements ODataObjectFactory {
    */
   @Override
   public ODataLink newAssociationLink(final String name, final URI link) {
-    return new ODataLink(client.getServiceVersion(), link, ODataLinkType.ASSOCIATION, name);
+    return new ODataLink.Builder().setVersion(client.getServiceVersion()).setURI(link).
+            setType(ODataLinkType.ASSOCIATION).setTitle(name).build();
   }
 
   /**
@@ -223,7 +228,8 @@ public class ODataObjectFactoryImpl implements ODataObjectFactory {
    */
   @Override
   public ODataLink newAssociationLink(final String name, final URI baseURI, final String href) {
-    return new ODataLink(client.getServiceVersion(), baseURI, href, ODataLinkType.ASSOCIATION, name);
+    return new ODataLink.Builder().setVersion(client.getServiceVersion()).setURI(baseURI, href).
+            setType(ODataLinkType.ASSOCIATION).setTitle(name).build();
   }
 
   /**
@@ -235,7 +241,8 @@ public class ODataObjectFactoryImpl implements ODataObjectFactory {
    */
   @Override
   public ODataLink newMediaEditLink(final String name, final URI link) {
-    return new ODataLink(client.getServiceVersion(), link, ODataLinkType.MEDIA_EDIT, name);
+    return new ODataLink.Builder().setVersion(client.getServiceVersion()).setURI(link).
+            setType(ODataLinkType.MEDIA_EDIT).setTitle(name).build();
   }
 
   /**
@@ -248,7 +255,8 @@ public class ODataObjectFactoryImpl implements ODataObjectFactory {
    */
   @Override
   public ODataLink newMediaEditLink(final String name, final URI baseURI, final String href) {
-    return new ODataLink(client.getServiceVersion(), baseURI, href, ODataLinkType.MEDIA_EDIT, name);
+    return new ODataLink.Builder().setVersion(client.getServiceVersion()).setURI(baseURI, href).
+            setType(ODataLinkType.MEDIA_EDIT).setTitle(name).build();
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataV3BinderImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataV3BinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataV3BinderImpl.java
index 7b092da..cf48c94 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataV3BinderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataV3BinderImpl.java
@@ -27,9 +27,4 @@ public class ODataV3BinderImpl extends AbstractODataBinder {
   public ODataV3BinderImpl(final ODataV3ClientImpl 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/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataV3DeserializerImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataV3DeserializerImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataV3DeserializerImpl.java
index 4a0f04a..814874e 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataV3DeserializerImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/ODataV3DeserializerImpl.java
@@ -18,7 +18,6 @@
  */
 package org.apache.olingo.client.core.op.impl;
 
-import java.io.IOException;
 import java.io.InputStream;
 
 import org.apache.olingo.client.api.ODataClient;
@@ -49,13 +48,9 @@ public class ODataV3DeserializerImpl extends AbstractODataDeserializer implement
 
   @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);
-    }
+    return format == ODataFormat.XML
+            ? xml(input, XMLServiceDocumentImpl.class)
+            : json(input, JSONServiceDocumentImpl.class);
   }
 
 }