You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2014/10/09 17:06:08 UTC

[01/19] Batch Parser

Repository: olingo-odata2
Updated Branches:
  refs/heads/master 14c6dd5be -> e7e44471c


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
new file mode 100644
index 0000000..bd3607a
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
@@ -0,0 +1,452 @@
+package org.apache.olingo.odata2.core.batch;
+
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+
+import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings;
+import org.junit.Test;
+
+public class BufferedReaderIncludingLineEndingsTest {
+
+  private static final String TEXT_COMBINED = "Test\r" +
+      "Test2\r\n" +
+      "Test3\n" +
+      "Test4\r" +
+      "\r" +
+      "\r\n" +
+      "\r\n" +
+      "Test5\n" +
+      "Test6\r\n" +
+      "Test7\n" +
+      "\n";
+
+  private static final String TEXT_SMALL = "Test\r" +
+      "123";
+  private static final String TEXT_EMPTY = "";
+
+  @Test
+  public void testSimpleText() throws IOException {
+    final String TEXT = "Test";
+    BufferedReaderIncludingLineEndings reader = create(TEXT);
+
+    assertEquals(TEXT, reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testNoText() throws IOException {
+    final String TEXT = "";
+    BufferedReaderIncludingLineEndings reader = create(TEXT);
+
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testNoBytes() throws IOException {
+    BufferedReaderIncludingLineEndings reader =
+        new BufferedReaderIncludingLineEndings(new InputStreamReader(new ByteArrayInputStream(new byte[0])));
+
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testCRLF() throws IOException {
+    final String TEXT = "Test\r\n" +
+        "Test2";
+
+    BufferedReaderIncludingLineEndings reader = create(TEXT);
+
+    assertEquals("Test\r\n", reader.readLine());
+    assertEquals("Test2", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testLF() throws IOException {
+    final String TEXT = "Test\n" +
+        "Test2";
+
+    BufferedReaderIncludingLineEndings reader = create(TEXT);
+
+    assertEquals("Test\n", reader.readLine());
+    assertEquals("Test2", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testCR() throws IOException {
+    final String TEXT = "Test\r" +
+        "Test2";
+
+    BufferedReaderIncludingLineEndings reader = create(TEXT);
+
+    assertEquals("Test\r", reader.readLine());
+    assertEquals("Test2", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testCombined() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create(TEXT_COMBINED);
+
+    assertEquals("Test\r", reader.readLine());
+    assertEquals("Test2\r\n", reader.readLine());
+    assertEquals("Test3\n", reader.readLine());
+    assertEquals("Test4\r", reader.readLine());
+    assertEquals("\r", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertEquals("Test5\n", reader.readLine());
+    assertEquals("Test6\r\n", reader.readLine());
+    assertEquals("Test7\n", reader.readLine());
+    assertEquals("\n", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testCombinedBufferSizeTwo() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create(TEXT_COMBINED, 2);
+
+    assertEquals("Test\r", reader.readLine());
+    assertEquals("Test2\r\n", reader.readLine());
+    assertEquals("Test3\n", reader.readLine());
+    assertEquals("Test4\r", reader.readLine());
+    assertEquals("\r", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertEquals("Test5\n", reader.readLine());
+    assertEquals("Test6\r\n", reader.readLine());
+    assertEquals("Test7\n", reader.readLine());
+    assertEquals("\n", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testCombinedBufferSizeOne() throws IOException {
+    final String TEXT = "Test\r" +
+        "Test2\r\n" +
+        "Test3\n" +
+        "Test4\r" +
+        "\r" +
+        "\r\n" +
+        "\r\n" +
+        "Test5\n" +
+        "Test6\r\n" +
+        "Test7\n" +
+        "\r\n";
+
+    BufferedReaderIncludingLineEndings reader = create(TEXT, 1);
+
+    assertEquals("Test\r", reader.readLine());
+    assertEquals("Test2\r\n", reader.readLine());
+    assertEquals("Test3\n", reader.readLine());
+    assertEquals("Test4\r", reader.readLine());
+    assertEquals("\r", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertEquals("Test5\n", reader.readLine());
+    assertEquals("Test6\r\n", reader.readLine());
+    assertEquals("Test7\n", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+
+    reader.close();
+  }
+
+  @Test
+  public void testDoubleLF() throws IOException {
+    final String TEXT = "Test\r" +
+        "\r";
+
+    BufferedReaderIncludingLineEndings reader = create(TEXT, 1);
+
+    assertEquals("Test\r", reader.readLine());
+    assertEquals("\r", reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testSkipSimple() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL);
+
+    assertEquals(5, reader.skip(5)); // Test\r
+    assertEquals("123", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testSkipBufferOne() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL, 1);
+
+    assertEquals(5, reader.skip(5)); // Test\r
+    assertEquals("123", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testReadThanSkip() throws IOException {
+    final String TEXT = "Test\r" +
+        "\r" +
+        "123";
+
+    BufferedReaderIncludingLineEndings reader = create(TEXT);
+
+    assertEquals("Test\r", reader.readLine());
+    assertEquals(1, reader.skip(1)); // Test\r
+    assertEquals("123", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testReadMoreBufferCapacityThanCharacterAvailable() throws IOException {
+    final String TEXT = "Foo";
+    char[] buffer = new char[20];
+
+    BufferedReaderIncludingLineEndings reader = create(TEXT);
+    assertEquals(3, reader.read(buffer, 0, 20));
+    assertEquals(-1, reader.read(buffer, 0, 20));
+    reader.close();
+
+    BufferedReaderIncludingLineEndings readerBufferOne = create(TEXT, 1);
+    assertEquals(3, readerBufferOne.read(buffer, 0, 20));
+    assertEquals(-1, readerBufferOne.read(buffer, 0, 20));
+    readerBufferOne.close();
+  }
+
+  @Test
+  public void testSkipZero() throws IOException {
+    final String TEXT = "Test\r" +
+        "123\r\n";
+
+    BufferedReaderIncludingLineEndings reader = create(TEXT);
+
+    assertEquals(0, reader.skip(0)); // Test\r
+    assertEquals("Test\r", reader.readLine());
+    assertEquals("123\r\n", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testSkipToMuch() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL);
+
+    assertEquals(8, reader.skip(10)); // Test\r
+    assertEquals(null, reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testReadBufferOne() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL, 1);
+
+    assertEquals('T', reader.read());
+    assertEquals('e', reader.read());
+    assertEquals('s', reader.read());
+    assertEquals('t', reader.read());
+    assertEquals('\r', reader.read());
+    assertEquals('1', reader.read());
+    assertEquals('2', reader.read());
+    assertEquals('3', reader.read());
+    assertEquals(-1, reader.read());
+    assertEquals(-1, reader.read());
+  }
+
+  @Test
+  public void testReadZeroBytes() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL, 1);
+
+    char[] buffer = new char[3];
+    assertEquals(0, reader.read(buffer, 0, 0));
+    assertEquals('T', reader.read());
+    assertEquals(0, reader.read(buffer, 0, 0));
+    assertEquals("est\r", reader.readLine());
+    assertEquals("123", reader.readLine());
+
+    reader.close();
+  }
+
+  @Test
+  public void testRead() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL);
+
+    assertEquals('T', reader.read());
+    assertEquals('e', reader.read());
+    assertEquals('s', reader.read());
+    assertEquals('t', reader.read());
+    assertEquals('\r', reader.read());
+    assertEquals('1', reader.read());
+    assertEquals('2', reader.read());
+    assertEquals('3', reader.read());
+    assertEquals(-1, reader.read());
+    assertEquals(-1, reader.read());
+  }
+
+  @Test(expected = IndexOutOfBoundsException.class)
+  public void testFailReadBufferAndOffsetBiggerThanBuffer() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create("");
+
+    final char[] buffer = new char[3];
+    reader.read(buffer, 1, 3);
+  }
+
+  @Test(expected = IndexOutOfBoundsException.class)
+  public void testFailLengthNegative() throws IOException {
+    final char[] buffer = new char[3];
+    BufferedReaderIncludingLineEndings reader = create("123");
+
+    reader.read(buffer, 1, -2);
+    reader.close();
+  }
+
+  @Test(expected = IndexOutOfBoundsException.class)
+  public void testFailOffsetNegative() throws IOException {
+    final char[] buffer = new char[3];
+    BufferedReaderIncludingLineEndings reader = create("123");
+
+    reader.read(buffer, -1, 2);
+    reader.close();
+  }
+
+  @Test
+  public void testReadAndReadLine() throws IOException {
+    final String TEXT = "Test\r" +
+        "bar\n" +
+        "123\r\n" +
+        "foo";
+
+    BufferedReaderIncludingLineEndings reader = create(TEXT);
+
+    assertEquals('T', reader.read());
+    assertEquals('e', reader.read());
+    assertEquals('s', reader.read());
+    assertEquals('t', reader.read());
+    assertEquals("\r", reader.readLine());
+    assertEquals("bar\n", reader.readLine());
+    assertEquals('1', reader.read());
+    assertEquals('2', reader.read());
+    assertEquals("3\r\n", reader.readLine());
+    assertEquals("foo", reader.readLine());
+    assertEquals(null, reader.readLine());
+    assertEquals(-1, reader.read());
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testSkipNegative() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create("123");
+    reader.skip(-1);
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testFailBufferSizeZero() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create(TEXT_EMPTY, 0);
+    reader.close();
+  }
+
+  @Test(expected = NullPointerException.class)
+  public void testInputStreamIsNull() throws IOException {
+    // Same behaviour like BufferedReader
+    BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(null);
+    reader.close();
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testFailBufferSizeNegative() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create(TEXT_EMPTY, -1);
+    reader.close();
+  }
+
+  @Test
+  public void testMarkSupoorted() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create(TEXT_EMPTY);
+
+    assertEquals(false, reader.markSupported());
+    reader.close();
+  }
+
+  @Test(expected = IOException.class)
+  public void testFailMark() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create("123");
+
+    reader.mark(1);
+  }
+
+  @Test(expected = IOException.class)
+  public void testFailReset() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create("123");
+
+    reader.reset();
+  }
+
+  @Test
+  public void testReady() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create("123\r123");
+    assertEquals(false, reader.ready());
+    assertEquals("123\r", reader.readLine());
+    assertEquals(true, reader.ready());
+    assertEquals("123", reader.readLine());
+    assertEquals(false, reader.ready());
+
+    reader.close();
+  }
+
+  @Test
+  public void testToList() throws IOException {
+    BufferedReaderIncludingLineEndings reader = create(TEXT_COMBINED);
+    List<String> stringList = reader.toList();
+
+    assertEquals(11, stringList.size());
+    assertEquals("Test\r", stringList.get(0));
+    assertEquals("Test2\r\n", stringList.get(1));
+    assertEquals("Test3\n", stringList.get(2));
+    assertEquals("Test4\r", stringList.get(3));
+    assertEquals("\r", stringList.get(4));
+    assertEquals("\r\n", stringList.get(5));
+    assertEquals("\r\n", stringList.get(6));
+    assertEquals("Test5\n", stringList.get(7));
+    assertEquals("Test6\r\n", stringList.get(8));
+    assertEquals("Test7\n", stringList.get(9));
+    assertEquals("\n", stringList.get(10));
+    reader.close();
+  }
+
+  private BufferedReaderIncludingLineEndings create(final String inputString) throws UnsupportedEncodingException {
+    return new BufferedReaderIncludingLineEndings(new InputStreamReader(new ByteArrayInputStream(inputString
+        .getBytes("UTF-8"))));
+  }
+
+  private BufferedReaderIncludingLineEndings create(final String inputString, int bufferSize)
+      throws UnsupportedEncodingException {
+    return new BufferedReaderIncludingLineEndings(new InputStreamReader(new ByteArrayInputStream(inputString
+        .getBytes("UTF-8"))), bufferSize);
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/test/resources/batchWithPost.batch
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/batchWithPost.batch b/odata2-lib/odata-core/src/test/resources/batchWithPost.batch
index 2fd509f..b7038e9 100644
--- a/odata2-lib/odata-core/src/test/resources/batchWithPost.batch
+++ b/odata2-lib/odata-core/src/test/resources/batchWithPost.batch
@@ -14,6 +14,7 @@ Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd
 --changeset_f980-1cb6-94dd
 Content-Type: application/http
 Content-Transfer-Encoding: binary
+Content-ID: changeRequest1
 
 PUT Employees('2')/EmployeeName HTTP/1.1
 Content-Length: 100000

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientBatchTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientBatchTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientBatchTest.java
index 0e1075f..91c5f0d 100644
--- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientBatchTest.java
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientBatchTest.java
@@ -44,8 +44,10 @@ import org.apache.olingo.odata2.api.ep.EntityProvider;
 import org.apache.olingo.odata2.fit.ref.AbstractRefTest;
 import org.apache.olingo.odata2.testutil.helper.StringHelper;
 import org.apache.olingo.odata2.testutil.server.ServletType;
+import org.junit.Ignore;
 import org.junit.Test;
 
+@Ignore
 public class ClientBatchTest extends AbstractRefTest {
   public ClientBatchTest(final ServletType servletType) {
     super(servletType);

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientDeltaResponseTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientDeltaResponseTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientDeltaResponseTest.java
index f2d0c4b..cedd92a 100644
--- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientDeltaResponseTest.java
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientDeltaResponseTest.java
@@ -51,8 +51,10 @@ import org.apache.olingo.odata2.ref.edm.ScenarioEdmProvider;
 import org.apache.olingo.odata2.testutil.fit.AbstractFitTest;
 import org.apache.olingo.odata2.testutil.server.ServletType;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
+@Ignore
 public class ClientDeltaResponseTest extends AbstractFitTest {
 
   public ClientDeltaResponseTest(final ServletType servletType) {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-fit/src/test/resources/batchWithContentId.batch
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/resources/batchWithContentId.batch b/odata2-lib/odata-fit/src/test/resources/batchWithContentId.batch
index 8fb0fa1..f58742e 100644
--- a/odata2-lib/odata-fit/src/test/resources/batchWithContentId.batch
+++ b/odata2-lib/odata-fit/src/test/resources/batchWithContentId.batch
@@ -17,6 +17,7 @@ Loml/s/2aje2bUNbJcpOZhijEEOfIcSPMrtqgm0xZWu20Vpo46S20sNLSs4NihYGtHuV6EAUVFEREBER
 --changeset_7638-3d26-8efd
 Content-Type: application/http
 Content-Transfer-Encoding: binary
+Content-Id: 2
 
 PUT $newEmployee/EmployeeName HTTP/1.1
 Content-Length: 100
@@ -30,6 +31,7 @@ Content-Id: 2
 --changeset_7638-3d26-8efd
 Content-Type: application/http
 Content-Transfer-Encoding: binary
+Content-Id: 3
 
 PUT $newEmployee/Age HTTP/1.1
 Content-Length: 100

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-fit/src/test/resources/batchWithContentIdPart2.batch
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/resources/batchWithContentIdPart2.batch b/odata2-lib/odata-fit/src/test/resources/batchWithContentIdPart2.batch
index b7cd3be..0a9ae53 100644
--- a/odata2-lib/odata-fit/src/test/resources/batchWithContentIdPart2.batch
+++ b/odata2-lib/odata-fit/src/test/resources/batchWithContentIdPart2.batch
@@ -14,10 +14,11 @@ Content-Type: multipart/mixed; boundary=changeset_824f-ce08-1e9d
 --changeset_824f-ce08-1e9d
 Content-Type: application/http
 Content-Transfer-Encoding: binary
+Content-ID: employee
 
 POST Employees HTTP/1.1
-Content-Type: application/octet-stream
 Content-ID: employee
+Content-Type: application/octet-stream
 Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1
 MaxDataServiceVersion: 2.0
 
@@ -25,12 +26,13 @@ MaxDataServiceVersion: 2.0
 --changeset_824f-ce08-1e9d
 Content-Type: application/http
 Content-Transfer-Encoding: binary
+Content-Id: AAA
 
 PUT $employee/EmployeeName HTTP/1.1
 Content-Length: 100000
-Content-Id: AAA
 Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1
 DataServiceVersion: 1.0
+Content-Id: AAA
 Content-Type: application/json;odata=verbose
 MaxDataServiceVersion: 2.0
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-fit/src/test/resources/changeset.batch
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/resources/changeset.batch b/odata2-lib/odata-fit/src/test/resources/changeset.batch
index 3b21367..31b2694 100644
--- a/odata2-lib/odata-fit/src/test/resources/changeset.batch
+++ b/odata2-lib/odata-fit/src/test/resources/changeset.batch
@@ -13,6 +13,7 @@ Content-Type: multipart/mixed; boundary=changeset_105a-d600-0156
 --changeset_105a-d600-0156
 Content-Type: application/http
 Content-Transfer-Encoding: binary
+Content-ID: putRequest
 
 PUT Employees('2')/EmployeeName HTTP/1.1
 Content-Length: 100000
@@ -28,6 +29,7 @@ MaxDataServiceVersion: 2.0
 --batch_123
 Content-Type: application/http
 Content-Transfer-Encoding: binary
+Content-ID: getRequest
 
 GET Employees('2')/EmployeeName HTTP/1.1
 Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1


[12/19] line ending issue again

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPageBuilderDeltaTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPageBuilderDeltaTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPageBuilderDeltaTest.java
index f16cbc6..947ed54 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPageBuilderDeltaTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPageBuilderDeltaTest.java
@@ -1,357 +1,357 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.access.data;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.olingo.odata2.jpa.processor.core.access.data.JPAPage.JPAPageBuilder;
-import org.junit.Test;
-
-public class JPAPageBuilderDeltaTest {
-
-  private static final int PAGE_SIZE = 10;
-
-  @Test
-  public void testBuildDefaultDelta() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .build();
-
-    assertEquals(20, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-    assertEquals(10, page.getPagedEntities().size());
-
-    List<Object> pagedEntities = page.getPagedEntities();
-
-    assertEquals("9", pagedEntities.get(0));
-    assertEquals("18", pagedEntities.get(9));
-  }
-
-  @Test
-  public void testBuildWithNoSkipTokenDelta() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(PAGE_SIZE)
-        .skipToken("0")
-        .build();
-
-    assertEquals(10, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    List<Object> pagedEntities = page.getPagedEntities();
-    assertEquals(10, pagedEntities.size());
-    assertEquals("0", pagedEntities.get(0));
-    assertEquals("9", pagedEntities.get(9));
-  }
-
-  @Test
-  public void testBuildDefaultZeroPageDelta() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(0)
-        .skipToken("10")
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(0, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-    assertEquals(0, page.getPagedEntities().size());
-
-  }
-
-  @Test
-  public void testBuildWithNullSkipToken() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(PAGE_SIZE)
-        .skipToken(null)
-        .build();
-
-    assertEquals(10, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-
-    List<Object> pagedEntities = page.getPagedEntities();
-    assertNotNull(pagedEntities);
-    assertEquals("0", pagedEntities.get(0));
-    assertEquals("9", pagedEntities.get(9));
-  }
-
-  @Test
-  public void testBuildWithInvalidSkipToken() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    try {
-      pageBuilder.entities(mockEntities())
-          .skipToken("AB");
-    } catch (NumberFormatException e) {
-      return;
-    }
-    fail("Exception Expected");
-  }
-
-  @Test
-  public void testBuildWithTop() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(PAGE_SIZE)
-        .skipToken("20")
-        .top(5)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(20, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-
-    List<Object> pagedEntities = page.getPagedEntities();
-    assertNotNull(pagedEntities);
-    assertEquals(5, pagedEntities.size());
-    assertEquals("19", pagedEntities.get(0));
-    assertEquals("23", pagedEntities.get(4));
-  }
-
-  @Test
-  public void testBuildWithTopZeroPage() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(0)
-        .skipToken("10")
-        .top(5)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(0, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-    assertEquals(5, page.getPagedEntities().size());
-  }
-
-  @Test
-  public void testBuildWithSkipZeroPage() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(0)
-        .skipToken("10")
-        .skip(5)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(0, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    assertEquals(0, page.getPagedEntities().size());
-  }
-
-  @Test
-  public void testBuildWithTopSkipZeroPage() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(0)
-        .skipToken("10")
-        .skip(5)
-        .top(5)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(0, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-    assertEquals(5, page.getPagedEntities().size());
-  }
-
-  @Test
-  public void testBuildWithTopExceeds() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(15)
-        .build();
-
-    assertEquals(20, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    List<Object> pagedEntities = page.getPagedEntities();
-    assertNotNull(pagedEntities);
-    assertEquals(10, pagedEntities.size());
-    assertEquals("9", pagedEntities.get(0));
-    assertEquals("18", pagedEntities.get(9));
-  }
-
-  @Test
-  public void testBuildWithTopSkipExceeds() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(5)
-        .skip(10)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    List<Object> pagedEntities = page.getPagedEntities();
-    assertEquals(0, pagedEntities.size());
-
-  }
-
-  @Test
-  public void testBuildWithTopSkipMore() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(5)
-        .skip(9)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    List<Object> pagedEntities = page.getPagedEntities();
-    assertNotNull(pagedEntities);
-
-    assertEquals("18", pagedEntities.get(0));
-    assertEquals(1, pagedEntities.size());
-  }
-
-  @Test
-  public void testBuildWithTopMoreSkip() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(15)
-        .skip(9)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    List<Object> pagedEntities = page.getPagedEntities();
-    assertNotNull(pagedEntities);
-
-    assertEquals("18", pagedEntities.get(0));
-    assertEquals(1, pagedEntities.size());
-  }
-
-  @Test
-  public void testBuildWithTopXSkipX() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(15)
-        .skip(15)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    List<Object> pagedEntities = page.getPagedEntities();
-    assertNotNull(pagedEntities);
-
-    assertEquals(0, pagedEntities.size());
-  }
-
-  @Test
-  public void testBuildWithNegativeTop() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(-5)
-        .build();
-
-    assertEquals(20, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    List<Object> pagedEntities = page.getPagedEntities();
-    assertNotNull(pagedEntities);
-
-    assertEquals("9", pagedEntities.get(0));
-    assertEquals(10, pagedEntities.size());
-  }
-
-  @Test
-  public void testBuildWithNegativeTopSkipToken() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(PAGE_SIZE)
-        .skipToken("-10")
-        .top(-5)
-        .skip(-1)
-        .build();
-
-    assertEquals(10, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    List<Object> pagedEntities = page.getPagedEntities();
-    assertNotNull(pagedEntities);
-
-    assertEquals(10, pagedEntities.size());
-
-  }
-
-  @Test
-  public void testBuildWithNoRecords() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    JPAPage page = pageBuilder.entities(mockEntities())
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(1)
-        .skip(1)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    List<Object> pagedEntities = page.getPagedEntities();
-    assertNotNull(pagedEntities);
-
-    assertEquals(1, pagedEntities.size());
-    assertEquals("10", pagedEntities.get(0));
-  }
-
-  private List<Object> mockEntities() {
-    List<Object> entities = new ArrayList<Object>();
-    for (int i = 0; i < 30; i++) {
-      entities.add(String.valueOf(i));
-    }
-    return entities;
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.access.data;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.jpa.processor.core.access.data.JPAPage.JPAPageBuilder;
+import org.junit.Test;
+
+public class JPAPageBuilderDeltaTest {
+
+  private static final int PAGE_SIZE = 10;
+
+  @Test
+  public void testBuildDefaultDelta() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .build();
+
+    assertEquals(20, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+    assertEquals(10, page.getPagedEntities().size());
+
+    List<Object> pagedEntities = page.getPagedEntities();
+
+    assertEquals("9", pagedEntities.get(0));
+    assertEquals("18", pagedEntities.get(9));
+  }
+
+  @Test
+  public void testBuildWithNoSkipTokenDelta() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(PAGE_SIZE)
+        .skipToken("0")
+        .build();
+
+    assertEquals(10, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    List<Object> pagedEntities = page.getPagedEntities();
+    assertEquals(10, pagedEntities.size());
+    assertEquals("0", pagedEntities.get(0));
+    assertEquals("9", pagedEntities.get(9));
+  }
+
+  @Test
+  public void testBuildDefaultZeroPageDelta() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(0)
+        .skipToken("10")
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(0, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+    assertEquals(0, page.getPagedEntities().size());
+
+  }
+
+  @Test
+  public void testBuildWithNullSkipToken() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(PAGE_SIZE)
+        .skipToken(null)
+        .build();
+
+    assertEquals(10, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+
+    List<Object> pagedEntities = page.getPagedEntities();
+    assertNotNull(pagedEntities);
+    assertEquals("0", pagedEntities.get(0));
+    assertEquals("9", pagedEntities.get(9));
+  }
+
+  @Test
+  public void testBuildWithInvalidSkipToken() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    try {
+      pageBuilder.entities(mockEntities())
+          .skipToken("AB");
+    } catch (NumberFormatException e) {
+      return;
+    }
+    fail("Exception Expected");
+  }
+
+  @Test
+  public void testBuildWithTop() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(PAGE_SIZE)
+        .skipToken("20")
+        .top(5)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(20, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+
+    List<Object> pagedEntities = page.getPagedEntities();
+    assertNotNull(pagedEntities);
+    assertEquals(5, pagedEntities.size());
+    assertEquals("19", pagedEntities.get(0));
+    assertEquals("23", pagedEntities.get(4));
+  }
+
+  @Test
+  public void testBuildWithTopZeroPage() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(0)
+        .skipToken("10")
+        .top(5)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(0, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+    assertEquals(5, page.getPagedEntities().size());
+  }
+
+  @Test
+  public void testBuildWithSkipZeroPage() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(0)
+        .skipToken("10")
+        .skip(5)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(0, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    assertEquals(0, page.getPagedEntities().size());
+  }
+
+  @Test
+  public void testBuildWithTopSkipZeroPage() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(0)
+        .skipToken("10")
+        .skip(5)
+        .top(5)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(0, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+    assertEquals(5, page.getPagedEntities().size());
+  }
+
+  @Test
+  public void testBuildWithTopExceeds() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(15)
+        .build();
+
+    assertEquals(20, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    List<Object> pagedEntities = page.getPagedEntities();
+    assertNotNull(pagedEntities);
+    assertEquals(10, pagedEntities.size());
+    assertEquals("9", pagedEntities.get(0));
+    assertEquals("18", pagedEntities.get(9));
+  }
+
+  @Test
+  public void testBuildWithTopSkipExceeds() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(5)
+        .skip(10)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    List<Object> pagedEntities = page.getPagedEntities();
+    assertEquals(0, pagedEntities.size());
+
+  }
+
+  @Test
+  public void testBuildWithTopSkipMore() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(5)
+        .skip(9)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    List<Object> pagedEntities = page.getPagedEntities();
+    assertNotNull(pagedEntities);
+
+    assertEquals("18", pagedEntities.get(0));
+    assertEquals(1, pagedEntities.size());
+  }
+
+  @Test
+  public void testBuildWithTopMoreSkip() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(15)
+        .skip(9)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    List<Object> pagedEntities = page.getPagedEntities();
+    assertNotNull(pagedEntities);
+
+    assertEquals("18", pagedEntities.get(0));
+    assertEquals(1, pagedEntities.size());
+  }
+
+  @Test
+  public void testBuildWithTopXSkipX() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(15)
+        .skip(15)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    List<Object> pagedEntities = page.getPagedEntities();
+    assertNotNull(pagedEntities);
+
+    assertEquals(0, pagedEntities.size());
+  }
+
+  @Test
+  public void testBuildWithNegativeTop() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(-5)
+        .build();
+
+    assertEquals(20, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    List<Object> pagedEntities = page.getPagedEntities();
+    assertNotNull(pagedEntities);
+
+    assertEquals("9", pagedEntities.get(0));
+    assertEquals(10, pagedEntities.size());
+  }
+
+  @Test
+  public void testBuildWithNegativeTopSkipToken() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(PAGE_SIZE)
+        .skipToken("-10")
+        .top(-5)
+        .skip(-1)
+        .build();
+
+    assertEquals(10, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    List<Object> pagedEntities = page.getPagedEntities();
+    assertNotNull(pagedEntities);
+
+    assertEquals(10, pagedEntities.size());
+
+  }
+
+  @Test
+  public void testBuildWithNoRecords() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    JPAPage page = pageBuilder.entities(mockEntities())
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(1)
+        .skip(1)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    List<Object> pagedEntities = page.getPagedEntities();
+    assertNotNull(pagedEntities);
+
+    assertEquals(1, pagedEntities.size());
+    assertEquals("10", pagedEntities.get(0));
+  }
+
+  private List<Object> mockEntities() {
+    List<Object> entities = new ArrayList<Object>();
+    for (int i = 0; i < 30; i++) {
+      entities.add(String.valueOf(i));
+    }
+    return entities;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPageBuilderTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPageBuilderTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPageBuilderTest.java
index 0232163..326c39f 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPageBuilderTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPageBuilderTest.java
@@ -1,560 +1,560 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.access.data;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.persistence.FlushModeType;
-import javax.persistence.LockModeType;
-import javax.persistence.Parameter;
-import javax.persistence.Query;
-import javax.persistence.TemporalType;
-
-import org.apache.olingo.odata2.jpa.processor.core.access.data.JPAPage.JPAPageBuilder;
-import org.junit.Test;
-
-public class JPAPageBuilderTest {
-
-  private static final int PAGE_SIZE = 10;
-
-  @Test
-  public void testBuildDefault() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-    assertEquals(1, page.getPagedEntities().size());
-
-    assertEquals(10, query.getFirstResult());
-    assertEquals(10, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildDefaultZeroPage() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(0)
-        .skipToken("10")
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(0, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-    assertEquals(0, page.getPagedEntities().size());
-
-    assertEquals(0, query.getFirstResult());
-    assertEquals(0, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithNoSkipToken() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(PAGE_SIZE)
-        .skipToken("0")
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-    assertEquals(1, page.getPagedEntities().size());
-
-    assertEquals(0, query.getFirstResult());
-    assertEquals(10, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithNullSkipToken() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(PAGE_SIZE)
-        .skipToken(null)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    assertEquals(0, query.getFirstResult());
-    assertEquals(10, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithInvalidSkipToken() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    try {
-      pageBuilder.query(query)
-          .skipToken("AB");
-    } catch (NumberFormatException e) {
-      return;
-    }
-    fail("Exception Expected");
-  }
-
-  @Test
-  public void testBuildWithTop() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(5)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    assertEquals(10, query.getFirstResult());
-    assertEquals(5, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithTopZeroPage() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(0)
-        .skipToken("10")
-        .top(5)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(0, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    assertEquals(0, query.getFirstResult());
-    assertEquals(5, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithSkipZeroPage() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(0)
-        .skipToken("10")
-        .skip(5)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(0, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    assertEquals(5, query.getFirstResult());
-    assertEquals(0, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithTopSkipZeroPage() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(0)
-        .skipToken("10")
-        .skip(5)
-        .top(5)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(0, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    assertEquals(5, query.getFirstResult());
-    assertEquals(5, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithTopExceeds() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(15)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    assertEquals(10, query.getFirstResult());
-    assertEquals(10, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithTopSkipExceeds() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(5)
-        .skip(10)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertEquals(0, page.getPagedEntities().size());
-
-    assertEquals(0, query.getFirstResult());
-    assertEquals(0, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithTopSkipMore() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(5)
-        .skip(9)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    assertEquals(19, query.getFirstResult());
-    assertEquals(1, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithTopMoreSkip() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(15)
-        .skip(9)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    assertEquals(19, query.getFirstResult());
-    assertEquals(1, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithTopXSkipX() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(15)
-        .skip(15)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    assertEquals(0, query.getFirstResult());
-    assertEquals(0, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithNegativeTop() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(-5)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    assertEquals(10, query.getFirstResult());
-    assertEquals(10, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithNegativeTopSkipToken() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(false);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(PAGE_SIZE)
-        .skipToken("-10")
-        .top(-5)
-        .skip(-1)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(0, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    assertEquals(0, query.getFirstResult());
-    assertEquals(10, query.getMaxResults());
-  }
-
-  @Test
-  public void testBuildWithNoRecords() {
-    JPAPageBuilder pageBuilder = new JPAPageBuilder();
-    Query query = mockQuery(true);
-
-    JPAPage page = pageBuilder.query(query)
-        .pageSize(PAGE_SIZE)
-        .skipToken("10")
-        .top(1)
-        .skip(1)
-        .build();
-
-    assertEquals(0, page.getNextPage());
-    assertEquals(10, page.getStartPage());
-    assertEquals(PAGE_SIZE, page.getPageSize());
-    assertNotNull(page.getPagedEntities());
-
-    assertEquals(11, query.getFirstResult());
-    assertEquals(1, query.getMaxResults());
-  }
-
-  private Query mockQuery(final boolean setNoRecords) {
-
-    return new Query() {
-
-      private int maxResults;
-      private int firstResult;
-
-      @Override
-      public Query setFirstResult(final int arg0) {
-        firstResult = arg0;
-        return this;
-      }
-
-      @Override
-      public Query setMaxResults(final int arg0) {
-        maxResults = arg0;
-        return this;
-      }
-
-      @Override
-      public int getMaxResults() {
-        return maxResults;
-      }
-
-      @Override
-      public int getFirstResult() {
-        return firstResult;
-      }
-
-      @Override
-      public List<Object> getResultList() {
-        List<Object> list = new ArrayList<Object>();
-        if (maxResults > 0 && setNoRecords == false) {
-          list.add(new Integer(1));
-        }
-        return list;
-      }
-
-      @Override
-      public <T> T unwrap(final Class<T> arg0) {
-        return null;
-      }
-
-      @Override
-      public Query setParameter(final int arg0, final Date arg1, final TemporalType arg2) {
-        return null;
-      }
-
-      @Override
-      public Query setParameter(final int arg0, final Calendar arg1, final TemporalType arg2) {
-        return null;
-      }
-
-      @Override
-      public Query setParameter(final String arg0, final Date arg1, final TemporalType arg2) {
-        return null;
-      }
-
-      @Override
-      public Query setParameter(final String arg0, final Calendar arg1, final TemporalType arg2) {
-        return null;
-      }
-
-      @Override
-      public Query setParameter(final Parameter<Date> arg0, final Date arg1, final TemporalType arg2) {
-        return null;
-      }
-
-      @Override
-      public Query setParameter(final Parameter<Calendar> arg0, final Calendar arg1, final TemporalType arg2) {
-        return null;
-      }
-
-      @Override
-      public Query setParameter(final int arg0, final Object arg1) {
-        return null;
-      }
-
-      @Override
-      public Query setParameter(final String arg0, final Object arg1) {
-        return null;
-      }
-
-      @Override
-      public <T> Query setParameter(final Parameter<T> arg0, final T arg1) {
-        return null;
-      }
-
-      @Override
-      public Query setLockMode(final LockModeType arg0) {
-        return null;
-      }
-
-      @Override
-      public Query setHint(final String arg0, final Object arg1) {
-        return null;
-      }
-
-      @Override
-      public Query setFlushMode(final FlushModeType arg0) {
-        return null;
-      }
-
-      @Override
-      public boolean isBound(final Parameter<?> arg0) {
-        return false;
-      }
-
-      @Override
-      public Object getSingleResult() {
-        return null;
-      }
-
-      @Override
-      public Set<Parameter<?>> getParameters() {
-        return null;
-      }
-
-      @Override
-      public Object getParameterValue(final int arg0) {
-        return null;
-      }
-
-      @Override
-      public Object getParameterValue(final String arg0) {
-        return null;
-      }
-
-      @Override
-      public <T> T getParameterValue(final Parameter<T> arg0) {
-        return null;
-      }
-
-      @Override
-      public <T> Parameter<T> getParameter(final int arg0, final Class<T> arg1) {
-        return null;
-      }
-
-      @Override
-      public <T> Parameter<T> getParameter(final String arg0, final Class<T> arg1) {
-        return null;
-      }
-
-      @Override
-      public Parameter<?> getParameter(final int arg0) {
-        return null;
-      }
-
-      @Override
-      public Parameter<?> getParameter(final String arg0) {
-        return null;
-      }
-
-      @Override
-      public LockModeType getLockMode() {
-        return null;
-      }
-
-      @Override
-      public Map<String, Object> getHints() {
-        return null;
-      }
-
-      @Override
-      public FlushModeType getFlushMode() {
-        return null;
-      }
-
-      @Override
-      public int executeUpdate() {
-        return 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.odata2.jpa.processor.core.access.data;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.FlushModeType;
+import javax.persistence.LockModeType;
+import javax.persistence.Parameter;
+import javax.persistence.Query;
+import javax.persistence.TemporalType;
+
+import org.apache.olingo.odata2.jpa.processor.core.access.data.JPAPage.JPAPageBuilder;
+import org.junit.Test;
+
+public class JPAPageBuilderTest {
+
+  private static final int PAGE_SIZE = 10;
+
+  @Test
+  public void testBuildDefault() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+    assertEquals(1, page.getPagedEntities().size());
+
+    assertEquals(10, query.getFirstResult());
+    assertEquals(10, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildDefaultZeroPage() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(0)
+        .skipToken("10")
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(0, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+    assertEquals(0, page.getPagedEntities().size());
+
+    assertEquals(0, query.getFirstResult());
+    assertEquals(0, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithNoSkipToken() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(PAGE_SIZE)
+        .skipToken("0")
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+    assertEquals(1, page.getPagedEntities().size());
+
+    assertEquals(0, query.getFirstResult());
+    assertEquals(10, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithNullSkipToken() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(PAGE_SIZE)
+        .skipToken(null)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    assertEquals(0, query.getFirstResult());
+    assertEquals(10, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithInvalidSkipToken() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    try {
+      pageBuilder.query(query)
+          .skipToken("AB");
+    } catch (NumberFormatException e) {
+      return;
+    }
+    fail("Exception Expected");
+  }
+
+  @Test
+  public void testBuildWithTop() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(5)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    assertEquals(10, query.getFirstResult());
+    assertEquals(5, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithTopZeroPage() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(0)
+        .skipToken("10")
+        .top(5)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(0, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    assertEquals(0, query.getFirstResult());
+    assertEquals(5, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithSkipZeroPage() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(0)
+        .skipToken("10")
+        .skip(5)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(0, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    assertEquals(5, query.getFirstResult());
+    assertEquals(0, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithTopSkipZeroPage() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(0)
+        .skipToken("10")
+        .skip(5)
+        .top(5)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(0, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    assertEquals(5, query.getFirstResult());
+    assertEquals(5, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithTopExceeds() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(15)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    assertEquals(10, query.getFirstResult());
+    assertEquals(10, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithTopSkipExceeds() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(5)
+        .skip(10)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertEquals(0, page.getPagedEntities().size());
+
+    assertEquals(0, query.getFirstResult());
+    assertEquals(0, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithTopSkipMore() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(5)
+        .skip(9)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    assertEquals(19, query.getFirstResult());
+    assertEquals(1, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithTopMoreSkip() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(15)
+        .skip(9)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    assertEquals(19, query.getFirstResult());
+    assertEquals(1, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithTopXSkipX() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(15)
+        .skip(15)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    assertEquals(0, query.getFirstResult());
+    assertEquals(0, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithNegativeTop() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(-5)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    assertEquals(10, query.getFirstResult());
+    assertEquals(10, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithNegativeTopSkipToken() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(false);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(PAGE_SIZE)
+        .skipToken("-10")
+        .top(-5)
+        .skip(-1)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(0, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    assertEquals(0, query.getFirstResult());
+    assertEquals(10, query.getMaxResults());
+  }
+
+  @Test
+  public void testBuildWithNoRecords() {
+    JPAPageBuilder pageBuilder = new JPAPageBuilder();
+    Query query = mockQuery(true);
+
+    JPAPage page = pageBuilder.query(query)
+        .pageSize(PAGE_SIZE)
+        .skipToken("10")
+        .top(1)
+        .skip(1)
+        .build();
+
+    assertEquals(0, page.getNextPage());
+    assertEquals(10, page.getStartPage());
+    assertEquals(PAGE_SIZE, page.getPageSize());
+    assertNotNull(page.getPagedEntities());
+
+    assertEquals(11, query.getFirstResult());
+    assertEquals(1, query.getMaxResults());
+  }
+
+  private Query mockQuery(final boolean setNoRecords) {
+
+    return new Query() {
+
+      private int maxResults;
+      private int firstResult;
+
+      @Override
+      public Query setFirstResult(final int arg0) {
+        firstResult = arg0;
+        return this;
+      }
+
+      @Override
+      public Query setMaxResults(final int arg0) {
+        maxResults = arg0;
+        return this;
+      }
+
+      @Override
+      public int getMaxResults() {
+        return maxResults;
+      }
+
+      @Override
+      public int getFirstResult() {
+        return firstResult;
+      }
+
+      @Override
+      public List<Object> getResultList() {
+        List<Object> list = new ArrayList<Object>();
+        if (maxResults > 0 && setNoRecords == false) {
+          list.add(new Integer(1));
+        }
+        return list;
+      }
+
+      @Override
+      public <T> T unwrap(final Class<T> arg0) {
+        return null;
+      }
+
+      @Override
+      public Query setParameter(final int arg0, final Date arg1, final TemporalType arg2) {
+        return null;
+      }
+
+      @Override
+      public Query setParameter(final int arg0, final Calendar arg1, final TemporalType arg2) {
+        return null;
+      }
+
+      @Override
+      public Query setParameter(final String arg0, final Date arg1, final TemporalType arg2) {
+        return null;
+      }
+
+      @Override
+      public Query setParameter(final String arg0, final Calendar arg1, final TemporalType arg2) {
+        return null;
+      }
+
+      @Override
+      public Query setParameter(final Parameter<Date> arg0, final Date arg1, final TemporalType arg2) {
+        return null;
+      }
+
+      @Override
+      public Query setParameter(final Parameter<Calendar> arg0, final Calendar arg1, final TemporalType arg2) {
+        return null;
+      }
+
+      @Override
+      public Query setParameter(final int arg0, final Object arg1) {
+        return null;
+      }
+
+      @Override
+      public Query setParameter(final String arg0, final Object arg1) {
+        return null;
+      }
+
+      @Override
+      public <T> Query setParameter(final Parameter<T> arg0, final T arg1) {
+        return null;
+      }
+
+      @Override
+      public Query setLockMode(final LockModeType arg0) {
+        return null;
+      }
+
+      @Override
+      public Query setHint(final String arg0, final Object arg1) {
+        return null;
+      }
+
+      @Override
+      public Query setFlushMode(final FlushModeType arg0) {
+        return null;
+      }
+
+      @Override
+      public boolean isBound(final Parameter<?> arg0) {
+        return false;
+      }
+
+      @Override
+      public Object getSingleResult() {
+        return null;
+      }
+
+      @Override
+      public Set<Parameter<?>> getParameters() {
+        return null;
+      }
+
+      @Override
+      public Object getParameterValue(final int arg0) {
+        return null;
+      }
+
+      @Override
+      public Object getParameterValue(final String arg0) {
+        return null;
+      }
+
+      @Override
+      public <T> T getParameterValue(final Parameter<T> arg0) {
+        return null;
+      }
+
+      @Override
+      public <T> Parameter<T> getParameter(final int arg0, final Class<T> arg1) {
+        return null;
+      }
+
+      @Override
+      public <T> Parameter<T> getParameter(final String arg0, final Class<T> arg1) {
+        return null;
+      }
+
+      @Override
+      public Parameter<?> getParameter(final int arg0) {
+        return null;
+      }
+
+      @Override
+      public Parameter<?> getParameter(final String arg0) {
+        return null;
+      }
+
+      @Override
+      public LockModeType getLockMode() {
+        return null;
+      }
+
+      @Override
+      public Map<String, Object> getHints() {
+        return null;
+      }
+
+      @Override
+      public FlushModeType getFlushMode() {
+        return null;
+      }
+
+      @Override
+      public int executeUpdate() {
+        return 0;
+      }
+    };
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java
index 3bc3f14..e39d3af 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java
@@ -1,62 +1,62 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ******************************************************************************/
-package org.apache.olingo.odata2.jpa.processor.core.mock;
-
-import org.apache.olingo.odata2.api.ODataService;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.api.uri.PathInfo;
-import org.easymock.EasyMock;
-
-public class ODataContextMock {
-
-  private ODataService odataService;
-  private PathInfo pathInfo;
-
-  public void setODataService(final ODataService service) {
-    odataService = service;
-  }
-
-  public void setPathInfo(final PathInfo pathInfo) {
-    this.pathInfo = pathInfo;
-  }
-
-  public ODataContext mock() throws ODataException {
-    ODataContext context = EasyMock.createMock(ODataContext.class);
-    EasyMock.expect(context.getService()).andReturn(odataService).anyTimes();
-    EasyMock.expect(context.getPathInfo()).andReturn(pathInfo).anyTimes();
-    ODataJPAServiceFactoryMock mockServiceFactory = new ODataJPAServiceFactoryMock(context);
-    mockServiceFactory.initializeODataJPAContext();
-    EasyMock.expect(context.getServiceFactory()).andReturn(mockServiceFactory).anyTimes();
-    EasyMock.replay(context);
-    return context;
-  }
-
-  public ODataContext mockWithoutOnJPAWriteContent() throws ODataException {
-    ODataContext context = EasyMock.createMock(ODataContext.class);
-    EasyMock.expect(context.getService()).andReturn(odataService).anyTimes();
-    EasyMock.expect(context.getPathInfo()).andReturn(pathInfo).anyTimes();
-    ODataJPAServiceFactoryMock mockServiceFactory = new ODataJPAServiceFactoryMock(context);
-    mockServiceFactory.initializeODataJPAContextX();
-    EasyMock.expect(context.getServiceFactory()).andReturn(mockServiceFactory).anyTimes();
-    EasyMock.replay(context);
-    return context;
-  }
-
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.mock;
+
+import org.apache.olingo.odata2.api.ODataService;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.uri.PathInfo;
+import org.easymock.EasyMock;
+
+public class ODataContextMock {
+
+  private ODataService odataService;
+  private PathInfo pathInfo;
+
+  public void setODataService(final ODataService service) {
+    odataService = service;
+  }
+
+  public void setPathInfo(final PathInfo pathInfo) {
+    this.pathInfo = pathInfo;
+  }
+
+  public ODataContext mock() throws ODataException {
+    ODataContext context = EasyMock.createMock(ODataContext.class);
+    EasyMock.expect(context.getService()).andReturn(odataService).anyTimes();
+    EasyMock.expect(context.getPathInfo()).andReturn(pathInfo).anyTimes();
+    ODataJPAServiceFactoryMock mockServiceFactory = new ODataJPAServiceFactoryMock(context);
+    mockServiceFactory.initializeODataJPAContext();
+    EasyMock.expect(context.getServiceFactory()).andReturn(mockServiceFactory).anyTimes();
+    EasyMock.replay(context);
+    return context;
+  }
+
+  public ODataContext mockWithoutOnJPAWriteContent() throws ODataException {
+    ODataContext context = EasyMock.createMock(ODataContext.class);
+    EasyMock.expect(context.getService()).andReturn(odataService).anyTimes();
+    EasyMock.expect(context.getPathInfo()).andReturn(pathInfo).anyTimes();
+    ODataJPAServiceFactoryMock mockServiceFactory = new ODataJPAServiceFactoryMock(context);
+    mockServiceFactory.initializeODataJPAContextX();
+    EasyMock.expect(context.getServiceFactory()).andReturn(mockServiceFactory).anyTimes();
+    EasyMock.replay(context);
+    return context;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAServiceFactoryMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAServiceFactoryMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAServiceFactoryMock.java
index 5fdeece..d7dfc2d 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAServiceFactoryMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAServiceFactoryMock.java
@@ -1,47 +1,47 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ******************************************************************************/
-package org.apache.olingo.odata2.jpa.processor.core.mock;
-
-import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
-import org.apache.olingo.odata2.jpa.processor.api.ODataJPAServiceFactory;
-import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
-
-public class ODataJPAServiceFactoryMock extends ODataJPAServiceFactory {
-  private ODataContext context = null;
-
-  public ODataJPAServiceFactoryMock(final ODataContext context) {
-    this.context = context;
-  }
-
-  @Override
-  public ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException {
-    ODataJPAContext oDataJPAContext = null;
-    oDataJPAContext = ODataJPAContextMock.mockODataJPAContext(context);
-    setOnWriteJPAContent(new OnJPAWriteContentMock());
-    return oDataJPAContext;
-  }
-
-  public ODataJPAContext initializeODataJPAContextX() throws ODataJPARuntimeException {
-    ODataJPAContext oDataJPAContext = null;
-    oDataJPAContext = ODataJPAContextMock.mockODataJPAContext(context);
-    setOnWriteJPAContent(null);
-    return oDataJPAContext;
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.mock;
+
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAServiceFactory;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+
+public class ODataJPAServiceFactoryMock extends ODataJPAServiceFactory {
+  private ODataContext context = null;
+
+  public ODataJPAServiceFactoryMock(final ODataContext context) {
+    this.context = context;
+  }
+
+  @Override
+  public ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException {
+    ODataJPAContext oDataJPAContext = null;
+    oDataJPAContext = ODataJPAContextMock.mockODataJPAContext(context);
+    setOnWriteJPAContent(new OnJPAWriteContentMock());
+    return oDataJPAContext;
+  }
+
+  public ODataJPAContext initializeODataJPAContextX() throws ODataJPARuntimeException {
+    ODataJPAContext oDataJPAContext = null;
+    oDataJPAContext = ODataJPAContextMock.mockODataJPAContext(context);
+    setOnWriteJPAContent(null);
+    return oDataJPAContext;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataServiceMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataServiceMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataServiceMock.java
index c5478db..dfaa329 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataServiceMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataServiceMock.java
@@ -1,106 +1,106 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ******************************************************************************/
-package org.apache.olingo.odata2.jpa.processor.core.mock;
-
-import java.util.List;
-
-import org.apache.olingo.odata2.api.ODataService;
-import org.apache.olingo.odata2.api.edm.Edm;
-import org.apache.olingo.odata2.api.edm.EdmAssociation;
-import org.apache.olingo.odata2.api.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.edm.EdmEntityContainer;
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
-import org.apache.olingo.odata2.api.edm.EdmServiceMetadata;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.EdmMockUtilV2;
-import org.easymock.EasyMock;
-
-public class ODataServiceMock {
-
-  private Edm edmMock = null;
-  public static final String SERVICE_ROOT = "http://apache.odata.org/OData.svc/";
-
-  public ODataService mock() throws ODataException {
-    ODataService odataService = EasyMock.createMock(ODataService.class);
-    EasyMock.expect(odataService.getEntityDataModel()).andReturn(mockEdm());
-    EasyMock.replay(odataService);
-    return odataService;
-
-  }
-
-  private Edm mockEdm() {
-    if (edmMock == null) {
-      edmMock = new EdmMock();
-    }
-    return edmMock;
-  }
-
-  public static class EdmMock implements Edm {
-
-    @Override
-    public EdmEntityContainer getEntityContainer(final String name) throws EdmException {
-      return EdmMockUtilV2.mockEdmEntityContainer(name);
-    }
-
-    @Override
-    public EdmEntityType getEntityType(final String namespace, final String name) throws EdmException {
-      // TODO Auto-generated method stub
-      return null;
-    }
-
-    @Override
-    public EdmComplexType getComplexType(final String namespace, final String name) throws EdmException {
-      // TODO Auto-generated method stub
-      return null;
-    }
-
-    @Override
-    public EdmAssociation getAssociation(final String namespace, final String name) throws EdmException {
-      // TODO Auto-generated method stub
-      return null;
-    }
-
-    @Override
-    public EdmServiceMetadata getServiceMetadata() {
-      // TODO Auto-generated method stub
-      return null;
-    }
-
-    @Override
-    public EdmEntityContainer getDefaultEntityContainer() throws EdmException {
-      return EdmMockUtilV2.mockEdmEntityContainer(null);
-    }
-
-    @Override
-    public List<EdmEntitySet> getEntitySets() throws EdmException {
-      // TODO Auto-generated method stub
-      return null;
-    }
-
-    @Override
-    public List<EdmFunctionImport> getFunctionImports() throws EdmException {
-      // TODO Auto-generated method stub
-      return null;
-    }
-
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.mock;
+
+import java.util.List;
+
+import org.apache.olingo.odata2.api.ODataService;
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.edm.EdmAssociation;
+import org.apache.olingo.odata2.api.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.edm.EdmEntityContainer;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.edm.EdmServiceMetadata;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.EdmMockUtilV2;
+import org.easymock.EasyMock;
+
+public class ODataServiceMock {
+
+  private Edm edmMock = null;
+  public static final String SERVICE_ROOT = "http://apache.odata.org/OData.svc/";
+
+  public ODataService mock() throws ODataException {
+    ODataService odataService = EasyMock.createMock(ODataService.class);
+    EasyMock.expect(odataService.getEntityDataModel()).andReturn(mockEdm());
+    EasyMock.replay(odataService);
+    return odataService;
+
+  }
+
+  private Edm mockEdm() {
+    if (edmMock == null) {
+      edmMock = new EdmMock();
+    }
+    return edmMock;
+  }
+
+  public static class EdmMock implements Edm {
+
+    @Override
+    public EdmEntityContainer getEntityContainer(final String name) throws EdmException {
+      return EdmMockUtilV2.mockEdmEntityContainer(name);
+    }
+
+    @Override
+    public EdmEntityType getEntityType(final String namespace, final String name) throws EdmException {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+    @Override
+    public EdmComplexType getComplexType(final String namespace, final String name) throws EdmException {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+    @Override
+    public EdmAssociation getAssociation(final String namespace, final String name) throws EdmException {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+    @Override
+    public EdmServiceMetadata getServiceMetadata() {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+    @Override
+    public EdmEntityContainer getDefaultEntityContainer() throws EdmException {
+      return EdmMockUtilV2.mockEdmEntityContainer(null);
+    }
+
+    @Override
+    public List<EdmEntitySet> getEntitySets() throws EdmException {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+    @Override
+    public List<EdmFunctionImport> getFunctionImports() throws EdmException {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/OnJPAWriteContentMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/OnJPAWriteContentMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/OnJPAWriteContentMock.java
index e0069ce..b571b12 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/OnJPAWriteContentMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/OnJPAWriteContentMock.java
@@ -1,58 +1,58 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.mock;
-
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.SQLException;
-
-import javax.sql.rowset.serial.SerialBlob;
-import javax.sql.rowset.serial.SerialClob;
-import javax.sql.rowset.serial.SerialException;
-
-import org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent;
-import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
-
-public class OnJPAWriteContentMock implements OnJPAWriteContent {
-
-  @Override
-  public Blob getJPABlob(final byte[] binaryData) throws ODataJPARuntimeException {
-    try {
-      return new SerialBlob(binaryData);
-    } catch (SerialException e) {
-      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
-    } catch (SQLException e) {
-      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
-    }
-    return null;
-  }
-
-  @Override
-  public Clob getJPAClob(final char[] characterData) throws ODataJPARuntimeException {
-    try {
-      return new SerialClob(characterData);
-    } catch (SerialException e) {
-      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
-    } catch (SQLException e) {
-      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
-    }
-    return null;
-  }
-
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.mock;
+
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+import javax.sql.rowset.serial.SerialBlob;
+import javax.sql.rowset.serial.SerialClob;
+import javax.sql.rowset.serial.SerialException;
+
+import org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+
+public class OnJPAWriteContentMock implements OnJPAWriteContent {
+
+  @Override
+  public Blob getJPABlob(final byte[] binaryData) throws ODataJPARuntimeException {
+    try {
+      return new SerialBlob(binaryData);
+    } catch (SerialException e) {
+      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    } catch (SQLException e) {
+      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    }
+    return null;
+  }
+
+  @Override
+  public Clob getJPAClob(final char[] characterData) throws ODataJPARuntimeException {
+    try {
+      return new SerialClob(characterData);
+    } catch (SerialException e) {
+      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    } catch (SQLException e) {
+      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    }
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathInfoMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathInfoMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathInfoMock.java
index 96a920c..b90b79c 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathInfoMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathInfoMock.java
@@ -1,51 +1,51 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.mock;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.uri.PathInfo;
-import org.apache.olingo.odata2.api.uri.PathSegment;
-import org.easymock.EasyMock;
-
-public class PathInfoMock {
-
-  private List<PathSegment> pathSegments;
-  private URI uri;
-
-  public void setPathSegments(final List<PathSegment> pathSegments) {
-    this.pathSegments = pathSegments;
-  }
-
-  public void setServiceRootURI(final String uriString) throws URISyntaxException {
-    uri = new URI(uriString);
-  }
-
-  public PathInfo mock() {
-    PathInfo pathInfo = EasyMock.createMock(PathInfo.class);
-    EasyMock.expect(pathInfo.getODataSegments()).andReturn(pathSegments);
-    EasyMock.expect(pathInfo.getServiceRoot()).andReturn(uri);
-
-    EasyMock.replay(pathInfo);
-    return pathInfo;
-
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.mock;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.uri.PathInfo;
+import org.apache.olingo.odata2.api.uri.PathSegment;
+import org.easymock.EasyMock;
+
+public class PathInfoMock {
+
+  private List<PathSegment> pathSegments;
+  private URI uri;
+
+  public void setPathSegments(final List<PathSegment> pathSegments) {
+    this.pathSegments = pathSegments;
+  }
+
+  public void setServiceRootURI(final String uriString) throws URISyntaxException {
+    uri = new URI(uriString);
+  }
+
+  public PathInfo mock() {
+    PathInfo pathInfo = EasyMock.createMock(PathInfo.class);
+    EasyMock.expect(pathInfo.getODataSegments()).andReturn(pathSegments);
+    EasyMock.expect(pathInfo.getServiceRoot()).andReturn(uri);
+
+    EasyMock.replay(pathInfo);
+    return pathInfo;
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathSegmentMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathSegmentMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathSegmentMock.java
index 77d1fbd..151cb9a 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathSegmentMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathSegmentMock.java
@@ -1,44 +1,44 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.mock;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.uri.PathSegment;
-
-public class PathSegmentMock implements PathSegment {
-
-  private String path;
-
-  public void setPath(final String path) {
-    this.path = path;
-  }
-
-  @Override
-  public String getPath() {
-    return path;
-  }
-
-  @Override
-  public Map<String, List<String>> getMatrixParameters() {
-    return null;
-  }
-
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.mock;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.uri.PathSegment;
+
+public class PathSegmentMock implements PathSegment {
+
+  private String path;
+
+  public void setPath(final String path) {
+    this.path = path;
+  }
+
+  @Override
+  public String getPath() {
+    return path;
+  }
+
+  @Override
+  public Map<String, List<String>> getMatrixParameters() {
+    return null;
+  }
+
+}


[06/19] git commit: Header class refactoring

Posted by ch...@apache.org.
Header class refactoring

Signed-off-by: Christian Amend <ch...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/05d20c1f
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/05d20c1f
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/05d20c1f

Branch: refs/heads/master
Commit: 05d20c1fa078f2c445b4fe30ab96d4a5f8d2b585
Parents: 1f90b73
Author: Christian Holzer <c....@sap.com>
Authored: Fri Oct 3 01:34:45 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Mon Oct 6 13:54:38 2014 +0200

----------------------------------------------------------------------
 .../odata2/core/batch/v2/BatchBodyPart.java     |  24 +--
 .../odata2/core/batch/v2/BatchParserCommon.java | 135 +------------
 .../olingo/odata2/core/batch/v2/BatchPart.java  |   6 +-
 .../core/batch/v2/BatchQueryOperation.java      |   6 +-
 .../batch/v2/BatchRequestTransformator.java     | 121 ++++-------
 .../batch/v2/BatchResponseTransformator.java    |  61 +++---
 .../core/batch/v2/BatchTransformatorCommon.java |  47 ++---
 .../olingo/odata2/core/batch/v2/Header.java     | 202 +++++++++++++++++++
 .../core/batch/BatchParserCommonTest.java       |  60 +++---
 .../batch/BatchTransformatorCommonTest.java     |  34 ++--
 .../olingo/odata2/core/batch/HeaderTest.java    | 161 +++++++++++++++
 11 files changed, 509 insertions(+), 348 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/05d20c1f/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
index 4edcf45..f74ea85 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
@@ -20,19 +20,16 @@ package org.apache.olingo.odata2.core.batch.v2;
 
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Locale;
-import java.util.Map;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
 import org.apache.olingo.odata2.api.commons.HttpHeaders;
-import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
 
 public class BatchBodyPart implements BatchPart {
   final private String boundary;
   final private boolean isStrict;
   final List<String> remainingMessage = new LinkedList<String>();
 
-  private Map<String, HeaderField> headers;
+  private Header headers;
   private boolean isChangeSet;
   private List<BatchQueryOperation> requests;
 
@@ -53,15 +50,15 @@ public class BatchBodyPart implements BatchPart {
     return this;
   }
 
-  private boolean isChangeSet(final Map<String, HeaderField> headers) throws BatchException {
-    final HeaderField contentTypeField = headers.get(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH));
+  private boolean isChangeSet(final Header headers) throws BatchException {
+    final List<String> contentTypes = headers.getHeaders(HttpHeaders.CONTENT_TYPE);
     boolean isChangeSet = false;
 
-    if (contentTypeField == null || contentTypeField.getValues().size() == 0) {
+    if (contentTypes.size() == 0) {
       throw new BatchException(BatchException.MISSING_CONTENT_TYPE);
     }
 
-    for (String contentType : contentTypeField.getValues()) {
+    for (String contentType : contentTypes) {
       if (isContentTypeMultiPartMixed(contentType)) {
         isChangeSet = true;
       }
@@ -97,7 +94,7 @@ public class BatchBodyPart implements BatchPart {
   private List<List<String>> splitChangeSet(final List<String> remainingMessage)
       throws BatchException {
 
-    final String changeSetBoundary = BatchParserCommon.getBoundary(getContentType());
+    final String changeSetBoundary = BatchParserCommon.getBoundary(headers.getHeaderNotNull(HttpHeaders.CONTENT_TYPE));
     validateChangeSetBoundary(changeSetBoundary);
 
     return BatchParserCommon.splitMessageByBoundary(remainingMessage, changeSetBoundary);
@@ -117,15 +114,8 @@ public class BatchBodyPart implements BatchPart {
     }
   }
 
-  private String getContentType() {
-    HeaderField contentTypeField = headers.get(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH));
-
-    return (contentTypeField != null && contentTypeField.getValues().size() > 0) ? contentTypeField.getValues().get(0)
-        : "";
-  }
-
   @Override
-  public Map<String, HeaderField> getHeaders() {
+  public Header getHeaders() {
     return headers;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/05d20c1f/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
index 8b7f62a..df62994 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
@@ -23,7 +23,6 @@ import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -148,8 +147,8 @@ public class BatchParserCommon {
     }
   }
 
-  public static Map<String, HeaderField> consumeHeaders(final List<String> remainingMessage) throws BatchException {
-    final Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
+  public static Header consumeHeaders(final List<String> remainingMessage) throws BatchException {
+    final Header headers = new Header();
     boolean isHeader = true;
     final Iterator<String> iter = remainingMessage.iterator();
     final AcceptParser acceptParser = new AcceptParser();
@@ -157,59 +156,30 @@ public class BatchParserCommon {
 
     while (iter.hasNext() && isHeader) {
       currentLine = iter.next();
-      Matcher headerMatcher = PATTERN_HEADER_LINE.matcher(currentLine);
+      final Matcher headerMatcher = PATTERN_HEADER_LINE.matcher(currentLine);
 
       if (headerMatcher.matches() && headerMatcher.groupCount() == 2) {
         iter.remove();
 
         String headerName = headerMatcher.group(1).trim();
-        String headerNameLowerCase = headerName.toLowerCase(Locale.ENGLISH);
         String headerValue = headerMatcher.group(2).trim();
 
-        if (HttpHeaders.ACCEPT.equalsIgnoreCase(headerNameLowerCase)) {
+        if (HttpHeaders.ACCEPT.equalsIgnoreCase(headerName)) {
           acceptParser.addAcceptHeaderValue(headerValue);
-        } else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(headerNameLowerCase)) {
+        } else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(headerName)) {
           acceptParser.addAcceptLanguageHeaderValue(headerValue);
         } else {
-          addHeaderValue(headers, headerName, headerNameLowerCase, headerValue);
+          headers.addHeader(headerName, Header.splitValuesByComma(headerValue));
         }
       } else {
         isHeader = false;
       }
     }
 
-    final List<String> acceptHeader = acceptParser.parseAcceptHeaders();
-    headers.put(HttpHeaders.ACCEPT.toLowerCase(), new HeaderField(HttpHeaders.ACCEPT, acceptHeader));
+    headers.addHeader(HttpHeaders.ACCEPT, acceptParser.parseAcceptHeaders());
+    headers.addHeader(HttpHeaders.ACCEPT_LANGUAGE, acceptParser.parseAcceptableLanguages());
 
-    final List<String> acceptLanguageHeader = acceptParser.parseAcceptableLanguages();
-    headers.put(HttpHeaders.ACCEPT_LANGUAGE.toLowerCase(), new HeaderField(HttpHeaders.ACCEPT_LANGUAGE,
-        acceptLanguageHeader));
-
-    return Collections.unmodifiableMap(headers);
-  }
-
-  private static void addHeaderValue(final Map<String, HeaderField> headers, final String headerName,
-      final String headerNameLowerCase, final String headerValue) {
-    HeaderField headerField = headers.get(headerNameLowerCase);
-    headerField = headerField == null ? new HeaderField(headerName) : headerField;
-    headers.put(headerNameLowerCase, headerField);
-
-    for (final String singleValue : splitHeaderValuesByComma(headerValue)) {
-      if (!headerField.getValues().contains(singleValue)) {
-        headerField.getValues().add(singleValue);
-      }
-    }
-  }
-
-  private static List<String> splitHeaderValuesByComma(final String headerValue) {
-    final List<String> singleValues = new ArrayList<String>();
-
-    String[] parts = headerValue.split(",");
-    for (final String value : parts) {
-      singleValues.add(value.trim());
-    }
-
-    return singleValues;
+    return headers;
   }
 
   public static void consumeBlankLine(final List<String> remainingMessage, final boolean isStrict)
@@ -338,91 +308,4 @@ public class BatchParserCommon {
 
     return boundary;
   }
-
-  public static Map<String, String> headerFieldMapToSingleMap(final Map<String, HeaderField> headers) {
-    final Map<String, String> singleMap = new HashMap<String, String>();
-
-    for (final String key : headers.keySet()) {
-      HeaderField field = headers.get(key);
-      String value = field.getValues().size() > 0 ? field.getValues().get(0) : "";
-      singleMap.put(field.getFieldName(), value);
-    }
-
-    return singleMap;
-  }
-
-  public static Map<String, List<String>> headerFieldMapToMultiMap(final Map<String, HeaderField> headers) {
-    final Map<String, List<String>> singleMap = new HashMap<String, List<String>>();
-
-    for (final String key : headers.keySet()) {
-      HeaderField field = headers.get(key);
-      singleMap.put(field.getFieldName(), field.getValues());
-    }
-
-    return singleMap;
-  }
-
-  public static class HeaderField implements Cloneable {
-    private String fieldName;
-    private List<String> values;
-
-    public HeaderField(final String fieldName) {
-      this(fieldName, new ArrayList<String>());
-    }
-
-    public HeaderField(final String fieldName, final List<String> values) {
-      this.fieldName = fieldName;
-      this.values = values;
-    }
-
-    public String getFieldName() {
-      return fieldName;
-    }
-
-    public List<String> getValues() {
-      return values;
-    }
-
-    public void setValues(final List<String> values) {
-      this.values = values;
-    }
-
-    @Override
-    public int hashCode() {
-      final int prime = 31;
-      int result = 1;
-      result = prime * result + ((fieldName == null) ? 0 : fieldName.hashCode());
-      return result;
-    }
-
-    @Override
-    public boolean equals(final Object obj) {
-      if (this == obj) {
-        return true;
-      }
-      if (obj == null) {
-        return false;
-      }
-      if (getClass() != obj.getClass()) {
-        return false;
-      }
-      HeaderField other = (HeaderField) obj;
-      if (fieldName == null) {
-        if (other.fieldName != null) {
-          return false;
-        }
-      } else if (!fieldName.equals(other.fieldName)) {
-        return false;
-      }
-      return true;
-    }
-
-    @Override
-    public HeaderField clone() {
-      List<String> newValues = new ArrayList<String>();
-      newValues.addAll(values);
-
-      return new HeaderField(fieldName, newValues);
-    }
-  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/05d20c1f/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchPart.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchPart.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchPart.java
index 258f48a..69f211f 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchPart.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchPart.java
@@ -18,12 +18,8 @@
  ******************************************************************************/
 package org.apache.olingo.odata2.core.batch.v2;
 
-import java.util.Map;
-
-import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
-
 public interface BatchPart {
-  public Map<String, HeaderField> getHeaders();
+  public Header getHeaders();
 
   public boolean isStrict();
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/05d20c1f/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
index 5176bb8..87dcb23 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
@@ -19,16 +19,14 @@
 package org.apache.olingo.odata2.core.batch.v2;
 
 import java.util.List;
-import java.util.Map;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
-import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
 
 public class BatchQueryOperation implements BatchPart {
 
   protected final boolean isStrict;
   protected String httpStatusLine;
-  protected Map<String, HeaderField> headers;
+  protected Header headers;
   protected List<String> body;
   protected int bodySize;
   protected List<String> message;
@@ -71,7 +69,7 @@ public class BatchQueryOperation implements BatchPart {
   }
 
   @Override
-  public Map<String, HeaderField> getHeaders() {
+  public Header getHeaders() {
     return headers;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/05d20c1f/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
index 5169575..a49a2e5 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
@@ -22,12 +22,10 @@ import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Set;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
@@ -40,7 +38,6 @@ import org.apache.olingo.odata2.api.processor.ODataRequest.ODataRequestBuilder;
 import org.apache.olingo.odata2.api.uri.PathInfo;
 import org.apache.olingo.odata2.core.batch.BatchHelper;
 import org.apache.olingo.odata2.core.batch.BatchRequestPartImpl;
-import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
 
 public class BatchRequestTransformator implements BatchTransformator {
 
@@ -55,7 +52,7 @@ public class BatchRequestTransformator implements BatchTransformator {
     final List<ODataRequest> requests = new LinkedList<ODataRequest>();
     final List<BatchParserResult> resultList = new ArrayList<BatchParserResult>();
 
-    validateBodyPartHeaders(bodyPart);
+    validateHeader(bodyPart, false);
 
     for (BatchQueryOperation queryOperation : bodyPart.getRequests()) {
       requests.add(processQueryOperation(bodyPart, pathInfo, baseUri, queryOperation));
@@ -65,11 +62,11 @@ public class BatchRequestTransformator implements BatchTransformator {
     return resultList;
   }
 
-  private void validateBodyPartHeaders(final BatchBodyPart bodyPart) throws BatchException {
-    Map<String, HeaderField> headers = bodyPart.getHeaders();
+  private void validateHeader(final BatchPart bodyPart, boolean isChangeSet) throws BatchException {
+    Header headers = bodyPart.getHeaders();
 
     BatchTransformatorCommon.validateContentType(headers);
-    BatchTransformatorCommon.validateContentTransferEncoding(headers, false);
+    BatchTransformatorCommon.validateContentTransferEncoding(headers, isChangeSet);
   }
 
   private ODataRequest processQueryOperation(final BatchBodyPart bodyPart, final PathInfo pathInfo,
@@ -77,24 +74,18 @@ public class BatchRequestTransformator implements BatchTransformator {
 
     if (bodyPart.isChangeSet()) {
       BatchQueryOperation encapsulatedQueryOperation = ((BatchChangeSetPart) queryOperation).getRequest();
-      Map<String, HeaderField> headers = transformHeader(encapsulatedQueryOperation, queryOperation);
-      validateChangeSetMultipartMimeHeaders(queryOperation, encapsulatedQueryOperation);
+      Header headers = transformHeader(encapsulatedQueryOperation, queryOperation);
+      validateHeader(queryOperation, true);
 
       return createRequest(queryOperation, headers, pathInfo, baseUri, bodyPart.isChangeSet());
     } else {
 
-      Map<String, HeaderField> headers = transformHeader(queryOperation, bodyPart);
+      Header headers = transformHeader(queryOperation, bodyPart);
       return createRequest(queryOperation, headers, pathInfo, baseUri, bodyPart.isChangeSet());
     }
   }
 
-  private void validateChangeSetMultipartMimeHeaders(final BatchQueryOperation queryOperation,
-      final BatchQueryOperation encapsulatedQueryOperation) throws BatchException {
-    BatchTransformatorCommon.validateContentType(queryOperation.getHeaders());
-    BatchTransformatorCommon.validateContentTransferEncoding(queryOperation.getHeaders(), true);
-  }
-
-  private ODataRequest createRequest(final BatchQueryOperation operation, final Map<String, HeaderField> headers,
+  private ODataRequest createRequest(final BatchQueryOperation operation, final Header headers,
       final PathInfo pathInfo, final String baseUri, final boolean isChangeSet) throws BatchException {
 
     ODataHttpMethod httpMethod = getHttpMethod(operation.getHttpStatusLine());
@@ -104,14 +95,18 @@ public class BatchRequestTransformator implements BatchTransformator {
 
     ODataRequestBuilder requestBuilder = ODataRequest.method(httpMethod)
         .acceptableLanguages(getAcceptLanguageHeaders(headers))
-        .acceptHeaders(getAcceptHeaders(headers))
+        .acceptHeaders(headers.getHeaders(HttpHeaders.ACCEPT))
         .allQueryParameters(BatchParserCommon.parseQueryParameter(operation.getHttpStatusLine()))
         .body(bodyStrean)
-        .requestHeaders(BatchParserCommon.headerFieldMapToMultiMap(headers))
+        .requestHeaders(headers.toMultiMap())
         .pathInfo(BatchParserCommon.parseRequestUri(operation.getHttpStatusLine(), pathInfo, baseUri));
-
-    addContentTypeHeader(requestBuilder, headers);
-
+    
+    final String contentType =headers.getHeader(HttpHeaders.CONTENT_TYPE);
+    if(contentType != null) {
+      requestBuilder.contentType(contentType);
+    }
+      
+    
     return requestBuilder.build();
   }
 
@@ -127,7 +122,7 @@ public class BatchRequestTransformator implements BatchTransformator {
         || (operation.getBody().size() == 1 && !operation.getBody().get(0).trim().equals(""));
   }
 
-  private InputStream getBodyStream(final BatchQueryOperation operation, final Map<String, HeaderField> headers,
+  private InputStream getBodyStream(final BatchQueryOperation operation, Header headers,
       final ODataHttpMethod httpMethod) throws BatchException {
 
     if (HTTP_BATCH_METHODS.contains(httpMethod.toString())) {
@@ -143,27 +138,18 @@ public class BatchRequestTransformator implements BatchTransformator {
     }
   }
 
-  private Map<String, HeaderField> transformHeader(final BatchPart operation, final BatchPart parentPart) {
-    final Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
-    final Map<String, HeaderField> operationHeader = operation.getHeaders();
-    final Map<String, HeaderField> parentHeaders = parentPart.getHeaders();
+  private Header transformHeader(final BatchPart operation, final BatchPart parentPart) {
+    final Header headers = operation.getHeaders().clone();
+    headers.removeHeaders(BatchHelper.HTTP_CONTENT_ID);
+    final List<String> operationContentIds = operation.getHeaders().getHeaders(BatchHelper.HTTP_CONTENT_ID);
+    final List<String> parentContentIds = parentPart.getHeaders().getHeaders(BatchHelper.HTTP_CONTENT_ID);
 
-    for (final String key : operation.getHeaders().keySet()) {
-      headers.put(key, operation.getHeaders().get(key).clone());
+    if (operationContentIds.size() != 0) {
+      headers.addHeader(BatchHelper.REQUEST_HEADER_CONTENT_ID, operationContentIds);
     }
 
-    headers.remove(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH));
-
-    if (operationHeader.containsKey(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH))) {
-      HeaderField operationContentField = operationHeader.get(BatchHelper.HTTP_CONTENT_ID.toLowerCase());
-      headers.put(BatchHelper.REQUEST_HEADER_CONTENT_ID.toLowerCase(Locale.ENGLISH), new HeaderField(
-          BatchHelper.REQUEST_HEADER_CONTENT_ID, operationContentField.getValues()));
-    }
-
-    if (parentHeaders.containsKey(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH))) {
-      HeaderField parentContentField = parentHeaders.get(BatchHelper.HTTP_CONTENT_ID.toLowerCase());
-      headers.put(BatchHelper.MIME_HEADER_CONTENT_ID.toLowerCase(Locale.ENGLISH), new HeaderField(
-          BatchHelper.MIME_HEADER_CONTENT_ID, parentContentField.getValues()));
+    if (parentContentIds.size() != 0) {
+      headers.addHeader(BatchHelper.MIME_HEADER_CONTENT_ID, parentContentIds);
     }
 
     return headers;
@@ -179,52 +165,19 @@ public class BatchRequestTransformator implements BatchTransformator {
     }
   }
 
-  private void addContentTypeHeader(final ODataRequestBuilder requestBuilder, final Map<String, HeaderField> header) {
-    String contentType = getContentTypeHeader(header);
-
-    if (contentType != null) {
-      requestBuilder.contentType(contentType);
-    }
-  }
-
-  private String getContentTypeHeader(final Map<String, HeaderField> headers) {
-    HeaderField contentTypeField = headers.get(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH));
-    String contentType = null;
-    if (contentTypeField != null) {
-      for (String requestContentType : contentTypeField.getValues()) {
-        contentType = contentType != null ? contentType + "," + requestContentType : requestContentType;
-      }
-    }
-
-    return contentType;
-  }
-
-  private List<String> getAcceptHeaders(final Map<String, HeaderField> headers) {
-    List<String> acceptHeaders = new ArrayList<String>();
-    HeaderField requestAcceptHeaderField = headers.get(HttpHeaders.ACCEPT.toLowerCase(Locale.ENGLISH));
-
-    if (requestAcceptHeaderField != null) {
-      acceptHeaders = requestAcceptHeaderField.getValues();
-    }
-
-    return acceptHeaders;
-  }
-
-  private List<Locale> getAcceptLanguageHeaders(final Map<String, HeaderField> headers) {
-    final HeaderField requestAcceptLanguageField = headers.get(HttpHeaders.ACCEPT_LANGUAGE.toLowerCase(Locale.ENGLISH));
+  private List<Locale> getAcceptLanguageHeaders(final Header headers) {
+    final List<String> acceptLanguageValues = headers.getHeaders(HttpHeaders.ACCEPT_LANGUAGE);
     List<Locale> acceptLanguages = new ArrayList<Locale>();
 
-    if (requestAcceptLanguageField != null) {
-      for (String acceptLanguage : requestAcceptLanguageField.getValues()) {
-        String[] part = acceptLanguage.split("-");
-        String language = part[0];
-        String country = "";
-        if (part.length == 2) {
-          country = part[part.length - 1];
-        }
-        Locale locale = new Locale(language, country);
-        acceptLanguages.add(locale);
+    for (String acceptLanguage : acceptLanguageValues) {
+      String[] part = acceptLanguage.split("-");
+      String language = part[0];
+      String country = "";
+      if (part.length == 2) {
+        country = part[part.length - 1];
       }
+      Locale locale = new Locale(language, country);
+      acceptLanguages.add(locale);
     }
 
     return acceptLanguages;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/05d20c1f/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
index d82d09e..ab983ac 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
@@ -20,8 +20,6 @@ package org.apache.olingo.odata2.core.batch.v2;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Locale;
-import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -31,7 +29,6 @@ import org.apache.olingo.odata2.api.client.batch.BatchSingleResponse;
 import org.apache.olingo.odata2.api.uri.PathInfo;
 import org.apache.olingo.odata2.core.batch.BatchHelper;
 import org.apache.olingo.odata2.core.batch.BatchSingleResponseImpl;
-import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
 
 public class BatchResponseTransformator implements BatchTransformator {
 
@@ -52,7 +49,6 @@ public class BatchResponseTransformator implements BatchTransformator {
     List<BatchParserResult> resultList = new ArrayList<BatchParserResult>();
 
     BatchTransformatorCommon.validateContentType(bodyPart.getHeaders());
-
     resultList.addAll(handleBodyPart(bodyPart));
 
     return resultList;
@@ -66,7 +62,9 @@ public class BatchResponseTransformator implements BatchTransformator {
         bodyPartResult.add(transformChangeSet((BatchChangeSetPart) operation));
       }
     } else {
-      bodyPartResult.add(transformQueryOperation(bodyPart.getRequests().get(0), getContentId(bodyPart.getHeaders())));
+      final String contentId = bodyPart.getHeaders().getHeader(BatchHelper.HTTP_CONTENT_ID);
+
+      bodyPartResult.add(transformQueryOperation(bodyPart.getRequests().get(0), contentId));
     }
 
     return bodyPartResult;
@@ -74,60 +72,53 @@ public class BatchResponseTransformator implements BatchTransformator {
 
   private BatchSingleResponse transformChangeSet(final BatchChangeSetPart changeSet) throws BatchException {
     BatchTransformatorCommon.validateContentTransferEncoding(changeSet.getHeaders(), true);
+    final String contentId = changeSet.getHeaders().getHeader(BatchHelper.HTTP_CONTENT_ID);
 
-    return transformQueryOperation(changeSet.getRequest(), getContentId(changeSet.getHeaders()));
+    return transformQueryOperation(changeSet.getRequest(), contentId);
   }
 
   private BatchSingleResponse transformQueryOperation(final BatchQueryOperation operation, final String contentId)
       throws BatchException {
+
+    final Matcher statusMatcher = prepareStatusLineMatcher(operation.getHttpStatusLine());
+
     BatchSingleResponseImpl response = new BatchSingleResponseImpl();
     response.setContentId(contentId);
-    response.setHeaders(BatchParserCommon.headerFieldMapToSingleMap(operation.getHeaders()));
-    response.setStatusCode(getStatusCode(operation.httpStatusLine));
-    response.setStatusInfo(getStatusInfo(operation.getHttpStatusLine()));
+    response.setHeaders(operation.getHeaders().toSingleMap());
+    response.setStatusCode(getStatusCode(statusMatcher));
+    response.setStatusInfo(getStatusInfo(statusMatcher));
     response.setBody(getBody(operation));
 
     return response;
   }
 
-  private String getContentId(final Map<String, HeaderField> headers) {
-    HeaderField contentIdField = headers.get(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH));
+  private Matcher prepareStatusLineMatcher(String httpStatusLine) throws BatchException {
+    final Pattern regexPattern = Pattern.compile(REG_EX_STATUS_LINE);
+    final Matcher matcher = regexPattern.matcher(httpStatusLine);
 
-    if (contentIdField != null) {
-      if (contentIdField.getValues().size() > 0) {
-        return contentIdField.getValues().get(0);
-      }
+    if (matcher.find()) {
+      return matcher;
+    } else {
+      throw new BatchException(BatchException.INVALID_STATUS_LINE);
     }
-
-    return null;
   }
 
   private String getBody(final BatchQueryOperation operation) throws BatchException {
     int contentLength = BatchTransformatorCommon.getContentLength(operation.getHeaders());
 
-    return BatchParserCommon.trimStringListToStringLength(operation.getBody(), contentLength);
-  }
-
-  private String getStatusCode(final String httpMethod) throws BatchException {
-    Pattern regexPattern = Pattern.compile(REG_EX_STATUS_LINE);
-    Matcher matcher = regexPattern.matcher(httpMethod);
-
-    if (matcher.find()) {
-      return matcher.group(1);
+    if (contentLength == -1) {
+      return BatchParserCommon.stringListToString(operation.getBody());
     } else {
-      throw new BatchException(BatchException.INVALID_STATUS_LINE);
+      return BatchParserCommon.trimStringListToStringLength(operation.getBody(), contentLength);
     }
   }
 
-  private String getStatusInfo(final String httpMethod) throws BatchException {
-    Pattern regexPattern = Pattern.compile(REG_EX_STATUS_LINE);
-    Matcher matcher = regexPattern.matcher(httpMethod);
+  private String getStatusCode(final Matcher matcher) throws BatchException {
+    return matcher.group(1);
+  }
 
-    if (matcher.find()) {
-      return matcher.group(2);
-    } else {
-      throw new BatchException(BatchException.INVALID_STATUS_LINE);
-    }
+  private String getStatusInfo(final Matcher matcher) throws BatchException {
+    return matcher.group(2);
   }
 
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/05d20c1f/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
index c9c8e0f..9c67f49 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
@@ -1,49 +1,38 @@
 package org.apache.olingo.odata2.core.batch.v2;
 
-import java.util.Locale;
-import java.util.Map;
+import java.util.List;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
 import org.apache.olingo.odata2.api.commons.HttpContentType;
 import org.apache.olingo.odata2.api.commons.HttpHeaders;
 import org.apache.olingo.odata2.core.batch.BatchHelper;
-import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
 
 public class BatchTransformatorCommon {
 
-  public static void validateContentType(final Map<String, HeaderField> headers) throws BatchException {
-    final HeaderField contentTypeField = headers.get(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH));
-    if (contentTypeField != null) {
-      if (contentTypeField.getValues().size() == 1) {
-        final String contentType = contentTypeField.getValues().get(0);
+  public static void validateContentType(final Header headers) throws BatchException {
+    List<String> contentTypes = headers.getHeaders(HttpHeaders.CONTENT_TYPE);
 
-        if (!BatchParserCommon.PATTERN_MULTIPART_BOUNDARY.matcher(contentType).matches()
-            && !BatchParserCommon.PATTERN_CONTENT_TYPE_APPLICATION_HTTP.matcher(contentType).matches()) {
-          throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(HttpContentType.MULTIPART_MIXED
-              + " or " + HttpContentType.APPLICATION_HTTP));
-        }
-      } else {
-        throw new BatchException(BatchException.INVALID_HEADER);
-      }
-    } else {
+    if (contentTypes.size() == 0) {
       throw new BatchException(BatchException.MISSING_CONTENT_TYPE);
     }
+    if (!headers.isHeaderMatching(HttpHeaders.CONTENT_TYPE, BatchParserCommon.PATTERN_MULTIPART_BOUNDARY)
+      & !headers.isHeaderMatching(HttpHeaders.CONTENT_TYPE, BatchParserCommon.PATTERN_CONTENT_TYPE_APPLICATION_HTTP)) {
+      throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(
+          HttpContentType.MULTIPART_MIXED + " or " + HttpContentType.APPLICATION_HTTP));
+    }
   }
 
-  public static void validateContentTransferEncoding(final Map<String, HeaderField> headers,
-      final boolean isChangeRequest)
+  public static void validateContentTransferEncoding(final Header headers, final boolean isChangeRequest)
       throws BatchException {
-    if (headers.containsKey(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING.toLowerCase(Locale.ENGLISH))) {
-      HeaderField encodingField = headers.get(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING.toLowerCase(Locale.ENGLISH));
+    final List<String> contentTransferEncodings = headers.getHeaders(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING);
 
-      if (encodingField.getValues().size() == 1) {
-        String encoding = encodingField.getValues().get(0);
+    if (contentTransferEncodings.size() != 0) {
+      if (contentTransferEncodings.size() == 1) {
+        String encoding = contentTransferEncodings.get(0);
 
         if (!BatchHelper.BINARY_ENCODING.equalsIgnoreCase(encoding)) {
           throw new BatchException(BatchException.INVALID_CONTENT_TRANSFER_ENCODING);
         }
-      } else if (encodingField.getValues().size() == 0) {
-        throw new BatchException(BatchException.INVALID_CONTENT_TRANSFER_ENCODING);
       } else {
         throw new BatchException(BatchException.INVALID_HEADER);
       }
@@ -54,12 +43,12 @@ public class BatchTransformatorCommon {
     }
   }
 
-  public static int getContentLength(final Map<String, HeaderField> headers) throws BatchException {
+  public static int getContentLength(final Header headers) throws BatchException {
+    final List<String> contentLengths = headers.getHeaders(HttpHeaders.CONTENT_LENGTH);
 
-    if (headers.containsKey(HttpHeaders.CONTENT_LENGTH.toLowerCase(Locale.ENGLISH))) {
+    if (contentLengths.size() == 1) {
       try {
-        int contentLength =
-            Integer.parseInt(headers.get(HttpHeaders.CONTENT_LENGTH.toLowerCase(Locale.ENGLISH)).getValues().get(0));
+        int contentLength = Integer.parseInt(contentLengths.get(0));
 
         if (contentLength < 0) {
           throw new BatchException(BatchException.INVALID_HEADER);

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/05d20c1f/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
new file mode 100644
index 0000000..7901b7b
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
@@ -0,0 +1,202 @@
+package org.apache.olingo.odata2.core.batch.v2;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+public class Header implements Cloneable {
+
+  private final Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
+  
+  public static List<String> splitValuesByComma(final String headerValue) {
+    final List<String> singleValues = new ArrayList<String>();
+
+    String[] parts = headerValue.split(",");
+    for (final String value : parts) {
+      singleValues.add(value.trim());
+    }
+
+    return singleValues;
+  }
+  
+  public void addHeader(final String name, final String value) {
+    final HeaderField headerField = getHeaderFieldOrDefault(name);
+    final List<String> headerValues = headerField.getValues();
+
+    if (!headerValues.contains(value)) {
+      headerValues.add(value);
+    }
+  }
+
+  public void addHeader(final String name, final List<String> values) {
+    final HeaderField headerField = getHeaderFieldOrDefault(name);
+    final List<String> headerValues = headerField.getValues();
+
+    for (final String value : values) {
+      if (!headerValues.contains(value)) {
+        headerValues.add(value);
+      }
+    }
+  }
+  
+  public boolean isHeaderMatching(final String name, final Pattern pattern) {
+    if(getHeaders(name).size() != 1 ) {
+      return false;
+    } else {
+      return pattern.matcher(getHeaders(name).get(0)).matches();
+    }
+  }
+  
+  public void removeHeaders(final String name) {
+    headers.remove(name.toLowerCase(Locale.ENGLISH));
+  }
+
+  public String getHeader(final String name) {
+    final HeaderField headerField = getHeaderField(name);
+
+    if (headerField == null) {
+      return null;
+    } else {
+      final List<String> headerValues = headerField.getValues();
+      final StringBuilder result = new StringBuilder();
+
+      for (final String value : headerValues) {
+        result.append(value);
+        result.append(", ");
+      }
+      
+      if(result.length()>0) {
+        result.delete(result.length() - 2, result.length());
+      }
+      
+      return result.toString();
+    }
+  }
+
+  public String getHeaderNotNull(final String name) {
+    final String value = getHeader(name);
+
+    return (value == null) ? "" : value;
+  }
+
+  public List<String> getHeaders(final String name) {
+    final HeaderField headerField = getHeaderField(name);
+
+    return (headerField == null) ? new ArrayList<String>() : headerField.getValues();
+  }
+
+  public HeaderField getHeaderField(final String name) {
+    return headers.get(name.toLowerCase(Locale.ENGLISH));
+  }
+
+  public Map<String, String> toSingleMap() {
+    final Map<String, String> singleMap = new HashMap<String, String>();
+
+    for (final String key : headers.keySet()) {
+      HeaderField field = headers.get(key);
+      singleMap.put(field.getFieldName(), getHeader(key));
+    }
+
+    return singleMap;
+  }
+
+  public Map<String, List<String>> toMultiMap() {
+    final Map<String, List<String>> singleMap = new HashMap<String, List<String>>();
+
+    for (final String key : headers.keySet()) {
+      HeaderField field = headers.get(key);
+      singleMap.put(field.getFieldName(), field.getValues());
+    }
+
+    return singleMap;
+  }
+
+  private HeaderField getHeaderFieldOrDefault(final String name) {
+    HeaderField headerField = headers.get(name.toLowerCase(Locale.ENGLISH));
+
+    if (headerField == null) {
+      headerField = new HeaderField(name);
+      headers.put(name.toLowerCase(Locale.ENGLISH), headerField);
+    }
+
+    return headerField;
+  }
+
+  @Override
+  public Header clone() {
+    final Header newInstance = new Header();
+
+    for (final String key : headers.keySet()) {
+      newInstance.headers.put(key, headers.get(key).clone());
+    }
+
+    return newInstance;
+  }
+
+  public static class HeaderField implements Cloneable {
+    private String fieldName;
+    private List<String> values;
+
+    public HeaderField(final String fieldName) {
+      this(fieldName, new ArrayList<String>());
+    }
+
+    public HeaderField(final String fieldName, final List<String> values) {
+      this.fieldName = fieldName;
+      this.values = values;
+    }
+
+    public String getFieldName() {
+      return fieldName;
+    }
+
+    public List<String> getValues() {
+      return values;
+    }
+
+    public void setValues(final List<String> values) {
+      this.values = values;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((fieldName == null) ? 0 : fieldName.hashCode());
+      return result;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+      if (this == obj) {
+        return true;
+      }
+      if (obj == null) {
+        return false;
+      }
+      if (getClass() != obj.getClass()) {
+        return false;
+      }
+      HeaderField other = (HeaderField) obj;
+      if (fieldName == null) {
+        if (other.fieldName != null) {
+          return false;
+        }
+      } else if (!fieldName.equals(other.fieldName)) {
+        return false;
+      }
+      return true;
+    }
+
+    @Override
+    public HeaderField clone() {
+      List<String> newValues = new ArrayList<String>();
+      newValues.addAll(values);
+
+      return new HeaderField(fieldName, newValues);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/05d20c1f/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
index 8451c55..56cbeeb 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
@@ -5,13 +5,11 @@ import static org.junit.Assert.*;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Locale;
-import java.util.Map;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
 import org.apache.olingo.odata2.api.commons.HttpHeaders;
 import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon;
-import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
+import org.apache.olingo.odata2.core.batch.v2.Header;
 import org.junit.Test;
 
 public class BatchParserCommonTest {
@@ -30,14 +28,14 @@ public class BatchParserCommonTest {
     message.addAll(Arrays.asList(messageRaw));
     
     
-    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
     
-    final HeaderField contentIdHeaders = header.get(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH));
+    final List<String> contentIdHeaders = header.getHeaders(BatchHelper.HTTP_CONTENT_ID);
     assertNotNull(contentIdHeaders);
-    assertEquals(2, contentIdHeaders.getValues().size());
-    assertEquals("1", contentIdHeaders.getValues().get(0));
-    assertEquals("2", contentIdHeaders.getValues().get(1));
+    assertEquals(2, contentIdHeaders.size());
+    assertEquals("1", contentIdHeaders.get(0));
+    assertEquals("2", contentIdHeaders.get(1));
   }
   
   @Test
@@ -52,13 +50,13 @@ public class BatchParserCommonTest {
     message.addAll(Arrays.asList(messageRaw));
     
     
-    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
     
-    final HeaderField contentIdHeaders = header.get(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH));
+    final List<String> contentIdHeaders = header.getHeaders(BatchHelper.HTTP_CONTENT_ID);
     assertNotNull(contentIdHeaders);
-    assertEquals(1, contentIdHeaders.getValues().size());
-    assertEquals("1", contentIdHeaders.getValues().get(0));
+    assertEquals(1, contentIdHeaders.size());
+    assertEquals("1", contentIdHeaders.get(0));
   }
   
   @Test
@@ -73,16 +71,16 @@ public class BatchParserCommonTest {
     message.addAll(Arrays.asList(messageRaw));
     
     
-    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
     
-    final HeaderField upgradeHeader = header.get("upgrade");
+    final List<String> upgradeHeader = header.getHeaders("upgrade");
     assertNotNull(upgradeHeader);
-    assertEquals(4, upgradeHeader.getValues().size());
-    assertEquals("HTTP/2.0", upgradeHeader.getValues().get(0));
-    assertEquals("SHTTP/1.3", upgradeHeader.getValues().get(1));
-    assertEquals("IRC/6.9", upgradeHeader.getValues().get(2));
-    assertEquals("RTA/x11", upgradeHeader.getValues().get(3));
+    assertEquals(4, upgradeHeader.size());
+    assertEquals("HTTP/2.0", upgradeHeader.get(0));
+    assertEquals("SHTTP/1.3", upgradeHeader.get(1));
+    assertEquals("IRC/6.9", upgradeHeader.get(2));
+    assertEquals("RTA/x11", upgradeHeader.get(3));
   }
   
   @Test
@@ -98,12 +96,12 @@ public class BatchParserCommonTest {
     message.addAll(Arrays.asList(messageRaw));
     
     
-    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
     
-    final HeaderField acceptHeader = header.get(HttpHeaders.ACCEPT.toLowerCase());
+    final List<String> acceptHeader = header.getHeaders(HttpHeaders.ACCEPT);
     assertNotNull(acceptHeader);
-    assertEquals(4, acceptHeader.getValues().size());
+    assertEquals(4, acceptHeader.size());
   }
   
   @Test
@@ -119,12 +117,12 @@ public class BatchParserCommonTest {
     message.addAll(Arrays.asList(messageRaw));
     
     
-    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
     
-    final HeaderField acceptHeader = header.get(HttpHeaders.ACCEPT.toLowerCase());
+    final List<String> acceptHeader = header.getHeaders(HttpHeaders.ACCEPT);
     assertNotNull(acceptHeader);
-    assertEquals(3, acceptHeader.getValues().size());
+    assertEquals(3, acceptHeader.size());
   }
   
   @Test
@@ -138,12 +136,12 @@ public class BatchParserCommonTest {
     List<String> message = new ArrayList<String>();
     message.addAll(Arrays.asList(messageRaw));
     
-    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
     
-    final HeaderField acceptLanguageHeader = header.get(HttpHeaders.ACCEPT_LANGUAGE.toLowerCase());
+    final List<String> acceptLanguageHeader = header.getHeaders(HttpHeaders.ACCEPT_LANGUAGE);
     assertNotNull(acceptLanguageHeader);
-    assertEquals(4, acceptLanguageHeader.getValues().size());
+    assertEquals(4, acceptLanguageHeader.size());
   }
   
   @Test
@@ -157,12 +155,12 @@ public class BatchParserCommonTest {
     List<String> message = new ArrayList<String>();
     message.addAll(Arrays.asList(messageRaw));
     
-    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
     
-    final HeaderField acceptLanguageHeader = header.get(HttpHeaders.ACCEPT_LANGUAGE.toLowerCase());
+    final List<String> acceptLanguageHeader = header.getHeaders(HttpHeaders.ACCEPT_LANGUAGE);
     assertNotNull(acceptLanguageHeader);
-    assertEquals(3, acceptLanguageHeader.getValues().size());
+    assertEquals(3, acceptLanguageHeader.size());
   }
   
   @Test

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/05d20c1f/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
index a70d15a..e98a295 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
@@ -1,15 +1,13 @@
 package org.apache.olingo.odata2.core.batch;
 
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
 import org.apache.olingo.odata2.api.commons.HttpContentType;
 import org.apache.olingo.odata2.api.commons.HttpHeaders;
-import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
 import org.apache.olingo.odata2.core.batch.v2.BatchTransformatorCommon;
+import org.apache.olingo.odata2.core.batch.v2.Header;
 import org.junit.Test;
 
 public class BatchTransformatorCommonTest {
@@ -19,7 +17,7 @@ public class BatchTransformatorCommonTest {
   @Test
   public void testValidateContentTypeApplicationHTTP() throws BatchException {
     List<String> contentTypeValues = Arrays.asList(new String[] { HttpContentType.APPLICATION_HTTP });
-    Map<String, HeaderField> headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
+    final Header headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
 
     BatchTransformatorCommon.validateContentType(headers);
   }
@@ -28,7 +26,7 @@ public class BatchTransformatorCommonTest {
   public void testValidateContentTypeMultipartMixed() throws BatchException {
     List<String> contentTypeValues =
         Arrays.asList(new String[] { HttpContentType.MULTIPART_MIXED + "; boundary=batch_32332_32323_fdsf" });
-    Map<String, HeaderField> headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
+    final Header headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
 
     BatchTransformatorCommon.validateContentType(headers);
   }
@@ -37,7 +35,7 @@ public class BatchTransformatorCommonTest {
   public void testValidateContentTypeMultipartMixedCaseInsensitiv() throws BatchException {
     List<String> contentTypeValues =
         Arrays.asList(new String[] { "mulTiPart/MiXed; boundary=batch_32332_32323_fdsf" });
-    Map<String, HeaderField> headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
+    final Header headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
 
     BatchTransformatorCommon.validateContentType(headers);
   }
@@ -45,14 +43,15 @@ public class BatchTransformatorCommonTest {
   @Test(expected = BatchException.class)
   public void testValidateContentTypeNoValue() throws BatchException {
     List<String> contentTypeValues = Arrays.asList(new String[] {});
-    Map<String, HeaderField> headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
+    final Header headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
 
     BatchTransformatorCommon.validateContentType(headers);
   }
 
   @Test(expected = BatchException.class)
   public void testValidateContentTypeMissingHeader() throws BatchException {
-    Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
+    final Header headers = new Header();
+    
     BatchTransformatorCommon.validateContentType(headers);
   }
 
@@ -60,7 +59,7 @@ public class BatchTransformatorCommonTest {
   public void testValidateContentTypeMultipleValues() throws BatchException {
     List<String> contentTypeValues =
         Arrays.asList(new String[] { HttpContentType.APPLICATION_HTTP, HttpContentType.MULTIPART_MIXED });
-    Map<String, HeaderField> headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
+    final Header headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
 
     BatchTransformatorCommon.validateContentType(headers);
   }
@@ -68,7 +67,7 @@ public class BatchTransformatorCommonTest {
   @Test
   public void testValidateContentTransferEncoding() throws BatchException {
     List<String> contentTransferEncoding = Arrays.asList(new String[] { BatchHelper.BINARY_ENCODING });
-    Map<String, HeaderField> headers = makeHeaders(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
+    final Header headers = makeHeaders(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
 
     BatchTransformatorCommon.validateContentTransferEncoding(headers, false);
   }
@@ -76,28 +75,29 @@ public class BatchTransformatorCommonTest {
   @Test(expected = BatchException.class)
   public void testValidateContentTransferEncodingMultipleValues() throws BatchException {
     List<String> contentTransferEncoding = Arrays.asList(new String[] { BatchHelper.BINARY_ENCODING, BASE64_ENCODING });
-    Map<String, HeaderField> headers = makeHeaders(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
+    final Header headers = makeHeaders(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
 
     BatchTransformatorCommon.validateContentTransferEncoding(headers, false);
   }
 
   @Test(expected = BatchException.class)
   public void testValidateContentTransferEncodingMissingHeader() throws BatchException {
-    Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
+    final Header headers = new Header();
+    
     BatchTransformatorCommon.validateContentTransferEncoding(headers, true);
   }
 
   @Test(expected = BatchException.class)
   public void testValidateContentTransferEncodingMissingValue() throws BatchException {
     List<String> contentTransferEncoding = Arrays.asList(new String[] {});
-    Map<String, HeaderField> headers = makeHeaders(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
+    final Header headers = makeHeaders(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
 
-    BatchTransformatorCommon.validateContentTransferEncoding(headers, false);
+    BatchTransformatorCommon.validateContentTransferEncoding(headers, true);
   }
 
-  private Map<String, HeaderField> makeHeaders(final String headerName, final List<String> values) {
-    Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
-    headers.put(headerName.toLowerCase(), new HeaderField(headerName, values));
+  private Header makeHeaders(final String headerName, final List<String> values) {
+    final Header headers = new Header();
+    headers.addHeader(headerName, values);
 
     return headers;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/05d20c1f/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java
new file mode 100644
index 0000000..128aa2e
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java
@@ -0,0 +1,161 @@
+package org.apache.olingo.odata2.core.batch;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.commons.HttpContentType;
+import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon;
+import org.apache.olingo.odata2.core.batch.v2.Header;
+import org.junit.Test;
+
+public class HeaderTest {
+
+  @Test
+  public void test() {
+    Header header = new Header();
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
+
+    assertEquals(HttpContentType.MULTIPART_MIXED, header.getHeader(HttpHeaders.CONTENT_TYPE));
+    assertEquals(1, header.getHeaders(HttpHeaders.CONTENT_TYPE).size());
+    assertEquals(HttpContentType.MULTIPART_MIXED, header.getHeaders(HttpHeaders.CONTENT_TYPE).get(0));
+  }
+
+  @Test
+  public void testNotAvailable() {
+    Header header = new Header();
+
+    assertNull(header.getHeader(HttpHeaders.CONTENT_TYPE));
+    assertEquals(0, header.getHeaders(HttpHeaders.CONTENT_TYPE).size());
+    assertEquals("", header.getHeaderNotNull(HttpHeaders.CONTENT_TYPE));
+  }
+
+  @Test
+  public void testCaseInsensitive() {
+    Header header = new Header();
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
+
+    assertEquals(HttpContentType.MULTIPART_MIXED, header.getHeader("cOnTenT-TyPE"));
+    assertEquals(1, header.getHeaders("cOnTenT-TyPE").size());
+    assertEquals(HttpContentType.MULTIPART_MIXED, header.getHeaders("cOnTenT-TyPE").get(0));
+  }
+
+  @Test
+  public void testDuplicatedAdd() {
+    Header header = new Header();
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
+
+    assertEquals(HttpContentType.MULTIPART_MIXED, header.getHeader(HttpHeaders.CONTENT_TYPE));
+    assertEquals(1, header.getHeaders(HttpHeaders.CONTENT_TYPE).size());
+    assertEquals(HttpContentType.MULTIPART_MIXED, header.getHeaders(HttpHeaders.CONTENT_TYPE).get(0));
+  }
+
+  @Test
+  public void testMatcher() {
+    Header header = new Header();
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED + ";boundary=123");
+
+    assertTrue(header.isHeaderMatching(HttpHeaders.CONTENT_TYPE, BatchParserCommon.PATTERN_MULTIPART_BOUNDARY));
+  }
+
+  @Test
+  public void testFieldName() {
+    Header header = new Header();
+    header.addHeader("MyFieldNamE", "myValue");
+
+    assertEquals("MyFieldNamE", header.getHeaderField("myfieldname").getFieldName());
+    assertEquals("MyFieldNamE", header.toSingleMap().keySet().toArray(new String[0])[0]);
+    assertEquals("MyFieldNamE", header.toMultiMap().keySet().toArray(new String[0])[0]);
+
+    assertEquals("myValue", header.toMultiMap().get("MyFieldNamE").get(0));
+    assertEquals("myValue", header.toSingleMap().get("MyFieldNamE"));
+  }
+
+  @Test
+  public void testDeepCopy() {
+    Header header = new Header();
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED + ";boundary=123");
+
+    Header copy = header.clone();
+    assertEquals(header.getHeaders(HttpHeaders.CONTENT_TYPE), copy.getHeaders(HttpHeaders.CONTENT_TYPE));
+    assertEquals(header.getHeader(HttpHeaders.CONTENT_TYPE), copy.getHeader(HttpHeaders.CONTENT_TYPE));
+    assertEquals(header.getHeaderField(HttpHeaders.CONTENT_TYPE), copy.getHeaderField(HttpHeaders.CONTENT_TYPE));
+
+    assertTrue(header.getHeaders(HttpHeaders.CONTENT_TYPE) != copy.getHeaders(HttpHeaders.CONTENT_TYPE));
+    assertTrue(header.getHeaderField(HttpHeaders.CONTENT_TYPE) != copy.getHeaderField(HttpHeaders.CONTENT_TYPE));
+  }
+
+  @Test
+  public void testMatcherNoHeader() {
+    Header header = new Header();
+
+    assertFalse(header.isHeaderMatching(HttpHeaders.CONTENT_TYPE, BatchParserCommon.PATTERN_MULTIPART_BOUNDARY));
+  }
+
+  @Test
+  public void testMatcherFail() {
+    Header header = new Header();
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED + ";boundary=123");
+
+    assertFalse(header.isHeaderMatching(HttpHeaders.CONTENT_TYPE, BatchParserCommon.PATTERN_HEADER_LINE));
+  }
+
+  @Test
+  public void testDuplicatedAddList() {
+    Header header = new Header();
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, Arrays.asList(new String[] { HttpContentType.MULTIPART_MIXED,
+        HttpContentType.APPLICATION_ATOM_SVC }));
+
+    assertEquals(HttpContentType.MULTIPART_MIXED + ", " + HttpContentType.APPLICATION_ATOM_SVC, header
+        .getHeader(HttpHeaders.CONTENT_TYPE));
+    assertEquals(2, header.getHeaders(HttpHeaders.CONTENT_TYPE).size());
+    assertEquals(HttpContentType.MULTIPART_MIXED, header.getHeaders(HttpHeaders.CONTENT_TYPE).get(0));
+    assertEquals(HttpContentType.APPLICATION_ATOM_SVC, header.getHeaders(HttpHeaders.CONTENT_TYPE).get(1));
+  }
+
+  @Test
+  public void testRemove() {
+    Header header = new Header();
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
+    header.removeHeaders(HttpHeaders.CONTENT_TYPE);
+
+    assertNull(header.getHeader(HttpHeaders.CONTENT_TYPE));
+    assertEquals(0, header.getHeaders(HttpHeaders.CONTENT_TYPE).size());
+  }
+
+  @Test
+  public void testMultipleValues() {
+    Header header = new Header();
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.APPLICATION_ATOM_SVC);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.APPLICATION_ATOM_XML);
+
+    final String fullHeaderString =
+        HttpContentType.MULTIPART_MIXED + ", " + HttpContentType.APPLICATION_ATOM_SVC + ", "
+            + HttpContentType.APPLICATION_ATOM_XML;
+
+    assertEquals(fullHeaderString, header.getHeader(HttpHeaders.CONTENT_TYPE));
+    assertEquals(3, header.getHeaders(HttpHeaders.CONTENT_TYPE).size());
+    assertEquals(HttpContentType.MULTIPART_MIXED, header.getHeaders(HttpHeaders.CONTENT_TYPE).get(0));
+    assertEquals(HttpContentType.APPLICATION_ATOM_SVC, header.getHeaders(HttpHeaders.CONTENT_TYPE).get(1));
+    assertEquals(HttpContentType.APPLICATION_ATOM_XML, header.getHeaders(HttpHeaders.CONTENT_TYPE).get(2));
+  }
+  
+  @Test
+  public void testSplitValues() {
+    final String values = "abc, def,123,77,   99, ysd";
+    List<String> splittedValues = Header.splitValuesByComma(values);
+
+    assertEquals(6, splittedValues.size());
+    assertEquals("abc", splittedValues.get(0));
+    assertEquals("def", splittedValues.get(1));
+    assertEquals("123", splittedValues.get(2));
+    assertEquals("77", splittedValues.get(3));
+    assertEquals("99", splittedValues.get(4));
+    assertEquals("ysd", splittedValues.get(5));
+  }
+}


[14/19] git commit: line ending issue again

Posted by ch...@apache.org.
line ending issue again


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

Branch: refs/heads/master
Commit: b155bda551bc6f8980684d2b2b44e29accb4c524
Parents: f0dc0f7
Author: Christian Amend <ch...@apache.org>
Authored: Thu Oct 9 16:40:52 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Oct 9 16:40:52 2014 +0200

----------------------------------------------------------------------
 odata2-jpa-processor/jpa-core/.gitignore        |   14 +-
 .../processor/core/access/data/JPAEntity.java   |  896 +++++++-------
 .../jpa/processor/core/access/data/JPAPage.java |  422 +++----
 .../core/callback/JPATombstoneCallBack.java     |  120 +-
 .../jpa/processor/core/model/JPAEdmFacets.java  |  188 +--
 .../processor/core/ODataEntityParserTest.java   |  488 ++++----
 .../JPAEntityParserForStaticMethodTest.java     |  660 +++++------
 .../core/access/data/JPAEntityTest.java         |  492 ++++----
 .../processor/core/access/data/JPALinkTest.java |   46 +-
 .../access/data/JPAPageBuilderDeltaTest.java    |  714 +++++------
 .../core/access/data/JPAPageBuilderTest.java    | 1120 +++++++++---------
 .../processor/core/mock/ODataContextMock.java   |  124 +-
 .../core/mock/ODataJPAServiceFactoryMock.java   |   94 +-
 .../processor/core/mock/ODataServiceMock.java   |  212 ++--
 .../core/mock/OnJPAWriteContentMock.java        |  116 +-
 .../jpa/processor/core/mock/PathInfoMock.java   |  102 +-
 .../processor/core/mock/PathSegmentMock.java    |   88 +-
 .../processor/core/mock/data/EdmMockUtilV2.java |  806 ++++++-------
 .../processor/core/mock/data/JPATypeMock.java   |  536 ++++-----
 .../core/mock/data/ODataEntryMockUtil.java      |  328 ++---
 .../core/mock/model/JPAPluralAttributeMock.java |  188 +--
 odata2-jpa-processor/jpa-ref/.gitignore         |   14 +-
 .../ref/converter/BlobToByteConverter.java      |  140 +--
 .../ref/factory/JPAEntityManagerFactory.java    |   92 +-
 .../SalesOrderItemTombstoneListener.java        |  186 +--
 .../listeners/SalesOrderTombstoneListener.java  |  114 +-
 .../odata2/jpa/processor/ref/model/Address.java |  188 +--
 .../jpa/processor/ref/model/Category.java       |  160 +--
 .../jpa/processor/ref/model/Customer.java       |  186 +--
 .../jpa/processor/ref/model/Material.java       |  272 ++---
 .../odata2/jpa/processor/ref/model/Note.java    |  242 ++--
 .../odata2/jpa/processor/ref/model/NoteKey.java |  166 +--
 .../jpa/processor/ref/model/SalesOrderItem.java |  270 ++---
 .../processor/ref/model/SalesOrderItemKey.java  |  178 +--
 .../odata2/jpa/processor/ref/model/Store.java   |  182 +--
 .../src/main/resources/META-INF/persistence.xml |   88 +-
 odata2-jpa-processor/jpa-web/.gitignore         |   14 +-
 .../ref/extension/OnDBWriteContent.java         |  110 +-
 .../jpa/processor/ref/extension/OrderValue.java |   84 +-
 .../jpa/processor/ref/util/DataGenerator.java   |  316 ++---
 40 files changed, 5378 insertions(+), 5378 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/.gitignore
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/.gitignore b/odata2-jpa-processor/jpa-core/.gitignore
index fe5d89b..a7ffe90 100644
--- a/odata2-jpa-processor/jpa-core/.gitignore
+++ b/odata2-jpa-processor/jpa-core/.gitignore
@@ -1,8 +1,8 @@
-.project
-.classpath
-.settings
-target
-bin
-*.bak
-classes
+.project
+.classpath
+.settings
+target
+bin
+*.bak
+classes
 .DS_Store
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
index 19ca88b..847e171 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
@@ -1,449 +1,449 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.access.data;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.SQLException;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.edm.EdmProperty;
-import org.apache.olingo.odata2.api.edm.EdmSimpleType;
-import org.apache.olingo.odata2.api.edm.EdmStructuralType;
-import org.apache.olingo.odata2.api.edm.EdmTypeKind;
-import org.apache.olingo.odata2.api.edm.EdmTyped;
-import org.apache.olingo.odata2.api.ep.entry.EntryMetadata;
-import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
-import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
-import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
-import org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent;
-import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
-import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
-import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
-
-public class JPAEntity {
-
-  private Object jpaEntity = null;
-  private JPAEntity parentJPAEntity = null;
-  private EdmEntityType oDataEntityType = null;
-  private EdmEntitySet oDataEntitySet = null;
-  private Class<?> jpaType = null;
-  private HashMap<String, Method> accessModifiersWrite = null;
-  private JPAEntityParser jpaEntityParser = null;
-  private ODataJPAContext oDataJPAContext;
-  private OnJPAWriteContent onJPAWriteContent = null;
-  public HashMap<String, List<Object>> relatedJPAEntityMap = null;
-
-  public JPAEntity(final EdmEntityType oDataEntityType, final EdmEntitySet oDataEntitySet,
-      final ODataJPAContext context) {
-    this.oDataEntityType = oDataEntityType;
-    this.oDataEntitySet = oDataEntitySet;
-    oDataJPAContext = context;
-    try {
-      JPAEdmMapping mapping = (JPAEdmMapping) oDataEntityType.getMapping();
-      jpaType = mapping.getJPAType();
-    } catch (EdmException e) {
-      return;
-    }
-    jpaEntityParser = new JPAEntityParser();
-    onJPAWriteContent = oDataJPAContext.getODataContext().getServiceFactory().getCallback(OnJPAWriteContent.class);
-  }
-
-  public void setAccessModifersWrite(final HashMap<String, Method> accessModifiersWrite) {
-    this.accessModifiersWrite = accessModifiersWrite;
-  }
-
-  public void setParentJPAEntity(final JPAEntity jpaEntity) {
-    parentJPAEntity = jpaEntity;
-  }
-
-  public JPAEntity getParentJPAEntity() {
-    return parentJPAEntity;
-  }
-
-  public Object getJPAEntity() {
-    return jpaEntity;
-  }
-
-  @SuppressWarnings("unchecked")
-  private void write(final Map<String, Object> oDataEntryProperties,
-      final boolean isCreate)
-      throws ODataJPARuntimeException {
-    try {
-
-      EdmStructuralType structuralType = null;
-      final List<String> keyNames = oDataEntityType.getKeyPropertyNames();
-
-      if (isCreate) {
-        jpaEntity = instantiateJPAEntity();
-      } else if (jpaEntity == null) {
-        throw ODataJPARuntimeException
-            .throwException(ODataJPARuntimeException.RESOURCE_NOT_FOUND, null);
-      }
-
-      if (accessModifiersWrite == null) {
-        accessModifiersWrite =
-            jpaEntityParser.getAccessModifiers(jpaEntity, oDataEntityType, JPAEntityParser.ACCESS_MODIFIER_SET);
-      }
-
-      if (oDataEntityType == null || oDataEntryProperties == null) {
-        throw ODataJPARuntimeException
-            .throwException(ODataJPARuntimeException.GENERAL, null);
-      }
-
-      final HashMap<String, String> embeddableKeys =
-          jpaEntityParser.getJPAEmbeddableKeyMap(jpaEntity.getClass().getName());
-      Set<String> propertyNames = null;
-      if (embeddableKeys != null) {
-        setEmbeddableKeyProperty(embeddableKeys, oDataEntityType.getKeyProperties(), oDataEntryProperties,
-            jpaEntity);
-
-        propertyNames = new HashSet<String>();
-        propertyNames.addAll(oDataEntryProperties.keySet());
-        for (String key : embeddableKeys.keySet()) {
-          propertyNames.remove(key);
-        }
-      } else {
-        propertyNames = oDataEntryProperties.keySet();
-      }
-
-      for (String propertyName : propertyNames) {
-        EdmTyped edmTyped = (EdmTyped) oDataEntityType.getProperty(propertyName);
-
-        Method accessModifier = null;
-
-        switch (edmTyped.getType().getKind()) {
-        case SIMPLE:
-          if (isCreate == false) {
-            if (keyNames.contains(edmTyped.getName())) {
-              continue;
-            }
-          }
-          accessModifier = accessModifiersWrite.get(propertyName);
-          setProperty(accessModifier, jpaEntity, oDataEntryProperties.get(propertyName), (EdmSimpleType) edmTyped
-              .getType());
-
-          break;
-        case COMPLEX:
-          structuralType = (EdmStructuralType) edmTyped.getType();
-          accessModifier = accessModifiersWrite.get(propertyName);
-          setComplexProperty(accessModifier, jpaEntity,
-              structuralType,
-              (HashMap<String, Object>) oDataEntryProperties.get(propertyName));
-          break;
-        case NAVIGATION:
-        case ENTITY:
-          if (isCreate) {
-            structuralType = (EdmStructuralType) edmTyped.getType();
-            EdmNavigationProperty navProperty = (EdmNavigationProperty) edmTyped;
-            EdmEntitySet edmRelatedEntitySet = oDataEntitySet.getRelatedEntitySet(navProperty);
-            List<ODataEntry> relatedEntries = (List<ODataEntry>) oDataEntryProperties.get(propertyName);
-            if (relatedJPAEntityMap == null) {
-              relatedJPAEntityMap = new HashMap<String, List<Object>>();
-            }
-            List<Object> relatedJPAEntities = new ArrayList<Object>();
-            JPAEntity relatedEntity =
-                new JPAEntity((EdmEntityType) structuralType, edmRelatedEntitySet, oDataJPAContext);
-            for (ODataEntry oDataEntry : relatedEntries) {
-              relatedEntity.setParentJPAEntity(this);
-              relatedEntity.create(oDataEntry);
-              relatedJPAEntities.add(relatedEntity.getJPAEntity());
-            }
-            relatedJPAEntityMap.put(navProperty.getName(), relatedJPAEntities);
-          }
-        default:
-          continue;
-        }
-      }
-    } catch (Exception e) {
-      if (e instanceof ODataJPARuntimeException) {
-        throw (ODataJPARuntimeException) e;
-      }
-      throw ODataJPARuntimeException
-          .throwException(ODataJPARuntimeException.GENERAL
-              .addContent(e.getMessage()), e);
-    }
-  }
-
-  public void create(final ODataEntry oDataEntry) throws ODataJPARuntimeException {
-    if (oDataEntry == null) {
-      throw ODataJPARuntimeException
-          .throwException(ODataJPARuntimeException.GENERAL, null);
-    }
-    Map<String, Object> oDataEntryProperties = oDataEntry.getProperties();
-    if (oDataEntry.containsInlineEntry()) {
-      normalizeInlineEntries(oDataEntryProperties);
-    }
-    write(oDataEntryProperties, true);
-
-    EntryMetadata entryMetadata = oDataEntry.getMetadata();
-    List<String> leftNavPrpNames = new ArrayList<String>();
-    try {
-      for (String navigationPropertyName : oDataEntityType.getNavigationPropertyNames()) {
-        List<String> links = entryMetadata.getAssociationUris(navigationPropertyName);
-        if (links.isEmpty()) {
-          continue;
-        } else {
-          EdmNavigationProperty navProperty =
-              (EdmNavigationProperty) oDataEntityType.getProperty(navigationPropertyName);
-          if (relatedJPAEntityMap != null && relatedJPAEntityMap.containsKey(navigationPropertyName)) {
-            JPALink.linkJPAEntities(relatedJPAEntityMap.get(navigationPropertyName), jpaEntity,
-                navProperty);
-          } else if (parentJPAEntity != null
-              &&
-              parentJPAEntity.getEdmEntitySet().getName().equals(
-                  oDataEntitySet.getRelatedEntitySet(navProperty).getName())) {
-            List<Object> targetJPAEntities = new ArrayList<Object>();
-            targetJPAEntities.add(parentJPAEntity.getJPAEntity());
-            JPALink.linkJPAEntities(targetJPAEntities, jpaEntity, navProperty);
-          } else {
-            leftNavPrpNames.add(navigationPropertyName);
-          }
-        }
-      }
-      if (!leftNavPrpNames.isEmpty()) {
-        JPALink link = new JPALink(oDataJPAContext);
-        link.setSourceJPAEntity(jpaEntity);
-        link.create(oDataEntitySet, oDataEntry, leftNavPrpNames);
-      }
-    } catch (EdmException e) {
-      throw ODataJPARuntimeException
-          .throwException(ODataJPARuntimeException.GENERAL
-              .addContent(e.getMessage()), e);
-    } catch (ODataJPAModelException e) {
-      throw ODataJPARuntimeException
-          .throwException(ODataJPARuntimeException.GENERAL
-              .addContent(e.getMessage()), e);
-    }
-  }
-
-  public EdmEntitySet getEdmEntitySet() {
-    return oDataEntitySet;
-  }
-
-  public void create(final Map<String, Object> oDataEntryProperties) throws ODataJPARuntimeException {
-    normalizeInlineEntries(oDataEntryProperties);
-    write(oDataEntryProperties, true);
-  }
-
-  public void update(final ODataEntry oDataEntry) throws ODataJPARuntimeException {
-    if (oDataEntry == null) {
-      throw ODataJPARuntimeException
-          .throwException(ODataJPARuntimeException.GENERAL, null);
-    }
-    Map<String, Object> oDataEntryProperties = oDataEntry.getProperties();
-    if (oDataEntry.containsInlineEntry()) {
-      normalizeInlineEntries(oDataEntryProperties);
-    }
-    write(oDataEntryProperties, false);
-    JPALink link = new JPALink(oDataJPAContext);
-    link.setSourceJPAEntity(jpaEntity);
-    try {
-      link.create(oDataEntitySet, oDataEntry, oDataEntityType.getNavigationPropertyNames());
-    } catch (EdmException e) {
-      throw ODataJPARuntimeException
-          .throwException(ODataJPARuntimeException.GENERAL
-              .addContent(e.getMessage()), e);
-    } catch (ODataJPAModelException e) {
-      throw ODataJPARuntimeException
-          .throwException(ODataJPARuntimeException.GENERAL
-              .addContent(e.getMessage()), e);
-    }
-  }
-
-  public void update(final Map<String, Object> oDataEntryProperties) throws ODataJPARuntimeException {
-    normalizeInlineEntries(oDataEntryProperties);
-    write(oDataEntryProperties, false);
-  }
-
-  public void setJPAEntity(final Object jpaEntity) {
-    this.jpaEntity = jpaEntity;
-  }
-
-  @SuppressWarnings("unchecked")
-  protected void setComplexProperty(Method accessModifier, final Object jpaEntity,
-      final EdmStructuralType edmComplexType, final HashMap<String, Object> propertyValue)
-      throws EdmException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
-      InstantiationException, ODataJPARuntimeException, NoSuchMethodException, SecurityException, SQLException {
-
-    JPAEdmMapping mapping = (JPAEdmMapping) edmComplexType.getMapping();
-    Object embeddableObject = mapping.getJPAType().newInstance();
-    accessModifier.invoke(jpaEntity, embeddableObject);
-
-    HashMap<String, Method> accessModifiers =
-        jpaEntityParser.getAccessModifiers(embeddableObject, edmComplexType, JPAEntityParser.ACCESS_MODIFIER_SET);
-
-    for (String edmPropertyName : edmComplexType.getPropertyNames()) {
-      EdmTyped edmTyped = (EdmTyped) edmComplexType.getProperty(edmPropertyName);
-      accessModifier = accessModifiers.get(edmPropertyName);
-      if (edmTyped.getType().getKind().toString().equals(EdmTypeKind.COMPLEX.toString())) {
-        EdmStructuralType structualType = (EdmStructuralType) edmTyped.getType();
-        setComplexProperty(accessModifier, embeddableObject, structualType, (HashMap<String, Object>) propertyValue
-            .get(edmPropertyName));
-      } else {
-        setProperty(accessModifier, embeddableObject, propertyValue.get(edmPropertyName), (EdmSimpleType) edmTyped
-            .getType());
-      }
-    }
-  }
-
-  protected void setProperty(final Method method, final Object entity, final Object entityPropertyValue,
-      final EdmSimpleType type) throws
-      IllegalAccessException, IllegalArgumentException, InvocationTargetException, ODataJPARuntimeException {
-    if (entityPropertyValue != null) {
-      Class<?> parameterType = method.getParameterTypes()[0];
-      if (type != null && type.getDefaultType().equals(String.class)) {
-        if (parameterType.equals(String.class)) {
-          method.invoke(entity, entityPropertyValue);
-        } else if (parameterType.equals(char[].class)) {
-          char[] characters = ((String) entityPropertyValue).toCharArray();
-          method.invoke(entity, characters);
-        } else if (parameterType.equals(char.class)) {
-          char c = ((String) entityPropertyValue).charAt(0);
-          method.invoke(entity, c);
-        } else if (parameterType.equals(Character[].class)) {
-          Character[] characters = JPAEntityParser.toCharacterArray((String) entityPropertyValue);
-          method.invoke(entity, (Object) characters);
-        } else if (parameterType.equals(Character.class)) {
-          Character c = Character.valueOf(((String) entityPropertyValue).charAt(0));
-          method.invoke(entity, c);
-        }
-      } else if (parameterType.equals(Blob.class)) {
-        if (onJPAWriteContent == null) {
-          throw ODataJPARuntimeException
-              .throwException(ODataJPARuntimeException.ERROR_JPA_BLOB_NULL, null);
-        } else {
-          method.invoke(entity, onJPAWriteContent.getJPABlob((byte[]) entityPropertyValue));
-        }
-      } else if (parameterType.equals(Clob.class)) {
-        if (onJPAWriteContent == null) {
-          throw ODataJPARuntimeException
-              .throwException(ODataJPARuntimeException.ERROR_JPA_CLOB_NULL, null);
-        } else {
-          method.invoke(entity, onJPAWriteContent.getJPAClob(((String) entityPropertyValue).toCharArray()));
-        }
-      } else if (parameterType.equals(Timestamp.class)) {
-        Timestamp ts = new Timestamp(((Calendar) entityPropertyValue).getTimeInMillis());
-        method.invoke(entity, ts);
-      } else if (parameterType.equals(java.util.Date.class)) {
-        method.invoke(entity, ((Calendar) entityPropertyValue).getTime());
-      } else if (parameterType.equals(java.sql.Date.class)) {
-        long timeInMs = ((Calendar) entityPropertyValue).getTimeInMillis();
-        method.invoke(entity, new java.sql.Date(timeInMs));
-      } else if (parameterType.equals(java.sql.Time.class)) {
-        long timeInMs = ((Calendar) entityPropertyValue).getTimeInMillis();
-        method.invoke(entity, new java.sql.Time(timeInMs));
-      } else {
-        method.invoke(entity, entityPropertyValue);
-      }
-    }
-  }
-
-  protected void setEmbeddableKeyProperty(final HashMap<String, String> embeddableKeys,
-      final List<EdmProperty> oDataEntryKeyProperties,
-      final Map<String, Object> oDataEntryProperties, final Object entity)
-      throws ODataJPARuntimeException, EdmException, IllegalAccessException, IllegalArgumentException,
-      InvocationTargetException, InstantiationException {
-
-    HashMap<String, Object> embeddableObjMap = new HashMap<String, Object>();
-    List<EdmProperty> leftODataEntryKeyProperties = new ArrayList<EdmProperty>();
-    HashMap<String, String> leftEmbeddableKeys = new HashMap<String, String>();
-
-    for (EdmProperty edmProperty : oDataEntryKeyProperties) {
-      if (oDataEntryProperties.containsKey(edmProperty.getName()) == false) {
-        continue;
-      }
-
-      String edmPropertyName = edmProperty.getName();
-      String embeddableKeyNameComposite = embeddableKeys.get(edmPropertyName);
-      if (embeddableKeyNameComposite == null) {
-        continue;
-      }
-      String embeddableKeyNameSplit[] = embeddableKeyNameComposite.split("\\.");
-      String methodPartName = null;
-      Method method = null;
-      Object embeddableObj = null;
-
-      if (embeddableObjMap.containsKey(embeddableKeyNameSplit[0]) == false) {
-        methodPartName = embeddableKeyNameSplit[0];
-        method = jpaEntityParser.getAccessModifierSet(entity, methodPartName);
-        embeddableObj = method.getParameterTypes()[0].newInstance();
-        method.invoke(entity, embeddableObj);
-        embeddableObjMap.put(embeddableKeyNameSplit[0], embeddableObj);
-      } else {
-        embeddableObj = embeddableObjMap.get(embeddableKeyNameSplit[0]);
-      }
-
-      if (embeddableKeyNameSplit.length == 2) {
-        methodPartName = embeddableKeyNameSplit[1];
-        method = jpaEntityParser.getAccessModifierSet(embeddableObj, methodPartName);
-        Object simpleObj = oDataEntryProperties.get(edmProperty.getName());
-        method.invoke(embeddableObj, simpleObj);
-      } else if (embeddableKeyNameSplit.length > 2) { // Deeply nested
-        leftODataEntryKeyProperties.add(edmProperty);
-        leftEmbeddableKeys
-            .put(edmPropertyName, embeddableKeyNameComposite.split(embeddableKeyNameSplit[0] + ".", 2)[1]);
-      }
-    }
-  }
-
-  protected Object instantiateJPAEntity() throws InstantiationException, IllegalAccessException {
-    if (jpaType == null) {
-      throw new InstantiationException();
-    }
-
-    return jpaType.newInstance();
-  }
-
-  private void normalizeInlineEntries(final Map<String, Object> oDataEntryProperties) throws ODataJPARuntimeException {
-    List<ODataEntry> entries = null;
-    try {
-      for (String navigationPropertyName : oDataEntityType.getNavigationPropertyNames()) {
-        Object inline = oDataEntryProperties.get(navigationPropertyName);
-        if (inline instanceof ODataFeed) {
-          entries = ((ODataFeed) inline).getEntries();
-        } else if (inline instanceof ODataEntry) {
-          entries = new ArrayList<ODataEntry>();
-          entries.add((ODataEntry) inline);
-        }
-        if (entries != null) {
-          oDataEntryProperties.put(navigationPropertyName, entries);
-          entries = null;
-        }
-      }
-    } catch (EdmException e) {
-      throw ODataJPARuntimeException
-          .throwException(ODataJPARuntimeException.GENERAL
-              .addContent(e.getMessage()), e);
-    }
-  }
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.access.data;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmStructuralType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.edm.EdmTyped;
+import org.apache.olingo.odata2.api.ep.entry.EntryMetadata;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
+import org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
+
+public class JPAEntity {
+
+  private Object jpaEntity = null;
+  private JPAEntity parentJPAEntity = null;
+  private EdmEntityType oDataEntityType = null;
+  private EdmEntitySet oDataEntitySet = null;
+  private Class<?> jpaType = null;
+  private HashMap<String, Method> accessModifiersWrite = null;
+  private JPAEntityParser jpaEntityParser = null;
+  private ODataJPAContext oDataJPAContext;
+  private OnJPAWriteContent onJPAWriteContent = null;
+  public HashMap<String, List<Object>> relatedJPAEntityMap = null;
+
+  public JPAEntity(final EdmEntityType oDataEntityType, final EdmEntitySet oDataEntitySet,
+      final ODataJPAContext context) {
+    this.oDataEntityType = oDataEntityType;
+    this.oDataEntitySet = oDataEntitySet;
+    oDataJPAContext = context;
+    try {
+      JPAEdmMapping mapping = (JPAEdmMapping) oDataEntityType.getMapping();
+      jpaType = mapping.getJPAType();
+    } catch (EdmException e) {
+      return;
+    }
+    jpaEntityParser = new JPAEntityParser();
+    onJPAWriteContent = oDataJPAContext.getODataContext().getServiceFactory().getCallback(OnJPAWriteContent.class);
+  }
+
+  public void setAccessModifersWrite(final HashMap<String, Method> accessModifiersWrite) {
+    this.accessModifiersWrite = accessModifiersWrite;
+  }
+
+  public void setParentJPAEntity(final JPAEntity jpaEntity) {
+    parentJPAEntity = jpaEntity;
+  }
+
+  public JPAEntity getParentJPAEntity() {
+    return parentJPAEntity;
+  }
+
+  public Object getJPAEntity() {
+    return jpaEntity;
+  }
+
+  @SuppressWarnings("unchecked")
+  private void write(final Map<String, Object> oDataEntryProperties,
+      final boolean isCreate)
+      throws ODataJPARuntimeException {
+    try {
+
+      EdmStructuralType structuralType = null;
+      final List<String> keyNames = oDataEntityType.getKeyPropertyNames();
+
+      if (isCreate) {
+        jpaEntity = instantiateJPAEntity();
+      } else if (jpaEntity == null) {
+        throw ODataJPARuntimeException
+            .throwException(ODataJPARuntimeException.RESOURCE_NOT_FOUND, null);
+      }
+
+      if (accessModifiersWrite == null) {
+        accessModifiersWrite =
+            jpaEntityParser.getAccessModifiers(jpaEntity, oDataEntityType, JPAEntityParser.ACCESS_MODIFIER_SET);
+      }
+
+      if (oDataEntityType == null || oDataEntryProperties == null) {
+        throw ODataJPARuntimeException
+            .throwException(ODataJPARuntimeException.GENERAL, null);
+      }
+
+      final HashMap<String, String> embeddableKeys =
+          jpaEntityParser.getJPAEmbeddableKeyMap(jpaEntity.getClass().getName());
+      Set<String> propertyNames = null;
+      if (embeddableKeys != null) {
+        setEmbeddableKeyProperty(embeddableKeys, oDataEntityType.getKeyProperties(), oDataEntryProperties,
+            jpaEntity);
+
+        propertyNames = new HashSet<String>();
+        propertyNames.addAll(oDataEntryProperties.keySet());
+        for (String key : embeddableKeys.keySet()) {
+          propertyNames.remove(key);
+        }
+      } else {
+        propertyNames = oDataEntryProperties.keySet();
+      }
+
+      for (String propertyName : propertyNames) {
+        EdmTyped edmTyped = (EdmTyped) oDataEntityType.getProperty(propertyName);
+
+        Method accessModifier = null;
+
+        switch (edmTyped.getType().getKind()) {
+        case SIMPLE:
+          if (isCreate == false) {
+            if (keyNames.contains(edmTyped.getName())) {
+              continue;
+            }
+          }
+          accessModifier = accessModifiersWrite.get(propertyName);
+          setProperty(accessModifier, jpaEntity, oDataEntryProperties.get(propertyName), (EdmSimpleType) edmTyped
+              .getType());
+
+          break;
+        case COMPLEX:
+          structuralType = (EdmStructuralType) edmTyped.getType();
+          accessModifier = accessModifiersWrite.get(propertyName);
+          setComplexProperty(accessModifier, jpaEntity,
+              structuralType,
+              (HashMap<String, Object>) oDataEntryProperties.get(propertyName));
+          break;
+        case NAVIGATION:
+        case ENTITY:
+          if (isCreate) {
+            structuralType = (EdmStructuralType) edmTyped.getType();
+            EdmNavigationProperty navProperty = (EdmNavigationProperty) edmTyped;
+            EdmEntitySet edmRelatedEntitySet = oDataEntitySet.getRelatedEntitySet(navProperty);
+            List<ODataEntry> relatedEntries = (List<ODataEntry>) oDataEntryProperties.get(propertyName);
+            if (relatedJPAEntityMap == null) {
+              relatedJPAEntityMap = new HashMap<String, List<Object>>();
+            }
+            List<Object> relatedJPAEntities = new ArrayList<Object>();
+            JPAEntity relatedEntity =
+                new JPAEntity((EdmEntityType) structuralType, edmRelatedEntitySet, oDataJPAContext);
+            for (ODataEntry oDataEntry : relatedEntries) {
+              relatedEntity.setParentJPAEntity(this);
+              relatedEntity.create(oDataEntry);
+              relatedJPAEntities.add(relatedEntity.getJPAEntity());
+            }
+            relatedJPAEntityMap.put(navProperty.getName(), relatedJPAEntities);
+          }
+        default:
+          continue;
+        }
+      }
+    } catch (Exception e) {
+      if (e instanceof ODataJPARuntimeException) {
+        throw (ODataJPARuntimeException) e;
+      }
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+  }
+
+  public void create(final ODataEntry oDataEntry) throws ODataJPARuntimeException {
+    if (oDataEntry == null) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL, null);
+    }
+    Map<String, Object> oDataEntryProperties = oDataEntry.getProperties();
+    if (oDataEntry.containsInlineEntry()) {
+      normalizeInlineEntries(oDataEntryProperties);
+    }
+    write(oDataEntryProperties, true);
+
+    EntryMetadata entryMetadata = oDataEntry.getMetadata();
+    List<String> leftNavPrpNames = new ArrayList<String>();
+    try {
+      for (String navigationPropertyName : oDataEntityType.getNavigationPropertyNames()) {
+        List<String> links = entryMetadata.getAssociationUris(navigationPropertyName);
+        if (links.isEmpty()) {
+          continue;
+        } else {
+          EdmNavigationProperty navProperty =
+              (EdmNavigationProperty) oDataEntityType.getProperty(navigationPropertyName);
+          if (relatedJPAEntityMap != null && relatedJPAEntityMap.containsKey(navigationPropertyName)) {
+            JPALink.linkJPAEntities(relatedJPAEntityMap.get(navigationPropertyName), jpaEntity,
+                navProperty);
+          } else if (parentJPAEntity != null
+              &&
+              parentJPAEntity.getEdmEntitySet().getName().equals(
+                  oDataEntitySet.getRelatedEntitySet(navProperty).getName())) {
+            List<Object> targetJPAEntities = new ArrayList<Object>();
+            targetJPAEntities.add(parentJPAEntity.getJPAEntity());
+            JPALink.linkJPAEntities(targetJPAEntities, jpaEntity, navProperty);
+          } else {
+            leftNavPrpNames.add(navigationPropertyName);
+          }
+        }
+      }
+      if (!leftNavPrpNames.isEmpty()) {
+        JPALink link = new JPALink(oDataJPAContext);
+        link.setSourceJPAEntity(jpaEntity);
+        link.create(oDataEntitySet, oDataEntry, leftNavPrpNames);
+      }
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (ODataJPAModelException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+  }
+
+  public EdmEntitySet getEdmEntitySet() {
+    return oDataEntitySet;
+  }
+
+  public void create(final Map<String, Object> oDataEntryProperties) throws ODataJPARuntimeException {
+    normalizeInlineEntries(oDataEntryProperties);
+    write(oDataEntryProperties, true);
+  }
+
+  public void update(final ODataEntry oDataEntry) throws ODataJPARuntimeException {
+    if (oDataEntry == null) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL, null);
+    }
+    Map<String, Object> oDataEntryProperties = oDataEntry.getProperties();
+    if (oDataEntry.containsInlineEntry()) {
+      normalizeInlineEntries(oDataEntryProperties);
+    }
+    write(oDataEntryProperties, false);
+    JPALink link = new JPALink(oDataJPAContext);
+    link.setSourceJPAEntity(jpaEntity);
+    try {
+      link.create(oDataEntitySet, oDataEntry, oDataEntityType.getNavigationPropertyNames());
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (ODataJPAModelException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+  }
+
+  public void update(final Map<String, Object> oDataEntryProperties) throws ODataJPARuntimeException {
+    normalizeInlineEntries(oDataEntryProperties);
+    write(oDataEntryProperties, false);
+  }
+
+  public void setJPAEntity(final Object jpaEntity) {
+    this.jpaEntity = jpaEntity;
+  }
+
+  @SuppressWarnings("unchecked")
+  protected void setComplexProperty(Method accessModifier, final Object jpaEntity,
+      final EdmStructuralType edmComplexType, final HashMap<String, Object> propertyValue)
+      throws EdmException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
+      InstantiationException, ODataJPARuntimeException, NoSuchMethodException, SecurityException, SQLException {
+
+    JPAEdmMapping mapping = (JPAEdmMapping) edmComplexType.getMapping();
+    Object embeddableObject = mapping.getJPAType().newInstance();
+    accessModifier.invoke(jpaEntity, embeddableObject);
+
+    HashMap<String, Method> accessModifiers =
+        jpaEntityParser.getAccessModifiers(embeddableObject, edmComplexType, JPAEntityParser.ACCESS_MODIFIER_SET);
+
+    for (String edmPropertyName : edmComplexType.getPropertyNames()) {
+      EdmTyped edmTyped = (EdmTyped) edmComplexType.getProperty(edmPropertyName);
+      accessModifier = accessModifiers.get(edmPropertyName);
+      if (edmTyped.getType().getKind().toString().equals(EdmTypeKind.COMPLEX.toString())) {
+        EdmStructuralType structualType = (EdmStructuralType) edmTyped.getType();
+        setComplexProperty(accessModifier, embeddableObject, structualType, (HashMap<String, Object>) propertyValue
+            .get(edmPropertyName));
+      } else {
+        setProperty(accessModifier, embeddableObject, propertyValue.get(edmPropertyName), (EdmSimpleType) edmTyped
+            .getType());
+      }
+    }
+  }
+
+  protected void setProperty(final Method method, final Object entity, final Object entityPropertyValue,
+      final EdmSimpleType type) throws
+      IllegalAccessException, IllegalArgumentException, InvocationTargetException, ODataJPARuntimeException {
+    if (entityPropertyValue != null) {
+      Class<?> parameterType = method.getParameterTypes()[0];
+      if (type != null && type.getDefaultType().equals(String.class)) {
+        if (parameterType.equals(String.class)) {
+          method.invoke(entity, entityPropertyValue);
+        } else if (parameterType.equals(char[].class)) {
+          char[] characters = ((String) entityPropertyValue).toCharArray();
+          method.invoke(entity, characters);
+        } else if (parameterType.equals(char.class)) {
+          char c = ((String) entityPropertyValue).charAt(0);
+          method.invoke(entity, c);
+        } else if (parameterType.equals(Character[].class)) {
+          Character[] characters = JPAEntityParser.toCharacterArray((String) entityPropertyValue);
+          method.invoke(entity, (Object) characters);
+        } else if (parameterType.equals(Character.class)) {
+          Character c = Character.valueOf(((String) entityPropertyValue).charAt(0));
+          method.invoke(entity, c);
+        }
+      } else if (parameterType.equals(Blob.class)) {
+        if (onJPAWriteContent == null) {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.ERROR_JPA_BLOB_NULL, null);
+        } else {
+          method.invoke(entity, onJPAWriteContent.getJPABlob((byte[]) entityPropertyValue));
+        }
+      } else if (parameterType.equals(Clob.class)) {
+        if (onJPAWriteContent == null) {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.ERROR_JPA_CLOB_NULL, null);
+        } else {
+          method.invoke(entity, onJPAWriteContent.getJPAClob(((String) entityPropertyValue).toCharArray()));
+        }
+      } else if (parameterType.equals(Timestamp.class)) {
+        Timestamp ts = new Timestamp(((Calendar) entityPropertyValue).getTimeInMillis());
+        method.invoke(entity, ts);
+      } else if (parameterType.equals(java.util.Date.class)) {
+        method.invoke(entity, ((Calendar) entityPropertyValue).getTime());
+      } else if (parameterType.equals(java.sql.Date.class)) {
+        long timeInMs = ((Calendar) entityPropertyValue).getTimeInMillis();
+        method.invoke(entity, new java.sql.Date(timeInMs));
+      } else if (parameterType.equals(java.sql.Time.class)) {
+        long timeInMs = ((Calendar) entityPropertyValue).getTimeInMillis();
+        method.invoke(entity, new java.sql.Time(timeInMs));
+      } else {
+        method.invoke(entity, entityPropertyValue);
+      }
+    }
+  }
+
+  protected void setEmbeddableKeyProperty(final HashMap<String, String> embeddableKeys,
+      final List<EdmProperty> oDataEntryKeyProperties,
+      final Map<String, Object> oDataEntryProperties, final Object entity)
+      throws ODataJPARuntimeException, EdmException, IllegalAccessException, IllegalArgumentException,
+      InvocationTargetException, InstantiationException {
+
+    HashMap<String, Object> embeddableObjMap = new HashMap<String, Object>();
+    List<EdmProperty> leftODataEntryKeyProperties = new ArrayList<EdmProperty>();
+    HashMap<String, String> leftEmbeddableKeys = new HashMap<String, String>();
+
+    for (EdmProperty edmProperty : oDataEntryKeyProperties) {
+      if (oDataEntryProperties.containsKey(edmProperty.getName()) == false) {
+        continue;
+      }
+
+      String edmPropertyName = edmProperty.getName();
+      String embeddableKeyNameComposite = embeddableKeys.get(edmPropertyName);
+      if (embeddableKeyNameComposite == null) {
+        continue;
+      }
+      String embeddableKeyNameSplit[] = embeddableKeyNameComposite.split("\\.");
+      String methodPartName = null;
+      Method method = null;
+      Object embeddableObj = null;
+
+      if (embeddableObjMap.containsKey(embeddableKeyNameSplit[0]) == false) {
+        methodPartName = embeddableKeyNameSplit[0];
+        method = jpaEntityParser.getAccessModifierSet(entity, methodPartName);
+        embeddableObj = method.getParameterTypes()[0].newInstance();
+        method.invoke(entity, embeddableObj);
+        embeddableObjMap.put(embeddableKeyNameSplit[0], embeddableObj);
+      } else {
+        embeddableObj = embeddableObjMap.get(embeddableKeyNameSplit[0]);
+      }
+
+      if (embeddableKeyNameSplit.length == 2) {
+        methodPartName = embeddableKeyNameSplit[1];
+        method = jpaEntityParser.getAccessModifierSet(embeddableObj, methodPartName);
+        Object simpleObj = oDataEntryProperties.get(edmProperty.getName());
+        method.invoke(embeddableObj, simpleObj);
+      } else if (embeddableKeyNameSplit.length > 2) { // Deeply nested
+        leftODataEntryKeyProperties.add(edmProperty);
+        leftEmbeddableKeys
+            .put(edmPropertyName, embeddableKeyNameComposite.split(embeddableKeyNameSplit[0] + ".", 2)[1]);
+      }
+    }
+  }
+
+  protected Object instantiateJPAEntity() throws InstantiationException, IllegalAccessException {
+    if (jpaType == null) {
+      throw new InstantiationException();
+    }
+
+    return jpaType.newInstance();
+  }
+
+  private void normalizeInlineEntries(final Map<String, Object> oDataEntryProperties) throws ODataJPARuntimeException {
+    List<ODataEntry> entries = null;
+    try {
+      for (String navigationPropertyName : oDataEntityType.getNavigationPropertyNames()) {
+        Object inline = oDataEntryProperties.get(navigationPropertyName);
+        if (inline instanceof ODataFeed) {
+          entries = ((ODataFeed) inline).getEntries();
+        } else if (inline instanceof ODataEntry) {
+          entries = new ArrayList<ODataEntry>();
+          entries.add((ODataEntry) inline);
+        }
+        if (entries != null) {
+          oDataEntryProperties.put(navigationPropertyName, entries);
+          entries = null;
+        }
+      }
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPage.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPage.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPage.java
index 7aff111..07d7dd9 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPage.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPage.java
@@ -1,211 +1,211 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.access.data;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.Query;
-
-import org.apache.olingo.odata2.jpa.processor.api.access.JPAPaging;
-
-public class JPAPage implements JPAPaging {
-
-  private int pageSize;
-  private int startPage;
-  private int nextPage;
-  private List<Object> pagedEntries;
-
-  protected JPAPage(final int startPage, final int nextPage, final List<Object> pagedEntities, final int pageSize) {
-    this.pageSize = pageSize;
-    this.startPage = startPage;
-    this.nextPage = nextPage;
-    pagedEntries = pagedEntities;
-  }
-
-  @Override
-  public int getPageSize() {
-    return pageSize;
-  }
-
-  @Override
-  public List<Object> getPagedEntities() {
-    return pagedEntries;
-  }
-
-  @Override
-  public int getNextPage() {
-    return nextPage;
-  }
-
-  @Override
-  public int getStartPage() {
-    return startPage;
-  }
-
-  public static class JPAPageBuilder {
-
-    private int pageSize;
-    private int startPage;
-    private int nextPage;
-    private int top = -1;
-    private int skip;
-    private int skipToken;
-    private Query query;
-    private List<Object> entities;
-    private List<Object> pagedEntities;
-
-    private static class TopSkip {
-      public int top;
-      public int skip;
-    }
-
-    public JPAPageBuilder() {}
-
-    public JPAPageBuilder pageSize(final int pageSize) {
-      this.pageSize = pageSize;
-      return this;
-    }
-
-    public JPAPageBuilder query(final Query query) {
-      this.query = query;
-      return this;
-    }
-
-    public JPAPage build() {
-      if (entities != null) {
-        return buildFromEntities();
-      } else {
-        return buildFromQuery();
-      }
-    }
-
-    private JPAPage buildFromEntities() {
-      TopSkip topSkip = formulateTopSkip();
-      pagedEntities = new ArrayList<Object>();
-      if (topSkip.skip <= 0) {
-        topSkip.skip = 1;
-      }
-      for (int i = topSkip.skip - 1, j = 0; (j < topSkip.top && i < entities.size()); j++) {
-        pagedEntities.add(entities.get(i++));
-      }
-      formulateNextPage();
-      return new JPAPage(startPage, nextPage, pagedEntities, pageSize);
-    }
-
-    @SuppressWarnings("unchecked")
-    private JPAPage buildFromQuery() {
-      TopSkip topSkip = formulateTopSkip();
-      query.setFirstResult(topSkip.skip);
-      query.setMaxResults(topSkip.top);
-      pagedEntities = query.getResultList();
-      formulateNextPage();
-      return new JPAPage(startPage, nextPage, pagedEntities, pageSize);
-    }
-
-    private TopSkip formulateTopSkip() {
-      TopSkip topSkip = new TopSkip();
-      int size = 0;
-      if (pageSize <= 0) {
-        if (skip > 0) {
-          topSkip.skip = skip;
-        }
-        if (top > 0) {
-          topSkip.top = top;
-        }
-      } else {
-        if (skip >= pageSize) { // No Records to fetch
-          startPage = skipToken;
-          nextPage = 0;
-        } else {
-          // Max Results
-          size = top + skip;
-          if (size > pageSize) {
-            if (skip == 0) {
-              topSkip.top = pageSize;
-            } else {
-              topSkip.top = pageSize - skip;
-            }
-          } else {
-            if (top > 0) {
-              topSkip.top = top;
-            } else {
-              topSkip.top = pageSize;
-            }
-          }
-
-          startPage = skipToken;
-          if (skip > 0) {
-            topSkip.skip = startPage + skip;
-          } else {
-            topSkip.skip = startPage;
-          }
-        }
-      }
-      return topSkip;
-    }
-
-    private void formulateNextPage() {
-      if (pagedEntities.size() == 0) {
-        nextPage = 0;
-      } else if (pagedEntities.size() < pageSize) {
-        nextPage = 0;
-      } else {
-        nextPage = startPage + pageSize;
-      }
-    }
-
-    public JPAPageBuilder skip(final int skip) {
-      this.skip = skip;
-      if (skip < 0) {
-        this.skip = 0;
-      } else {
-        this.skip = skip;
-      }
-      return this;
-    }
-
-    public JPAPageBuilder skipToken(final String skipToken) throws NumberFormatException {
-      if (skipToken == null) {
-        this.skipToken = 0;
-      } else {
-        this.skipToken = new Integer(skipToken).intValue();
-        if (this.skipToken < 0) {
-          this.skipToken = 0;
-        }
-      }
-
-      return this;
-    }
-
-    public JPAPageBuilder top(final int top) {
-      if (top < 0) {
-        this.top = 0;
-      } else {
-        this.top = top;
-      }
-      return this;
-    }
-
-    public JPAPageBuilder entities(final List<Object> result) {
-      entities = result;
-      return this;
-    }
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.access.data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Query;
+
+import org.apache.olingo.odata2.jpa.processor.api.access.JPAPaging;
+
+public class JPAPage implements JPAPaging {
+
+  private int pageSize;
+  private int startPage;
+  private int nextPage;
+  private List<Object> pagedEntries;
+
+  protected JPAPage(final int startPage, final int nextPage, final List<Object> pagedEntities, final int pageSize) {
+    this.pageSize = pageSize;
+    this.startPage = startPage;
+    this.nextPage = nextPage;
+    pagedEntries = pagedEntities;
+  }
+
+  @Override
+  public int getPageSize() {
+    return pageSize;
+  }
+
+  @Override
+  public List<Object> getPagedEntities() {
+    return pagedEntries;
+  }
+
+  @Override
+  public int getNextPage() {
+    return nextPage;
+  }
+
+  @Override
+  public int getStartPage() {
+    return startPage;
+  }
+
+  public static class JPAPageBuilder {
+
+    private int pageSize;
+    private int startPage;
+    private int nextPage;
+    private int top = -1;
+    private int skip;
+    private int skipToken;
+    private Query query;
+    private List<Object> entities;
+    private List<Object> pagedEntities;
+
+    private static class TopSkip {
+      public int top;
+      public int skip;
+    }
+
+    public JPAPageBuilder() {}
+
+    public JPAPageBuilder pageSize(final int pageSize) {
+      this.pageSize = pageSize;
+      return this;
+    }
+
+    public JPAPageBuilder query(final Query query) {
+      this.query = query;
+      return this;
+    }
+
+    public JPAPage build() {
+      if (entities != null) {
+        return buildFromEntities();
+      } else {
+        return buildFromQuery();
+      }
+    }
+
+    private JPAPage buildFromEntities() {
+      TopSkip topSkip = formulateTopSkip();
+      pagedEntities = new ArrayList<Object>();
+      if (topSkip.skip <= 0) {
+        topSkip.skip = 1;
+      }
+      for (int i = topSkip.skip - 1, j = 0; (j < topSkip.top && i < entities.size()); j++) {
+        pagedEntities.add(entities.get(i++));
+      }
+      formulateNextPage();
+      return new JPAPage(startPage, nextPage, pagedEntities, pageSize);
+    }
+
+    @SuppressWarnings("unchecked")
+    private JPAPage buildFromQuery() {
+      TopSkip topSkip = formulateTopSkip();
+      query.setFirstResult(topSkip.skip);
+      query.setMaxResults(topSkip.top);
+      pagedEntities = query.getResultList();
+      formulateNextPage();
+      return new JPAPage(startPage, nextPage, pagedEntities, pageSize);
+    }
+
+    private TopSkip formulateTopSkip() {
+      TopSkip topSkip = new TopSkip();
+      int size = 0;
+      if (pageSize <= 0) {
+        if (skip > 0) {
+          topSkip.skip = skip;
+        }
+        if (top > 0) {
+          topSkip.top = top;
+        }
+      } else {
+        if (skip >= pageSize) { // No Records to fetch
+          startPage = skipToken;
+          nextPage = 0;
+        } else {
+          // Max Results
+          size = top + skip;
+          if (size > pageSize) {
+            if (skip == 0) {
+              topSkip.top = pageSize;
+            } else {
+              topSkip.top = pageSize - skip;
+            }
+          } else {
+            if (top > 0) {
+              topSkip.top = top;
+            } else {
+              topSkip.top = pageSize;
+            }
+          }
+
+          startPage = skipToken;
+          if (skip > 0) {
+            topSkip.skip = startPage + skip;
+          } else {
+            topSkip.skip = startPage;
+          }
+        }
+      }
+      return topSkip;
+    }
+
+    private void formulateNextPage() {
+      if (pagedEntities.size() == 0) {
+        nextPage = 0;
+      } else if (pagedEntities.size() < pageSize) {
+        nextPage = 0;
+      } else {
+        nextPage = startPage + pageSize;
+      }
+    }
+
+    public JPAPageBuilder skip(final int skip) {
+      this.skip = skip;
+      if (skip < 0) {
+        this.skip = 0;
+      } else {
+        this.skip = skip;
+      }
+      return this;
+    }
+
+    public JPAPageBuilder skipToken(final String skipToken) throws NumberFormatException {
+      if (skipToken == null) {
+        this.skipToken = 0;
+      } else {
+        this.skipToken = new Integer(skipToken).intValue();
+        if (this.skipToken < 0) {
+          this.skipToken = 0;
+        }
+      }
+
+      return this;
+    }
+
+    public JPAPageBuilder top(final int top) {
+      if (top < 0) {
+        this.top = 0;
+      } else {
+        this.top = top;
+      }
+      return this;
+    }
+
+    public JPAPageBuilder entities(final List<Object> result) {
+      entities = result;
+      return this;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBack.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBack.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBack.java
index 6ae9b2b..a462696 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBack.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBack.java
@@ -1,60 +1,60 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.callback;
-
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.ep.callback.TombstoneCallback;
-import org.apache.olingo.odata2.api.ep.callback.TombstoneCallbackResult;
-import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
-
-public class JPATombstoneCallBack implements TombstoneCallback {
-
-  private static final String DELTA_TOKEN_STRING = "?!deltatoken=";
-  private String baseUri;
-  private String deltaTokenValue;
-  private GetEntitySetUriInfo resultsView;
-
-  public JPATombstoneCallBack(final String baseUri, final GetEntitySetUriInfo resultsView,
-      final String deltaTokenValue) {
-    this.baseUri = baseUri;
-    this.deltaTokenValue = deltaTokenValue;
-    this.resultsView = resultsView;
-  }
-
-  @Override
-  public TombstoneCallbackResult getTombstoneCallbackResult() {
-    TombstoneCallbackResult jpaTombstoneCallBackResult = new TombstoneCallbackResult();
-
-    jpaTombstoneCallBackResult.setDeltaLink(buildToken());
-    return jpaTombstoneCallBackResult;
-  }
-
-  private String buildToken() {
-    StringBuilder tokenBuilder = new StringBuilder();
-    tokenBuilder.append(baseUri);
-    try {
-      tokenBuilder.append(resultsView.getTargetEntitySet().getName());
-    } catch (EdmException e) {
-      // Nothing
-    }
-    tokenBuilder.append(DELTA_TOKEN_STRING);
-    tokenBuilder.append(deltaTokenValue);
-    return tokenBuilder.toString();
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.callback;
+
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.ep.callback.TombstoneCallback;
+import org.apache.olingo.odata2.api.ep.callback.TombstoneCallbackResult;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+
+public class JPATombstoneCallBack implements TombstoneCallback {
+
+  private static final String DELTA_TOKEN_STRING = "?!deltatoken=";
+  private String baseUri;
+  private String deltaTokenValue;
+  private GetEntitySetUriInfo resultsView;
+
+  public JPATombstoneCallBack(final String baseUri, final GetEntitySetUriInfo resultsView,
+      final String deltaTokenValue) {
+    this.baseUri = baseUri;
+    this.deltaTokenValue = deltaTokenValue;
+    this.resultsView = resultsView;
+  }
+
+  @Override
+  public TombstoneCallbackResult getTombstoneCallbackResult() {
+    TombstoneCallbackResult jpaTombstoneCallBackResult = new TombstoneCallbackResult();
+
+    jpaTombstoneCallBackResult.setDeltaLink(buildToken());
+    return jpaTombstoneCallBackResult;
+  }
+
+  private String buildToken() {
+    StringBuilder tokenBuilder = new StringBuilder();
+    tokenBuilder.append(baseUri);
+    try {
+      tokenBuilder.append(resultsView.getTargetEntitySet().getName());
+    } catch (EdmException e) {
+      // Nothing
+    }
+    tokenBuilder.append(DELTA_TOKEN_STRING);
+    tokenBuilder.append(deltaTokenValue);
+    return tokenBuilder.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmFacets.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmFacets.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmFacets.java
index 916b49c..51cd37b 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmFacets.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmFacets.java
@@ -1,94 +1,94 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.model;
-
-import java.lang.reflect.AnnotatedElement;
-
-import javax.persistence.Column;
-import javax.persistence.metamodel.Attribute;
-
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
-import org.apache.olingo.odata2.api.edm.provider.Facets;
-import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
-
-public class JPAEdmFacets {
-  public static void setFacets(final Attribute<?, ?> jpaAttribute, final SimpleProperty edmProperty) {
-    EdmSimpleTypeKind edmTypeKind = edmProperty.getType();
-    Facets facets = new Facets();
-    edmProperty.setFacets(facets);
-
-    Column column = null;
-    if (jpaAttribute.getJavaMember() instanceof AnnotatedElement) {
-      column = ((AnnotatedElement) jpaAttribute
-          .getJavaMember()).getAnnotation(Column.class);
-    }
-
-    if (column == null) {
-      return;
-    }
-
-    setNullable(column, edmProperty);
-
-    switch (edmTypeKind) {
-    case Binary:
-      setMaxLength(column, edmProperty);
-      break;
-    case DateTime:
-      setPrecision(column, edmProperty);
-      break;
-    case DateTimeOffset:
-      setPrecision(column, edmProperty);
-      break;
-    case Time:
-      setPrecision(column, edmProperty);
-      break;
-    case Decimal:
-      setPrecision(column, edmProperty);
-      setScale(column, edmProperty);
-      break;
-    case String:
-      setMaxLength(column, edmProperty);
-      break;
-    default:
-      break;
-    }
-  }
-
-  private static void setNullable(final Column column, final SimpleProperty edmProperty) {
-    ((Facets) edmProperty.getFacets()).setNullable(column.nullable());
-  }
-
-  private static void setMaxLength(final Column column, final SimpleProperty edmProperty) {
-    if (column.length() > 0) {
-      ((Facets) edmProperty.getFacets()).setMaxLength(column.length());
-    }
-  }
-
-  private static void setPrecision(final Column column, final SimpleProperty edmProperty) {
-    if (column.precision() > 0) {
-      ((Facets) edmProperty.getFacets()).setPrecision(column.precision());
-    }
-  }
-
-  private static void setScale(final Column column, final SimpleProperty edmProperty) {
-    if (column.scale() > 0) {
-      ((Facets) edmProperty.getFacets()).setScale(column.scale());
-    }
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.model;
+
+import java.lang.reflect.AnnotatedElement;
+
+import javax.persistence.Column;
+import javax.persistence.metamodel.Attribute;
+
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.provider.Facets;
+import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
+
+public class JPAEdmFacets {
+  public static void setFacets(final Attribute<?, ?> jpaAttribute, final SimpleProperty edmProperty) {
+    EdmSimpleTypeKind edmTypeKind = edmProperty.getType();
+    Facets facets = new Facets();
+    edmProperty.setFacets(facets);
+
+    Column column = null;
+    if (jpaAttribute.getJavaMember() instanceof AnnotatedElement) {
+      column = ((AnnotatedElement) jpaAttribute
+          .getJavaMember()).getAnnotation(Column.class);
+    }
+
+    if (column == null) {
+      return;
+    }
+
+    setNullable(column, edmProperty);
+
+    switch (edmTypeKind) {
+    case Binary:
+      setMaxLength(column, edmProperty);
+      break;
+    case DateTime:
+      setPrecision(column, edmProperty);
+      break;
+    case DateTimeOffset:
+      setPrecision(column, edmProperty);
+      break;
+    case Time:
+      setPrecision(column, edmProperty);
+      break;
+    case Decimal:
+      setPrecision(column, edmProperty);
+      setScale(column, edmProperty);
+      break;
+    case String:
+      setMaxLength(column, edmProperty);
+      break;
+    default:
+      break;
+    }
+  }
+
+  private static void setNullable(final Column column, final SimpleProperty edmProperty) {
+    ((Facets) edmProperty.getFacets()).setNullable(column.nullable());
+  }
+
+  private static void setMaxLength(final Column column, final SimpleProperty edmProperty) {
+    if (column.length() > 0) {
+      ((Facets) edmProperty.getFacets()).setMaxLength(column.length());
+    }
+  }
+
+  private static void setPrecision(final Column column, final SimpleProperty edmProperty) {
+    if (column.precision() > 0) {
+      ((Facets) edmProperty.getFacets()).setPrecision(column.precision());
+    }
+  }
+
+  private static void setScale(final Column column, final SimpleProperty edmProperty) {
+    if (column.scale() > 0) {
+      ((Facets) edmProperty.getFacets()).setScale(column.scale());
+    }
+  }
+}


[13/19] line ending issue again

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataEntityParserTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataEntityParserTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataEntityParserTest.java
index adf7b80..3f133c1 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataEntityParserTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataEntityParserTest.java
@@ -1,244 +1,244 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.uri.PathSegment;
-import org.apache.olingo.odata2.api.uri.UriInfo;
-import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
-import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
-import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
-import org.apache.olingo.odata2.jpa.processor.core.mock.ODataContextMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.ODataJPAContextMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.ODataServiceMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.PathInfoMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.PathSegmentMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.EdmMockUtilV2;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock;
-import org.junit.Test;
-
-public class ODataEntityParserTest {
-
-  private ODataEntityParser parser;
-
-  private ODataJPAContext mock(final String path) {
-    ODataServiceMock serviceMock = new ODataServiceMock();
-    ODataContextMock contextMock = new ODataContextMock();
-    PathInfoMock pathInfoMock = new PathInfoMock();
-    PathSegmentMock pathSegmentMock = new PathSegmentMock();
-    ODataJPAContext odataJPAContext = null;
-
-    try {
-
-      pathSegmentMock.setPath(path);
-
-      List<PathSegment> pathSegments = new ArrayList<PathSegment>();
-      pathSegments.add(pathSegmentMock);
-      pathInfoMock.setPathSegments(pathSegments);
-      pathInfoMock.setServiceRootURI(ODataServiceMock.SERVICE_ROOT);
-
-      contextMock.setPathInfo(pathInfoMock.mock());
-      contextMock.setODataService(serviceMock.mock());
-
-      odataJPAContext = ODataJPAContextMock.mockODataJPAContext(contextMock.mock());
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (URISyntaxException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-
-    return odataJPAContext;
-  }
-
-  @Test
-  public void testParseURISegment() {
-
-    try {
-      parser = new ODataEntityParser(mock("JPATypeMock(2)"));
-      UriInfo uriInfo = parser.parseURISegment(0, 1);
-      assertNotNull(uriInfo);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testParseURISegmentInvalidIndex00() {
-    try {
-      parser = new ODataEntityParser(mock("JPATypeMock(2)"));
-      UriInfo uriInfo = parser.parseURISegment(0, 0);
-      assertNull(uriInfo);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testParseURISegmentInvalidIndex01() {
-    try {
-      parser = new ODataEntityParser(mock("JPATypeMock(2)"));
-      UriInfo uriInfo = parser.parseURISegment(-1, -1);
-      assertNull(uriInfo);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testParseURISegmentInvalidIndex02() {
-    try {
-      parser = new ODataEntityParser(mock("JPATypeMock(2)"));
-      UriInfo uriInfo = parser.parseURISegment(3, -1);
-      assertNull(uriInfo);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testParseURISegmentInvalidEntityType() {
-    try {
-      parser = new ODataEntityParser(mock("JPATypeMockInvalid(2)"));
-      parser.parseURISegment(0, 1);
-      fail("Exception Expected");
-    } catch (ODataJPARuntimeException e) {
-      assertEquals(true, true);
-    }
-  }
-
-  @Test
-  public void testParseBindingLink() {
-    try {
-      parser = new ODataEntityParser(mock("JPATypeMock(2)"));
-      UriInfo uriInfo = parser.parseBindingLink("JPATypeMock(2)", new HashMap<String, String>());
-      assertNotNull(uriInfo);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-
-  }
-
-  @Test
-  public void testParseBindingLinkNegative() {
-    try {
-      parser = new ODataEntityParser(mock("JPATypeMock(2)"));
-      parser.parseBindingLink("JPATypeMockInvalid(2)", new HashMap<String, String>());
-      fail("Exception Expected");
-    } catch (ODataJPARuntimeException e) {
-      assertEquals(true, true);
-    }
-  }
-
-  @Test
-  public void testParseLink() {
-    parser = new ODataEntityParser(mock("JPATypeMock(2)"));
-    try {
-      UriInfo uriInfo =
-          parser.parseLink(EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false), mockURIContent(0),
-              "application/json");
-      assertNotNull(uriInfo);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (EdmException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testParseLinkWithoutServiceRoot() {
-    parser = new ODataEntityParser(mock("JPATypeMock(2)"));
-    try {
-      UriInfo uriInfo =
-          parser.parseLink(EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false), mockURIContent(1),
-              "application/json");
-      assertNotNull(uriInfo);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (EdmException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testParseLinkNegative() {
-    parser = new ODataEntityParser(mock("JPATypeMock(2)"));
-    try {
-      parser.parseLink(EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false), mockURIContent(2),
-          "application/json");
-      fail("Exception Expected");
-    } catch (ODataJPARuntimeException e) {
-      assertEquals(true, true);
-    } catch (EdmException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  private InputStream mockURIContent(final int variant) {
-    String uri = null;
-    InputStream is = null;
-    switch (variant) {
-    case 0:
-      uri = "{ \"uri\": \"" + ODataServiceMock.SERVICE_ROOT + "JPATypeMock(2)\" }";
-      break;
-    case 1:
-      uri = "{ \"uri\": \"JPATypeMock(2)\" }";
-      break;
-    case 2:
-      uri = "{ \"uri\": \"" + ODataServiceMock.SERVICE_ROOT + "JPATypeMockInvalid(2)\" }";
-    }
-
-    try {
-      is = new ByteArrayInputStream(uri.getBytes("utf-8"));
-    } catch (UnsupportedEncodingException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-    return is;
-
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.uri.PathSegment;
+import org.apache.olingo.odata2.api.uri.UriInfo;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
+import org.apache.olingo.odata2.jpa.processor.core.mock.ODataContextMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.ODataJPAContextMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.ODataServiceMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.PathInfoMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.PathSegmentMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.EdmMockUtilV2;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock;
+import org.junit.Test;
+
+public class ODataEntityParserTest {
+
+  private ODataEntityParser parser;
+
+  private ODataJPAContext mock(final String path) {
+    ODataServiceMock serviceMock = new ODataServiceMock();
+    ODataContextMock contextMock = new ODataContextMock();
+    PathInfoMock pathInfoMock = new PathInfoMock();
+    PathSegmentMock pathSegmentMock = new PathSegmentMock();
+    ODataJPAContext odataJPAContext = null;
+
+    try {
+
+      pathSegmentMock.setPath(path);
+
+      List<PathSegment> pathSegments = new ArrayList<PathSegment>();
+      pathSegments.add(pathSegmentMock);
+      pathInfoMock.setPathSegments(pathSegments);
+      pathInfoMock.setServiceRootURI(ODataServiceMock.SERVICE_ROOT);
+
+      contextMock.setPathInfo(pathInfoMock.mock());
+      contextMock.setODataService(serviceMock.mock());
+
+      odataJPAContext = ODataJPAContextMock.mockODataJPAContext(contextMock.mock());
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (URISyntaxException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+
+    return odataJPAContext;
+  }
+
+  @Test
+  public void testParseURISegment() {
+
+    try {
+      parser = new ODataEntityParser(mock("JPATypeMock(2)"));
+      UriInfo uriInfo = parser.parseURISegment(0, 1);
+      assertNotNull(uriInfo);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testParseURISegmentInvalidIndex00() {
+    try {
+      parser = new ODataEntityParser(mock("JPATypeMock(2)"));
+      UriInfo uriInfo = parser.parseURISegment(0, 0);
+      assertNull(uriInfo);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testParseURISegmentInvalidIndex01() {
+    try {
+      parser = new ODataEntityParser(mock("JPATypeMock(2)"));
+      UriInfo uriInfo = parser.parseURISegment(-1, -1);
+      assertNull(uriInfo);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testParseURISegmentInvalidIndex02() {
+    try {
+      parser = new ODataEntityParser(mock("JPATypeMock(2)"));
+      UriInfo uriInfo = parser.parseURISegment(3, -1);
+      assertNull(uriInfo);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testParseURISegmentInvalidEntityType() {
+    try {
+      parser = new ODataEntityParser(mock("JPATypeMockInvalid(2)"));
+      parser.parseURISegment(0, 1);
+      fail("Exception Expected");
+    } catch (ODataJPARuntimeException e) {
+      assertEquals(true, true);
+    }
+  }
+
+  @Test
+  public void testParseBindingLink() {
+    try {
+      parser = new ODataEntityParser(mock("JPATypeMock(2)"));
+      UriInfo uriInfo = parser.parseBindingLink("JPATypeMock(2)", new HashMap<String, String>());
+      assertNotNull(uriInfo);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+
+  }
+
+  @Test
+  public void testParseBindingLinkNegative() {
+    try {
+      parser = new ODataEntityParser(mock("JPATypeMock(2)"));
+      parser.parseBindingLink("JPATypeMockInvalid(2)", new HashMap<String, String>());
+      fail("Exception Expected");
+    } catch (ODataJPARuntimeException e) {
+      assertEquals(true, true);
+    }
+  }
+
+  @Test
+  public void testParseLink() {
+    parser = new ODataEntityParser(mock("JPATypeMock(2)"));
+    try {
+      UriInfo uriInfo =
+          parser.parseLink(EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false), mockURIContent(0),
+              "application/json");
+      assertNotNull(uriInfo);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (EdmException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testParseLinkWithoutServiceRoot() {
+    parser = new ODataEntityParser(mock("JPATypeMock(2)"));
+    try {
+      UriInfo uriInfo =
+          parser.parseLink(EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false), mockURIContent(1),
+              "application/json");
+      assertNotNull(uriInfo);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (EdmException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testParseLinkNegative() {
+    parser = new ODataEntityParser(mock("JPATypeMock(2)"));
+    try {
+      parser.parseLink(EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false), mockURIContent(2),
+          "application/json");
+      fail("Exception Expected");
+    } catch (ODataJPARuntimeException e) {
+      assertEquals(true, true);
+    } catch (EdmException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  private InputStream mockURIContent(final int variant) {
+    String uri = null;
+    InputStream is = null;
+    switch (variant) {
+    case 0:
+      uri = "{ \"uri\": \"" + ODataServiceMock.SERVICE_ROOT + "JPATypeMock(2)\" }";
+      break;
+    case 1:
+      uri = "{ \"uri\": \"JPATypeMock(2)\" }";
+      break;
+    case 2:
+      uri = "{ \"uri\": \"" + ODataServiceMock.SERVICE_ROOT + "JPATypeMockInvalid(2)\" }";
+    }
+
+    try {
+      is = new ByteArrayInputStream(uri.getBytes("utf-8"));
+    } catch (UnsupportedEncodingException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+    return is;
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserForStaticMethodTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserForStaticMethodTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserForStaticMethodTest.java
index 7d09a18..e7d4c5f 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserForStaticMethodTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserForStaticMethodTest.java
@@ -1,330 +1,330 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.access.data;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.SQLException;
-
-import javax.sql.rowset.serial.SerialBlob;
-import javax.sql.rowset.serial.SerialClob;
-import javax.sql.rowset.serial.SerialException;
-
-import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
-import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
-import org.junit.Test;
-
-public class JPAEntityParserForStaticMethodTest {
-
-  @Test
-  public void testToStringDefault() {
-
-    Character[] input = new Character[] { 'A', 'B' };
-    assertEquals("AB", JPAEntityParser.toString(input));
-
-  }
-
-  @Test
-  public void testToStringNull() {
-    Character[] input = null;
-    assertNull(JPAEntityParser.toString(input));
-  }
-
-  @Test
-  public void testToStringPartialNull() {
-    Character[] input = new Character[] { 'A', null };
-    assertEquals("A", JPAEntityParser.toString(input));
-  }
-
-  @Test
-  public void testToCharacterArrayDefault() {
-    String input = new String("AB");
-    Character[] ch = JPAEntityParser.toCharacterArray(input);
-
-    assertEquals(2, ch.length);
-    assertTrue(ch[0].equals('A'));
-    assertTrue(ch[1].equals('B'));
-  }
-
-  @Test
-  public void testToCharacterArrayNull() {
-    String input = null;
-    Character[] ch = JPAEntityParser.toCharacterArray(input);
-
-    assertNull(ch);
-  }
-
-  @Test
-  public void testGetPropertyCharacter() {
-    try {
-      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharacter", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
-      assertEquals("A", output);
-
-    } catch (NoSuchMethodException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (SecurityException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testGetPropertyCharacterNull() {
-    try {
-      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharacterNull", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
-      assertNull(output);
-
-    } catch (NoSuchMethodException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (SecurityException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testGetPropertyCharacterArray() {
-    try {
-      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharacterArray", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
-      assertEquals("AB", output);
-
-    } catch (NoSuchMethodException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (SecurityException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testGetPropertyCharacterArrayNull() {
-    try {
-      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharacterArrayNull", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
-      assertNull(output);
-
-    } catch (NoSuchMethodException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (SecurityException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testGetPropertyChar() {
-    try {
-      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getChar", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
-      assertEquals("A", output);
-
-    } catch (NoSuchMethodException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (SecurityException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testGetPropertyCharNull() {
-    try {
-      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharNull", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
-      assertNull(output);
-
-    } catch (NoSuchMethodException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (SecurityException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testGetPropertyCharArray() {
-    try {
-      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharArray", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
-      assertEquals("AB", output);
-
-    } catch (NoSuchMethodException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (SecurityException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testGetPropertyCharArrayNull() {
-    try {
-      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharArrayNull", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
-      assertNull(output);
-
-    } catch (NoSuchMethodException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (SecurityException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testGetPropertyCharArrayValueNull() {
-    try {
-      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharArrayValueNull", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
-      assertEquals("A\u0000", output);
-
-    } catch (NoSuchMethodException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (SecurityException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testGetString() {
-    char[] expectedChar = new char[] { 'a', 'b', 'c' };
-    try {
-      Clob clob = new SerialClob(expectedChar);
-      String actualString = JPAEntityParser.getString(clob);
-
-      assertEquals(new String(expectedChar), actualString);
-
-    } catch (SerialException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (SQLException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  @Test
-  public void testGetBytes() {
-    final String fileName = "SalesOrderProcessingMappingModels.xml";
-
-    try {
-      FileInputStream fis = getFileStream(fileName);
-
-      ByteArrayOutputStream baos = new ByteArrayOutputStream();
-      int content = fis.read();
-      while (content != -1) {
-        baos.write(content);
-        content = fis.read();
-      }
-      Blob blob = new SerialBlob(baos.toByteArray());
-      byte[] actualBytes = (byte[]) JPAEntityParser.getBytes(blob);
-      byte[] expectedBytes = baos.toByteArray();
-
-      assertEquals(expectedBytes.length, actualBytes.length);
-      int size = actualBytes.length;
-      int index = 0;
-      while (index < size) {
-        assertEquals(expectedBytes[index], actualBytes[index]);
-        index++;
-      }
-
-    } catch (FileNotFoundException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (SerialException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (SQLException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (IOException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-  }
-
-  private FileInputStream getFileStream(final String name) throws SerialException, FileNotFoundException {
-    final String fileName = "SalesOrderProcessingMappingModels.xml";
-    FileInputStream fis;
-
-    URL fileURL = JPAEntityParserForStaticMethodTest.class.getClassLoader().getResource(fileName);
-    fis = new FileInputStream(fileURL.getPath());
-
-    return fis;
-
-  }
-
-  public Character getCharacter() {
-    return new Character('A');
-  }
-
-  public Character getCharacterNull() {
-    return null;
-  }
-
-  public Character[] getCharacterArray() {
-    return new Character[] { 'A', 'B' };
-  }
-
-  public Character[] getCharacterArrayNull() {
-    return null;
-  }
-
-  public char getChar() {
-    return 'A';
-  }
-
-  public char getCharNull() {
-    return '\u0000';
-  }
-
-  public char[] getCharArray() {
-    return new char[] { 'A', 'B' };
-  }
-
-  public char[] getCharArrayNull() {
-    return null;
-  }
-
-  public char[] getCharArrayValueNull() {
-    return new char[] { 'A', '\u0000' };
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.access.data;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+import javax.sql.rowset.serial.SerialBlob;
+import javax.sql.rowset.serial.SerialClob;
+import javax.sql.rowset.serial.SerialException;
+
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
+import org.junit.Test;
+
+public class JPAEntityParserForStaticMethodTest {
+
+  @Test
+  public void testToStringDefault() {
+
+    Character[] input = new Character[] { 'A', 'B' };
+    assertEquals("AB", JPAEntityParser.toString(input));
+
+  }
+
+  @Test
+  public void testToStringNull() {
+    Character[] input = null;
+    assertNull(JPAEntityParser.toString(input));
+  }
+
+  @Test
+  public void testToStringPartialNull() {
+    Character[] input = new Character[] { 'A', null };
+    assertEquals("A", JPAEntityParser.toString(input));
+  }
+
+  @Test
+  public void testToCharacterArrayDefault() {
+    String input = new String("AB");
+    Character[] ch = JPAEntityParser.toCharacterArray(input);
+
+    assertEquals(2, ch.length);
+    assertTrue(ch[0].equals('A'));
+    assertTrue(ch[1].equals('B'));
+  }
+
+  @Test
+  public void testToCharacterArrayNull() {
+    String input = null;
+    Character[] ch = JPAEntityParser.toCharacterArray(input);
+
+    assertNull(ch);
+  }
+
+  @Test
+  public void testGetPropertyCharacter() {
+    try {
+      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharacter", (Class<?>[]) null);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      assertEquals("A", output);
+
+    } catch (NoSuchMethodException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SecurityException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testGetPropertyCharacterNull() {
+    try {
+      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharacterNull", (Class<?>[]) null);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      assertNull(output);
+
+    } catch (NoSuchMethodException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SecurityException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testGetPropertyCharacterArray() {
+    try {
+      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharacterArray", (Class<?>[]) null);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      assertEquals("AB", output);
+
+    } catch (NoSuchMethodException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SecurityException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testGetPropertyCharacterArrayNull() {
+    try {
+      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharacterArrayNull", (Class<?>[]) null);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      assertNull(output);
+
+    } catch (NoSuchMethodException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SecurityException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testGetPropertyChar() {
+    try {
+      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getChar", (Class<?>[]) null);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      assertEquals("A", output);
+
+    } catch (NoSuchMethodException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SecurityException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testGetPropertyCharNull() {
+    try {
+      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharNull", (Class<?>[]) null);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      assertNull(output);
+
+    } catch (NoSuchMethodException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SecurityException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testGetPropertyCharArray() {
+    try {
+      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharArray", (Class<?>[]) null);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      assertEquals("AB", output);
+
+    } catch (NoSuchMethodException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SecurityException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testGetPropertyCharArrayNull() {
+    try {
+      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharArrayNull", (Class<?>[]) null);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      assertNull(output);
+
+    } catch (NoSuchMethodException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SecurityException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testGetPropertyCharArrayValueNull() {
+    try {
+      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharArrayValueNull", (Class<?>[]) null);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      assertEquals("A\u0000", output);
+
+    } catch (NoSuchMethodException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SecurityException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testGetString() {
+    char[] expectedChar = new char[] { 'a', 'b', 'c' };
+    try {
+      Clob clob = new SerialClob(expectedChar);
+      String actualString = JPAEntityParser.getString(clob);
+
+      assertEquals(new String(expectedChar), actualString);
+
+    } catch (SerialException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SQLException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testGetBytes() {
+    final String fileName = "SalesOrderProcessingMappingModels.xml";
+
+    try {
+      FileInputStream fis = getFileStream(fileName);
+
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      int content = fis.read();
+      while (content != -1) {
+        baos.write(content);
+        content = fis.read();
+      }
+      Blob blob = new SerialBlob(baos.toByteArray());
+      byte[] actualBytes = (byte[]) JPAEntityParser.getBytes(blob);
+      byte[] expectedBytes = baos.toByteArray();
+
+      assertEquals(expectedBytes.length, actualBytes.length);
+      int size = actualBytes.length;
+      int index = 0;
+      while (index < size) {
+        assertEquals(expectedBytes[index], actualBytes[index]);
+        index++;
+      }
+
+    } catch (FileNotFoundException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SerialException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SQLException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (IOException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  private FileInputStream getFileStream(final String name) throws SerialException, FileNotFoundException {
+    final String fileName = "SalesOrderProcessingMappingModels.xml";
+    FileInputStream fis;
+
+    URL fileURL = JPAEntityParserForStaticMethodTest.class.getClassLoader().getResource(fileName);
+    fis = new FileInputStream(fileURL.getPath());
+
+    return fis;
+
+  }
+
+  public Character getCharacter() {
+    return new Character('A');
+  }
+
+  public Character getCharacterNull() {
+    return null;
+  }
+
+  public Character[] getCharacterArray() {
+    return new Character[] { 'A', 'B' };
+  }
+
+  public Character[] getCharacterArrayNull() {
+    return null;
+  }
+
+  public char getChar() {
+    return 'A';
+  }
+
+  public char getCharNull() {
+    return '\u0000';
+  }
+
+  public char[] getCharArray() {
+    return new char[] { 'A', 'B' };
+  }
+
+  public char[] getCharArrayNull() {
+    return null;
+  }
+
+  public char[] getCharArrayValueNull() {
+    return new char[] { 'A', '\u0000' };
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityTest.java
index 3bfac96..e601bd8 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityTest.java
@@ -1,246 +1,246 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.access.data;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
-import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
-import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
-import org.apache.olingo.odata2.jpa.processor.core.mock.ODataContextMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.ODataJPAContextMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.EdmMockUtilV2;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPARelatedTypeMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPATypeEmbeddableMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPATypeEmbeddableMock2;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.ODataEntryMockUtil;
-import org.junit.Test;
-
-public class JPAEntityTest {
-
-  private JPAEntity jpaEntity = null;
-
-  @Test
-  public void testCreateODataEntryWithComplexType() {
-    try {
-      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, true);
-      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
-
-      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
-      jpaEntity.create(ODataEntryMockUtil.mockODataEntryWithComplexType(JPATypeMock.ENTITY_NAME));
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (EdmException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-    JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
-    assertEquals(jpaTypeMock.getMInt(), ODataEntryMockUtil.VALUE_MINT);
-    assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
-    assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
-    JPATypeEmbeddableMock jpaEmbeddableMock = jpaTypeMock.getComplexType();
-    assertNotNull(jpaEmbeddableMock);
-
-    assertEquals(jpaEmbeddableMock.getMShort(), ODataEntryMockUtil.VALUE_SHORT);
-    JPATypeEmbeddableMock2 jpaEmbeddableMock2 = jpaEmbeddableMock.getMEmbeddable();
-    assertNotNull(jpaEmbeddableMock2);
-    assertEquals(jpaEmbeddableMock2.getMFloat(), ODataEntryMockUtil.VALUE_MFLOAT, 1);
-    assertEquals(jpaEmbeddableMock2.getMUUID(), ODataEntryMockUtil.VALUE_UUID);
-  }
-
-  @Test
-  public void testCreateODataEntry() {
-    try {
-      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
-      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
-
-      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
-      jpaEntity.create(ODataEntryMockUtil.mockODataEntry(JPATypeMock.ENTITY_NAME));
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (EdmException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-    JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
-    assertEquals(jpaTypeMock.getMInt(), ODataEntryMockUtil.VALUE_MINT);
-    assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
-    assertEquals(ODataEntryMockUtil.VALUE_C.charAt(0), jpaTypeMock.getMC());
-    assertEquals(ODataEntryMockUtil.VALUE_CARRAY, new String(jpaTypeMock.getMCArray()));
-    assertEquals(ODataEntryMockUtil.VALUE_CHAR, jpaTypeMock.getMChar().toString());
-    assertEquals(ODataEntryMockUtil.VALUE_CHARARRAY, JPAEntityParser.toString(jpaTypeMock.getMCharArray()));
-    assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
-  }
-
-  @Test
-  public void testCreateODataEntryWithInline() {
-    try {
-      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
-      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
-
-      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
-      jpaEntity.create(ODataEntryMockUtil.mockODataEntryWithInline(JPATypeMock.ENTITY_NAME));
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (EdmException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-    JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
-    assertEquals(jpaTypeMock.getMInt(), ODataEntryMockUtil.VALUE_MINT);
-    assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
-    assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
-
-    JPARelatedTypeMock relatedType = jpaTypeMock.getMRelatedEntity();
-    assertEquals(relatedType.getMByte(), ODataEntryMockUtil.VALUE_MBYTE);
-    assertEquals(relatedType.getMByteArray(), ODataEntryMockUtil.VALUE_MBYTEARRAY);
-    assertEquals(relatedType.getMDouble(), ODataEntryMockUtil.VALUE_MDOUBLE, 0.0);
-    assertEquals(relatedType.getMLong(), ODataEntryMockUtil.VALUE_MLONG);
-  }
-
-  @Test
-  public void testCreateODataEntryProperty() {
-    try {
-      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
-      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
-
-      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
-      jpaEntity.create(ODataEntryMockUtil.mockODataEntryProperties(JPATypeMock.ENTITY_NAME));
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (EdmException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-    JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
-    assertEquals(jpaTypeMock.getMInt(), ODataEntryMockUtil.VALUE_MINT);
-    assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
-    assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
-  }
-
-  @Test
-  public void testCreateODataEntryPropertyWithOutCallBack() {
-    try {
-      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
-      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
-
-      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContextWithoutCallBack());
-      jpaEntity.create(ODataEntryMockUtil.mockODataEntryProperties(JPATypeMock.ENTITY_NAME));
-    } catch (ODataJPARuntimeException e) {
-      assertEquals(ODataJPARuntimeException.ERROR_JPA_BLOB_NULL.getKey(), e.getMessageReference().getKey());
-      return;
-    } catch (EdmException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-    fail(ODataJPATestConstants.EXCEPTION_EXPECTED);
-  }
-
-  @Test
-  public void testUpdateODataEntry() {
-    try {
-      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
-      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
-
-      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
-      JPATypeMock jpaTypeMock = new JPATypeMock();
-      jpaEntity.setJPAEntity(jpaTypeMock);
-      jpaEntity.update(ODataEntryMockUtil.mockODataEntry(JPATypeMock.ENTITY_NAME));
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (EdmException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-    JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
-    assertEquals(jpaTypeMock.getMInt(), 0);// Key should not be changed
-    assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
-    assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
-  }
-
-  @Test
-  public void testUpdateODataEntryProperty() {
-    try {
-      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
-      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
-
-      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
-      JPATypeMock jpaTypeMock = new JPATypeMock();
-      jpaEntity.setJPAEntity(jpaTypeMock);
-      jpaEntity.update(ODataEntryMockUtil.mockODataEntryProperties(JPATypeMock.ENTITY_NAME));
-    } catch (ODataJPARuntimeException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (EdmException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    } catch (ODataException e) {
-      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
-          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
-    }
-    JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
-    assertEquals(jpaTypeMock.getMInt(), 0);// Key should not be changed
-    assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
-    assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
-  }
-
-  private ODataJPAContext mockODataJPAContext() throws ODataException {
-    ODataContext context = new ODataContextMock().mock();
-    ODataJPAContext jpaContext = ODataJPAContextMock.mockODataJPAContext(context);
-    return jpaContext;
-  }
-
-  private ODataJPAContext mockODataJPAContextWithoutCallBack() throws ODataException {
-    ODataContext context = new ODataContextMock().mockWithoutOnJPAWriteContent();
-    ODataJPAContext jpaContext = ODataJPAContextMock.mockODataJPAContext(context);
-    return jpaContext;
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.access.data;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
+import org.apache.olingo.odata2.jpa.processor.core.mock.ODataContextMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.ODataJPAContextMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.EdmMockUtilV2;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPARelatedTypeMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPATypeEmbeddableMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPATypeEmbeddableMock2;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.ODataEntryMockUtil;
+import org.junit.Test;
+
+public class JPAEntityTest {
+
+  private JPAEntity jpaEntity = null;
+
+  @Test
+  public void testCreateODataEntryWithComplexType() {
+    try {
+      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, true);
+      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
+      jpaEntity.create(ODataEntryMockUtil.mockODataEntryWithComplexType(JPATypeMock.ENTITY_NAME));
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (EdmException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+    JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
+    assertEquals(jpaTypeMock.getMInt(), ODataEntryMockUtil.VALUE_MINT);
+    assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
+    assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
+    JPATypeEmbeddableMock jpaEmbeddableMock = jpaTypeMock.getComplexType();
+    assertNotNull(jpaEmbeddableMock);
+
+    assertEquals(jpaEmbeddableMock.getMShort(), ODataEntryMockUtil.VALUE_SHORT);
+    JPATypeEmbeddableMock2 jpaEmbeddableMock2 = jpaEmbeddableMock.getMEmbeddable();
+    assertNotNull(jpaEmbeddableMock2);
+    assertEquals(jpaEmbeddableMock2.getMFloat(), ODataEntryMockUtil.VALUE_MFLOAT, 1);
+    assertEquals(jpaEmbeddableMock2.getMUUID(), ODataEntryMockUtil.VALUE_UUID);
+  }
+
+  @Test
+  public void testCreateODataEntry() {
+    try {
+      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
+      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
+      jpaEntity.create(ODataEntryMockUtil.mockODataEntry(JPATypeMock.ENTITY_NAME));
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (EdmException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+    JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
+    assertEquals(jpaTypeMock.getMInt(), ODataEntryMockUtil.VALUE_MINT);
+    assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
+    assertEquals(ODataEntryMockUtil.VALUE_C.charAt(0), jpaTypeMock.getMC());
+    assertEquals(ODataEntryMockUtil.VALUE_CARRAY, new String(jpaTypeMock.getMCArray()));
+    assertEquals(ODataEntryMockUtil.VALUE_CHAR, jpaTypeMock.getMChar().toString());
+    assertEquals(ODataEntryMockUtil.VALUE_CHARARRAY, JPAEntityParser.toString(jpaTypeMock.getMCharArray()));
+    assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
+  }
+
+  @Test
+  public void testCreateODataEntryWithInline() {
+    try {
+      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
+      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
+      jpaEntity.create(ODataEntryMockUtil.mockODataEntryWithInline(JPATypeMock.ENTITY_NAME));
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (EdmException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+    JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
+    assertEquals(jpaTypeMock.getMInt(), ODataEntryMockUtil.VALUE_MINT);
+    assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
+    assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
+
+    JPARelatedTypeMock relatedType = jpaTypeMock.getMRelatedEntity();
+    assertEquals(relatedType.getMByte(), ODataEntryMockUtil.VALUE_MBYTE);
+    assertEquals(relatedType.getMByteArray(), ODataEntryMockUtil.VALUE_MBYTEARRAY);
+    assertEquals(relatedType.getMDouble(), ODataEntryMockUtil.VALUE_MDOUBLE, 0.0);
+    assertEquals(relatedType.getMLong(), ODataEntryMockUtil.VALUE_MLONG);
+  }
+
+  @Test
+  public void testCreateODataEntryProperty() {
+    try {
+      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
+      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
+      jpaEntity.create(ODataEntryMockUtil.mockODataEntryProperties(JPATypeMock.ENTITY_NAME));
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (EdmException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+    JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
+    assertEquals(jpaTypeMock.getMInt(), ODataEntryMockUtil.VALUE_MINT);
+    assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
+    assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
+  }
+
+  @Test
+  public void testCreateODataEntryPropertyWithOutCallBack() {
+    try {
+      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
+      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContextWithoutCallBack());
+      jpaEntity.create(ODataEntryMockUtil.mockODataEntryProperties(JPATypeMock.ENTITY_NAME));
+    } catch (ODataJPARuntimeException e) {
+      assertEquals(ODataJPARuntimeException.ERROR_JPA_BLOB_NULL.getKey(), e.getMessageReference().getKey());
+      return;
+    } catch (EdmException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+    fail(ODataJPATestConstants.EXCEPTION_EXPECTED);
+  }
+
+  @Test
+  public void testUpdateODataEntry() {
+    try {
+      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
+      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
+      JPATypeMock jpaTypeMock = new JPATypeMock();
+      jpaEntity.setJPAEntity(jpaTypeMock);
+      jpaEntity.update(ODataEntryMockUtil.mockODataEntry(JPATypeMock.ENTITY_NAME));
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (EdmException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+    JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
+    assertEquals(jpaTypeMock.getMInt(), 0);// Key should not be changed
+    assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
+    assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
+  }
+
+  @Test
+  public void testUpdateODataEntryProperty() {
+    try {
+      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
+      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
+      JPATypeMock jpaTypeMock = new JPATypeMock();
+      jpaEntity.setJPAEntity(jpaTypeMock);
+      jpaEntity.update(ODataEntryMockUtil.mockODataEntryProperties(JPATypeMock.ENTITY_NAME));
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (EdmException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
+          + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+    JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
+    assertEquals(jpaTypeMock.getMInt(), 0);// Key should not be changed
+    assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
+    assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
+  }
+
+  private ODataJPAContext mockODataJPAContext() throws ODataException {
+    ODataContext context = new ODataContextMock().mock();
+    ODataJPAContext jpaContext = ODataJPAContextMock.mockODataJPAContext(context);
+    return jpaContext;
+  }
+
+  private ODataJPAContext mockODataJPAContextWithoutCallBack() throws ODataException {
+    ODataContext context = new ODataContextMock().mockWithoutOnJPAWriteContent();
+    ODataJPAContext jpaContext = ODataJPAContextMock.mockODataJPAContext(context);
+    return jpaContext;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALinkTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALinkTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALinkTest.java
index 7a0b754..df614f5 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALinkTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALinkTest.java
@@ -1,23 +1,23 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.access.data;
-
-public class JPALinkTest {
-
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.access.data;
+
+public class JPALinkTest {
+
+}


[09/19] line ending issue again

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-web/.gitignore
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/.gitignore b/odata2-jpa-processor/jpa-web/.gitignore
index fe5d89b..a7ffe90 100644
--- a/odata2-jpa-processor/jpa-web/.gitignore
+++ b/odata2-jpa-processor/jpa-web/.gitignore
@@ -1,8 +1,8 @@
-.project
-.classpath
-.settings
-target
-bin
-*.bak
-classes
+.project
+.classpath
+.settings
+target
+bin
+*.bak
+classes
 .DS_Store
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/OnDBWriteContent.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/OnDBWriteContent.java b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/OnDBWriteContent.java
index 678b62a..f93a977 100644
--- a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/OnDBWriteContent.java
+++ b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/OnDBWriteContent.java
@@ -1,55 +1,55 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ******************************************************************************/
-package org.apache.olingo.odata2.jpa.processor.ref.extension;
-
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.SQLException;
-
-import javax.sql.rowset.serial.SerialException;
-
-import org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent;
-import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
-import org.hsqldb.jdbc.JDBCBlob;
-import org.hsqldb.jdbc.JDBCClob;
-
-public class OnDBWriteContent implements OnJPAWriteContent {
-
-  @Override
-  public Blob getJPABlob(final byte[] binaryData) throws ODataJPARuntimeException {
-    try {
-      return new JDBCBlob(binaryData);
-    } catch (SerialException e) {
-      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
-    } catch (SQLException e) {
-      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
-    }
-    return null;
-  }
-
-  @Override
-  public Clob getJPAClob(final char[] characterData) throws ODataJPARuntimeException {
-    try {
-      return new JDBCClob(new String(characterData));
-    } catch (SQLException e) {
-      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
-    }
-    return null;
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.extension;
+
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+import javax.sql.rowset.serial.SerialException;
+
+import org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.hsqldb.jdbc.JDBCBlob;
+import org.hsqldb.jdbc.JDBCClob;
+
+public class OnDBWriteContent implements OnJPAWriteContent {
+
+  @Override
+  public Blob getJPABlob(final byte[] binaryData) throws ODataJPARuntimeException {
+    try {
+      return new JDBCBlob(binaryData);
+    } catch (SerialException e) {
+      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    } catch (SQLException e) {
+      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    }
+    return null;
+  }
+
+  @Override
+  public Clob getJPAClob(final char[] characterData) throws ODataJPARuntimeException {
+    try {
+      return new JDBCClob(new String(characterData));
+    } catch (SQLException e) {
+      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    }
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/OrderValue.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/OrderValue.java b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/OrderValue.java
index 7b056e0..e65221d 100644
--- a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/OrderValue.java
+++ b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/OrderValue.java
@@ -1,42 +1,42 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.ref.extension;
-
-public class OrderValue {
-
-  private double amount;
-  private String currency;
-
-  public double getAmount() {
-    return amount;
-  }
-
-  public void setAmount(final double amount) {
-    this.amount = amount;
-  }
-
-  public String getCurrency() {
-    return currency;
-  }
-
-  public void setCurrency(final String currency) {
-    this.currency = currency;
-  }
-
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.extension;
+
+public class OrderValue {
+
+  private double amount;
+  private String currency;
+
+  public double getAmount() {
+    return amount;
+  }
+
+  public void setAmount(final double amount) {
+    this.amount = amount;
+  }
+
+  public String getCurrency() {
+    return currency;
+  }
+
+  public void setCurrency(final String currency) {
+    this.currency = currency;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/util/DataGenerator.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/util/DataGenerator.java b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/util/DataGenerator.java
index e840119..e8c74dd 100644
--- a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/util/DataGenerator.java
+++ b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/util/DataGenerator.java
@@ -1,158 +1,158 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.ref.util;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.ResourceBundle;
-import java.util.Set;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.olingo.odata2.jpa.processor.ref.model.Material;
-import org.apache.olingo.odata2.jpa.processor.ref.model.Store;
-import org.eclipse.persistence.internal.jpa.EntityManagerImpl;
-import org.eclipse.persistence.queries.DataModifyQuery;
-import org.eclipse.persistence.queries.SQLCall;
-import org.eclipse.persistence.sessions.Session;
-
-/**
- * This is a utility class for generating and cleaning data. The generated data would be used by the application.
- * 
- * 
- */
-public class DataGenerator {
-
-  private EntityManager entityManager;
-
-  /**
-   * This is configuration property to hold comma separated names of Insert Files
-   */
-  private static final String SQL_INSERT_CONFIG = "SQL_Insert_Config";
-
-  /**
-   * This is key which will be used to fetch file names from SQL Insert Config File.
-   */
-  private static final String SQL_INSERT_FILE_NAMES_KEY = "insert_file_names";
-
-  private static final String SQL_DELETE_CONFIG = "SQL_Cleanup";
-  private static final String SQL_DELETE_STATEMENTS_KEY = "delete_queries";
-
-  public DataGenerator(final EntityManager entityManager) {
-    this.entityManager = entityManager;
-  }
-
-  /**
-   * This method generates data to be used in the application. It does so by
-   * reading properties file. Currently it iterates through comma separated
-   * file names in file SQLInsertConfig and gets the insert statements from
-   * those files in the order provided in the file.
-   */
-  public void generate() {
-    String[] resourceSQLPropFileNames = getSQLInsertFileNames();
-    if (resourceSQLPropFileNames.length > 0) { // If configuration is proper with at least one file
-      Session session = ((EntityManagerImpl) entityManager).getActiveSession();
-      ResourceBundle[] resourceBundleArr = new ResourceBundle[resourceSQLPropFileNames.length];
-      entityManager.getTransaction().begin();
-
-      for (int i = 0; i < resourceSQLPropFileNames.length; i++) { // For each Entity SQL property file,
-        System.out.println("Reading from File - " + resourceSQLPropFileNames[i]);
-        resourceBundleArr[i] = ResourceBundle.getBundle(resourceSQLPropFileNames[i]);// Get SQL statements as properties
-
-        Set<String> keySet = resourceBundleArr[i].keySet();
-
-        for (String string : keySet) {
-          String currentSQL = (String) string;
-          String sqlQuery = resourceBundleArr[i].getString(currentSQL);
-          System.out.println("Executing Query - " + sqlQuery);
-          SQLCall sqlCall = new SQLCall(sqlQuery);
-
-          DataModifyQuery query = new DataModifyQuery();
-          query.setCall(sqlCall);
-          session.executeQuery(query);
-        }
-      }
-      setMaterialInStore();
-      entityManager.flush();
-      entityManager.getTransaction().commit();
-    }
-
-  }
-
-  @SuppressWarnings("unchecked")
-  private void setMaterialInStore() {
-    Query query = entityManager.createQuery("SELECT e FROM Material e");
-    List<Material> materials = (List<Material>) query.getResultList();
-
-    query = entityManager.createQuery("SELECT e FROM Store e");
-    List<Store> stores = (List<Store>) query.getResultList();
-
-    int storeSize = stores.size();
-    int i = 0;
-    for (Material material : materials) {
-      List<Store> storesA = Arrays.asList(stores.get(i), stores.get(i + 1));
-      material.setStores(storesA);
-      i++;
-      if (i > storeSize - 2) {
-        i = 0;
-      }
-      entityManager.persist(material);
-    }
-    entityManager.flush();
-  }
-
-  private String[] getSQLInsertFileNames() {
-    ResourceBundle resourceBundle = ResourceBundle.getBundle(SQL_INSERT_CONFIG);// File names from properties
-    String namesStr = resourceBundle.getString(SQL_INSERT_FILE_NAMES_KEY);
-    return namesStr.split(",");
-  }
-
-  private String[] getSQLDeleteStatements() {
-    ResourceBundle resourceBundle = ResourceBundle.getBundle(SQL_DELETE_CONFIG);// File names from properties
-    String deleteStatements = resourceBundle.getString(SQL_DELETE_STATEMENTS_KEY);
-    return deleteStatements.split(",");
-  }
-
-  /**
-   * This method deletes data from JPA tables created. This method reads comma
-   * separated SQL delete statements from DataDeleteSQLs properties files and
-   * executes them in order.
-   */
-  public void clean() {
-    // Delete using SQLs
-    String[] deleteStatements = getSQLDeleteStatements();
-    if (deleteStatements.length > 0) { // If configuration is proper with at least one delete Statements
-      Session session = ((EntityManagerImpl) entityManager).getActiveSession();
-      entityManager.getTransaction().begin();
-      for (String deleteStatement : deleteStatements) {
-        System.out.println("Cleaning - " + deleteStatement);
-        SQLCall sqlCall = new SQLCall(deleteStatement);
-
-        DataModifyQuery query = new DataModifyQuery();
-        query.setCall(sqlCall);
-        session.executeQuery(query);
-      }
-      entityManager.getTransaction().commit();
-    } else {
-      System.err.println("Delete configuration file doesn't have any delete statements.");
-    }
-  }
-
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.util;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.ResourceBundle;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.olingo.odata2.jpa.processor.ref.model.Material;
+import org.apache.olingo.odata2.jpa.processor.ref.model.Store;
+import org.eclipse.persistence.internal.jpa.EntityManagerImpl;
+import org.eclipse.persistence.queries.DataModifyQuery;
+import org.eclipse.persistence.queries.SQLCall;
+import org.eclipse.persistence.sessions.Session;
+
+/**
+ * This is a utility class for generating and cleaning data. The generated data would be used by the application.
+ * 
+ * 
+ */
+public class DataGenerator {
+
+  private EntityManager entityManager;
+
+  /**
+   * This is configuration property to hold comma separated names of Insert Files
+   */
+  private static final String SQL_INSERT_CONFIG = "SQL_Insert_Config";
+
+  /**
+   * This is key which will be used to fetch file names from SQL Insert Config File.
+   */
+  private static final String SQL_INSERT_FILE_NAMES_KEY = "insert_file_names";
+
+  private static final String SQL_DELETE_CONFIG = "SQL_Cleanup";
+  private static final String SQL_DELETE_STATEMENTS_KEY = "delete_queries";
+
+  public DataGenerator(final EntityManager entityManager) {
+    this.entityManager = entityManager;
+  }
+
+  /**
+   * This method generates data to be used in the application. It does so by
+   * reading properties file. Currently it iterates through comma separated
+   * file names in file SQLInsertConfig and gets the insert statements from
+   * those files in the order provided in the file.
+   */
+  public void generate() {
+    String[] resourceSQLPropFileNames = getSQLInsertFileNames();
+    if (resourceSQLPropFileNames.length > 0) { // If configuration is proper with at least one file
+      Session session = ((EntityManagerImpl) entityManager).getActiveSession();
+      ResourceBundle[] resourceBundleArr = new ResourceBundle[resourceSQLPropFileNames.length];
+      entityManager.getTransaction().begin();
+
+      for (int i = 0; i < resourceSQLPropFileNames.length; i++) { // For each Entity SQL property file,
+        System.out.println("Reading from File - " + resourceSQLPropFileNames[i]);
+        resourceBundleArr[i] = ResourceBundle.getBundle(resourceSQLPropFileNames[i]);// Get SQL statements as properties
+
+        Set<String> keySet = resourceBundleArr[i].keySet();
+
+        for (String string : keySet) {
+          String currentSQL = (String) string;
+          String sqlQuery = resourceBundleArr[i].getString(currentSQL);
+          System.out.println("Executing Query - " + sqlQuery);
+          SQLCall sqlCall = new SQLCall(sqlQuery);
+
+          DataModifyQuery query = new DataModifyQuery();
+          query.setCall(sqlCall);
+          session.executeQuery(query);
+        }
+      }
+      setMaterialInStore();
+      entityManager.flush();
+      entityManager.getTransaction().commit();
+    }
+
+  }
+
+  @SuppressWarnings("unchecked")
+  private void setMaterialInStore() {
+    Query query = entityManager.createQuery("SELECT e FROM Material e");
+    List<Material> materials = (List<Material>) query.getResultList();
+
+    query = entityManager.createQuery("SELECT e FROM Store e");
+    List<Store> stores = (List<Store>) query.getResultList();
+
+    int storeSize = stores.size();
+    int i = 0;
+    for (Material material : materials) {
+      List<Store> storesA = Arrays.asList(stores.get(i), stores.get(i + 1));
+      material.setStores(storesA);
+      i++;
+      if (i > storeSize - 2) {
+        i = 0;
+      }
+      entityManager.persist(material);
+    }
+    entityManager.flush();
+  }
+
+  private String[] getSQLInsertFileNames() {
+    ResourceBundle resourceBundle = ResourceBundle.getBundle(SQL_INSERT_CONFIG);// File names from properties
+    String namesStr = resourceBundle.getString(SQL_INSERT_FILE_NAMES_KEY);
+    return namesStr.split(",");
+  }
+
+  private String[] getSQLDeleteStatements() {
+    ResourceBundle resourceBundle = ResourceBundle.getBundle(SQL_DELETE_CONFIG);// File names from properties
+    String deleteStatements = resourceBundle.getString(SQL_DELETE_STATEMENTS_KEY);
+    return deleteStatements.split(",");
+  }
+
+  /**
+   * This method deletes data from JPA tables created. This method reads comma
+   * separated SQL delete statements from DataDeleteSQLs properties files and
+   * executes them in order.
+   */
+  public void clean() {
+    // Delete using SQLs
+    String[] deleteStatements = getSQLDeleteStatements();
+    if (deleteStatements.length > 0) { // If configuration is proper with at least one delete Statements
+      Session session = ((EntityManagerImpl) entityManager).getActiveSession();
+      entityManager.getTransaction().begin();
+      for (String deleteStatement : deleteStatements) {
+        System.out.println("Cleaning - " + deleteStatement);
+        SQLCall sqlCall = new SQLCall(deleteStatement);
+
+        DataModifyQuery query = new DataModifyQuery();
+        query.setCall(sqlCall);
+        session.executeQuery(query);
+      }
+      entityManager.getTransaction().commit();
+    } else {
+      System.err.println("Delete configuration file doesn't have any delete statements.");
+    }
+  }
+
+}


[17/19] git commit: Revert input stream splitting

Posted by ch...@apache.org.
Revert input stream splitting

Signed-off-by: Christian Amend <ch...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/8dfd515e
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/8dfd515e
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/8dfd515e

Branch: refs/heads/master
Commit: 8dfd515e89e1ddf0ec91f347264bb4be9144c6d3
Parents: dbaa667
Author: Christian Holzer <c....@sap.com>
Authored: Thu Oct 9 16:31:23 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Oct 9 16:45:27 2014 +0200

----------------------------------------------------------------------
 .../odata2/core/batch/v2/BatchParser.java       | 14 ++++-
 .../odata2/core/batch/v2/BatchParserCommon.java | 56 --------------------
 2 files changed, 13 insertions(+), 57 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/8dfd515e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
index bf4ce93..09bf987 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
@@ -20,6 +20,7 @@ package org.apache.olingo.odata2.core.batch.v2;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -80,7 +81,7 @@ public class BatchParser {
     final String baseUri = getBaseUri();
     final String boundary = BatchParserCommon.getBoundary(contentTypeMime, 1);
     final List<BatchParserResult> resultList = new LinkedList<BatchParserResult>();
-    final List<List<Line>> bodyPartStrings = BatchParserCommon.splitRequestByBoundary(in, boundary);
+    final List<List<Line>> bodyPartStrings = splitBodyParts(in, boundary);
 
     for (List<Line> bodyPartString : bodyPartStrings) {
       BatchBodyPart bodyPart = new BatchBodyPart(bodyPartString, boundary, isStrict).parse();
@@ -89,6 +90,17 @@ public class BatchParser {
 
     return resultList;
   }
+  
+  private List<List<Line>> splitBodyParts(final InputStream in, final String boundary)
+      throws IOException, BatchException {
+
+    final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
+    final List<Line> message = reader.toList();
+    reader.close();
+
+    return BatchParserCommon.splitMessageByBoundary(message, boundary);
+  }
+
 
   private String getBaseUri() throws BatchException {
     String baseUri = "";

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/8dfd515e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
index 5c6cd69..cac340e 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
@@ -19,9 +19,7 @@
 package org.apache.olingo.odata2.core.batch.v2;
 
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
@@ -93,60 +91,6 @@ public class BatchParserCommon {
     return new ByteArrayInputStream(message.getBytes());
   }
 
-  static List<List<Line>> splitRequestByBoundary(final InputStream in, final String boundary)
-      throws BatchException, IOException {
-    final List<List<Line>> messageParts = new LinkedList<List<Line>>();
-    List<Line> currentPart = new ArrayList<Line>();
-    boolean isEndReached = false;
-
-    final String quotedBoundary = Pattern.quote(boundary);
-    final Pattern boundaryDelimiterPattern = Pattern.compile("--" + quotedBoundary + "--[\\s ]*");
-    final Pattern boundaryPattern = Pattern.compile("--" + quotedBoundary + "[\\s ]*");
-
-    final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
-    String currentLine;
-    int lineNumber = 1;
-
-    while ((currentLine = reader.readLine()) != null) {
-      if (boundaryDelimiterPattern.matcher(currentLine.toString()).matches()) {
-        removeEndingCRLFFromList(currentPart);
-        messageParts.add(currentPart);
-        isEndReached = true;
-      } else if (boundaryPattern.matcher(currentLine.toString()).matches()) {
-        removeEndingCRLFFromList(currentPart);
-        messageParts.add(currentPart);
-        currentPart = new LinkedList<Line>();
-      } else {
-        currentPart.add(new Line(currentLine, lineNumber));
-      }
-
-      if (isEndReached) {
-        break;
-      }
-
-      lineNumber++;
-    }
-    reader.close();
-
-    // Remove preamble
-    if (messageParts.size() > 0) {
-      messageParts.remove(0);
-    } else {
-
-      throw new BatchException(BatchException.MISSING_BOUNDARY_DELIMITER.addContent(1));
-    }
-
-    if (!isEndReached) {
-      throw new BatchException(BatchException.MISSING_CLOSE_DELIMITER.addContent(1));
-    }
-
-    if (messageParts.size() == 0) {
-      throw new BatchException(BatchException.NO_MATCH_WITH_BOUNDARY_STRING.addContent(boundary).addContent(0));
-    }
-
-    return messageParts;
-  }
-
   static List<List<Line>> splitMessageByBoundary(final List<Line> message, final String boundary)
       throws BatchException {
     final List<List<Line>> messageParts = new LinkedList<List<Line>>();


[10/19] line ending issue again

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/converter/BlobToByteConverter.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/converter/BlobToByteConverter.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/converter/BlobToByteConverter.java
index e950d69..16835fe 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/converter/BlobToByteConverter.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/converter/BlobToByteConverter.java
@@ -1,70 +1,70 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.ref.converter;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.sql.Blob;
-import java.sql.SQLException;
-
-import javax.persistence.AttributeConverter;
-import javax.persistence.Converter;
-
-import org.hsqldb.jdbc.JDBCBlob;
-
-@Converter(autoApply = true)
-public class BlobToByteConverter implements AttributeConverter<Blob, byte[]> {
-
-  @Override
-  public byte[] convertToDatabaseColumn(final Blob arg0) {
-    if (arg0 == null) {
-      return null;
-    }
-    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-    InputStream is;
-    try {
-      is = arg0.getBinaryStream();
-      int b;
-      b = is.read();
-      while (b != -1) {
-        buffer.write(b);
-        b = is.read();
-      }
-    } catch (SQLException e) {
-      e.printStackTrace();
-    } catch (IOException e) {
-      e.printStackTrace();
-    }
-    return buffer.toByteArray();
-  }
-
-  @Override
-  public Blob convertToEntityAttribute(final byte[] arg0) {
-    try {
-      if (arg0 == null) {
-        return null;
-      }
-      return new JDBCBlob(arg0);
-    } catch (SQLException e) {
-      e.printStackTrace();
-    }
-    return null;
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.converter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Blob;
+import java.sql.SQLException;
+
+import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
+
+import org.hsqldb.jdbc.JDBCBlob;
+
+@Converter(autoApply = true)
+public class BlobToByteConverter implements AttributeConverter<Blob, byte[]> {
+
+  @Override
+  public byte[] convertToDatabaseColumn(final Blob arg0) {
+    if (arg0 == null) {
+      return null;
+    }
+    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+    InputStream is;
+    try {
+      is = arg0.getBinaryStream();
+      int b;
+      b = is.read();
+      while (b != -1) {
+        buffer.write(b);
+        b = is.read();
+      }
+    } catch (SQLException e) {
+      e.printStackTrace();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+    return buffer.toByteArray();
+  }
+
+  @Override
+  public Blob convertToEntityAttribute(final byte[] arg0) {
+    try {
+      if (arg0 == null) {
+        return null;
+      }
+      return new JDBCBlob(arg0);
+    } catch (SQLException e) {
+      e.printStackTrace();
+    }
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/factory/JPAEntityManagerFactory.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/factory/JPAEntityManagerFactory.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/factory/JPAEntityManagerFactory.java
index 1f4a7a8..9e53eb3 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/factory/JPAEntityManagerFactory.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/factory/JPAEntityManagerFactory.java
@@ -1,46 +1,46 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ******************************************************************************/
-package org.apache.olingo.odata2.jpa.processor.ref.factory;
-
-import java.util.HashMap;
-
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.Persistence;
-
-public class JPAEntityManagerFactory {
-  private static HashMap<String, EntityManagerFactory> emfMap;
-
-  public static EntityManagerFactory getEntityManagerFactory(final String pUnit) {
-    if (pUnit == null) {
-      return null;
-    }
-    if (emfMap == null) {
-      emfMap = new HashMap<String, EntityManagerFactory>();
-    }
-
-    if (emfMap.containsKey(pUnit)) {
-      return emfMap.get(pUnit);
-    } else {
-      EntityManagerFactory emf = Persistence.createEntityManagerFactory(pUnit);
-      emfMap.put(pUnit, emf);
-      return emf;
-    }
-
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.factory;
+
+import java.util.HashMap;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+public class JPAEntityManagerFactory {
+  private static HashMap<String, EntityManagerFactory> emfMap;
+
+  public static EntityManagerFactory getEntityManagerFactory(final String pUnit) {
+    if (pUnit == null) {
+      return null;
+    }
+    if (emfMap == null) {
+      emfMap = new HashMap<String, EntityManagerFactory>();
+    }
+
+    if (emfMap.containsKey(pUnit)) {
+      return emfMap.get(pUnit);
+    } else {
+      EntityManagerFactory emf = Persistence.createEntityManagerFactory(pUnit);
+      emfMap.put(pUnit, emf);
+      return emf;
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/SalesOrderItemTombstoneListener.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/SalesOrderItemTombstoneListener.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/SalesOrderItemTombstoneListener.java
index 05de214..26c5b81 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/SalesOrderItemTombstoneListener.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/SalesOrderItemTombstoneListener.java
@@ -1,93 +1,93 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ******************************************************************************/
-package org.apache.olingo.odata2.jpa.processor.ref.listeners;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
-import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneContext;
-import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneEntityListener;
-import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
-import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
-import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContext;
-import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContextType;
-import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement;
-
-public class SalesOrderItemTombstoneListener extends ODataJPATombstoneEntityListener {
-
-  @Override
-  public Query getQuery(final GetEntitySetUriInfo resultsView, final EntityManager em) {
-    JPQLContextType contextType = null;
-
-    try {
-      if (!resultsView.getStartEntitySet().getName().equals(resultsView.getTargetEntitySet().getName())) {
-        contextType = JPQLContextType.JOIN;
-      } else {
-        contextType = JPQLContextType.SELECT;
-      }
-
-      JPQLContext jpqlContext = JPQLContext.createBuilder(contextType, resultsView).build();
-      JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext).build();
-      String deltaToken = ODataJPATombstoneContext.getDeltaToken();
-
-      Query query = null;
-      if (deltaToken != null) {
-        String statement = jpqlStatement.toString();
-        String[] statementParts = statement.split(JPQLStatement.KEYWORD.WHERE);
-        String deltaCondition = jpqlContext.getJPAEntityAlias() + ".creationDate >= {ts '" + deltaToken + "'}";
-        if (statementParts.length > 1) {
-          statement =
-              statementParts[0] + JPQLStatement.DELIMITER.SPACE + JPQLStatement.KEYWORD.WHERE
-                  + JPQLStatement.DELIMITER.SPACE + deltaCondition + JPQLStatement.DELIMITER.SPACE
-                  + JPQLStatement.Operator.AND + statementParts[1];
-        } else {
-          statement =
-              statementParts[0] + JPQLStatement.DELIMITER.SPACE + JPQLStatement.KEYWORD.WHERE
-                  + JPQLStatement.DELIMITER.SPACE + deltaCondition;
-        }
-
-        query = em.createQuery(statement);
-      } else {
-        query = em.createQuery(jpqlStatement.toString());
-      }
-
-      return query;
-    } catch (EdmException e) {
-      return null;
-    } catch (ODataJPAModelException e) {
-      return null;
-    } catch (ODataJPARuntimeException e) {
-      return null;
-    }
-  }
-
-  @Override
-  public String generateDeltaToken(final List<Object> deltas, final Query query) {
-    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.000");
-
-    Date date = new Date(System.currentTimeMillis());
-    return dateFormat.format(date);
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.listeners;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneContext;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneEntityListener;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContext;
+import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContextType;
+import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement;
+
+public class SalesOrderItemTombstoneListener extends ODataJPATombstoneEntityListener {
+
+  @Override
+  public Query getQuery(final GetEntitySetUriInfo resultsView, final EntityManager em) {
+    JPQLContextType contextType = null;
+
+    try {
+      if (!resultsView.getStartEntitySet().getName().equals(resultsView.getTargetEntitySet().getName())) {
+        contextType = JPQLContextType.JOIN;
+      } else {
+        contextType = JPQLContextType.SELECT;
+      }
+
+      JPQLContext jpqlContext = JPQLContext.createBuilder(contextType, resultsView).build();
+      JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext).build();
+      String deltaToken = ODataJPATombstoneContext.getDeltaToken();
+
+      Query query = null;
+      if (deltaToken != null) {
+        String statement = jpqlStatement.toString();
+        String[] statementParts = statement.split(JPQLStatement.KEYWORD.WHERE);
+        String deltaCondition = jpqlContext.getJPAEntityAlias() + ".creationDate >= {ts '" + deltaToken + "'}";
+        if (statementParts.length > 1) {
+          statement =
+              statementParts[0] + JPQLStatement.DELIMITER.SPACE + JPQLStatement.KEYWORD.WHERE
+                  + JPQLStatement.DELIMITER.SPACE + deltaCondition + JPQLStatement.DELIMITER.SPACE
+                  + JPQLStatement.Operator.AND + statementParts[1];
+        } else {
+          statement =
+              statementParts[0] + JPQLStatement.DELIMITER.SPACE + JPQLStatement.KEYWORD.WHERE
+                  + JPQLStatement.DELIMITER.SPACE + deltaCondition;
+        }
+
+        query = em.createQuery(statement);
+      } else {
+        query = em.createQuery(jpqlStatement.toString());
+      }
+
+      return query;
+    } catch (EdmException e) {
+      return null;
+    } catch (ODataJPAModelException e) {
+      return null;
+    } catch (ODataJPARuntimeException e) {
+      return null;
+    }
+  }
+
+  @Override
+  public String generateDeltaToken(final List<Object> deltas, final Query query) {
+    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.000");
+
+    Date date = new Date(System.currentTimeMillis());
+    return dateFormat.format(date);
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/SalesOrderTombstoneListener.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/SalesOrderTombstoneListener.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/SalesOrderTombstoneListener.java
index 0545eac..55f2013 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/SalesOrderTombstoneListener.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/SalesOrderTombstoneListener.java
@@ -1,57 +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.odata2.jpa.processor.ref.listeners;
-
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PostLoad;
-import javax.persistence.Query;
-
-import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
-import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneContext;
-import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneEntityListener;
-import org.apache.olingo.odata2.jpa.processor.ref.model.SalesOrderHeader;
-
-public class SalesOrderTombstoneListener extends ODataJPATombstoneEntityListener {
-
-  public static String ENTITY_NAME = "SalesOrderHeader";
-
-  @PostLoad
-  public void handleDelta(final Object entity) {
-    SalesOrderHeader so = (SalesOrderHeader) entity;
-
-    if (so.getCreationDate().getTime().getTime() < ODataJPATombstoneContext.getDeltaTokenUTCTimeStamp()) {
-      return;
-    } else {
-      addToDelta(entity, ENTITY_NAME);
-    }
-  }
-
-  @Override
-  public String generateDeltaToken(final List<Object> deltas, final Query query) {
-    return String.valueOf(System.currentTimeMillis());
-  }
-
-  @Override
-  public Query getQuery(final GetEntitySetUriInfo resultsView, final EntityManager em) {
-    return null;
-  }
-
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.listeners;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PostLoad;
+import javax.persistence.Query;
+
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneContext;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneEntityListener;
+import org.apache.olingo.odata2.jpa.processor.ref.model.SalesOrderHeader;
+
+public class SalesOrderTombstoneListener extends ODataJPATombstoneEntityListener {
+
+  public static String ENTITY_NAME = "SalesOrderHeader";
+
+  @PostLoad
+  public void handleDelta(final Object entity) {
+    SalesOrderHeader so = (SalesOrderHeader) entity;
+
+    if (so.getCreationDate().getTime().getTime() < ODataJPATombstoneContext.getDeltaTokenUTCTimeStamp()) {
+      return;
+    } else {
+      addToDelta(entity, ENTITY_NAME);
+    }
+  }
+
+  @Override
+  public String generateDeltaToken(final List<Object> deltas, final Query query) {
+    return String.valueOf(System.currentTimeMillis());
+  }
+
+  @Override
+  public Query getQuery(final GetEntitySetUriInfo resultsView, final EntityManager em) {
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Address.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Address.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Address.java
index 0ae4adf..14adb5e 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Address.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Address.java
@@ -1,94 +1,94 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.ref.model;
-
-import javax.persistence.Column;
-import javax.persistence.Embeddable;
-
-@Embeddable
-public class Address {
-
-  public Address() {
-    super();
-  }
-
-  public Address(final short houseNumber, final String streetName, final String city,
-      final String country) {
-    this();
-    this.houseNumber = houseNumber;
-    this.streetName = streetName;
-    this.city = city;
-    this.country = country;
-  }
-
-  @Column(name = "HOUSE_NUMBER")
-  private short houseNumber;
-
-  @Column(name = "STREET_NAME")
-  private String streetName;
-
-  @Column(name = "CITY")
-  private String city;
-
-  @Column(name = "COUNTRY")
-  private String country;
-
-  @Column(name = "PINCODE")
-  private String pincode;
-
-  public String getPincode() {
-    return pincode;
-  }
-
-  public void setPincode(final String pincode) {
-    this.pincode = pincode;
-  }
-
-  public short getHouseNumber() {
-    return houseNumber;
-  }
-
-  public void setHouseNumber(final short houseNumber) {
-    this.houseNumber = houseNumber;
-  }
-
-  public String getStreetName() {
-    return streetName;
-  }
-
-  public void setStreetName(final String streetName) {
-    this.streetName = streetName;
-  }
-
-  public String getCity() {
-    return city;
-  }
-
-  public void setCity(final String city) {
-    this.city = city;
-  }
-
-  public String getCountry() {
-    return country;
-  }
-
-  public void setCountry(final String country) {
-    this.country = country;
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.model;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+
+@Embeddable
+public class Address {
+
+  public Address() {
+    super();
+  }
+
+  public Address(final short houseNumber, final String streetName, final String city,
+      final String country) {
+    this();
+    this.houseNumber = houseNumber;
+    this.streetName = streetName;
+    this.city = city;
+    this.country = country;
+  }
+
+  @Column(name = "HOUSE_NUMBER")
+  private short houseNumber;
+
+  @Column(name = "STREET_NAME")
+  private String streetName;
+
+  @Column(name = "CITY")
+  private String city;
+
+  @Column(name = "COUNTRY")
+  private String country;
+
+  @Column(name = "PINCODE")
+  private String pincode;
+
+  public String getPincode() {
+    return pincode;
+  }
+
+  public void setPincode(final String pincode) {
+    this.pincode = pincode;
+  }
+
+  public short getHouseNumber() {
+    return houseNumber;
+  }
+
+  public void setHouseNumber(final short houseNumber) {
+    this.houseNumber = houseNumber;
+  }
+
+  public String getStreetName() {
+    return streetName;
+  }
+
+  public void setStreetName(final String streetName) {
+    this.streetName = streetName;
+  }
+
+  public String getCity() {
+    return city;
+  }
+
+  public void setCity(final String city) {
+    this.city = city;
+  }
+
+  public String getCountry() {
+    return country;
+  }
+
+  public void setCountry(final String country) {
+    this.country = country;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Category.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Category.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Category.java
index 7c8965e..d21e5bc 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Category.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Category.java
@@ -1,80 +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.odata2.jpa.processor.ref.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.OneToMany;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "T_CATEGORY")
-public class Category {
-
-  @Id
-  @Column(name = "CODE")
-  private char code[] = new char[2];
-
-  @Id
-  @Column(name = "ID")
-  private long id;
-
-  @Column(name = "DESC")
-  private String description;
-
-  @OneToMany(mappedBy = "category")
-  private List<Material> materials = new ArrayList<Material>();
-
-  public List<Material> getMaterials() {
-    return materials;
-  }
-
-  public void setMaterials(final List<Material> materials) {
-    this.materials = materials;
-  }
-
-  public long getId() {
-    return id;
-  }
-
-  public void setId(final long id) {
-    this.id = id;
-  }
-
-  public char[] getCode() {
-    return code;
-  }
-
-  public void setCode(final char[] code) {
-    this.code = code;
-  }
-
-  public String getDescription() {
-    return description;
-  }
-
-  public void setDescription(final String description) {
-    this.description = description;
-  }
-
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "T_CATEGORY")
+public class Category {
+
+  @Id
+  @Column(name = "CODE")
+  private char code[] = new char[2];
+
+  @Id
+  @Column(name = "ID")
+  private long id;
+
+  @Column(name = "DESC")
+  private String description;
+
+  @OneToMany(mappedBy = "category")
+  private List<Material> materials = new ArrayList<Material>();
+
+  public List<Material> getMaterials() {
+    return materials;
+  }
+
+  public void setMaterials(final List<Material> materials) {
+    this.materials = materials;
+  }
+
+  public long getId() {
+    return id;
+  }
+
+  public void setId(final long id) {
+    this.id = id;
+  }
+
+  public char[] getCode() {
+    return code;
+  }
+
+  public void setCode(final char[] code) {
+    this.code = code;
+  }
+
+  public String getDescription() {
+    return description;
+  }
+
+  public void setDescription(final String description) {
+    this.description = description;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java
index 48243d0..6dabd2a 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java
@@ -1,93 +1,93 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ******************************************************************************/
-package org.apache.olingo.odata2.jpa.processor.ref.model;
-
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Embedded;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.OneToMany;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "T_CUSTOMER")
-public class Customer {
-
-  @Id
-  @Column(name = "ID")
-  private Long id;
-
-  @Column(name = "NAME")
-  private String name;
-
-  @Embedded
-  private Address address;
-
-  @Column(name = "CREATED_AT")
-  private Timestamp createdAt;
-
-  @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
-  private List<SalesOrderHeader> orders = new ArrayList<SalesOrderHeader>();
-
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(final Long id) {
-    this.id = id;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public void setName(final String name) {
-    this.name = name;
-  }
-
-  public List<SalesOrderHeader> getOrders() {
-    return orders;
-  }
-
-  public void setOrders(final List<SalesOrderHeader> orders) {
-    this.orders = orders;
-  }
-
-  public Address getAddress() {
-    return address;
-  }
-
-  public void setAddress(final Address address) {
-    this.address = address;
-  }
-
-  public Timestamp getCreatedAt() {
-    return createdAt;
-  }
-
-  public void setCreatedAt(final Timestamp createdAt) {
-    this.createdAt = createdAt;
-  }
-
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.model;
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "T_CUSTOMER")
+public class Customer {
+
+  @Id
+  @Column(name = "ID")
+  private Long id;
+
+  @Column(name = "NAME")
+  private String name;
+
+  @Embedded
+  private Address address;
+
+  @Column(name = "CREATED_AT")
+  private Timestamp createdAt;
+
+  @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
+  private List<SalesOrderHeader> orders = new ArrayList<SalesOrderHeader>();
+
+  public Long getId() {
+    return id;
+  }
+
+  public void setId(final Long id) {
+    this.id = id;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(final String name) {
+    this.name = name;
+  }
+
+  public List<SalesOrderHeader> getOrders() {
+    return orders;
+  }
+
+  public void setOrders(final List<SalesOrderHeader> orders) {
+    this.orders = orders;
+  }
+
+  public Address getAddress() {
+    return address;
+  }
+
+  public void setAddress(final Address address) {
+    this.address = address;
+  }
+
+  public Timestamp getCreatedAt() {
+    return createdAt;
+  }
+
+  public void setCreatedAt(final Timestamp createdAt) {
+    this.createdAt = createdAt;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Material.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Material.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Material.java
index 8a2ef0c..f6e798c 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Material.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Material.java
@@ -1,136 +1,136 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.ref.model;
-
-import java.sql.Blob;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.persistence.Column;
-import javax.persistence.Convert;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinColumns;
-import javax.persistence.Lob;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "T_MATERIAL")
-public class Material {
-
-  public Material() {}
-
-  public Material(final String materialName, final char[] typeCode, final double price,
-      final String measurementUnit) {
-    super();
-    this.materialName = materialName;
-    this.price = price;
-    this.measurementUnit = measurementUnit;
-  }
-
-  @Id
-  @Column(name = "MATERIAL_ID")
-  private long materialId;
-
-  @Column(name = "MATERIAL_NAME")
-  private String materialName;
-
-  @Column(name = "PRICE")
-  private double price;
-
-  @Column(name = "MEASUREMENT_UNIT")
-  private String measurementUnit;
-
-  @Lob
-  @Column(name = "MIMAGE")
-  @Convert(converter = org.apache.olingo.odata2.jpa.processor.ref.converter.BlobToByteConverter.class)
-  private Blob materialImage;
-
-  public Blob getMaterialImage() {
-    return materialImage;
-  }
-
-  public void setMaterialImage(final Blob materialImage) {
-    this.materialImage = materialImage;
-  }
-
-  @ManyToMany
-  private List<Store> stores = new ArrayList<Store>();
-
-  @ManyToOne
-  @JoinColumns({ @JoinColumn(name = "TYPE_CODE", referencedColumnName = "CODE"),
-      @JoinColumn(name = "CAT_ID", referencedColumnName = "ID") })
-  private Category category;
-
-  public long getMaterialId() {
-    return materialId;
-  }
-
-  public void setMaterialId(final long materialId) {
-    this.materialId = materialId;
-  }
-
-  public Category getCategory() {
-    return category;
-  }
-
-  public void setCategory(final Category category) {
-    this.category = category;
-  }
-
-  public String getMaterialName() {
-    return materialName;
-  }
-
-  public void setMaterialName(final String materialName) {
-    this.materialName = materialName;
-  }
-
-  public double getPrice() {
-    return price;
-  }
-
-  public void setPrice(final double price) {
-    this.price = price;
-  }
-
-  public String getMeasurementUnit() {
-    return measurementUnit;
-  }
-
-  public void setMeasurementUnit(final String measurementUnit) {
-    this.measurementUnit = measurementUnit;
-  }
-
-  public List<Store> getStores() {
-    return stores;
-  }
-
-  public void setStores(final List<Store> stores) {
-    this.stores = stores;
-    Iterator<Store> itr = stores.iterator();
-    while (itr.hasNext()) {
-      itr.next().getMaterials().add(this);
-    }
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.model;
+
+import java.sql.Blob;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Convert;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import javax.persistence.Lob;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "T_MATERIAL")
+public class Material {
+
+  public Material() {}
+
+  public Material(final String materialName, final char[] typeCode, final double price,
+      final String measurementUnit) {
+    super();
+    this.materialName = materialName;
+    this.price = price;
+    this.measurementUnit = measurementUnit;
+  }
+
+  @Id
+  @Column(name = "MATERIAL_ID")
+  private long materialId;
+
+  @Column(name = "MATERIAL_NAME")
+  private String materialName;
+
+  @Column(name = "PRICE")
+  private double price;
+
+  @Column(name = "MEASUREMENT_UNIT")
+  private String measurementUnit;
+
+  @Lob
+  @Column(name = "MIMAGE")
+  @Convert(converter = org.apache.olingo.odata2.jpa.processor.ref.converter.BlobToByteConverter.class)
+  private Blob materialImage;
+
+  public Blob getMaterialImage() {
+    return materialImage;
+  }
+
+  public void setMaterialImage(final Blob materialImage) {
+    this.materialImage = materialImage;
+  }
+
+  @ManyToMany
+  private List<Store> stores = new ArrayList<Store>();
+
+  @ManyToOne
+  @JoinColumns({ @JoinColumn(name = "TYPE_CODE", referencedColumnName = "CODE"),
+      @JoinColumn(name = "CAT_ID", referencedColumnName = "ID") })
+  private Category category;
+
+  public long getMaterialId() {
+    return materialId;
+  }
+
+  public void setMaterialId(final long materialId) {
+    this.materialId = materialId;
+  }
+
+  public Category getCategory() {
+    return category;
+  }
+
+  public void setCategory(final Category category) {
+    this.category = category;
+  }
+
+  public String getMaterialName() {
+    return materialName;
+  }
+
+  public void setMaterialName(final String materialName) {
+    this.materialName = materialName;
+  }
+
+  public double getPrice() {
+    return price;
+  }
+
+  public void setPrice(final double price) {
+    this.price = price;
+  }
+
+  public String getMeasurementUnit() {
+    return measurementUnit;
+  }
+
+  public void setMeasurementUnit(final String measurementUnit) {
+    this.measurementUnit = measurementUnit;
+  }
+
+  public List<Store> getStores() {
+    return stores;
+  }
+
+  public void setStores(final List<Store> stores) {
+    this.stores = stores;
+    Iterator<Store> itr = stores.iterator();
+    while (itr.hasNext()) {
+      itr.next().getMaterials().add(this);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Note.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Note.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Note.java
index 5691dca..434770e 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Note.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Note.java
@@ -1,121 +1,121 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ******************************************************************************/
-package org.apache.olingo.odata2.jpa.processor.ref.model;
-
-import java.sql.Clob;
-import java.util.Calendar;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.JoinColumn;
-import javax.persistence.Lob;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-@Entity
-@IdClass(value = NoteKey.class)
-@Table(name = "T_NOTE")
-public class Note {
-
-  public Note() {}
-
-  public Note(final Calendar creationTime, final Calendar creationDate, final String createdBy,
-      final Clob text) {
-    super();
-    this.creationTime = creationTime;
-    this.creationDate = creationDate;
-    this.createdBy = createdBy;
-    this.text = text;
-  }
-
-  @Id
-  @Temporal(TemporalType.TIME)
-  private Calendar creationTime;
-
-  @Id
-  @Temporal(TemporalType.DATE)
-  private Calendar creationDate;
-
-  @Id
-  private String createdBy;
-
-  @Column
-  @Lob
-  private Clob text;
-
-  @Column(name = "SO_ID")
-  private long soId;
-
-  @JoinColumn(name = "SO_ID", referencedColumnName = "SO_ID", insertable = false, updatable = false)
-  @ManyToOne
-  private SalesOrderHeader salesOrderHeader;
-
-  public Calendar getCreationTime() {
-    return creationTime;
-  }
-
-  public void setCreationTime(final Calendar creationTime) {
-    this.creationTime = creationTime;
-  }
-
-  public Calendar getCreationDate() {
-    return creationDate;
-  }
-
-  public void setCreationDate(final Calendar creationDate) {
-    this.creationDate = creationDate;
-  }
-
-  public String getCreatedBy() {
-    return createdBy;
-  }
-
-  public void setCreatedBy(final String createdBy) {
-    this.createdBy = createdBy;
-  }
-
-  public Clob getText() {
-    return text;
-  }
-
-  public void setText(final Clob text) {
-    this.text = text;
-  }
-
-  public long getSoId() {
-    return soId;
-  }
-
-  public void setSoId(final long soId) {
-    this.soId = soId;
-  }
-
-  public SalesOrderHeader getSalesOrderHeader() {
-    return salesOrderHeader;
-  }
-
-  public void setSalesOrderHeader(final SalesOrderHeader salesOrderHeader) {
-    this.salesOrderHeader = salesOrderHeader;
-    this.salesOrderHeader.getNotes().add(this);
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.model;
+
+import java.sql.Clob;
+import java.util.Calendar;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+@Entity
+@IdClass(value = NoteKey.class)
+@Table(name = "T_NOTE")
+public class Note {
+
+  public Note() {}
+
+  public Note(final Calendar creationTime, final Calendar creationDate, final String createdBy,
+      final Clob text) {
+    super();
+    this.creationTime = creationTime;
+    this.creationDate = creationDate;
+    this.createdBy = createdBy;
+    this.text = text;
+  }
+
+  @Id
+  @Temporal(TemporalType.TIME)
+  private Calendar creationTime;
+
+  @Id
+  @Temporal(TemporalType.DATE)
+  private Calendar creationDate;
+
+  @Id
+  private String createdBy;
+
+  @Column
+  @Lob
+  private Clob text;
+
+  @Column(name = "SO_ID")
+  private long soId;
+
+  @JoinColumn(name = "SO_ID", referencedColumnName = "SO_ID", insertable = false, updatable = false)
+  @ManyToOne
+  private SalesOrderHeader salesOrderHeader;
+
+  public Calendar getCreationTime() {
+    return creationTime;
+  }
+
+  public void setCreationTime(final Calendar creationTime) {
+    this.creationTime = creationTime;
+  }
+
+  public Calendar getCreationDate() {
+    return creationDate;
+  }
+
+  public void setCreationDate(final Calendar creationDate) {
+    this.creationDate = creationDate;
+  }
+
+  public String getCreatedBy() {
+    return createdBy;
+  }
+
+  public void setCreatedBy(final String createdBy) {
+    this.createdBy = createdBy;
+  }
+
+  public Clob getText() {
+    return text;
+  }
+
+  public void setText(final Clob text) {
+    this.text = text;
+  }
+
+  public long getSoId() {
+    return soId;
+  }
+
+  public void setSoId(final long soId) {
+    this.soId = soId;
+  }
+
+  public SalesOrderHeader getSalesOrderHeader() {
+    return salesOrderHeader;
+  }
+
+  public void setSalesOrderHeader(final SalesOrderHeader salesOrderHeader) {
+    this.salesOrderHeader = salesOrderHeader;
+    this.salesOrderHeader.getNotes().add(this);
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/NoteKey.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/NoteKey.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/NoteKey.java
index 2585f97..8079d92 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/NoteKey.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/NoteKey.java
@@ -1,83 +1,83 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.ref.model;
-
-import java.io.Serializable;
-import java.util.Calendar;
-
-public class NoteKey implements Serializable {
-
-  /**
-   * 
-   */
-  private static final long serialVersionUID = 1L;
-
-  public Calendar getCreationTime() {
-    return creationTime;
-  }
-
-  public void setCreationTime(final Calendar creationTime) {
-    this.creationTime = creationTime;
-  }
-
-  public Calendar getCreationDate() {
-    return creationDate;
-  }
-
-  public void setCreationDate(final Calendar creationDate) {
-    this.creationDate = creationDate;
-  }
-
-  public String getCreatedBy() {
-    return createdBy;
-  }
-
-  public void setCreatedBy(final String createdBy) {
-    this.createdBy = createdBy;
-  }
-
-  @Override
-  public int hashCode() {
-    return creationTime.hashCode() + creationDate.hashCode() + createdBy.hashCode();
-  }
-
-  @Override
-  public boolean equals(final Object obj) {
-    if (obj instanceof Note) {
-      Note note = (Note) obj;
-
-      if (!note.getCreatedBy().equals(getCreatedBy())) {
-        return false;
-      }
-      if (!note.getCreationDate().equals(getCreationDate())) {
-        return false;
-      }
-      if (!note.getCreationTime().equals(getCreationTime())) {
-        return false;
-      }
-      return true;
-    }
-    return false;
-  }
-
-  private Calendar creationTime;
-  private Calendar creationDate;
-  private String createdBy;
-
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.model;
+
+import java.io.Serializable;
+import java.util.Calendar;
+
+public class NoteKey implements Serializable {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 1L;
+
+  public Calendar getCreationTime() {
+    return creationTime;
+  }
+
+  public void setCreationTime(final Calendar creationTime) {
+    this.creationTime = creationTime;
+  }
+
+  public Calendar getCreationDate() {
+    return creationDate;
+  }
+
+  public void setCreationDate(final Calendar creationDate) {
+    this.creationDate = creationDate;
+  }
+
+  public String getCreatedBy() {
+    return createdBy;
+  }
+
+  public void setCreatedBy(final String createdBy) {
+    this.createdBy = createdBy;
+  }
+
+  @Override
+  public int hashCode() {
+    return creationTime.hashCode() + creationDate.hashCode() + createdBy.hashCode();
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj instanceof Note) {
+      Note note = (Note) obj;
+
+      if (!note.getCreatedBy().equals(getCreatedBy())) {
+        return false;
+      }
+      if (!note.getCreationDate().equals(getCreationDate())) {
+        return false;
+      }
+      if (!note.getCreationTime().equals(getCreationTime())) {
+        return false;
+      }
+      return true;
+    }
+    return false;
+  }
+
+  private Calendar creationTime;
+  private Calendar creationDate;
+  private String createdBy;
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/SalesOrderItem.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/SalesOrderItem.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/SalesOrderItem.java
index a819ff0..6da7a3c 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/SalesOrderItem.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/SalesOrderItem.java
@@ -1,135 +1,135 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.ref.model;
-
-import javax.persistence.Column;
-import javax.persistence.EmbeddedId;
-import javax.persistence.Entity;
-import javax.persistence.EntityListeners;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import javax.persistence.Transient;
-
-@Entity
-@Table(name = "T_SALESORDERITEM")
-@EntityListeners(org.apache.olingo.odata2.jpa.processor.ref.listeners.SalesOrderItemTombstoneListener.class)
-public class SalesOrderItem {
-
-  public SalesOrderItem() {}
-
-  public SalesOrderItem(final int quantity, final double amount,
-      final double discount, final Material material) {
-    super();
-    this.quantity = quantity;
-    this.amount = amount;
-    this.discount = discount;
-    this.material = material;
-  }
-
-  @EmbeddedId
-  private SalesOrderItemKey salesOrderItemKey;
-
-  @Column
-  private int quantity;
-
-  @Column
-  private double amount;
-
-  @Column
-  private double discount;
-
-  @Transient
-  private double netAmount;
-
-  @Column
-  private boolean delivered;
-
-  public Boolean isDelivered() {
-    return delivered;
-  }
-
-  public void setDelivered(final Boolean deliveryStatus) {
-    delivered = deliveryStatus;
-  }
-
-  @JoinColumn(name = "Material_Id")
-  @ManyToOne
-  private Material material;
-
-  @JoinColumn(name = "Sales_Order_Id", referencedColumnName = "SO_ID", insertable = false, updatable = false)
-  @ManyToOne
-  private SalesOrderHeader salesOrderHeader;
-
-  public SalesOrderItemKey getSalesOrderItemKey() {
-    return salesOrderItemKey;
-  }
-
-  public void setSalesOrderItemKey(final SalesOrderItemKey salesOrderItemKey) {
-    this.salesOrderItemKey = salesOrderItemKey;
-  }
-
-  public int getQuantity() {
-    return quantity;
-  }
-
-  public void setQuantity(final int quantity) {
-    this.quantity = quantity;
-  }
-
-  public double getAmount() {
-    return amount;
-  }
-
-  public void setAmount(final double amount) {
-    this.amount = amount;
-  }
-
-  public double getDiscount() {
-    return discount;
-  }
-
-  public void setDiscount(final double discount) {
-    this.discount = discount;
-  }
-
-  public double getNetAmount() {
-    return netAmount;
-  }
-
-  public void setNetAmount(final double netAmount) {
-    this.netAmount = netAmount;
-  }
-
-  public Material getMaterial() {
-    return material;
-  }
-
-  public void setMaterial(final Material material) {
-    this.material = material;
-  }
-
-  public SalesOrderHeader getSalesOrderHeader() {
-    return salesOrderHeader;
-  }
-
-  public void setSalesOrderHeader(final SalesOrderHeader salesOrderHeader) {
-    this.salesOrderHeader = salesOrderHeader;
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.model;
+
+import javax.persistence.Column;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+@Entity
+@Table(name = "T_SALESORDERITEM")
+@EntityListeners(org.apache.olingo.odata2.jpa.processor.ref.listeners.SalesOrderItemTombstoneListener.class)
+public class SalesOrderItem {
+
+  public SalesOrderItem() {}
+
+  public SalesOrderItem(final int quantity, final double amount,
+      final double discount, final Material material) {
+    super();
+    this.quantity = quantity;
+    this.amount = amount;
+    this.discount = discount;
+    this.material = material;
+  }
+
+  @EmbeddedId
+  private SalesOrderItemKey salesOrderItemKey;
+
+  @Column
+  private int quantity;
+
+  @Column
+  private double amount;
+
+  @Column
+  private double discount;
+
+  @Transient
+  private double netAmount;
+
+  @Column
+  private boolean delivered;
+
+  public Boolean isDelivered() {
+    return delivered;
+  }
+
+  public void setDelivered(final Boolean deliveryStatus) {
+    delivered = deliveryStatus;
+  }
+
+  @JoinColumn(name = "Material_Id")
+  @ManyToOne
+  private Material material;
+
+  @JoinColumn(name = "Sales_Order_Id", referencedColumnName = "SO_ID", insertable = false, updatable = false)
+  @ManyToOne
+  private SalesOrderHeader salesOrderHeader;
+
+  public SalesOrderItemKey getSalesOrderItemKey() {
+    return salesOrderItemKey;
+  }
+
+  public void setSalesOrderItemKey(final SalesOrderItemKey salesOrderItemKey) {
+    this.salesOrderItemKey = salesOrderItemKey;
+  }
+
+  public int getQuantity() {
+    return quantity;
+  }
+
+  public void setQuantity(final int quantity) {
+    this.quantity = quantity;
+  }
+
+  public double getAmount() {
+    return amount;
+  }
+
+  public void setAmount(final double amount) {
+    this.amount = amount;
+  }
+
+  public double getDiscount() {
+    return discount;
+  }
+
+  public void setDiscount(final double discount) {
+    this.discount = discount;
+  }
+
+  public double getNetAmount() {
+    return netAmount;
+  }
+
+  public void setNetAmount(final double netAmount) {
+    this.netAmount = netAmount;
+  }
+
+  public Material getMaterial() {
+    return material;
+  }
+
+  public void setMaterial(final Material material) {
+    this.material = material;
+  }
+
+  public SalesOrderHeader getSalesOrderHeader() {
+    return salesOrderHeader;
+  }
+
+  public void setSalesOrderHeader(final SalesOrderHeader salesOrderHeader) {
+    this.salesOrderHeader = salesOrderHeader;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/SalesOrderItemKey.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/SalesOrderItemKey.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/SalesOrderItemKey.java
index efc09d2..282259b 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/SalesOrderItemKey.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/SalesOrderItemKey.java
@@ -1,89 +1,89 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.ref.model;
-
-import java.io.Serializable;
-
-import javax.persistence.Column;
-import javax.persistence.Embeddable;
-
-@Embeddable
-public class SalesOrderItemKey implements Serializable {
-
-  private static final long serialVersionUID = 1L;
-
-  public SalesOrderItemKey() {}
-
-  public SalesOrderItemKey(final long liId) {
-    super();
-    this.liId = liId;
-  }
-
-  @Column(name = "Sales_Order_Id", nullable = false)
-  private long soId;
-
-  @Column(name = "Sales_Order_Item_Id", unique = true)
-  private long liId;
-
-  @Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = 1;
-    result = prime * result + (int) (liId ^ (liId >>> 32));
-    result = prime * result + (int) (soId ^ (soId >>> 32));
-    return result;
-  }
-
-  @Override
-  public boolean equals(final Object obj) {
-    if (this == obj) {
-      return true;
-    }
-    if (obj == null) {
-      return false;
-    }
-    if (getClass() != obj.getClass()) {
-      return false;
-    }
-    SalesOrderItemKey other = (SalesOrderItemKey) obj;
-    if (liId != other.liId) {
-      return false;
-    }
-    if (soId != other.soId) {
-      return false;
-    }
-    return true;
-  }
-
-  public long getSoId() {
-    return soId;
-  }
-
-  public void setSoId(final long soId) {
-    this.soId = soId;
-  }
-
-  public long getLiId() {
-    return liId;
-  }
-
-  public void setLiId(final long liId) {
-    this.liId = liId;
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.model;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+
+@Embeddable
+public class SalesOrderItemKey implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+
+  public SalesOrderItemKey() {}
+
+  public SalesOrderItemKey(final long liId) {
+    super();
+    this.liId = liId;
+  }
+
+  @Column(name = "Sales_Order_Id", nullable = false)
+  private long soId;
+
+  @Column(name = "Sales_Order_Item_Id", unique = true)
+  private long liId;
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + (int) (liId ^ (liId >>> 32));
+    result = prime * result + (int) (soId ^ (soId >>> 32));
+    return result;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if (this == obj) {
+      return true;
+    }
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    SalesOrderItemKey other = (SalesOrderItemKey) obj;
+    if (liId != other.liId) {
+      return false;
+    }
+    if (soId != other.soId) {
+      return false;
+    }
+    return true;
+  }
+
+  public long getSoId() {
+    return soId;
+  }
+
+  public void setSoId(final long soId) {
+    this.soId = soId;
+  }
+
+  public long getLiId() {
+    return liId;
+  }
+
+  public void setLiId(final long liId) {
+    this.liId = liId;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Store.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Store.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Store.java
index b88bc3a..e609dc2 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Store.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Store.java
@@ -1,92 +1,92 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.ref.model;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.persistence.Column;
-import javax.persistence.Embedded;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToMany;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "T_STORE")
-public class Store {
-
-  public Store() {}
-
-  public Store(final String storeName, final Address storeAddress) {
-    super();
-    this.storeName = storeName;
-    this.storeAddress = storeAddress;
-  }
-
-  @Id
-  @Column(name = "STORE_ID")
-  private long storeId;
-
-  @Column(name = "STORE_NAME", unique = true)
-  private String storeName;
-
-  @Embedded
-  private Address storeAddress;
-
-  @ManyToMany(mappedBy = "stores")
-  private List<Material> materials = new ArrayList<Material>();
-
-  public long getStoreId() {
-    return storeId;
-  }
-
-  public void setStoreId(final long storeId) {
-    this.storeId = storeId;
-  }
-
-  public String getStoreName() {
-    return storeName;
-  }
-
-  public void setStoreName(final String storeName) {
-    this.storeName = storeName;
-  }
-
-  public Address getStoreAddress() {
-    return storeAddress;
-  }
-
-  public void setStoreAddress(final Address storeAddress) {
-    this.storeAddress = storeAddress;
-  }
-
-  public List<Material> getMaterials() {
-    return materials;
-  }
-
-  public void setMaterials(final List<Material> materials) {
-    this.materials = materials;
-    Iterator<Material> itr = materials.iterator();
-    while (itr.hasNext()) {
-      itr.next().getStores().add(this);
-    }
-  }
+/*******************************************************************************
+ * 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.odata2.jpa.processor.ref.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "T_STORE")
+public class Store {
+
+  public Store() {}
+
+  public Store(final String storeName, final Address storeAddress) {
+    super();
+    this.storeName = storeName;
+    this.storeAddress = storeAddress;
+  }
+
+  @Id
+  @Column(name = "STORE_ID")
+  private long storeId;
+
+  @Column(name = "STORE_NAME", unique = true)
+  private String storeName;
+
+  @Embedded
+  private Address storeAddress;
+
+  @ManyToMany(mappedBy = "stores")
+  private List<Material> materials = new ArrayList<Material>();
+
+  public long getStoreId() {
+    return storeId;
+  }
+
+  public void setStoreId(final long storeId) {
+    this.storeId = storeId;
+  }
+
+  public String getStoreName() {
+    return storeName;
+  }
+
+  public void setStoreName(final String storeName) {
+    this.storeName = storeName;
+  }
+
+  public Address getStoreAddress() {
+    return storeAddress;
+  }
+
+  public void setStoreAddress(final Address storeAddress) {
+    this.storeAddress = storeAddress;
+  }
+
+  public List<Material> getMaterials() {
+    return materials;
+  }
+
+  public void setMaterials(final List<Material> materials) {
+    this.materials = materials;
+    Iterator<Material> itr = materials.iterator();
+    while (itr.hasNext()) {
+      itr.next().getStores().add(this);
+    }
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/resources/META-INF/persistence.xml b/odata2-jpa-processor/jpa-ref/src/main/resources/META-INF/persistence.xml
index 5bbfcf4..023aee1 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/resources/META-INF/persistence.xml
+++ b/odata2-jpa-processor/jpa-ref/src/main/resources/META-INF/persistence.xml
@@ -1,44 +1,44 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
-	license agreements. See the NOTICE file distributed with this work for additional 
-	information regarding copyright ownership. The ASF licenses this file to 
-	you under the Apache License, Version 2.0 (the "License"); you may not use 
-	this file except in compliance with the License. You may obtain a copy of 
-	the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
-	by applicable law or agreed to in writing, software distributed under the 
-	License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
-	OF ANY KIND, either express or implied. See the License for the specific 
-	language governing permissions and limitations under the License. -->
-<persistence version="2.0"
-	xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
-	<persistence-unit name="salesorderprocessing"
-		transaction-type="RESOURCE_LOCAL">
-		<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
-		<class>org.apache.olingo.odata2.jpa.processor.ref.model.SalesOrderHeader</class>
-		<class>org.apache.olingo.odata2.jpa.processor.ref.model.SalesOrderItem</class>
-		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Note</class>
-		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Store</class>
-		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Customer</class>
-		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Category</class>
-		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Material</class>
-		<class>org.apache.olingo.odata2.jpa.processor.ref.model.AppointmentActivity</class>
-				<class>org.apache.olingo.odata2.jpa.processor.ref.model.Activity</class>
-		<class>org.apache.olingo.odata2.jpa.processor.ref.model.ActivityParty</class>
-		<class>org.apache.olingo.odata2.jpa.processor.ref.converter.BlobToByteConverter</class>
-		<properties>
-			<property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" />
-			<property name="javax.persistence.jdbc.url"
-				value="jdbc:hsqldb:mem:org.apache.olingo.jpa.sample" />
-			<property name="javax.persistence.jdbc.user" value="sa" />
-			<property name="javax.persistence.jdbc.password" value="" />
-			<property name="eclipselink.target-database"
-				value="org.eclipse.persistence.platform.database.HSQLPlatform" />
-			<property name="eclipselink.logging.level" value="ALL" />
-			<property name="eclipselink.orm.throw.exceptions" value="true" />
-			<property name="eclipselink.ddl-generation" value="create-tables" />
-			<property name="eclipselink.ddl-generation.output-mode"
-				value="database" />
-		</properties>
-	</persistence-unit>
-</persistence>
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+	license agreements. See the NOTICE file distributed with this work for additional 
+	information regarding copyright ownership. The ASF licenses this file to 
+	you under the Apache License, Version 2.0 (the "License"); you may not use 
+	this file except in compliance with the License. You may obtain a copy of 
+	the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
+	by applicable law or agreed to in writing, software distributed under the 
+	License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
+	OF ANY KIND, either express or implied. See the License for the specific 
+	language governing permissions and limitations under the License. -->
+<persistence version="2.0"
+	xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
+	<persistence-unit name="salesorderprocessing"
+		transaction-type="RESOURCE_LOCAL">
+		<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+		<class>org.apache.olingo.odata2.jpa.processor.ref.model.SalesOrderHeader</class>
+		<class>org.apache.olingo.odata2.jpa.processor.ref.model.SalesOrderItem</class>
+		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Note</class>
+		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Store</class>
+		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Customer</class>
+		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Category</class>
+		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Material</class>
+		<class>org.apache.olingo.odata2.jpa.processor.ref.model.AppointmentActivity</class>
+				<class>org.apache.olingo.odata2.jpa.processor.ref.model.Activity</class>
+		<class>org.apache.olingo.odata2.jpa.processor.ref.model.ActivityParty</class>
+		<class>org.apache.olingo.odata2.jpa.processor.ref.converter.BlobToByteConverter</class>
+		<properties>
+			<property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" />
+			<property name="javax.persistence.jdbc.url"
+				value="jdbc:hsqldb:mem:org.apache.olingo.jpa.sample" />
+			<property name="javax.persistence.jdbc.user" value="sa" />
+			<property name="javax.persistence.jdbc.password" value="" />
+			<property name="eclipselink.target-database"
+				value="org.eclipse.persistence.platform.database.HSQLPlatform" />
+			<property name="eclipselink.logging.level" value="ALL" />
+			<property name="eclipselink.orm.throw.exceptions" value="true" />
+			<property name="eclipselink.ddl-generation" value="create-tables" />
+			<property name="eclipselink.ddl-generation.output-mode"
+				value="database" />
+		</properties>
+	</persistence-unit>
+</persistence>


[16/19] git commit: Code cleaning and batch feet adjustments

Posted by ch...@apache.org.
Code cleaning and batch feet adjustments

Signed-off-by: Christian Amend <ch...@apache.org>


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

Branch: refs/heads/master
Commit: dbaa667b8a4f80444bf303d20d76b87a570da6a3
Parents: 1f76b21
Author: Christian Holzer <c....@sap.com>
Authored: Thu Oct 9 16:20:15 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Oct 9 16:45:27 2014 +0200

----------------------------------------------------------------------
 .../odata2/core/batch/v2/BatchBodyPart.java     |  2 +-
 .../odata2/core/batch/v2/BatchParser.java       | 11 ---
 .../odata2/core/batch/v2/BatchParserCommon.java | 22 ++---
 .../batch/v2/BatchRequestTransformator.java     |  4 +-
 .../v2/BufferedReaderIncludingLineEndings.java  | 19 +++--
 .../olingo/odata2/core/batch/v2/Header.java     | 18 ++--
 .../core/batch/BatchRequestParserTest.java      | 29 ++-----
 .../src/test/resources/batchLarge.batch         | 88 +-------------------
 8 files changed, 40 insertions(+), 153 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/dbaa667b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
index 288ca1c..d60c29a 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
@@ -112,7 +112,7 @@ public class BatchBodyPart implements BatchPart {
     return requestList;
   }
 
-  private void validateChangeSetBoundary(final String changeSetBoundary, Header header) throws BatchException {
+  private void validateChangeSetBoundary(final String changeSetBoundary, final Header header) throws BatchException {
     if (changeSetBoundary.equals(boundary)) {
       throw new BatchException(BatchException.INVALID_BOUNDARY.addContent(header.getHeaderField(
           HttpHeaders.CONTENT_TYPE).getLineNumber()));

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/dbaa667b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
index 76b5215..bf4ce93 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
@@ -89,17 +89,6 @@ public class BatchParser {
 
     return resultList;
   }
-  
-  //TODO remove
-//  private List<List<Line>> splitBodyParts(final InputStream in, final String boundary)
-//      throws IOException, BatchException {
-//
-//    final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
-//    final List<Line> message = reader.toList();
-//    reader.close();
-//
-//    return BatchParserCommon.splitMessageByBoundary(message, boundary);
-//  }
 
   private String getBaseUri() throws BatchException {
     String baseUri = "";

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/dbaa667b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
index 3592688..5c6cd69 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
@@ -92,22 +92,22 @@ public class BatchParserCommon {
 
     return new ByteArrayInputStream(message.getBytes());
   }
-  
+
   static List<List<Line>> splitRequestByBoundary(final InputStream in, final String boundary)
       throws BatchException, IOException {
     final List<List<Line>> messageParts = new LinkedList<List<Line>>();
     List<Line> currentPart = new ArrayList<Line>();
     boolean isEndReached = false;
-    //32ms
+
     final String quotedBoundary = Pattern.quote(boundary);
-    final Pattern boundaryDelimiterPattern = Pattern.compile("--" + quotedBoundary +  "--[\\s ]*");
+    final Pattern boundaryDelimiterPattern = Pattern.compile("--" + quotedBoundary + "--[\\s ]*");
     final Pattern boundaryPattern = Pattern.compile("--" + quotedBoundary + "[\\s ]*");
-    
+
     final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
     String currentLine;
     int lineNumber = 1;
-    
-    while((currentLine = reader.readLine()) != null) {
+
+    while ((currentLine = reader.readLine()) != null) {
       if (boundaryDelimiterPattern.matcher(currentLine.toString()).matches()) {
         removeEndingCRLFFromList(currentPart);
         messageParts.add(currentPart);
@@ -146,17 +146,17 @@ public class BatchParserCommon {
 
     return messageParts;
   }
-  
+
   static List<List<Line>> splitMessageByBoundary(final List<Line> message, final String boundary)
       throws BatchException {
     final List<List<Line>> messageParts = new LinkedList<List<Line>>();
     List<Line> currentPart = new ArrayList<Line>();
     boolean isEndReached = false;
-    
+
     final String quotedBoundary = Pattern.quote(boundary);
-    final Pattern boundaryDelimiterPattern = Pattern.compile("--" + quotedBoundary +  "--[\\s ]*");
+    final Pattern boundaryDelimiterPattern = Pattern.compile("--" + quotedBoundary + "--[\\s ]*");
     final Pattern boundaryPattern = Pattern.compile("--" + quotedBoundary + "[\\s ]*");
-    
+
     for (Line currentLine : message) {
       if (boundaryDelimiterPattern.matcher(currentLine.toString()).matches()) {
         removeEndingCRLFFromList(currentPart);
@@ -313,7 +313,7 @@ public class BatchParserCommon {
 
   public static PathInfo parseRequestUri(final Line httpStatusLine, final PathInfo batchRequestPathInfo,
       final String baseUri, final int line)
-      throws BatchException {
+          throws BatchException {
 
     final String odataPathSegmentsAsString;
     final String queryParametersAsString;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/dbaa667b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
index c7ffa88..4faac22 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
@@ -63,7 +63,7 @@ public class BatchRequestTransformator implements BatchTransformator {
     return resultList;
   }
 
-  private void validateHeader(final BatchPart bodyPart, boolean isChangeSet) throws BatchException {
+  private void validateHeader(final BatchPart bodyPart, final boolean isChangeSet) throws BatchException {
     Header headers = bodyPart.getHeaders();
 
     BatchTransformatorCommon.validateContentType(headers);
@@ -123,7 +123,7 @@ public class BatchRequestTransformator implements BatchTransformator {
         || (operation.getBody().size() == 1 && !operation.getBody().get(0).toString().trim().equals(""));
   }
 
-  private InputStream getBodyStream(final BatchQueryOperation operation, Header headers,
+  private InputStream getBodyStream(final BatchQueryOperation operation, final Header headers,
       final ODataHttpMethod httpMethod) throws BatchException {
 
     if (HTTP_BATCH_METHODS.contains(httpMethod.toString())) {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/dbaa667b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
index 7b81dc8..5c7fb7c 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
@@ -57,7 +57,8 @@ public class BufferedReaderIncludingLineEndings extends Reader {
     }
 
     // Check if buffer is filled. Return if EOF is reached
-    if (isBufferReloadRequired() || isEOF()) {
+    // Is buffer refill required
+    if (limit == offset || isEOF()) {
       fillBuffer();
 
       if (isEOF()) {
@@ -70,7 +71,8 @@ public class BufferedReaderIncludingLineEndings extends Reader {
     int currentOutputOffset = bufferOffset;
 
     while (bytesToRead != 0) {
-      if (isBufferReloadRequired()) {
+      // Is buffer refill required?
+      if (limit == offset) {
         fillBuffer();
 
         if (isEOF()) {
@@ -113,6 +115,7 @@ public class BufferedReaderIncludingLineEndings extends Reader {
     boolean foundLineEnd = false; // EOF will be considered as line ending
 
     while (!foundLineEnd) {
+     // Is buffer refill required?
       if (limit == offset) {
         if (fillBuffer() == EOF) {
           foundLineEnd = true;
@@ -129,6 +132,7 @@ public class BufferedReaderIncludingLineEndings extends Reader {
           foundLineEnd = true;
 
           // Check next char. Consume \n if available
+          // Is buffer refill required?
           if (limit == offset) {
             fillBuffer();
           }
@@ -152,7 +156,8 @@ public class BufferedReaderIncludingLineEndings extends Reader {
 
   @Override
   public boolean ready() throws IOException {
-    return !isEOF() && !isBufferReloadRequired();
+    // Not EOF and buffer refill is not required
+    return !isEOF() && !(limit == offset);
   }
 
   @Override
@@ -181,8 +186,8 @@ public class BufferedReaderIncludingLineEndings extends Reader {
       long charactersSkiped = 0;
 
       while (charactersToSkip != 0) {
-        // Check if buffer is empty
-        if (isBufferReloadRequired()) {
+        // Is buffer refill required?
+        if (limit == offset) {
           fillBuffer();
 
           if (isEOF()) {
@@ -204,10 +209,6 @@ public class BufferedReaderIncludingLineEndings extends Reader {
     }
   }
 
-  private boolean isBufferReloadRequired() {
-    return limit == offset;
-  }
-
   private boolean isEOF() {
     return limit == EOF;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/dbaa667b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
index 6c90e02..d2e26da 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
@@ -11,11 +11,11 @@ public class Header implements Cloneable {
 
   private final Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
   private int lineNumber;
-  
-  public Header(int lineNumer) {
-    this.lineNumber = lineNumer;
+
+  public Header(final int lineNumer) {
+    lineNumber = lineNumer;
   }
-  
+
   public void addHeader(final String name, final String value, final int lineNumber) {
     final HeaderField headerField = getHeaderFieldOrDefault(name, lineNumber);
     final List<String> headerValues = headerField.getValues();
@@ -50,13 +50,13 @@ public class Header implements Cloneable {
 
   public String getHeader(final String name) {
     final HeaderField headerField = getHeaderField(name);
-    
+
     return (headerField == null) ? null : headerField.getValue();
   }
 
   public String getHeaderNotNull(final String name) {
     final HeaderField headerField = getHeaderField(name);
-    
+
     return (headerField == null) ? "" : headerField.getValueNotNull();
   }
 
@@ -69,11 +69,11 @@ public class Header implements Cloneable {
   public HeaderField getHeaderField(final String name) {
     return headers.get(name.toLowerCase(Locale.ENGLISH));
   }
-  
+
   public int getLineNumber() {
     return lineNumber;
   }
-  
+
   public Map<String, String> toSingleMap() {
     final Map<String, String> singleMap = new HashMap<String, String>();
 
@@ -87,7 +87,7 @@ public class Header implements Cloneable {
 
   public Map<String, List<String>> toMultiMap() {
     final Map<String, List<String>> singleMap = new HashMap<String, List<String>>();
-    
+
     for (final String key : headers.keySet()) {
       HeaderField field = headers.get(key);
       singleMap.put(field.getFieldName(), field.getValues());

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/dbaa667b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
index f9287b5..52550fb 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
@@ -29,7 +29,6 @@ import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.List;
-import java.util.Random;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
 import org.apache.olingo.odata2.api.batch.BatchRequestPart;
@@ -1075,29 +1074,13 @@ public class BatchRequestParserTest {
 
   @Test
   public void testLargeBatch() throws BatchException, IOException {
-    for (int j = 0; j < 200; j++) {
-      String fileName = "/batchLarge.batch";
-      InputStream in = ClassLoader.class.getResourceAsStream(fileName);
-      if (in == null) {
-        throw new IOException("Requested file '" + fileName + "' was not found.");
-      }
-
-      StringBuilder builder = new StringBuilder();
-      Random rnd = new Random();
-      for (int i = 0; i < 300; i++) {
-        builder.append((char) ('A' + rnd.nextInt('Z' - 'A')));
-      }
-
-      // String request = builder.toString() + CRLF + inputStreamToString(in);
-      String request = inputStreamToString(in).replace("Walldorf", builder.toString());
-      in.close();
-      InputStream requestStream = new ByteArrayInputStream(request.getBytes());
-
-      long start = System.currentTimeMillis();
-      BatchParser parser = new BatchParser(contentType, batchProperties, true);
-      parser.parseBatchRequest(requestStream);
-      System.out.println(System.currentTimeMillis() - start);
+    String fileName = "/batchLarge.batch";
+    InputStream in = ClassLoader.class.getResourceAsStream(fileName);
+    if (in == null) {
+      throw new IOException("Requested file '" + fileName + "' was not found.");
     }
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    parser.parseBatchRequest(in);
   }
 
   private List<BatchRequestPart> parse(final String batch) throws BatchException {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/dbaa667b/odata2-lib/odata-core/src/test/resources/batchLarge.batch
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/batchLarge.batch b/odata2-lib/odata-core/src/test/resources/batchLarge.batch
index 3be0982..6d0fc6e 100644
--- a/odata2-lib/odata-core/src/test/resources/batchLarge.batch
+++ b/odata2-lib/odata-core/src/test/resources/batchLarge.batch
@@ -5,17 +5,13 @@ Content-Transfer-Encoding: binary
 GET Employees HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
 Accept: application/atom+xml
 MaxDataServiceVersion: 2.0
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
 DataServiceVersion: 2.0
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept-Encoding: gzip,deflate
 Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
 
-
 --batch_8194-cf13-1f56
 Content-Type: application/http
 Content-Transfer-Encoding: binary
@@ -23,17 +19,13 @@ Content-Transfer-Encoding: binary
 GET Employees HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
 Accept: application/atom+xml
 MaxDataServiceVersion: 2.0
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
 DataServiceVersion: 2.0
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept-Encoding: gzip,deflate
 Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
 
-
 --batch_8194-cf13-1f56
 Content-Type: application/http
 Content-Transfer-Encoding: binary
@@ -41,17 +33,13 @@ Content-Transfer-Encoding: binary
 GET Employees HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
 Accept: application/atom+xml
 MaxDataServiceVersion: 2.0
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
 DataServiceVersion: 2.0
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept-Encoding: gzip,deflate
 Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
 
-
 --batch_8194-cf13-1f56
 Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd
 
@@ -63,11 +51,6 @@ Content-ID: 1
 POST Employees HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -283,11 +266,6 @@ Content-ID: 1
 POST Employees HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -503,11 +481,7 @@ Content-ID: 1
 PUT Employees('1') HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -553,11 +527,6 @@ Content-ID: 1
 POST Employees HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -773,11 +742,6 @@ Content-ID: 1
 POST Employees HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -993,11 +957,6 @@ Content-ID: 1
 PUT Employees('1') HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -1043,11 +1002,6 @@ Content-ID: 1
 POST Employees HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -1263,11 +1217,6 @@ Content-ID: 1
 POST Employees HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -1483,11 +1432,6 @@ Content-ID: 1
 PUT Employees('1') HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -1533,11 +1477,6 @@ Content-ID: 1
 POST Employees HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -1753,11 +1692,6 @@ Content-ID: 1
 POST Employees HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -1973,11 +1907,6 @@ Content-ID: 1
 PUT Employees('1') HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -2023,11 +1952,6 @@ Content-ID: 1
 POST Employees HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -2243,11 +2167,6 @@ Content-ID: 1
 POST Employees HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate
@@ -2463,11 +2382,6 @@ Content-ID: 1
 PUT Employees('1') HTTP/1.1
 Host: http://localhost/odata
 Connection: keep-alive
-Content-Length: 1117
-Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
-Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
-X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
-User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
 Content-Type: application/atom+xml
 Accept: */*
 Accept-Encoding: gzip,deflate


[19/19] git commit: [OLINGO-436] License Header added

Posted by ch...@apache.org.
[OLINGO-436] License Header added


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

Branch: refs/heads/master
Commit: e7e44471cc460571fcc6efe3b4ebce13609da2fe
Parents: d82220e
Author: Christian Amend <ch...@apache.org>
Authored: Thu Oct 9 17:05:10 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Oct 9 17:05:10 2014 +0200

----------------------------------------------------------------------
 .../odata2/api/batch/BatchParserResult.java       | 18 ++++++++++++++++++
 .../core/batch/v2/BatchTransformatorCommon.java   | 18 ++++++++++++++++++
 .../olingo/odata2/core/batch/v2/Header.java       | 18 ++++++++++++++++++
 .../odata2/core/batch/BatchParserCommonTest.java  | 18 ++++++++++++++++++
 .../core/batch/BatchTransformatorCommonTest.java  | 18 ++++++++++++++++++
 .../BufferedReaderIncludingLineEndingsTest.java   | 18 ++++++++++++++++++
 .../olingo/odata2/core/batch/HeaderTest.java      | 18 ++++++++++++++++++
 7 files changed, 126 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/e7e44471/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java
index e11b69e..1e2054f 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java
@@ -1,3 +1,21 @@
+/*******************************************************************************
+ * 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.odata2.api.batch;
 
 public interface BatchParserResult {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/e7e44471/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
index 498dd2d..521b4e1 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
@@ -1,3 +1,21 @@
+/*******************************************************************************
+ * 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.odata2.core.batch.v2;
 
 import java.util.List;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/e7e44471/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
index d2e26da..ba44b25 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
@@ -1,3 +1,21 @@
+/*******************************************************************************
+ * 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.odata2.core.batch.v2;
 
 import java.util.ArrayList;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/e7e44471/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
index 4369c1e..89eb14a 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
@@ -1,3 +1,21 @@
+/*******************************************************************************
+ * 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.odata2.core.batch;
 
 import static org.junit.Assert.*;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/e7e44471/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
index 7437caf..3e18304 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
@@ -1,3 +1,21 @@
+/*******************************************************************************
+ * 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.odata2.core.batch;
 
 import java.util.Arrays;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/e7e44471/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
index 482dc3b..1161530 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
@@ -1,3 +1,21 @@
+/*******************************************************************************
+ * 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.odata2.core.batch;
 
 import static org.junit.Assert.*;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/e7e44471/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java
index bfe7b24..9561567 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java
@@ -1,3 +1,21 @@
+/*******************************************************************************
+ * 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.odata2.core.batch;
 
 import static org.junit.Assert.*;


[11/19] line ending issue again

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtilV2.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtilV2.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtilV2.java
index 095d7e1..fbe6206 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtilV2.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtilV2.java
@@ -1,403 +1,403 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.mock.data;
-
-import java.sql.Blob;
-import java.sql.Clob;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.UUID;
-
-import org.apache.olingo.odata2.api.edm.EdmAssociation;
-import org.apache.olingo.odata2.api.edm.EdmAssociationEnd;
-import org.apache.olingo.odata2.api.edm.EdmComplexType;
-import org.apache.olingo.odata2.api.edm.EdmEntityContainer;
-import org.apache.olingo.odata2.api.edm.EdmEntitySet;
-import org.apache.olingo.odata2.api.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmMapping;
-import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
-import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
-import org.apache.olingo.odata2.api.edm.EdmProperty;
-import org.apache.olingo.odata2.api.edm.EdmSimpleType;
-import org.apache.olingo.odata2.api.edm.EdmTypeKind;
-import org.apache.olingo.odata2.api.edm.provider.Mapping;
-import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPARelatedTypeMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPATypeEmbeddableMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPATypeEmbeddableMock2;
-import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl;
-import org.easymock.EasyMock;
-
-public class EdmMockUtilV2 {
-
-  public static interface JPAEdmMappingMock extends JPAEdmMapping, EdmMapping {
-
-  }
-
-  public static EdmEntityContainer mockEdmEntityContainer(final String entityName) throws EdmException {
-    EdmEntityContainer entityContainer = EasyMock.createMock(EdmEntityContainer.class);
-    entityContainer = EasyMock.createMock(EdmEntityContainer.class);
-    EasyMock.expect(entityContainer.getEntitySet(JPATypeMock.ENTITY_NAME)).andReturn(
-        mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false));
-    EasyMock.expect(entityContainer.getFunctionImport(JPATypeMock.ENTITY_NAME)).andReturn(null);
-    EasyMock.expect(entityContainer.getEntitySet("JPATypeMockInvalid")).andReturn(null);
-    EasyMock.expect(entityContainer.getFunctionImport("JPATypeMockInvalid")).andReturn(null);
-    EasyMock.replay(entityContainer);
-
-    return entityContainer;
-  }
-
-  public static EdmEntityType mockEdmEntityType(final String entityName, final boolean withComplexType)
-      throws EdmException {
-
-    EdmEntityType entityType = EasyMock.createMock(EdmEntityType.class);
-    EasyMock.expect(entityType.getName()).andReturn(entityName).anyTimes();
-    EasyMock.expect(entityType.getKeyPropertyNames()).andReturn(mockSimpleKeyPropertyNames(entityName));
-    if (withComplexType == false) {
-      EasyMock.expect(entityType.getPropertyNames()).andReturn(mockPropertyNames(entityName)).anyTimes();
-    } else {
-      EasyMock.expect(entityType.getPropertyNames()).andReturn(mockPropertyNamesWithComplexType(entityName)).anyTimes();
-    }
-
-    EasyMock.expect(entityType.getNavigationPropertyNames()).andReturn(mockNavigationPropertyNames(entityName))
-        .anyTimes();
-    EasyMock.expect(entityType.getKind()).andReturn(EdmTypeKind.ENTITY);
-    EasyMock.expect(entityType.getMapping()).andReturn((EdmMapping) mockEdmMapping(entityName, null, null));
-    EasyMock.expect(entityType.getKeyProperties()).andReturn(mockKeyProperties(entityName)).anyTimes();
-    if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
-      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MINT)).andReturn(
-          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MINT)).anyTimes();
-      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MSTRING)).andReturn(
-          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MSTRING)).anyTimes();
-      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MDATETIME)).andReturn(
-          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MDATETIME)).anyTimes();
-      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MBLOB)).andReturn(
-          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MBLOB)).anyTimes();
-      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_CLOB)).andReturn(
-          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_CLOB)).anyTimes();
-      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MC)).andReturn(
-          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MC)).anyTimes();
-      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MCARRAY)).andReturn(
-          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MCARRAY)).anyTimes();
-      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MCHAR)).andReturn(
-          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MCHAR)).anyTimes();
-      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MCHARARRAY)).andReturn(
-          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MCHARARRAY)).anyTimes();
-      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE)).andReturn(
-          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE)).anyTimes();
-      EasyMock.expect(entityType.getProperty(JPATypeMock.NAVIGATION_PROPERTY_X)).andReturn(
-          mockEdmNavigationProperty(JPATypeMock.NAVIGATION_PROPERTY_X, EdmMultiplicity.ONE)).anyTimes();
-    } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
-      EasyMock.expect(entityType.getProperty(JPARelatedTypeMock.PROPERTY_NAME_MLONG)).andReturn(
-          mockEdmProperty(entityName, JPARelatedTypeMock.PROPERTY_NAME_MLONG)).anyTimes();
-      EasyMock.expect(entityType.getProperty(JPARelatedTypeMock.PROPERTY_NAME_MBYTE)).andReturn(
-          mockEdmProperty(entityName, JPARelatedTypeMock.PROPERTY_NAME_MBYTE)).anyTimes();
-      EasyMock.expect(entityType.getProperty(JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY)).andReturn(
-          mockEdmProperty(entityName, JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY)).anyTimes();
-      EasyMock.expect(entityType.getProperty(JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE)).andReturn(
-          mockEdmProperty(entityName, JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE)).anyTimes();
-    }
-    EasyMock.replay(entityType);
-    return entityType;
-  }
-
-  public static List<EdmProperty> mockKeyProperties(final String entityName) throws EdmException {
-    List<EdmProperty> edmProperties = new ArrayList<EdmProperty>();
-    edmProperties.add(mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MINT));
-
-    return edmProperties;
-  }
-
-  public static List<String> mockNavigationPropertyNames(final String entityName) {
-    List<String> propertyNames = new ArrayList<String>();
-    propertyNames.add(JPATypeMock.NAVIGATION_PROPERTY_X);
-    propertyNames.add(JPATypeMock.NAVIGATION_PROPERTY_XS);
-    return propertyNames;
-  }
-
-  public static List<String> mockSimpleKeyPropertyNames(final String entityName) {
-    List<String> keyPropertyNames = new ArrayList<String>();
-    if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
-      keyPropertyNames.add(JPATypeMock.PROPERTY_NAME_MINT);
-    } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
-      keyPropertyNames.add(JPARelatedTypeMock.PROPERTY_NAME_MLONG);
-    }
-
-    return keyPropertyNames;
-  }
-
-  public static List<String> mockPropertyNames(final String entityName) {
-    List<String> propertyNames = new ArrayList<String>();
-
-    if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
-      propertyNames.add(JPATypeMock.PROPERTY_NAME_MINT);
-      propertyNames.add(JPATypeMock.PROPERTY_NAME_MDATETIME);
-      propertyNames.add(JPATypeMock.PROPERTY_NAME_MSTRING);
-      propertyNames.add(JPATypeMock.PROPERTY_NAME_MBLOB);
-      propertyNames.add(JPATypeMock.PROPERTY_NAME_CLOB);
-      propertyNames.add(JPATypeMock.PROPERTY_NAME_MC);
-      propertyNames.add(JPATypeMock.PROPERTY_NAME_MCARRAY);
-      propertyNames.add(JPATypeMock.PROPERTY_NAME_MCHAR);
-      propertyNames.add(JPATypeMock.PROPERTY_NAME_MCHARARRAY);
-    } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
-      propertyNames.add(JPARelatedTypeMock.PROPERTY_NAME_MLONG);
-      propertyNames.add(JPARelatedTypeMock.PROPERTY_NAME_MBYTE);
-      propertyNames.add(JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY);
-      propertyNames.add(JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE);
-    } else if (entityName.equals(JPATypeEmbeddableMock.ENTITY_NAME)) {
-      propertyNames.add(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT);
-      propertyNames.add(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE);
-    } else if (entityName.equals(JPATypeEmbeddableMock2.ENTITY_NAME)) {
-      propertyNames.add(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT);
-      propertyNames.add(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID);
-    }
-
-    return propertyNames;
-  }
-
-  public static List<String> mockPropertyNamesWithComplexType(final String entityName) {
-    List<String> propertyNames = mockPropertyNames(entityName);
-    propertyNames.add(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE);
-
-    return propertyNames;
-
-  }
-
-  public static EdmAssociationEnd mockEdmAssociatioEnd(final String navigationPropertyName, final String role)
-      throws EdmException {
-    EdmAssociationEnd associationEnd = EasyMock.createMock(EdmAssociationEnd.class);
-    EasyMock.expect(associationEnd.getMultiplicity()).andReturn(EdmMultiplicity.ONE);
-    EdmEntityType entityType = EasyMock.createMock(EdmEntityType.class);
-    EasyMock.expect(entityType.getMapping()).andReturn((EdmMapping) mockEdmMapping("JPARelatedTypeMock", null, null));
-    EasyMock.replay(entityType);
-
-    EasyMock.expect(associationEnd.getEntityType()).andReturn(entityType);
-    EasyMock.replay(associationEnd);
-    return associationEnd;
-  }
-
-  public static EdmAssociation mockEdmAssociation(final String navigationPropertyName) throws EdmException {
-    EdmAssociation edmAssociation = EasyMock.createMock(EdmAssociation.class);
-    EasyMock.expect(edmAssociation.getEnd("TO")).andReturn(mockEdmAssociatioEnd(navigationPropertyName, "TO"));
-    EasyMock.expect(edmAssociation.getEnd("FROM")).andReturn(mockEdmAssociatioEnd(navigationPropertyName, "FROM"));
-    EasyMock.replay(edmAssociation);
-    return edmAssociation;
-  }
-
-  public static EdmEntitySet mockEdmEntitySet(final String entityName, final boolean withComplexType)
-      throws EdmException {
-    EdmEntitySet entitySet = null;
-    if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
-      entitySet = EasyMock.createMock(EdmEntitySet.class);
-      EasyMock.expect(entitySet.getEntityType()).andReturn(mockEdmEntityType(entityName, withComplexType)).anyTimes();
-      EasyMock.expect(entitySet.getRelatedEntitySet(EasyMock.isA(EdmNavigationProperty.class))).andReturn(
-          mockEdmEntitySet(JPARelatedTypeMock.ENTITY_NAME, false)).anyTimes();
-    } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
-      entitySet = EasyMock.createMock(EdmEntitySet.class);
-      EasyMock.expect(entitySet.getEntityType()).andReturn(mockEdmEntityType(entityName, withComplexType)).anyTimes();
-    }
-
-    EasyMock.replay(entitySet);
-    return entitySet;
-  }
-
-  public static EdmNavigationProperty mockEdmNavigationProperty(final String navigationPropertyName,
-      final EdmMultiplicity multiplicity) throws EdmException {
-
-    EdmEntityType edmEntityType = mockEdmEntityType(JPARelatedTypeMock.ENTITY_NAME, false);
-
-    EdmNavigationProperty navigationProperty = EasyMock.createMock(EdmNavigationProperty.class);
-    EasyMock.expect(navigationProperty.getType()).andReturn(edmEntityType).anyTimes();
-    EasyMock.expect(navigationProperty.getMultiplicity()).andReturn(multiplicity);
-    EasyMock.expect(navigationProperty.getMapping()).andReturn(
-        (EdmMapping) mockEdmMapping(null, null, navigationPropertyName)).anyTimes();
-    EasyMock.expect(navigationProperty.getToRole()).andReturn("TO");
-    EasyMock.expect(navigationProperty.getRelationship()).andReturn(mockEdmAssociation(navigationPropertyName));
-    if (multiplicity.equals(EdmMultiplicity.ONE)) {
-      EasyMock.expect(navigationProperty.getName()).andReturn(JPATypeMock.NAVIGATION_PROPERTY_X).anyTimes();
-    }
-
-    EasyMock.replay(navigationProperty);
-
-    return navigationProperty;
-  }
-
-  public static EdmProperty mockEdmProperty(final String entityName, final String propertyName) throws EdmException {
-    EdmProperty edmProperty = EasyMock.createMock(EdmProperty.class);
-
-    if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MINT) ||
-        propertyName.equals(JPATypeMock.PROPERTY_NAME_MSTRING) ||
-        propertyName.equals(JPATypeMock.PROPERTY_NAME_MDATETIME) ||
-        propertyName.equals(JPATypeMock.PROPERTY_NAME_MBLOB) ||
-        propertyName.equals(JPATypeMock.PROPERTY_NAME_CLOB) ||
-        propertyName.equals(JPATypeMock.PROPERTY_NAME_MCARRAY) ||
-        propertyName.equals(JPATypeMock.PROPERTY_NAME_MC) ||
-        propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHAR) ||
-        propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHARARRAY) ||
-        propertyName.equals(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT) ||
-        propertyName.equals(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT) ||
-        propertyName.equals(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID) ||
-        propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MLONG) ||
-        propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MBYTE) ||
-        propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE) ||
-        propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY)) {
-
-      EdmSimpleType edmType = EasyMock.createMock(EdmSimpleType.class);
-      EasyMock.expect(edmProperty.getType()).andReturn(edmType).anyTimes();
-      EasyMock.expect(edmType.getKind()).andReturn(EdmTypeKind.SIMPLE).anyTimes();
-      if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MSTRING) ||
-          propertyName.equals(JPATypeMock.PROPERTY_NAME_MCARRAY) ||
-          propertyName.equals(JPATypeMock.PROPERTY_NAME_MC) ||
-          propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHAR) ||
-          propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHARARRAY)) {
-        EasyMock.<Class<?>> expect(edmType.getDefaultType()).andReturn(String.class).anyTimes();
-      } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MBLOB)) {
-        EasyMock.<Class<?>> expect(edmType.getDefaultType()).andReturn(Blob.class).anyTimes();
-      } else {
-        EasyMock.<Class<?>> expect(edmType.getDefaultType()).andReturn(Integer.class).anyTimes();
-      }
-
-      EasyMock.expect(edmType.isCompatible(EasyMock.isA(EdmSimpleType.class))).andReturn(true).anyTimes();
-      EasyMock.replay(edmType);
-      EasyMock.expect(edmProperty.getName()).andReturn(propertyName).anyTimes();
-      EasyMock.expect(edmProperty.getMapping()).andReturn((EdmMapping) mockEdmMapping(entityName, propertyName, null))
-          .anyTimes();
-
-    } else if (propertyName.equals(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE) ||
-        propertyName.equals(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE)) {
-      EdmComplexType complexType = mockComplexType(propertyName);
-
-      EasyMock.expect(edmProperty.getType()).andReturn(complexType).anyTimes();
-      EasyMock.expect(edmProperty.getName()).andReturn(propertyName).anyTimes();
-      EasyMock.expect(edmProperty.getMapping()).andReturn((EdmMapping) mockEdmMapping(null, propertyName, null))
-          .anyTimes();
-
-    }
-
-    EasyMock.replay(edmProperty);
-    return edmProperty;
-  }
-
-  public static EdmComplexType mockComplexType(final String complexPropertyName) throws EdmException {
-
-    String complexTypeName = null;
-    if (complexPropertyName.equals(JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE)) {
-      complexTypeName = JPATypeEmbeddableMock2.ENTITY_NAME;
-    } else if (complexPropertyName.equals(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE)) {
-      complexTypeName = JPATypeEmbeddableMock.ENTITY_NAME;
-    }
-
-    EdmComplexType edmComplexType = EasyMock.createMock(EdmComplexType.class);
-    EasyMock.expect(edmComplexType.getKind()).andReturn(EdmTypeKind.COMPLEX);
-    EasyMock.expect(edmComplexType.getPropertyNames()).andReturn(mockPropertyNames(complexTypeName)).anyTimes();
-    EasyMock.expect(edmComplexType.getMapping()).andReturn((EdmMapping) mockEdmMapping(complexTypeName, null, null));
-
-    if (complexTypeName.equals(JPATypeEmbeddableMock.ENTITY_NAME)) {
-      EasyMock.expect(edmComplexType.getProperty(JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT)).andReturn(
-          mockEdmProperty(complexTypeName, JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT)).anyTimes();
-      EasyMock.expect(edmComplexType.getProperty(JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE)).andReturn(
-          mockEdmProperty(complexTypeName, JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE)).anyTimes();
-    } else if (complexTypeName.equals(JPATypeEmbeddableMock2.ENTITY_NAME)) {
-      EasyMock.expect(edmComplexType.getProperty(JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT)).andReturn(
-          mockEdmProperty(complexTypeName, JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT)).anyTimes();
-      EasyMock.expect(edmComplexType.getProperty(JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID)).andReturn(
-          mockEdmProperty(complexTypeName, JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID)).anyTimes();
-    }
-
-    EasyMock.replay(edmComplexType);
-    return edmComplexType;
-  }
-
-  public static JPAEdmMapping mockEdmMapping(final String entityName, final String propertyName,
-      final String navigationPropertyName) {
-    JPAEdmMapping mapping = new JPAEdmMappingImpl();
-
-    if (propertyName == null && entityName != null) {
-      if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
-        mapping.setJPAType(JPATypeMock.class);
-      } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
-        mapping.setJPAType(JPARelatedTypeMock.class);
-      } else if (entityName.equals(JPATypeEmbeddableMock.ENTITY_NAME)) {
-        mapping.setJPAType(JPATypeEmbeddableMock.class);
-      } else if (entityName.equals(JPATypeEmbeddableMock2.ENTITY_NAME)) {
-        mapping.setJPAType(JPATypeEmbeddableMock2.class);
-      }
-    } else if (entityName == null && navigationPropertyName != null) {
-      mapping.setJPAType(JPARelatedTypeMock.class);
-      mapping.setJPAColumnName(JPATypeMock.NAVIGATION_PROPERTY_X);
-    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MINT)) {
-      mapping.setJPAType(int.class);
-      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MINT);
-    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MSTRING)) {
-      mapping.setJPAType(String.class);
-      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MSTRING);
-    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MBLOB)) {
-      mapping.setJPAType(Blob.class);
-      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MBLOB);
-    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_CLOB)) {
-      mapping.setJPAType(Clob.class);
-      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_CLOB);
-    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MC)) {
-      mapping.setJPAType(char.class);
-      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MC);
-    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MCARRAY)) {
-      mapping.setJPAType(char[].class);
-      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MCARRAY);
-    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHAR)) {
-      mapping.setJPAType(Character.class);
-      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MCHAR);
-    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHARARRAY)) {
-      mapping.setJPAType(Character[].class);
-      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MCHARARRAY);
-    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MDATETIME)) {
-      mapping.setJPAType(Calendar.class);
-      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MDATETIME);
-    } else if (propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MLONG)) {
-      mapping.setJPAType(long.class);
-      ((Mapping) mapping).setInternalName(JPARelatedTypeMock.PROPERTY_NAME_MLONG);
-    } else if (propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE)) {
-      mapping.setJPAType(double.class);
-      ((Mapping) mapping).setInternalName(JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE);
-    } else if (propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MBYTE)) {
-      mapping.setJPAType(byte.class);
-      ((Mapping) mapping).setInternalName(JPARelatedTypeMock.PROPERTY_NAME_MBYTE);
-    } else if (propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY)) {
-      mapping.setJPAType(byte[].class);
-      ((Mapping) mapping).setInternalName(JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY);
-    } else if (propertyName.equals(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT)) {
-      mapping.setJPAType(Short.TYPE);
-      ((Mapping) mapping).setInternalName(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT);
-    } else if (propertyName.equals(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT)) {
-      mapping.setJPAType(Float.TYPE);
-      ((Mapping) mapping).setInternalName(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT);
-    } else if (propertyName.equals(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID)) {
-      mapping.setJPAType(UUID.class);
-      ((Mapping) mapping).setInternalName(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID);
-    } else if (propertyName.equals(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE)) {
-      mapping.setJPAType(JPATypeEmbeddableMock2.class);
-      ((Mapping) mapping).setInternalName(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE);
-    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE)) {
-      mapping.setJPAType(JPATypeEmbeddableMock.class);
-      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE);
-    }
-    return mapping;
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.mock.data;
+
+import java.sql.Blob;
+import java.sql.Clob;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.olingo.odata2.api.edm.EdmAssociation;
+import org.apache.olingo.odata2.api.edm.EdmAssociationEnd;
+import org.apache.olingo.odata2.api.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.edm.EdmEntityContainer;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.edm.provider.Mapping;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPARelatedTypeMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPATypeEmbeddableMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPATypeEmbeddableMock2;
+import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl;
+import org.easymock.EasyMock;
+
+public class EdmMockUtilV2 {
+
+  public static interface JPAEdmMappingMock extends JPAEdmMapping, EdmMapping {
+
+  }
+
+  public static EdmEntityContainer mockEdmEntityContainer(final String entityName) throws EdmException {
+    EdmEntityContainer entityContainer = EasyMock.createMock(EdmEntityContainer.class);
+    entityContainer = EasyMock.createMock(EdmEntityContainer.class);
+    EasyMock.expect(entityContainer.getEntitySet(JPATypeMock.ENTITY_NAME)).andReturn(
+        mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false));
+    EasyMock.expect(entityContainer.getFunctionImport(JPATypeMock.ENTITY_NAME)).andReturn(null);
+    EasyMock.expect(entityContainer.getEntitySet("JPATypeMockInvalid")).andReturn(null);
+    EasyMock.expect(entityContainer.getFunctionImport("JPATypeMockInvalid")).andReturn(null);
+    EasyMock.replay(entityContainer);
+
+    return entityContainer;
+  }
+
+  public static EdmEntityType mockEdmEntityType(final String entityName, final boolean withComplexType)
+      throws EdmException {
+
+    EdmEntityType entityType = EasyMock.createMock(EdmEntityType.class);
+    EasyMock.expect(entityType.getName()).andReturn(entityName).anyTimes();
+    EasyMock.expect(entityType.getKeyPropertyNames()).andReturn(mockSimpleKeyPropertyNames(entityName));
+    if (withComplexType == false) {
+      EasyMock.expect(entityType.getPropertyNames()).andReturn(mockPropertyNames(entityName)).anyTimes();
+    } else {
+      EasyMock.expect(entityType.getPropertyNames()).andReturn(mockPropertyNamesWithComplexType(entityName)).anyTimes();
+    }
+
+    EasyMock.expect(entityType.getNavigationPropertyNames()).andReturn(mockNavigationPropertyNames(entityName))
+        .anyTimes();
+    EasyMock.expect(entityType.getKind()).andReturn(EdmTypeKind.ENTITY);
+    EasyMock.expect(entityType.getMapping()).andReturn((EdmMapping) mockEdmMapping(entityName, null, null));
+    EasyMock.expect(entityType.getKeyProperties()).andReturn(mockKeyProperties(entityName)).anyTimes();
+    if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MINT)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MINT)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MSTRING)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MSTRING)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MDATETIME)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MDATETIME)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MBLOB)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MBLOB)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_CLOB)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_CLOB)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MC)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MC)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MCARRAY)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MCARRAY)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MCHAR)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MCHAR)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MCHARARRAY)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MCHARARRAY)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.NAVIGATION_PROPERTY_X)).andReturn(
+          mockEdmNavigationProperty(JPATypeMock.NAVIGATION_PROPERTY_X, EdmMultiplicity.ONE)).anyTimes();
+    } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
+      EasyMock.expect(entityType.getProperty(JPARelatedTypeMock.PROPERTY_NAME_MLONG)).andReturn(
+          mockEdmProperty(entityName, JPARelatedTypeMock.PROPERTY_NAME_MLONG)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPARelatedTypeMock.PROPERTY_NAME_MBYTE)).andReturn(
+          mockEdmProperty(entityName, JPARelatedTypeMock.PROPERTY_NAME_MBYTE)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY)).andReturn(
+          mockEdmProperty(entityName, JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE)).andReturn(
+          mockEdmProperty(entityName, JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE)).anyTimes();
+    }
+    EasyMock.replay(entityType);
+    return entityType;
+  }
+
+  public static List<EdmProperty> mockKeyProperties(final String entityName) throws EdmException {
+    List<EdmProperty> edmProperties = new ArrayList<EdmProperty>();
+    edmProperties.add(mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MINT));
+
+    return edmProperties;
+  }
+
+  public static List<String> mockNavigationPropertyNames(final String entityName) {
+    List<String> propertyNames = new ArrayList<String>();
+    propertyNames.add(JPATypeMock.NAVIGATION_PROPERTY_X);
+    propertyNames.add(JPATypeMock.NAVIGATION_PROPERTY_XS);
+    return propertyNames;
+  }
+
+  public static List<String> mockSimpleKeyPropertyNames(final String entityName) {
+    List<String> keyPropertyNames = new ArrayList<String>();
+    if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
+      keyPropertyNames.add(JPATypeMock.PROPERTY_NAME_MINT);
+    } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
+      keyPropertyNames.add(JPARelatedTypeMock.PROPERTY_NAME_MLONG);
+    }
+
+    return keyPropertyNames;
+  }
+
+  public static List<String> mockPropertyNames(final String entityName) {
+    List<String> propertyNames = new ArrayList<String>();
+
+    if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_MINT);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_MDATETIME);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_MSTRING);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_MBLOB);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_CLOB);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_MC);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_MCARRAY);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_MCHAR);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_MCHARARRAY);
+    } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
+      propertyNames.add(JPARelatedTypeMock.PROPERTY_NAME_MLONG);
+      propertyNames.add(JPARelatedTypeMock.PROPERTY_NAME_MBYTE);
+      propertyNames.add(JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY);
+      propertyNames.add(JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE);
+    } else if (entityName.equals(JPATypeEmbeddableMock.ENTITY_NAME)) {
+      propertyNames.add(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT);
+      propertyNames.add(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE);
+    } else if (entityName.equals(JPATypeEmbeddableMock2.ENTITY_NAME)) {
+      propertyNames.add(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT);
+      propertyNames.add(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID);
+    }
+
+    return propertyNames;
+  }
+
+  public static List<String> mockPropertyNamesWithComplexType(final String entityName) {
+    List<String> propertyNames = mockPropertyNames(entityName);
+    propertyNames.add(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE);
+
+    return propertyNames;
+
+  }
+
+  public static EdmAssociationEnd mockEdmAssociatioEnd(final String navigationPropertyName, final String role)
+      throws EdmException {
+    EdmAssociationEnd associationEnd = EasyMock.createMock(EdmAssociationEnd.class);
+    EasyMock.expect(associationEnd.getMultiplicity()).andReturn(EdmMultiplicity.ONE);
+    EdmEntityType entityType = EasyMock.createMock(EdmEntityType.class);
+    EasyMock.expect(entityType.getMapping()).andReturn((EdmMapping) mockEdmMapping("JPARelatedTypeMock", null, null));
+    EasyMock.replay(entityType);
+
+    EasyMock.expect(associationEnd.getEntityType()).andReturn(entityType);
+    EasyMock.replay(associationEnd);
+    return associationEnd;
+  }
+
+  public static EdmAssociation mockEdmAssociation(final String navigationPropertyName) throws EdmException {
+    EdmAssociation edmAssociation = EasyMock.createMock(EdmAssociation.class);
+    EasyMock.expect(edmAssociation.getEnd("TO")).andReturn(mockEdmAssociatioEnd(navigationPropertyName, "TO"));
+    EasyMock.expect(edmAssociation.getEnd("FROM")).andReturn(mockEdmAssociatioEnd(navigationPropertyName, "FROM"));
+    EasyMock.replay(edmAssociation);
+    return edmAssociation;
+  }
+
+  public static EdmEntitySet mockEdmEntitySet(final String entityName, final boolean withComplexType)
+      throws EdmException {
+    EdmEntitySet entitySet = null;
+    if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
+      entitySet = EasyMock.createMock(EdmEntitySet.class);
+      EasyMock.expect(entitySet.getEntityType()).andReturn(mockEdmEntityType(entityName, withComplexType)).anyTimes();
+      EasyMock.expect(entitySet.getRelatedEntitySet(EasyMock.isA(EdmNavigationProperty.class))).andReturn(
+          mockEdmEntitySet(JPARelatedTypeMock.ENTITY_NAME, false)).anyTimes();
+    } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
+      entitySet = EasyMock.createMock(EdmEntitySet.class);
+      EasyMock.expect(entitySet.getEntityType()).andReturn(mockEdmEntityType(entityName, withComplexType)).anyTimes();
+    }
+
+    EasyMock.replay(entitySet);
+    return entitySet;
+  }
+
+  public static EdmNavigationProperty mockEdmNavigationProperty(final String navigationPropertyName,
+      final EdmMultiplicity multiplicity) throws EdmException {
+
+    EdmEntityType edmEntityType = mockEdmEntityType(JPARelatedTypeMock.ENTITY_NAME, false);
+
+    EdmNavigationProperty navigationProperty = EasyMock.createMock(EdmNavigationProperty.class);
+    EasyMock.expect(navigationProperty.getType()).andReturn(edmEntityType).anyTimes();
+    EasyMock.expect(navigationProperty.getMultiplicity()).andReturn(multiplicity);
+    EasyMock.expect(navigationProperty.getMapping()).andReturn(
+        (EdmMapping) mockEdmMapping(null, null, navigationPropertyName)).anyTimes();
+    EasyMock.expect(navigationProperty.getToRole()).andReturn("TO");
+    EasyMock.expect(navigationProperty.getRelationship()).andReturn(mockEdmAssociation(navigationPropertyName));
+    if (multiplicity.equals(EdmMultiplicity.ONE)) {
+      EasyMock.expect(navigationProperty.getName()).andReturn(JPATypeMock.NAVIGATION_PROPERTY_X).anyTimes();
+    }
+
+    EasyMock.replay(navigationProperty);
+
+    return navigationProperty;
+  }
+
+  public static EdmProperty mockEdmProperty(final String entityName, final String propertyName) throws EdmException {
+    EdmProperty edmProperty = EasyMock.createMock(EdmProperty.class);
+
+    if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MINT) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_MSTRING) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_MDATETIME) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_MBLOB) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_CLOB) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_MCARRAY) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_MC) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHAR) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHARARRAY) ||
+        propertyName.equals(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT) ||
+        propertyName.equals(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT) ||
+        propertyName.equals(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID) ||
+        propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MLONG) ||
+        propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MBYTE) ||
+        propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE) ||
+        propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY)) {
+
+      EdmSimpleType edmType = EasyMock.createMock(EdmSimpleType.class);
+      EasyMock.expect(edmProperty.getType()).andReturn(edmType).anyTimes();
+      EasyMock.expect(edmType.getKind()).andReturn(EdmTypeKind.SIMPLE).anyTimes();
+      if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MSTRING) ||
+          propertyName.equals(JPATypeMock.PROPERTY_NAME_MCARRAY) ||
+          propertyName.equals(JPATypeMock.PROPERTY_NAME_MC) ||
+          propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHAR) ||
+          propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHARARRAY)) {
+        EasyMock.<Class<?>> expect(edmType.getDefaultType()).andReturn(String.class).anyTimes();
+      } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MBLOB)) {
+        EasyMock.<Class<?>> expect(edmType.getDefaultType()).andReturn(Blob.class).anyTimes();
+      } else {
+        EasyMock.<Class<?>> expect(edmType.getDefaultType()).andReturn(Integer.class).anyTimes();
+      }
+
+      EasyMock.expect(edmType.isCompatible(EasyMock.isA(EdmSimpleType.class))).andReturn(true).anyTimes();
+      EasyMock.replay(edmType);
+      EasyMock.expect(edmProperty.getName()).andReturn(propertyName).anyTimes();
+      EasyMock.expect(edmProperty.getMapping()).andReturn((EdmMapping) mockEdmMapping(entityName, propertyName, null))
+          .anyTimes();
+
+    } else if (propertyName.equals(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE)) {
+      EdmComplexType complexType = mockComplexType(propertyName);
+
+      EasyMock.expect(edmProperty.getType()).andReturn(complexType).anyTimes();
+      EasyMock.expect(edmProperty.getName()).andReturn(propertyName).anyTimes();
+      EasyMock.expect(edmProperty.getMapping()).andReturn((EdmMapping) mockEdmMapping(null, propertyName, null))
+          .anyTimes();
+
+    }
+
+    EasyMock.replay(edmProperty);
+    return edmProperty;
+  }
+
+  public static EdmComplexType mockComplexType(final String complexPropertyName) throws EdmException {
+
+    String complexTypeName = null;
+    if (complexPropertyName.equals(JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE)) {
+      complexTypeName = JPATypeEmbeddableMock2.ENTITY_NAME;
+    } else if (complexPropertyName.equals(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE)) {
+      complexTypeName = JPATypeEmbeddableMock.ENTITY_NAME;
+    }
+
+    EdmComplexType edmComplexType = EasyMock.createMock(EdmComplexType.class);
+    EasyMock.expect(edmComplexType.getKind()).andReturn(EdmTypeKind.COMPLEX);
+    EasyMock.expect(edmComplexType.getPropertyNames()).andReturn(mockPropertyNames(complexTypeName)).anyTimes();
+    EasyMock.expect(edmComplexType.getMapping()).andReturn((EdmMapping) mockEdmMapping(complexTypeName, null, null));
+
+    if (complexTypeName.equals(JPATypeEmbeddableMock.ENTITY_NAME)) {
+      EasyMock.expect(edmComplexType.getProperty(JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT)).andReturn(
+          mockEdmProperty(complexTypeName, JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT)).anyTimes();
+      EasyMock.expect(edmComplexType.getProperty(JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE)).andReturn(
+          mockEdmProperty(complexTypeName, JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE)).anyTimes();
+    } else if (complexTypeName.equals(JPATypeEmbeddableMock2.ENTITY_NAME)) {
+      EasyMock.expect(edmComplexType.getProperty(JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT)).andReturn(
+          mockEdmProperty(complexTypeName, JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT)).anyTimes();
+      EasyMock.expect(edmComplexType.getProperty(JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID)).andReturn(
+          mockEdmProperty(complexTypeName, JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID)).anyTimes();
+    }
+
+    EasyMock.replay(edmComplexType);
+    return edmComplexType;
+  }
+
+  public static JPAEdmMapping mockEdmMapping(final String entityName, final String propertyName,
+      final String navigationPropertyName) {
+    JPAEdmMapping mapping = new JPAEdmMappingImpl();
+
+    if (propertyName == null && entityName != null) {
+      if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
+        mapping.setJPAType(JPATypeMock.class);
+      } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
+        mapping.setJPAType(JPARelatedTypeMock.class);
+      } else if (entityName.equals(JPATypeEmbeddableMock.ENTITY_NAME)) {
+        mapping.setJPAType(JPATypeEmbeddableMock.class);
+      } else if (entityName.equals(JPATypeEmbeddableMock2.ENTITY_NAME)) {
+        mapping.setJPAType(JPATypeEmbeddableMock2.class);
+      }
+    } else if (entityName == null && navigationPropertyName != null) {
+      mapping.setJPAType(JPARelatedTypeMock.class);
+      mapping.setJPAColumnName(JPATypeMock.NAVIGATION_PROPERTY_X);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MINT)) {
+      mapping.setJPAType(int.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MINT);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MSTRING)) {
+      mapping.setJPAType(String.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MSTRING);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MBLOB)) {
+      mapping.setJPAType(Blob.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MBLOB);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_CLOB)) {
+      mapping.setJPAType(Clob.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_CLOB);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MC)) {
+      mapping.setJPAType(char.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MC);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MCARRAY)) {
+      mapping.setJPAType(char[].class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MCARRAY);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHAR)) {
+      mapping.setJPAType(Character.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MCHAR);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHARARRAY)) {
+      mapping.setJPAType(Character[].class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MCHARARRAY);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MDATETIME)) {
+      mapping.setJPAType(Calendar.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MDATETIME);
+    } else if (propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MLONG)) {
+      mapping.setJPAType(long.class);
+      ((Mapping) mapping).setInternalName(JPARelatedTypeMock.PROPERTY_NAME_MLONG);
+    } else if (propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE)) {
+      mapping.setJPAType(double.class);
+      ((Mapping) mapping).setInternalName(JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE);
+    } else if (propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MBYTE)) {
+      mapping.setJPAType(byte.class);
+      ((Mapping) mapping).setInternalName(JPARelatedTypeMock.PROPERTY_NAME_MBYTE);
+    } else if (propertyName.equals(JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY)) {
+      mapping.setJPAType(byte[].class);
+      ((Mapping) mapping).setInternalName(JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY);
+    } else if (propertyName.equals(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT)) {
+      mapping.setJPAType(Short.TYPE);
+      ((Mapping) mapping).setInternalName(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT);
+    } else if (propertyName.equals(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT)) {
+      mapping.setJPAType(Float.TYPE);
+      ((Mapping) mapping).setInternalName(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT);
+    } else if (propertyName.equals(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID)) {
+      mapping.setJPAType(UUID.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID);
+    } else if (propertyName.equals(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE)) {
+      mapping.setJPAType(JPATypeEmbeddableMock2.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE)) {
+      mapping.setJPAType(JPATypeEmbeddableMock.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE);
+    }
+    return mapping;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/JPATypeMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/JPATypeMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/JPATypeMock.java
index dd8207b..59701fb 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/JPATypeMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/JPATypeMock.java
@@ -1,268 +1,268 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.mock.data;
-
-import java.sql.Blob;
-import java.sql.Clob;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.UUID;
-
-/* ========================================================================= */
-public class JPATypeMock {
-
-  public static final String ENTITY_NAME = "JPATypeMock";
-  public static final String PROPERTY_NAME_MINT = "mInt";
-  public static final String PROPERTY_NAME_MSTRING = "mString";
-  public static final String PROPERTY_NAME_MDATETIME = "mDateTime";
-  public static final String PROPERTY_NAME_MBLOB = "mBlob";
-  public static final String PROPERTY_NAME_CLOB = "mClob";
-  public static final String PROPERTY_NAME_MCHAR = "mChar";
-  public static final String PROPERTY_NAME_MCHARARRAY = "mCharArray";
-  public static final String PROPERTY_NAME_MC = "mC";
-  public static final String PROPERTY_NAME_MCARRAY = "mCArray";
-  public static final String PROPERTY_NAME_MKEY = "key";
-  public static final String PROPERTY_NAME_MCOMPLEXTYPE = "complexType";
-
-  public static final String NAVIGATION_PROPERTY_X = "mRelatedEntity";
-  public static final String NAVIGATION_PROPERTY_XS = "mRelatedEntities";
-
-  private JPATypeEmbeddableMock key;
-  private JPATypeEmbeddableMock complexType;
-  private int mInt;
-  private String mString;
-  private Calendar mDateTime;
-  private Blob mBlob;
-  private Clob mClob;
-  private char mC;
-  private char[] mCArray;
-  private Character mChar;
-  private Character[] mCharArray;
-
-  public Clob getMClob() {
-    return mClob;
-  }
-
-  public void setMClob(final Clob mClob) {
-    this.mClob = mClob;
-  }
-
-  public char getMC() {
-    return mC;
-  }
-
-  public void setMC(final char mC) {
-    this.mC = mC;
-  }
-
-  public char[] getMCArray() {
-    return mCArray;
-  }
-
-  public void setMCArray(final char[] mCArray) {
-    this.mCArray = mCArray;
-  }
-
-  public Character getMChar() {
-    return mChar;
-  }
-
-  public void setMChar(final Character mChar) {
-    this.mChar = mChar;
-  }
-
-  public Character[] getMCharArray() {
-    return mCharArray;
-  }
-
-  public void setMCharArray(final Character[] mCharArray) {
-    this.mCharArray = mCharArray;
-  }
-
-  private JPARelatedTypeMock mRelatedEntity;
-  private List<JPARelatedTypeMock> mRelatedEntities = new ArrayList<JPATypeMock.JPARelatedTypeMock>();
-
-  public String getMString() {
-    return mString;
-  }
-
-  public void setMString(final String mString) {
-    this.mString = mString;
-  }
-
-  public JPATypeEmbeddableMock getKey() {
-    return key;
-  }
-
-  public void setKey(final JPATypeEmbeddableMock key) {
-    this.key = key;
-  }
-
-  public int getMInt() {
-    return mInt;
-  }
-
-  public void setMInt(final int mInt) {
-    this.mInt = mInt;
-  }
-
-  public Calendar getMDateTime() {
-    return mDateTime;
-  }
-
-  public void setMDateTime(final Calendar mDateTime) {
-    this.mDateTime = mDateTime;
-  }
-
-  public JPARelatedTypeMock getMRelatedEntity() {
-    return mRelatedEntity;
-  }
-
-  public void setMRelatedEntity(final JPARelatedTypeMock mRelatedEntity) {
-    this.mRelatedEntity = mRelatedEntity;
-  }
-
-  public List<JPARelatedTypeMock> getMRelatedEntities() {
-    return mRelatedEntities;
-  }
-
-  public void setMRelatedEntities(final List<JPARelatedTypeMock> mRelatedEntities) {
-    this.mRelatedEntities = mRelatedEntities;
-  }
-
-  public JPATypeEmbeddableMock getComplexType() {
-    return complexType;
-  }
-
-  public void setComplexType(final JPATypeEmbeddableMock complexType) {
-    this.complexType = complexType;
-  }
-
-  public Blob getMBlob() {
-    return mBlob;
-  }
-
-  public void setMBlob(final Blob mBlob) {
-    this.mBlob = mBlob;
-  }
-
-  /* ========================================================================= */
-  public static class JPATypeEmbeddableMock {
-
-    public static final String ENTITY_NAME = "JPATypeEmbeddableMock";
-    public static final String PROPERTY_NAME_MSHORT = "mShort";
-    public static final String PROPERTY_NAME_MEMBEDDABLE = "mEmbeddable";
-
-    private short mShort;
-    private JPATypeEmbeddableMock2 mEmbeddable;
-
-    public short getMShort() {
-      return mShort;
-    }
-
-    public void setMShort(final short mShort) {
-      this.mShort = mShort;
-    }
-
-    public JPATypeEmbeddableMock2 getMEmbeddable() {
-      return mEmbeddable;
-    }
-
-    public void setMEmbeddable(final JPATypeEmbeddableMock2 mEmbeddable) {
-      this.mEmbeddable = mEmbeddable;
-    }
-
-  }
-
-  /* ========================================================================= */
-  public static class JPATypeEmbeddableMock2 {
-
-    public static final String ENTITY_NAME = "JPATypeEmbeddableMock2";
-    public static final String PROPERTY_NAME_MUUID = "mUUID";
-    public static final String PROPERTY_NAME_MFLOAT = "mFloat";
-
-    private UUID mUUID;
-    private float mFloat;
-
-    public UUID getMUUID() {
-      return mUUID;
-    }
-
-    public void setMUUID(final UUID mUUID) {
-      this.mUUID = mUUID;
-    }
-
-    public float getMFloat() {
-      return mFloat;
-    }
-
-    public void setMFloat(final float mFloat) {
-      this.mFloat = mFloat;
-    }
-
-  }
-
-  /* ========================================================================= */
-  public static final class JPARelatedTypeMock {
-    public static final String ENTITY_NAME = "JPARelatedTypeMock";
-    public static final String PROPERTY_NAME_MLONG = "mLong";
-    public static final String PROPERTY_NAME_MDOUBLE = "mDouble";
-    public static final String PROPERTY_NAME_MBYTE = "mByte";
-    public static final String PROPERTY_NAME_MBYTEARRAY = "mByteArray";
-
-    private long mLong;
-    private double mDouble;
-    private byte mByte;
-    private byte mByteArray[];
-
-    public long getMLong() {
-      return mLong;
-    }
-
-    public void setMLong(final long key) {
-      mLong = key;
-    }
-
-    public double getMDouble() {
-      return mDouble;
-    }
-
-    public void setMDouble(final double mDouble) {
-      this.mDouble = mDouble;
-    }
-
-    public byte getMByte() {
-      return mByte;
-    }
-
-    public void setMByte(final byte mByte) {
-      this.mByte = mByte;
-    }
-
-    public byte[] getMByteArray() {
-      return mByteArray;
-    }
-
-    public void setMByteArray(final byte mByteArray[]) {
-      this.mByteArray = mByteArray;
-    }
-
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.mock.data;
+
+import java.sql.Blob;
+import java.sql.Clob;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.UUID;
+
+/* ========================================================================= */
+public class JPATypeMock {
+
+  public static final String ENTITY_NAME = "JPATypeMock";
+  public static final String PROPERTY_NAME_MINT = "mInt";
+  public static final String PROPERTY_NAME_MSTRING = "mString";
+  public static final String PROPERTY_NAME_MDATETIME = "mDateTime";
+  public static final String PROPERTY_NAME_MBLOB = "mBlob";
+  public static final String PROPERTY_NAME_CLOB = "mClob";
+  public static final String PROPERTY_NAME_MCHAR = "mChar";
+  public static final String PROPERTY_NAME_MCHARARRAY = "mCharArray";
+  public static final String PROPERTY_NAME_MC = "mC";
+  public static final String PROPERTY_NAME_MCARRAY = "mCArray";
+  public static final String PROPERTY_NAME_MKEY = "key";
+  public static final String PROPERTY_NAME_MCOMPLEXTYPE = "complexType";
+
+  public static final String NAVIGATION_PROPERTY_X = "mRelatedEntity";
+  public static final String NAVIGATION_PROPERTY_XS = "mRelatedEntities";
+
+  private JPATypeEmbeddableMock key;
+  private JPATypeEmbeddableMock complexType;
+  private int mInt;
+  private String mString;
+  private Calendar mDateTime;
+  private Blob mBlob;
+  private Clob mClob;
+  private char mC;
+  private char[] mCArray;
+  private Character mChar;
+  private Character[] mCharArray;
+
+  public Clob getMClob() {
+    return mClob;
+  }
+
+  public void setMClob(final Clob mClob) {
+    this.mClob = mClob;
+  }
+
+  public char getMC() {
+    return mC;
+  }
+
+  public void setMC(final char mC) {
+    this.mC = mC;
+  }
+
+  public char[] getMCArray() {
+    return mCArray;
+  }
+
+  public void setMCArray(final char[] mCArray) {
+    this.mCArray = mCArray;
+  }
+
+  public Character getMChar() {
+    return mChar;
+  }
+
+  public void setMChar(final Character mChar) {
+    this.mChar = mChar;
+  }
+
+  public Character[] getMCharArray() {
+    return mCharArray;
+  }
+
+  public void setMCharArray(final Character[] mCharArray) {
+    this.mCharArray = mCharArray;
+  }
+
+  private JPARelatedTypeMock mRelatedEntity;
+  private List<JPARelatedTypeMock> mRelatedEntities = new ArrayList<JPATypeMock.JPARelatedTypeMock>();
+
+  public String getMString() {
+    return mString;
+  }
+
+  public void setMString(final String mString) {
+    this.mString = mString;
+  }
+
+  public JPATypeEmbeddableMock getKey() {
+    return key;
+  }
+
+  public void setKey(final JPATypeEmbeddableMock key) {
+    this.key = key;
+  }
+
+  public int getMInt() {
+    return mInt;
+  }
+
+  public void setMInt(final int mInt) {
+    this.mInt = mInt;
+  }
+
+  public Calendar getMDateTime() {
+    return mDateTime;
+  }
+
+  public void setMDateTime(final Calendar mDateTime) {
+    this.mDateTime = mDateTime;
+  }
+
+  public JPARelatedTypeMock getMRelatedEntity() {
+    return mRelatedEntity;
+  }
+
+  public void setMRelatedEntity(final JPARelatedTypeMock mRelatedEntity) {
+    this.mRelatedEntity = mRelatedEntity;
+  }
+
+  public List<JPARelatedTypeMock> getMRelatedEntities() {
+    return mRelatedEntities;
+  }
+
+  public void setMRelatedEntities(final List<JPARelatedTypeMock> mRelatedEntities) {
+    this.mRelatedEntities = mRelatedEntities;
+  }
+
+  public JPATypeEmbeddableMock getComplexType() {
+    return complexType;
+  }
+
+  public void setComplexType(final JPATypeEmbeddableMock complexType) {
+    this.complexType = complexType;
+  }
+
+  public Blob getMBlob() {
+    return mBlob;
+  }
+
+  public void setMBlob(final Blob mBlob) {
+    this.mBlob = mBlob;
+  }
+
+  /* ========================================================================= */
+  public static class JPATypeEmbeddableMock {
+
+    public static final String ENTITY_NAME = "JPATypeEmbeddableMock";
+    public static final String PROPERTY_NAME_MSHORT = "mShort";
+    public static final String PROPERTY_NAME_MEMBEDDABLE = "mEmbeddable";
+
+    private short mShort;
+    private JPATypeEmbeddableMock2 mEmbeddable;
+
+    public short getMShort() {
+      return mShort;
+    }
+
+    public void setMShort(final short mShort) {
+      this.mShort = mShort;
+    }
+
+    public JPATypeEmbeddableMock2 getMEmbeddable() {
+      return mEmbeddable;
+    }
+
+    public void setMEmbeddable(final JPATypeEmbeddableMock2 mEmbeddable) {
+      this.mEmbeddable = mEmbeddable;
+    }
+
+  }
+
+  /* ========================================================================= */
+  public static class JPATypeEmbeddableMock2 {
+
+    public static final String ENTITY_NAME = "JPATypeEmbeddableMock2";
+    public static final String PROPERTY_NAME_MUUID = "mUUID";
+    public static final String PROPERTY_NAME_MFLOAT = "mFloat";
+
+    private UUID mUUID;
+    private float mFloat;
+
+    public UUID getMUUID() {
+      return mUUID;
+    }
+
+    public void setMUUID(final UUID mUUID) {
+      this.mUUID = mUUID;
+    }
+
+    public float getMFloat() {
+      return mFloat;
+    }
+
+    public void setMFloat(final float mFloat) {
+      this.mFloat = mFloat;
+    }
+
+  }
+
+  /* ========================================================================= */
+  public static final class JPARelatedTypeMock {
+    public static final String ENTITY_NAME = "JPARelatedTypeMock";
+    public static final String PROPERTY_NAME_MLONG = "mLong";
+    public static final String PROPERTY_NAME_MDOUBLE = "mDouble";
+    public static final String PROPERTY_NAME_MBYTE = "mByte";
+    public static final String PROPERTY_NAME_MBYTEARRAY = "mByteArray";
+
+    private long mLong;
+    private double mDouble;
+    private byte mByte;
+    private byte mByteArray[];
+
+    public long getMLong() {
+      return mLong;
+    }
+
+    public void setMLong(final long key) {
+      mLong = key;
+    }
+
+    public double getMDouble() {
+      return mDouble;
+    }
+
+    public void setMDouble(final double mDouble) {
+      this.mDouble = mDouble;
+    }
+
+    public byte getMByte() {
+      return mByte;
+    }
+
+    public void setMByte(final byte mByte) {
+      this.mByte = mByte;
+    }
+
+    public byte[] getMByteArray() {
+      return mByteArray;
+    }
+
+    public void setMByteArray(final byte mByteArray[]) {
+      this.mByteArray = mByteArray;
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/ODataEntryMockUtil.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/ODataEntryMockUtil.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/ODataEntryMockUtil.java
index 13e1f05..4f95a0e 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/ODataEntryMockUtil.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/ODataEntryMockUtil.java
@@ -1,164 +1,164 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.mock.data;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TimeZone;
-import java.util.UUID;
-
-import org.apache.olingo.odata2.api.ep.entry.EntryMetadata;
-import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
-import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPARelatedTypeMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPATypeEmbeddableMock;
-import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPATypeEmbeddableMock2;
-import org.easymock.EasyMock;
-
-public class ODataEntryMockUtil {
-
-  public static final int VALUE_MINT = 20;
-  public static Calendar VALUE_DATE_TIME = null;
-  public static byte[] VALUE_BLOB = null;
-  public static final String VALUE_CLOB = "ABC";
-  public static final String VALUE_C = "D";
-  public static final String VALUE_CARRAY = "EFG";
-  public static final String VALUE_CHAR = "I";
-  public static final String VALUE_CHARARRAY = "LMN";
-  public static final String VALUE_MSTRING = "Mock";
-  public static final long VALUE_MLONG = 1234567890L;
-  public static final double VALUE_MDOUBLE = 20.12;
-  public static final byte VALUE_MBYTE = 0XA;
-  public static final byte[] VALUE_MBYTEARRAY = new byte[] { 0XA, 0XB };
-  public static final float VALUE_MFLOAT = 2.00F;
-  public static final UUID VALUE_UUID = UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d");
-  public static final short VALUE_SHORT = 2;
-
-  public static ODataEntry mockODataEntry(final String entityName) {
-    ODataEntry oDataEntry = EasyMock.createMock(ODataEntry.class);
-    EasyMock.expect(oDataEntry.getProperties()).andReturn(mockODataEntryProperties(entityName)).anyTimes();
-
-    enhanceMockODataEntry(oDataEntry, false, new ArrayList<String>());
-    EasyMock.replay(oDataEntry);
-    return oDataEntry;
-  }
-
-  public static ODataEntry mockODataEntryWithComplexType(final String entityName) {
-    ODataEntry oDataEntry = EasyMock.createMock(ODataEntry.class);
-    EasyMock.expect(oDataEntry.getProperties()).andReturn(mockODataEntryPropertiesWithComplexType(entityName))
-        .anyTimes();
-
-    enhanceMockODataEntry(oDataEntry, false, new ArrayList<String>());
-    EasyMock.replay(oDataEntry);
-    return oDataEntry;
-  }
-
-  public static Map<String, Object> mockODataEntryProperties(final String entityName) {
-    Map<String, Object> propertyMap = new HashMap<String, Object>();
-
-    if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
-      propertyMap.put(JPATypeMock.PROPERTY_NAME_MINT, VALUE_MINT);
-
-      VALUE_DATE_TIME = Calendar.getInstance(TimeZone.getDefault());
-      VALUE_DATE_TIME.set(2013, 1, 1, 1, 1, 1);
-      propertyMap.put(JPATypeMock.PROPERTY_NAME_MDATETIME, VALUE_DATE_TIME);
-
-      VALUE_BLOB = VALUE_MBYTEARRAY;
-      propertyMap.put(JPATypeMock.PROPERTY_NAME_MBLOB, VALUE_BLOB);
-
-      propertyMap.put(JPATypeMock.PROPERTY_NAME_CLOB, VALUE_CLOB);
-      propertyMap.put(JPATypeMock.PROPERTY_NAME_MC, VALUE_C);
-      propertyMap.put(JPATypeMock.PROPERTY_NAME_MCARRAY, VALUE_CARRAY);
-      propertyMap.put(JPATypeMock.PROPERTY_NAME_MCHAR, VALUE_CHAR);
-      propertyMap.put(JPATypeMock.PROPERTY_NAME_MCHARARRAY, VALUE_CHARARRAY);
-      propertyMap.put(JPATypeMock.PROPERTY_NAME_MSTRING, VALUE_MSTRING);
-    } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
-      propertyMap.put(JPARelatedTypeMock.PROPERTY_NAME_MLONG, VALUE_MLONG);
-      propertyMap.put(JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE, VALUE_MDOUBLE);
-      propertyMap.put(JPARelatedTypeMock.PROPERTY_NAME_MBYTE, VALUE_MBYTE);
-      propertyMap.put(JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY, VALUE_MBYTEARRAY);
-    } else if (entityName.equals(JPATypeEmbeddableMock.ENTITY_NAME)) {
-      propertyMap.put(JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT, VALUE_SHORT);
-      propertyMap.put(JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE,
-          mockODataEntryProperties(JPATypeEmbeddableMock2.ENTITY_NAME));
-    } else if (entityName.equals(JPATypeEmbeddableMock2.ENTITY_NAME)) {
-      propertyMap.put(JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT, VALUE_MFLOAT);
-      propertyMap.put(JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID, VALUE_UUID);
-    }
-
-    return propertyMap;
-  }
-
-  public static Map<String, Object> mockODataEntryPropertiesWithComplexType(final String entityName) {
-    Map<String, Object> propertyMap = mockODataEntryProperties(entityName);
-    propertyMap
-        .put(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE, mockODataEntryProperties(JPATypeEmbeddableMock.ENTITY_NAME));
-    return propertyMap;
-  }
-
-  public static Map<String, Object> mockODataEntryPropertiesWithInline(final String entityName) {
-    Map<String, Object> propertyMap = mockODataEntryProperties(entityName);
-    List<ODataEntry> relatedEntries = new ArrayList<ODataEntry>();
-    relatedEntries.add(mockODataEntry(JPARelatedTypeMock.ENTITY_NAME));
-    ODataFeed feed = EasyMock.createMock(ODataFeed.class);
-    EasyMock.expect(feed.getEntries()).andReturn(relatedEntries);
-    EasyMock.replay(feed);
-    propertyMap.put(JPATypeMock.NAVIGATION_PROPERTY_X, feed);
-
-    return propertyMap;
-
-  }
-
-  public static ODataEntry mockODataEntryWithInline(final String entityName) {
-    ODataEntry oDataEntry = EasyMock.createMock(ODataEntry.class);
-    EasyMock.expect(oDataEntry.getProperties()).andReturn(mockODataEntryPropertiesWithInline(entityName)).anyTimes();
-    if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
-      List<String> links = new ArrayList<String>();
-      links.add(JPATypeMock.ENTITY_NAME + "(" + ODataEntryMockUtil.VALUE_MINT + ")/"
-          + JPATypeMock.NAVIGATION_PROPERTY_X);
-      enhanceMockODataEntry(oDataEntry, true, links);
-    } else {
-      enhanceMockODataEntry(oDataEntry, false, new ArrayList<String>());
-    }
-    EasyMock.replay(oDataEntry);
-    return oDataEntry;
-  }
-
-  private static void
-      enhanceMockODataEntry(final ODataEntry oDataEntry, final boolean hasInline, final List<String> associationURIs) {
-    EasyMock.expect(oDataEntry.containsInlineEntry()).andReturn(hasInline).anyTimes();
-    EntryMetadata entryMetadata = EasyMock.createMock(EntryMetadata.class);
-    if (hasInline) {
-      EasyMock.expect(entryMetadata.getAssociationUris(JPATypeMock.NAVIGATION_PROPERTY_X)).andReturn(associationURIs)
-          .anyTimes();
-      EasyMock.expect(entryMetadata.getAssociationUris(JPATypeMock.NAVIGATION_PROPERTY_XS)).andReturn(
-          new ArrayList<String>())
-          .anyTimes();
-    } else {
-      EasyMock.expect(entryMetadata.getAssociationUris(EasyMock.isA(String.class))).andReturn(associationURIs)
-          .anyTimes();
-    }
-
-    EasyMock.replay(entryMetadata);
-    EasyMock.expect(oDataEntry.getMetadata()).andReturn(entryMetadata).anyTimes();
-  }
-}
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.mock.data;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.UUID;
+
+import org.apache.olingo.odata2.api.ep.entry.EntryMetadata;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPARelatedTypeMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPATypeEmbeddableMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock.JPATypeEmbeddableMock2;
+import org.easymock.EasyMock;
+
+public class ODataEntryMockUtil {
+
+  public static final int VALUE_MINT = 20;
+  public static Calendar VALUE_DATE_TIME = null;
+  public static byte[] VALUE_BLOB = null;
+  public static final String VALUE_CLOB = "ABC";
+  public static final String VALUE_C = "D";
+  public static final String VALUE_CARRAY = "EFG";
+  public static final String VALUE_CHAR = "I";
+  public static final String VALUE_CHARARRAY = "LMN";
+  public static final String VALUE_MSTRING = "Mock";
+  public static final long VALUE_MLONG = 1234567890L;
+  public static final double VALUE_MDOUBLE = 20.12;
+  public static final byte VALUE_MBYTE = 0XA;
+  public static final byte[] VALUE_MBYTEARRAY = new byte[] { 0XA, 0XB };
+  public static final float VALUE_MFLOAT = 2.00F;
+  public static final UUID VALUE_UUID = UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d");
+  public static final short VALUE_SHORT = 2;
+
+  public static ODataEntry mockODataEntry(final String entityName) {
+    ODataEntry oDataEntry = EasyMock.createMock(ODataEntry.class);
+    EasyMock.expect(oDataEntry.getProperties()).andReturn(mockODataEntryProperties(entityName)).anyTimes();
+
+    enhanceMockODataEntry(oDataEntry, false, new ArrayList<String>());
+    EasyMock.replay(oDataEntry);
+    return oDataEntry;
+  }
+
+  public static ODataEntry mockODataEntryWithComplexType(final String entityName) {
+    ODataEntry oDataEntry = EasyMock.createMock(ODataEntry.class);
+    EasyMock.expect(oDataEntry.getProperties()).andReturn(mockODataEntryPropertiesWithComplexType(entityName))
+        .anyTimes();
+
+    enhanceMockODataEntry(oDataEntry, false, new ArrayList<String>());
+    EasyMock.replay(oDataEntry);
+    return oDataEntry;
+  }
+
+  public static Map<String, Object> mockODataEntryProperties(final String entityName) {
+    Map<String, Object> propertyMap = new HashMap<String, Object>();
+
+    if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_MINT, VALUE_MINT);
+
+      VALUE_DATE_TIME = Calendar.getInstance(TimeZone.getDefault());
+      VALUE_DATE_TIME.set(2013, 1, 1, 1, 1, 1);
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_MDATETIME, VALUE_DATE_TIME);
+
+      VALUE_BLOB = VALUE_MBYTEARRAY;
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_MBLOB, VALUE_BLOB);
+
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_CLOB, VALUE_CLOB);
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_MC, VALUE_C);
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_MCARRAY, VALUE_CARRAY);
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_MCHAR, VALUE_CHAR);
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_MCHARARRAY, VALUE_CHARARRAY);
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_MSTRING, VALUE_MSTRING);
+    } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
+      propertyMap.put(JPARelatedTypeMock.PROPERTY_NAME_MLONG, VALUE_MLONG);
+      propertyMap.put(JPARelatedTypeMock.PROPERTY_NAME_MDOUBLE, VALUE_MDOUBLE);
+      propertyMap.put(JPARelatedTypeMock.PROPERTY_NAME_MBYTE, VALUE_MBYTE);
+      propertyMap.put(JPARelatedTypeMock.PROPERTY_NAME_MBYTEARRAY, VALUE_MBYTEARRAY);
+    } else if (entityName.equals(JPATypeEmbeddableMock.ENTITY_NAME)) {
+      propertyMap.put(JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT, VALUE_SHORT);
+      propertyMap.put(JPATypeEmbeddableMock.PROPERTY_NAME_MEMBEDDABLE,
+          mockODataEntryProperties(JPATypeEmbeddableMock2.ENTITY_NAME));
+    } else if (entityName.equals(JPATypeEmbeddableMock2.ENTITY_NAME)) {
+      propertyMap.put(JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT, VALUE_MFLOAT);
+      propertyMap.put(JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID, VALUE_UUID);
+    }
+
+    return propertyMap;
+  }
+
+  public static Map<String, Object> mockODataEntryPropertiesWithComplexType(final String entityName) {
+    Map<String, Object> propertyMap = mockODataEntryProperties(entityName);
+    propertyMap
+        .put(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE, mockODataEntryProperties(JPATypeEmbeddableMock.ENTITY_NAME));
+    return propertyMap;
+  }
+
+  public static Map<String, Object> mockODataEntryPropertiesWithInline(final String entityName) {
+    Map<String, Object> propertyMap = mockODataEntryProperties(entityName);
+    List<ODataEntry> relatedEntries = new ArrayList<ODataEntry>();
+    relatedEntries.add(mockODataEntry(JPARelatedTypeMock.ENTITY_NAME));
+    ODataFeed feed = EasyMock.createMock(ODataFeed.class);
+    EasyMock.expect(feed.getEntries()).andReturn(relatedEntries);
+    EasyMock.replay(feed);
+    propertyMap.put(JPATypeMock.NAVIGATION_PROPERTY_X, feed);
+
+    return propertyMap;
+
+  }
+
+  public static ODataEntry mockODataEntryWithInline(final String entityName) {
+    ODataEntry oDataEntry = EasyMock.createMock(ODataEntry.class);
+    EasyMock.expect(oDataEntry.getProperties()).andReturn(mockODataEntryPropertiesWithInline(entityName)).anyTimes();
+    if (entityName.equals(JPATypeMock.ENTITY_NAME)) {
+      List<String> links = new ArrayList<String>();
+      links.add(JPATypeMock.ENTITY_NAME + "(" + ODataEntryMockUtil.VALUE_MINT + ")/"
+          + JPATypeMock.NAVIGATION_PROPERTY_X);
+      enhanceMockODataEntry(oDataEntry, true, links);
+    } else {
+      enhanceMockODataEntry(oDataEntry, false, new ArrayList<String>());
+    }
+    EasyMock.replay(oDataEntry);
+    return oDataEntry;
+  }
+
+  private static void
+      enhanceMockODataEntry(final ODataEntry oDataEntry, final boolean hasInline, final List<String> associationURIs) {
+    EasyMock.expect(oDataEntry.containsInlineEntry()).andReturn(hasInline).anyTimes();
+    EntryMetadata entryMetadata = EasyMock.createMock(EntryMetadata.class);
+    if (hasInline) {
+      EasyMock.expect(entryMetadata.getAssociationUris(JPATypeMock.NAVIGATION_PROPERTY_X)).andReturn(associationURIs)
+          .anyTimes();
+      EasyMock.expect(entryMetadata.getAssociationUris(JPATypeMock.NAVIGATION_PROPERTY_XS)).andReturn(
+          new ArrayList<String>())
+          .anyTimes();
+    } else {
+      EasyMock.expect(entryMetadata.getAssociationUris(EasyMock.isA(String.class))).andReturn(associationURIs)
+          .anyTimes();
+    }
+
+    EasyMock.replay(entryMetadata);
+    EasyMock.expect(oDataEntry.getMetadata()).andReturn(entryMetadata).anyTimes();
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/model/JPAPluralAttributeMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/model/JPAPluralAttributeMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/model/JPAPluralAttributeMock.java
index 23e7330..dd88da7 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/model/JPAPluralAttributeMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/model/JPAPluralAttributeMock.java
@@ -1,95 +1,95 @@
-/*******************************************************************************
- * 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.odata2.jpa.processor.core.mock.model;
-
-import java.lang.reflect.Member;
-import java.util.ArrayList;
-
-import javax.persistence.metamodel.ManagedType;
-import javax.persistence.metamodel.PluralAttribute;
-import javax.persistence.metamodel.Type;
-
-public class JPAPluralAttributeMock implements PluralAttribute<Object, ArrayList<String>, String> {
-
-  @Override
-  public String getName() {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public javax.persistence.metamodel.Attribute.PersistentAttributeType getPersistentAttributeType() {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public ManagedType<Object> getDeclaringType() {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public Class<ArrayList<String>> getJavaType() {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public Member getJavaMember() {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public boolean isAssociation() {
-    // TODO Auto-generated method stub
-    return false;
-  }
-
-  @Override
-  public boolean isCollection() {
-    return false;
-  }
-
-  @Override
-  public javax.persistence.metamodel.Bindable.BindableType getBindableType() {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public Class<String> getBindableJavaType() {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public javax.persistence.metamodel.PluralAttribute.CollectionType getCollectionType() {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public Type<String> getElementType() {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
+/*******************************************************************************
+ * 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.odata2.jpa.processor.core.mock.model;
+
+import java.lang.reflect.Member;
+import java.util.ArrayList;
+
+import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.Type;
+
+public class JPAPluralAttributeMock implements PluralAttribute<Object, ArrayList<String>, String> {
+
+  @Override
+  public String getName() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public javax.persistence.metamodel.Attribute.PersistentAttributeType getPersistentAttributeType() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public ManagedType<Object> getDeclaringType() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public Class<ArrayList<String>> getJavaType() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public Member getJavaMember() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public boolean isAssociation() {
+    // TODO Auto-generated method stub
+    return false;
+  }
+
+  @Override
+  public boolean isCollection() {
+    return false;
+  }
+
+  @Override
+  public javax.persistence.metamodel.Bindable.BindableType getBindableType() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public Class<String> getBindableJavaType() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public javax.persistence.metamodel.PluralAttribute.CollectionType getCollectionType() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public Type<String> getElementType() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/b155bda5/odata2-jpa-processor/jpa-ref/.gitignore
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/.gitignore b/odata2-jpa-processor/jpa-ref/.gitignore
index fe5d89b..a7ffe90 100644
--- a/odata2-jpa-processor/jpa-ref/.gitignore
+++ b/odata2-jpa-processor/jpa-ref/.gitignore
@@ -1,8 +1,8 @@
-.project
-.classpath
-.settings
-target
-bin
-*.bak
-classes
+.project
+.classpath
+.settings
+target
+bin
+*.bak
+classes
 .DS_Store
\ No newline at end of file


[05/19] git commit: Code Review - Bug fix and refactoring

Posted by ch...@apache.org.
Code Review - Bug fix and refactoring

Signed-off-by: Christian Amend <ch...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/1f90b733
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/1f90b733
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/1f90b733

Branch: refs/heads/master
Commit: 1f90b733a25a41c43f93ceb0f78369e6c27ef753
Parents: ffb21db
Author: Christian Holzer <c....@sap.com>
Authored: Thu Oct 2 19:12:38 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Mon Oct 6 13:54:37 2014 +0200

----------------------------------------------------------------------
 .../olingo/odata2/core/batch/AcceptParser.java  |  64 +++++--
 .../odata2/core/batch/v2/BatchBodyPart.java     |  27 +--
 .../odata2/core/batch/v2/BatchChangeSet.java    |  55 ------
 .../core/batch/v2/BatchChangeSetPart.java       |  55 ++++++
 .../odata2/core/batch/v2/BatchParser.java       |   2 +-
 .../odata2/core/batch/v2/BatchParserCommon.java | 122 +++++++------
 .../core/batch/v2/BatchQueryOperation.java      |  10 +-
 .../batch/v2/BatchRequestTransformator.java     |  16 +-
 .../batch/v2/BatchResponseTransformator.java    |  13 +-
 .../core/batch/v2/BatchTransformatorCommon.java |  24 +--
 .../odata2/core/batch/AcceptParserTest.java     |  77 +++++---
 .../core/batch/BatchParserCommonTest.java       | 182 +++++++++++++++----
 .../core/batch/BatchRequestParserTest.java      | 124 +++++++++----
 .../batch/BatchTransformatorCommonTest.java     |  12 +-
 14 files changed, 516 insertions(+), 267 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/AcceptParser.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/AcceptParser.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/AcceptParser.java
index 946fccf..48bfb1b 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/AcceptParser.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/AcceptParser.java
@@ -6,9 +6,9 @@
  * 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
@@ -20,6 +20,7 @@ package org.apache.olingo.odata2.core.batch;
 
 import java.util.ArrayList;
 import java.util.Comparator;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Scanner;
@@ -30,10 +31,11 @@ import java.util.regex.Pattern;
 import org.apache.olingo.odata2.api.batch.BatchException;
 
 /**
- *  
+ *
  */
 public class AcceptParser {
 
+  private static final String COMMA = ",";
   private static final String BAD_REQUEST = "400";
   private static final String ALL = "*";
   private static final String REG_EX_QUALITY_FACTOR = "q=((?:1\\.0{0,3})|(?:0\\.[0-9]{0,2}[1-9]))";
@@ -48,10 +50,15 @@ public class AcceptParser {
 
   private static final double QUALITY_PARAM_FACTOR = 0.001;
 
-  public static List<String> parseAcceptHeaders(final String headerValue) throws BatchException {
-    TreeSet<Accept> acceptTree = getAcceptTree();
-    List<String> acceptHeaders = new ArrayList<String>();
-    Scanner acceptHeaderScanner = new Scanner(headerValue);
+  private List<String> acceptHeaderValues = new ArrayList<String>();
+  private List<String> acceptLanguageHeaderValues = new ArrayList<String>();
+
+  public List<String> parseAcceptHeaders() throws BatchException {
+    final String headerValue = concatenateHeaderLines(acceptHeaderValues);
+    final TreeSet<Accept> acceptTree = getAcceptTree();
+    final List<String> acceptHeaders = new ArrayList<String>();
+    final Scanner acceptHeaderScanner = new Scanner(headerValue);
+
     acceptHeaderScanner.useDelimiter(",\\s?");
     while (acceptHeaderScanner.hasNext()) {
       if (acceptHeaderScanner.hasNext(REG_EX_ACCEPT_WITH_Q_FACTOR)) {
@@ -75,18 +82,21 @@ public class AcceptParser {
       }
     }
     for (Accept accept : acceptTree) {
-      acceptHeaders.add(accept.getValue());
+      if (!acceptHeaders.contains(accept.getValue())) {
+        acceptHeaders.add(accept.getValue());
+      }
     }
     acceptHeaderScanner.close();
     return acceptHeaders;
   }
 
-  private static double getQualityFactor(final String acceptHeaderValue, double qualityFactor) {
+  private double getQualityFactor(final String acceptHeaderValue, double qualityFactor) {
     int paramNumber = 0;
     double typeFactor = 0.0;
     double subtypeFactor = 0.0;
     String[] mediaRange = acceptHeaderValue.split("(?=[^;]+);");
     String[] mediaTypes = mediaRange[0].split("/");
+
     if (mediaTypes.length == 2) {
       String type = mediaTypes[0];
       String subtype = mediaTypes[1];
@@ -101,13 +111,15 @@ public class AcceptParser {
       String[] parameters = mediaRange[1].split(";\\s?");
       paramNumber = parameters.length;
     }
+
     qualityFactor = qualityFactor + paramNumber * QUALITY_PARAM_FACTOR + typeFactor + subtypeFactor;
     return qualityFactor;
   }
 
-  public static List<String> parseAcceptableLanguages(final String headerValue) throws BatchException {
-    List<String> acceptLanguages = new LinkedList<String>();
-    TreeSet<Accept> acceptTree = getAcceptTree();
+  public List<String> parseAcceptableLanguages() throws BatchException {
+    final String headerValue = concatenateHeaderLines(acceptLanguageHeaderValues);
+    final List<String> acceptLanguages = new LinkedList<String>();
+    final TreeSet<Accept> acceptTree = getAcceptTree();
     Scanner acceptLanguageScanner = new Scanner(headerValue);
     acceptLanguageScanner.useDelimiter(",\\s?");
 
@@ -132,13 +144,37 @@ public class AcceptParser {
       }
     }
     for (Accept accept : acceptTree) {
-      acceptLanguages.add(accept.getValue());
+      if (!acceptLanguages.contains(accept.getValue())) {
+        acceptLanguages.add(accept.getValue());
+      }
     }
     acceptLanguageScanner.close();
     return acceptLanguages;
   }
 
-  private static TreeSet<Accept> getAcceptTree() {
+  private String concatenateHeaderLines(final List<String> headerValues) {
+    final StringBuilder builder = new StringBuilder();
+    final Iterator<String> iter = headerValues.iterator();
+
+    while (iter.hasNext()) {
+      builder.append(iter.next());
+      if (iter.hasNext()) {
+        builder.append(COMMA);
+      }
+    }
+
+    return builder.toString();
+  }
+
+  public void addAcceptHeaderValue(final String headerValue) {
+    acceptHeaderValues.add(headerValue);
+  }
+
+  public void addAcceptLanguageHeaderValue(final String headerValue) {
+    acceptLanguageHeaderValues.add(headerValue);
+  }
+
+  private TreeSet<Accept> getAcceptTree() {
     TreeSet<Accept> treeSet = new TreeSet<Accept>(new Comparator<Accept>() {
       @Override
       public int compare(final Accept o1, final Accept o2) {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
index e355f84..4edcf45 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
@@ -24,18 +24,16 @@ import java.util.Locale;
 import java.util.Map;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
-import org.apache.olingo.odata2.api.commons.HttpContentType;
 import org.apache.olingo.odata2.api.commons.HttpHeaders;
 import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
 
 public class BatchBodyPart implements BatchPart {
-  final private Map<String, HeaderField> headers;
   final private String boundary;
-  final private boolean isChangeSet;
   final private boolean isStrict;
-  final private List<String> body;
-  private boolean isParsed = false;
+  final List<String> remainingMessage = new LinkedList<String>();
+
+  private Map<String, HeaderField> headers;
+  private boolean isChangeSet;
   private List<BatchQueryOperation> requests;
 
   public BatchBodyPart(final List<String> bodyPartMessage, final String boundary, final boolean isStrict)
@@ -43,19 +41,14 @@ public class BatchBodyPart implements BatchPart {
     this.boundary = boundary;
     this.isStrict = isStrict;
 
-    List<String> remainingMessage = new LinkedList<String>();
     remainingMessage.addAll(bodyPartMessage);
+  }
 
+  public BatchBodyPart parse() throws BatchException {
     headers = BatchParserCommon.consumeHeaders(remainingMessage);
     BatchParserCommon.consumeBlankLine(remainingMessage, isStrict);
     isChangeSet = isChangeSet(headers);
-    body = remainingMessage;
-  }
-
-  public BatchBodyPart parse(final int contentLength) throws BatchException {
-    List<String> remainingMessage = BatchParserCommon.trimStringListToLength(body, contentLength);
     requests = consumeRequest(remainingMessage);
-    isParsed = true;
 
     return this;
   }
@@ -78,7 +71,7 @@ public class BatchBodyPart implements BatchPart {
   }
 
   private boolean isContentTypeMultiPartMixed(final String contentType) {
-    return contentType.contains(HttpContentType.MULTIPART_MIXED);
+    return BatchParserCommon.PATTERN_MULTIPART_BOUNDARY.matcher(contentType).matches();
   }
 
   private List<BatchQueryOperation> consumeRequest(final List<String> remainingMessage) throws BatchException {
@@ -95,7 +88,7 @@ public class BatchBodyPart implements BatchPart {
     final List<BatchQueryOperation> requestList = new LinkedList<BatchQueryOperation>();
 
     for (List<String> changeRequest : changeRequests) {
-      requestList.add(new BatchChangeSet(changeRequest, isStrict).parse());
+      requestList.add(new BatchChangeSetPart(changeRequest, isStrict).parse());
     }
 
     return requestList;
@@ -146,10 +139,6 @@ public class BatchBodyPart implements BatchPart {
   }
 
   public List<BatchQueryOperation> getRequests() {
-    if (!isParsed) {
-      throw new ODataRuntimeException("Batch part must be parsed first");
-    }
-
     return requests;
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSet.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSet.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSet.java
deleted file mode 100644
index 5331ff8..0000000
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSet.java
+++ /dev/null
@@ -1,55 +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.odata2.core.batch.v2;
-
-import java.util.List;
-
-import org.apache.olingo.odata2.api.batch.BatchException;
-
-public class BatchChangeSet extends BatchQueryOperation {
-  private BatchQueryOperation request;
-
-  public BatchChangeSet(final List<String> message, final boolean isStrict) throws BatchException {
-    super(message, isStrict);
-  }
-
-  @Override
-  public BatchChangeSet parse() throws BatchException {
-    headers = BatchParserCommon.consumeHeaders(message);
-    BatchParserCommon.consumeBlankLine(message, isStrict);
-
-    request = new BatchQueryOperation(message, isStrict).parse();
-
-    return this;
-  }
-
-  public BatchQueryOperation getRequest() {
-    return request;
-  }
-
-  @Override
-  public List<String> getBody() {
-    return request.getBody();
-  }
-
-  @Override
-  public String getHttpMethod() {
-    return request.getHttpMethod();
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSetPart.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSetPart.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSetPart.java
new file mode 100644
index 0000000..746c368
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSetPart.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.batch.v2;
+
+import java.util.List;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+
+public class BatchChangeSetPart extends BatchQueryOperation {
+  private BatchQueryOperation request;
+
+  public BatchChangeSetPart(final List<String> message, final boolean isStrict) throws BatchException {
+    super(message, isStrict);
+  }
+
+  @Override
+  public BatchChangeSetPart parse() throws BatchException {
+    headers = BatchParserCommon.consumeHeaders(message);
+    BatchParserCommon.consumeBlankLine(message, isStrict);
+
+    request = new BatchQueryOperation(message, isStrict).parse();
+
+    return this;
+  }
+
+  public BatchQueryOperation getRequest() {
+    return request;
+  }
+
+  @Override
+  public List<String> getBody() {
+    return request.getBody();
+  }
+
+  @Override
+  public String getHttpStatusLine() {
+    return request.getHttpStatusLine();
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
index b64453b..6fb7dbd 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
@@ -83,7 +83,7 @@ public class BatchParser {
     final List<List<String>> bodyPartStrings = splitBodyParts(in, boundary);
 
     for (List<String> bodyPartString : bodyPartStrings) {
-      BatchBodyPart bodyPart = new BatchBodyPart(bodyPartString, boundary, isStrict);
+      BatchBodyPart bodyPart = new BatchBodyPart(bodyPartString, boundary, isStrict).parse();
       resultList.addAll(transformator.transform(bodyPart, batchRequestPathInfo, baseUri));
     }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
index 51314dd..8b7f62a 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
@@ -44,32 +44,23 @@ import org.apache.olingo.odata2.core.batch.AcceptParser;
 import org.apache.olingo.odata2.core.commons.Decoder;
 
 public class BatchParserCommon {
-  private static final String BOUNDARY_IDENTIFIER = "boundary=";
   private static final String REG_EX_BOUNDARY =
       "([a-zA-Z0-9_\\-\\.'\\+]{1,70})|\"([a-zA-Z0-9_\\-\\.'\\+\\s\\" +
           "(\\),/:=\\?]{1,69}[a-zA-Z0-9_\\-\\.'\\+\\(\\),/:=\\?])\""; // See RFC 2046
 
-  private static final Pattern REG_EX_HEADER = Pattern.compile("([a-zA-Z\\-]+):\\s?(.*)\\s*");
+  private static final String REX_EX_MULTIPART_BOUNDARY = "multipart/mixed;\\s*boundary=(.+)";
+  private static final String REG_EX_APPLICATION_HTTP = "application/http";
+  public static final Pattern PATTERN_MULTIPART_BOUNDARY = Pattern.compile(REX_EX_MULTIPART_BOUNDARY,
+      Pattern.CASE_INSENSITIVE);
+  public static final Pattern PATTERN_HEADER_LINE = Pattern.compile("([a-zA-Z\\-]+):\\s?(.*)\\s*");
+  public static final Pattern PATTERN_CONTENT_TYPE_APPLICATION_HTTP = Pattern.compile(REG_EX_APPLICATION_HTTP,
+      Pattern.CASE_INSENSITIVE);
 
-  public static List<String> trimStringListToLength(final List<String> list, final int length) {
-    final Iterator<String> iter = list.iterator();
-    final List<String> result = new ArrayList<String>();
-    boolean isEndReached = false;
-    int currentLength = 0;
-
-    while (!isEndReached && iter.hasNext()) {
-      String currentLine = iter.next();
-
-      if (currentLength + currentLine.length() <= length) {
-        result.add(currentLine);
-        currentLength += currentLine.length();
-      } else {
-        result.add(currentLine.substring(0, length - currentLength));
-        isEndReached = true;
-      }
-    }
+  public static String trimStringListToStringLength(final List<String> list, final int length) {
+    final String message = stringListToString(list);
+    final int lastIndex = Math.min(length, message.length());
 
-    return result;
+    return (lastIndex > 0) ? message.substring(0, lastIndex) : "";
   }
 
   public static String stringListToString(final List<String> list) {
@@ -82,13 +73,21 @@ public class BatchParserCommon {
     return builder.toString();
   }
 
-  public static InputStream convertMessageToInputStream(final List<String> message, final int contentLength)
+  public static InputStream convertMessageToInputStream(final List<String> messageList, final int contentLength)
       throws BatchException {
-    List<String> shortenedMessage = BatchParserCommon.trimStringListToLength(message, contentLength);
+    final String message = trimStringListToStringLength(messageList, contentLength);
 
-    return new ByteArrayInputStream(BatchParserCommon.stringListToString(shortenedMessage).getBytes());
+    return new ByteArrayInputStream(message.getBytes());
   }
 
+  public static InputStream convertMessageToInputStream(final List<String> messageList)
+      throws BatchException {
+    final String message = stringListToString(messageList);
+
+    return new ByteArrayInputStream(message.getBytes());
+  }
+
+  // TODO Splitten von InputStream, sodass nur eine Iteration erfolgen muss
   static List<List<String>> splitMessageByBoundary(final List<String> message, final String boundary)
       throws BatchException {
     final List<List<String>> messageParts = new LinkedList<List<String>>();
@@ -149,15 +148,16 @@ public class BatchParserCommon {
     }
   }
 
-  static Map<String, HeaderField> consumeHeaders(final List<String> remainingMessage) throws BatchException {
+  public static Map<String, HeaderField> consumeHeaders(final List<String> remainingMessage) throws BatchException {
     final Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
     boolean isHeader = true;
+    final Iterator<String> iter = remainingMessage.iterator();
+    final AcceptParser acceptParser = new AcceptParser();
     String currentLine;
-    Iterator<String> iter = remainingMessage.iterator();
 
     while (iter.hasNext() && isHeader) {
       currentLine = iter.next();
-      Matcher headerMatcher = REG_EX_HEADER.matcher(currentLine);
+      Matcher headerMatcher = PATTERN_HEADER_LINE.matcher(currentLine);
 
       if (headerMatcher.matches() && headerMatcher.groupCount() == 2) {
         iter.remove();
@@ -167,38 +167,55 @@ public class BatchParserCommon {
         String headerValue = headerMatcher.group(2).trim();
 
         if (HttpHeaders.ACCEPT.equalsIgnoreCase(headerNameLowerCase)) {
-          List<String> acceptHeaders = AcceptParser.parseAcceptHeaders(headerValue);
-          headers.put(headerNameLowerCase, new HeaderField(headerName, acceptHeaders));
+          acceptParser.addAcceptHeaderValue(headerValue);
         } else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(headerNameLowerCase)) {
-          List<String> acceptLanguageHeaders = AcceptParser.parseAcceptableLanguages(headerValue);
-          headers.put(headerNameLowerCase, new HeaderField(headerName, acceptLanguageHeaders));
+          acceptParser.addAcceptLanguageHeaderValue(headerValue);
         } else {
-          HeaderField headerField = headers.get(headerNameLowerCase);
-          headerField = headerField == null ? new HeaderField(headerName) : headerField;
-          headers.put(headerNameLowerCase, headerField);
-          headerField.getValues().add(headerValue);
+          addHeaderValue(headers, headerName, headerNameLowerCase, headerValue);
         }
       } else {
         isHeader = false;
       }
     }
 
+    final List<String> acceptHeader = acceptParser.parseAcceptHeaders();
+    headers.put(HttpHeaders.ACCEPT.toLowerCase(), new HeaderField(HttpHeaders.ACCEPT, acceptHeader));
+
+    final List<String> acceptLanguageHeader = acceptParser.parseAcceptableLanguages();
+    headers.put(HttpHeaders.ACCEPT_LANGUAGE.toLowerCase(), new HeaderField(HttpHeaders.ACCEPT_LANGUAGE,
+        acceptLanguageHeader));
+
     return Collections.unmodifiableMap(headers);
   }
 
-  static void consumeBlankLine(final List<String> remainingMessage, final boolean isStrict) throws BatchException {
-    if (remainingMessage.size() > 0 && "".equals(remainingMessage.get(0).trim())) {
-      remainingMessage.remove(0);
-    } else {
-      if (isStrict) {
-        throw new BatchException(BatchException.MISSING_BLANK_LINE);
+  private static void addHeaderValue(final Map<String, HeaderField> headers, final String headerName,
+      final String headerNameLowerCase, final String headerValue) {
+    HeaderField headerField = headers.get(headerNameLowerCase);
+    headerField = headerField == null ? new HeaderField(headerName) : headerField;
+    headers.put(headerNameLowerCase, headerField);
+
+    for (final String singleValue : splitHeaderValuesByComma(headerValue)) {
+      if (!headerField.getValues().contains(singleValue)) {
+        headerField.getValues().add(singleValue);
       }
     }
   }
 
-  static void consumeLastBlankLine(final List<String> message, final boolean isStrict) throws BatchException {
-    if (message.size() > 0 && "".equals(message.get(message.size() - 1).trim())) {
-      message.remove(message.size() - 1);
+  private static List<String> splitHeaderValuesByComma(final String headerValue) {
+    final List<String> singleValues = new ArrayList<String>();
+
+    String[] parts = headerValue.split(",");
+    for (final String value : parts) {
+      singleValues.add(value.trim());
+    }
+
+    return singleValues;
+  }
+
+  public static void consumeBlankLine(final List<String> remainingMessage, final boolean isStrict)
+      throws BatchException {
+    if (remainingMessage.size() > 0 && "".equals(remainingMessage.get(0).trim())) {
+      remainingMessage.remove(0);
     } else {
       if (isStrict) {
         throw new BatchException(BatchException.MISSING_BLANK_LINE);
@@ -206,25 +223,22 @@ public class BatchParserCommon {
     }
   }
 
-  static String getBoundary(final String contentType) throws BatchException {
-    if (contentType.contains(HttpContentType.MULTIPART_MIXED)) {
-      String[] parts = contentType.split(BOUNDARY_IDENTIFIER);
+  public static String getBoundary(final String contentType) throws BatchException {
+    final Matcher boundaryMatcher = PATTERN_MULTIPART_BOUNDARY.matcher(contentType);
 
-      if (parts.length == 2) {
-        if (parts[1].matches(REG_EX_BOUNDARY)) {
-          return trimQuota(parts[1].trim());
-        } else {
-          throw new BatchException(BatchException.INVALID_BOUNDARY);
-        }
+    if (boundaryMatcher.matches()) {
+      final String boundary = boundaryMatcher.group(1);
+      if (boundary.matches(REG_EX_BOUNDARY)) {
+        return trimQuota(boundary);
       } else {
-        throw new BatchException(BatchException.MISSING_PARAMETER_IN_CONTENT_TYPE);
+        throw new BatchException(BatchException.INVALID_BOUNDARY);
       }
     } else {
       throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(HttpContentType.MULTIPART_MIXED));
     }
   }
 
-  static Map<String, List<String>> parseQueryParameter(final String httpRequest) {
+  public static Map<String, List<String>> parseQueryParameter(final String httpRequest) {
     Map<String, List<String>> queryParameter = new HashMap<String, List<String>>();
 
     String[] requestParts = httpRequest.split(" ");

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
index 179fffb..5176bb8 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
@@ -27,7 +27,7 @@ import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
 public class BatchQueryOperation implements BatchPart {
 
   protected final boolean isStrict;
-  protected String httpMethod;
+  protected String httpStatusLine;
   protected Map<String, HeaderField> headers;
   protected List<String> body;
   protected int bodySize;
@@ -39,7 +39,7 @@ public class BatchQueryOperation implements BatchPart {
   }
 
   public BatchQueryOperation parse() throws BatchException {
-    httpMethod = consumeHttpMethod(message);
+    httpStatusLine = consumeHttpStatusLine(message);
     headers = BatchParserCommon.consumeHeaders(message);
     BatchParserCommon.consumeBlankLine(message, isStrict);
     body = message;
@@ -47,7 +47,7 @@ public class BatchQueryOperation implements BatchPart {
     return this;
   }
 
-  protected String consumeHttpMethod(final List<String> message) throws BatchException {
+  protected String consumeHttpStatusLine(final List<String> message) throws BatchException {
     if (message.size() > 0 && !message.get(0).trim().equals("")) {
       String method = message.get(0);
       message.remove(0);
@@ -58,8 +58,8 @@ public class BatchQueryOperation implements BatchPart {
     }
   }
 
-  public String getHttpMethod() {
-    return httpMethod;
+  public String getHttpStatusLine() {
+    return httpStatusLine;
   }
 
   public List<String> getBody() {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
index 3626686..5169575 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
@@ -55,7 +55,6 @@ public class BatchRequestTransformator implements BatchTransformator {
     final List<ODataRequest> requests = new LinkedList<ODataRequest>();
     final List<BatchParserResult> resultList = new ArrayList<BatchParserResult>();
 
-    BatchTransformatorCommon.parsePartSyntax(bodyPart);
     validateBodyPartHeaders(bodyPart);
 
     for (BatchQueryOperation queryOperation : bodyPart.getRequests()) {
@@ -77,7 +76,7 @@ public class BatchRequestTransformator implements BatchTransformator {
       final String baseUri, final BatchQueryOperation queryOperation) throws BatchException {
 
     if (bodyPart.isChangeSet()) {
-      BatchQueryOperation encapsulatedQueryOperation = ((BatchChangeSet) queryOperation).getRequest();
+      BatchQueryOperation encapsulatedQueryOperation = ((BatchChangeSetPart) queryOperation).getRequest();
       Map<String, HeaderField> headers = transformHeader(encapsulatedQueryOperation, queryOperation);
       validateChangeSetMultipartMimeHeaders(queryOperation, encapsulatedQueryOperation);
 
@@ -98,7 +97,7 @@ public class BatchRequestTransformator implements BatchTransformator {
   private ODataRequest createRequest(final BatchQueryOperation operation, final Map<String, HeaderField> headers,
       final PathInfo pathInfo, final String baseUri, final boolean isChangeSet) throws BatchException {
 
-    ODataHttpMethod httpMethod = getHttpMethod(operation.getHttpMethod());
+    ODataHttpMethod httpMethod = getHttpMethod(operation.getHttpStatusLine());
     validateHttpMethod(httpMethod, isChangeSet);
     validateBody(httpMethod, operation);
     InputStream bodyStrean = getBodyStream(operation, headers, httpMethod);
@@ -106,10 +105,10 @@ public class BatchRequestTransformator implements BatchTransformator {
     ODataRequestBuilder requestBuilder = ODataRequest.method(httpMethod)
         .acceptableLanguages(getAcceptLanguageHeaders(headers))
         .acceptHeaders(getAcceptHeaders(headers))
-        .allQueryParameters(BatchParserCommon.parseQueryParameter(operation.getHttpMethod()))
+        .allQueryParameters(BatchParserCommon.parseQueryParameter(operation.getHttpStatusLine()))
         .body(bodyStrean)
         .requestHeaders(BatchParserCommon.headerFieldMapToMultiMap(headers))
-        .pathInfo(BatchParserCommon.parseRequestUri(operation.getHttpMethod(), pathInfo, baseUri));
+        .pathInfo(BatchParserCommon.parseRequestUri(operation.getHttpStatusLine(), pathInfo, baseUri));
 
     addContentTypeHeader(requestBuilder, headers);
 
@@ -135,9 +134,12 @@ public class BatchRequestTransformator implements BatchTransformator {
       return new ByteArrayInputStream(new byte[0]);
     } else {
       int contentLength = BatchTransformatorCommon.getContentLength(headers);
-      contentLength = (contentLength >= 0) ? contentLength : Integer.MAX_VALUE;
 
-      return BatchParserCommon.convertMessageToInputStream(operation.getBody(), contentLength);
+      if (contentLength == -1) {
+        return BatchParserCommon.convertMessageToInputStream(operation.getBody());
+      } else {
+        return BatchParserCommon.convertMessageToInputStream(operation.getBody(), contentLength);
+      }
     }
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
index 88f5064..d82d09e 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
@@ -51,7 +51,6 @@ public class BatchResponseTransformator implements BatchTransformator {
 
     List<BatchParserResult> resultList = new ArrayList<BatchParserResult>();
 
-    BatchTransformatorCommon.parsePartSyntax(bodyPart);
     BatchTransformatorCommon.validateContentType(bodyPart.getHeaders());
 
     resultList.addAll(handleBodyPart(bodyPart));
@@ -64,7 +63,7 @@ public class BatchResponseTransformator implements BatchTransformator {
 
     if (bodyPart.isChangeSet()) {
       for (BatchQueryOperation operation : bodyPart.getRequests()) {
-        bodyPartResult.add(transformChangeSet((BatchChangeSet) operation));
+        bodyPartResult.add(transformChangeSet((BatchChangeSetPart) operation));
       }
     } else {
       bodyPartResult.add(transformQueryOperation(bodyPart.getRequests().get(0), getContentId(bodyPart.getHeaders())));
@@ -73,7 +72,7 @@ public class BatchResponseTransformator implements BatchTransformator {
     return bodyPartResult;
   }
 
-  private BatchSingleResponse transformChangeSet(final BatchChangeSet changeSet) throws BatchException {
+  private BatchSingleResponse transformChangeSet(final BatchChangeSetPart changeSet) throws BatchException {
     BatchTransformatorCommon.validateContentTransferEncoding(changeSet.getHeaders(), true);
 
     return transformQueryOperation(changeSet.getRequest(), getContentId(changeSet.getHeaders()));
@@ -84,8 +83,8 @@ public class BatchResponseTransformator implements BatchTransformator {
     BatchSingleResponseImpl response = new BatchSingleResponseImpl();
     response.setContentId(contentId);
     response.setHeaders(BatchParserCommon.headerFieldMapToSingleMap(operation.getHeaders()));
-    response.setStatusCode(getStatusCode(operation.httpMethod));
-    response.setStatusInfo(getStatusInfo(operation.getHttpMethod()));
+    response.setStatusCode(getStatusCode(operation.httpStatusLine));
+    response.setStatusInfo(getStatusInfo(operation.getHttpStatusLine()));
     response.setBody(getBody(operation));
 
     return response;
@@ -105,8 +104,8 @@ public class BatchResponseTransformator implements BatchTransformator {
 
   private String getBody(final BatchQueryOperation operation) throws BatchException {
     int contentLength = BatchTransformatorCommon.getContentLength(operation.getHeaders());
-    List<String> body = BatchParserCommon.trimStringListToLength(operation.getBody(), contentLength);
-    return BatchParserCommon.stringListToString(body);
+
+    return BatchParserCommon.trimStringListToStringLength(operation.getBody(), contentLength);
   }
 
   private String getStatusCode(final String httpMethod) throws BatchException {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
index 2098708..c9c8e0f 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
@@ -12,20 +12,16 @@ import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
 public class BatchTransformatorCommon {
 
   public static void validateContentType(final Map<String, HeaderField> headers) throws BatchException {
-    if (headers.containsKey(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH))) {
-      HeaderField contentTypeField = headers.get(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH));
-
+    final HeaderField contentTypeField = headers.get(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH));
+    if (contentTypeField != null) {
       if (contentTypeField.getValues().size() == 1) {
-        String contentType = contentTypeField.getValues().get(0);
-
-        if (!(HttpContentType.APPLICATION_HTTP.equalsIgnoreCase(contentType)
-        || contentType.contains(HttpContentType.MULTIPART_MIXED))) {
+        final String contentType = contentTypeField.getValues().get(0);
 
+        if (!BatchParserCommon.PATTERN_MULTIPART_BOUNDARY.matcher(contentType).matches()
+            && !BatchParserCommon.PATTERN_CONTENT_TYPE_APPLICATION_HTTP.matcher(contentType).matches()) {
           throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(HttpContentType.MULTIPART_MIXED
               + " or " + HttpContentType.APPLICATION_HTTP));
         }
-      } else if (contentTypeField.getValues().size() == 0) {
-        throw new BatchException(BatchException.MISSING_CONTENT_TYPE);
       } else {
         throw new BatchException(BatchException.INVALID_HEADER);
       }
@@ -34,7 +30,8 @@ public class BatchTransformatorCommon {
     }
   }
 
-  public static void validateContentTransferEncoding(final Map<String, HeaderField> headers, boolean isChangeRequest)
+  public static void validateContentTransferEncoding(final Map<String, HeaderField> headers,
+      final boolean isChangeRequest)
       throws BatchException {
     if (headers.containsKey(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING.toLowerCase(Locale.ENGLISH))) {
       HeaderField encodingField = headers.get(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING.toLowerCase(Locale.ENGLISH));
@@ -57,11 +54,6 @@ public class BatchTransformatorCommon {
     }
   }
 
-  public static void parsePartSyntax(final BatchBodyPart bodyPart) throws BatchException {
-    int contentLength = BatchTransformatorCommon.getContentLength(bodyPart.getHeaders());
-    bodyPart.parse(contentLength);
-  }
-
   public static int getContentLength(final Map<String, HeaderField> headers) throws BatchException {
 
     if (headers.containsKey(HttpHeaders.CONTENT_LENGTH.toLowerCase(Locale.ENGLISH))) {
@@ -79,6 +71,6 @@ public class BatchTransformatorCommon {
       }
     }
 
-    return Integer.MAX_VALUE;
+    return -1;
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/AcceptParserTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/AcceptParserTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/AcceptParserTest.java
index a3c0512..b7d7fac 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/AcceptParserTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/AcceptParserTest.java
@@ -31,8 +31,10 @@ public class AcceptParserTest {
 
   @Test
   public void testAcceptHeader() throws BatchException {
-    List<String> acceptHeaders =
-        AcceptParser.parseAcceptHeaders("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptHeaderValue("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
+    List<String> acceptHeaders = parser.parseAcceptHeaders();
+    
     assertNotNull(acceptHeaders);
     assertEquals(4, acceptHeaders.size());
     assertEquals("text/html", acceptHeaders.get(0));
@@ -43,48 +45,58 @@ public class AcceptParserTest {
 
   @Test
   public void testAcceptHeaderWithParameter() throws BatchException {
-    List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("application/json;odata=verbose;q=1.0, */*;q=0.1");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptHeaderValue("application/json;odata=verbose;q=1.0, */*;q=0.1");
+    List<String> acceptHeaders = parser.parseAcceptHeaders();
+    
     assertNotNull(acceptHeaders);
     assertEquals(2, acceptHeaders.size());
     assertEquals("application/json;odata=verbose", acceptHeaders.get(0));
-    ;
     assertEquals("*/*", acceptHeaders.get(1));
   }
 
   @Test
   public void testAcceptHeaderWithParameterAndLws() throws BatchException {
-    List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("application/json;  odata=verbose;q=1.0, */*;q=0.1");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptHeaderValue("application/json;  odata=verbose;q=1.0, */*;q=0.1");
+    List<String> acceptHeaders = parser.parseAcceptHeaders();
+
     assertNotNull(acceptHeaders);
     assertEquals(2, acceptHeaders.size());
     assertEquals("application/json;  odata=verbose", acceptHeaders.get(0));
-    ;
     assertEquals("*/*", acceptHeaders.get(1));
   }
 
   @Test
   public void testAcceptHeaderWithTabulator() throws BatchException {
-    List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("application/json;\todata=verbose;q=1.0, */*;q=0.1");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptHeaderValue("application/json;\todata=verbose;q=1.0, */*;q=0.1");
+    List<String> acceptHeaders = parser.parseAcceptHeaders();
+    
     assertNotNull(acceptHeaders);
     assertEquals(2, acceptHeaders.size());
     assertEquals("application/json;" + TAB + "odata=verbose", acceptHeaders.get(0));
-    ;
     assertEquals("*/*", acceptHeaders.get(1));
   }
 
   @Test
   public void testAcceptHeaderWithTwoParameters() throws BatchException {
-    List<String> acceptHeaders =
-        AcceptParser.parseAcceptHeaders("application/xml;another=test ; param=alskdf, */*;q=0.1");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptHeaderValue("application/xml;another=test ; param=alskdf, */*;q=0.1");
+    List<String> acceptHeaders = parser.parseAcceptHeaders();
+
     assertNotNull(acceptHeaders);
     assertEquals(2, acceptHeaders.size());
     assertEquals("application/xml;another=test ; param=alskdf", acceptHeaders.get(0));
-    ;
     assertEquals("*/*", acceptHeaders.get(1));
   }
 
   @Test
   public void testAcceptHeader2() throws BatchException {
-    List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("text/html;level=1, application/*, */*;q=0.1");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptHeaderValue("text/html;level=1, application/*, */*;q=0.1");
+    List<String> acceptHeaders = parser.parseAcceptHeaders();
+
     assertNotNull(acceptHeaders);
     assertEquals(3, acceptHeaders.size());
     assertEquals("text/html;level=1", acceptHeaders.get(0));
@@ -94,7 +106,10 @@ public class AcceptParserTest {
 
   @Test
   public void testMoreSpecificMediaType() throws BatchException {
-    List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("application/*, application/xml");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptHeaderValue("application/*, application/xml");
+    List<String> acceptHeaders = parser.parseAcceptHeaders();
+    
     assertNotNull(acceptHeaders);
     assertEquals(2, acceptHeaders.size());
     assertEquals("application/xml", acceptHeaders.get(0));
@@ -103,28 +118,40 @@ public class AcceptParserTest {
 
   @Test
   public void testQualityParameter() throws BatchException {
-    List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("application/*, */*; q=0.012");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptHeaderValue("application/*, */*; q=0.012");
+    List<String> acceptHeaders = parser.parseAcceptHeaders();
+    
     assertNotNull(acceptHeaders);
   }
 
   @Test(expected = BatchException.class)
   public void testInvalidAcceptHeader() throws BatchException {
-    AcceptParser.parseAcceptHeaders("appi cation/*, */*;q=0.1");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptHeaderValue("appi cation/*, */*;q=0.1");
+    parser.parseAcceptHeaders();
   }
 
   @Test(expected = BatchException.class)
   public void testInvalidQualityParameter() throws BatchException {
-    AcceptParser.parseAcceptHeaders("appication/*, */*;q=0,9");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptHeaderValue("appication/*, */*;q=0,9");
+    parser.parseAcceptHeaders();
   }
 
   @Test(expected = BatchException.class)
   public void testInvalidQualityParameter2() throws BatchException {
-    AcceptParser.parseAcceptHeaders("appication/*, */*;q=1.0001");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptHeaderValue("appication/*, */*;q=1.0001");
+    parser.parseAcceptHeaders();
   }
 
   @Test
   public void testAcceptLanguages() throws BatchException {
-    List<String> acceptLanguageHeaders = AcceptParser.parseAcceptableLanguages("en-US,en;q=0.7,en-UK;q=0.9");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptLanguageHeaderValue("en-US,en;q=0.7,en-UK;q=0.9");
+    List<String> acceptLanguageHeaders = parser.parseAcceptableLanguages();
+
     assertNotNull(acceptLanguageHeaders);
     assertEquals(3, acceptLanguageHeaders.size());
     assertEquals("en-US", acceptLanguageHeaders.get(0));
@@ -134,20 +161,28 @@ public class AcceptParserTest {
 
   @Test
   public void testAllAcceptLanguages() throws BatchException {
-    List<String> acceptLanguageHeaders = AcceptParser.parseAcceptableLanguages("*");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptLanguageHeaderValue("*");
+    List<String> acceptLanguageHeaders = parser.parseAcceptableLanguages();
+    
     assertNotNull(acceptLanguageHeaders);
     assertEquals(1, acceptLanguageHeaders.size());
   }
 
   @Test
   public void testLongAcceptLanguageValue() throws BatchException {
-    List<String> acceptLanguageHeaders = AcceptParser.parseAcceptableLanguages("english");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptLanguageHeaderValue("english");
+    List<String> acceptLanguageHeaders = parser.parseAcceptableLanguages();
+    
     assertNotNull(acceptLanguageHeaders);
     assertEquals("english", acceptLanguageHeaders.get(0));
   }
 
   @Test(expected = BatchException.class)
   public void testInvalidAcceptLanguageValue() throws BatchException {
-    AcceptParser.parseAcceptableLanguages("en_US");
+    AcceptParser parser = new AcceptParser();
+    parser.addAcceptLanguageHeaderValue("en_US");
+    parser.parseAcceptableLanguages();
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
index c9e9a6b..8451c55 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
@@ -1,54 +1,170 @@
 package org.apache.olingo.odata2.core.batch;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Locale;
+import java.util.Map;
 
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.commons.HttpHeaders;
 import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon;
+import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
 import org.junit.Test;
 
 public class BatchParserCommonTest {
-
+  
+  private static final String CRLF = "\r\n";
+  
   @Test
-  public void testTrimList() {
-    final List<String> list = Arrays.asList(new String[] { "123\r\n", "abc", "a\n", "\r", "123" });
-    final List<String> trimedList = BatchParserCommon.trimStringListToLength(list, 7);
-
-    assertEquals(2, trimedList.size());
-    assertEquals("123\r\n", trimedList.get(0));
-    assertEquals("ab", trimedList.get(1));
+  public void testMultipleHeader() throws BatchException {
+    String[] messageRaw = new String[] {
+        "Content-Id: 1" + CRLF,
+        "Content-Id: 2" + CRLF,
+        "content-type: Application/http" + CRLF,
+        "content-transfer-encoding: Binary" + CRLF
+      };
+    List<String> message = new ArrayList<String>();
+    message.addAll(Arrays.asList(messageRaw));
+    
+    
+    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    assertNotNull(header);
+    
+    final HeaderField contentIdHeaders = header.get(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH));
+    assertNotNull(contentIdHeaders);
+    assertEquals(2, contentIdHeaders.getValues().size());
+    assertEquals("1", contentIdHeaders.getValues().get(0));
+    assertEquals("2", contentIdHeaders.getValues().get(1));
   }
-
+  
   @Test
-  public void testTrimListWithEmptyString() {
-    final List<String> list = Arrays.asList(new String[] { "123\r\n", "", "abc", "a\n", "\r", "123" });
-    final List<String> trimedList = BatchParserCommon.trimStringListToLength(list, 7);
-
-    assertEquals(3, trimedList.size());
-    assertEquals("123\r\n", trimedList.get(0));
-    assertEquals("", trimedList.get(1));
-    assertEquals("ab", trimedList.get(2));
+  public void testMultipleHeaderSameValue() throws BatchException {
+    String[] messageRaw = new String[] {
+        "Content-Id: 1" + CRLF,
+        "Content-Id: 1" + CRLF,
+        "content-type: Application/http" + CRLF,
+        "content-transfer-encoding: Binary" + CRLF
+      };
+    List<String> message = new ArrayList<String>();
+    message.addAll(Arrays.asList(messageRaw));
+    
+    
+    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    assertNotNull(header);
+    
+    final HeaderField contentIdHeaders = header.get(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH));
+    assertNotNull(contentIdHeaders);
+    assertEquals(1, contentIdHeaders.getValues().size());
+    assertEquals("1", contentIdHeaders.getValues().get(0));
   }
-
+  
   @Test
-  public void testTrimListTryToReadMoreThanStringLength() {
-    final List<String> list = Arrays.asList(new String[] { "abc\r\n", "123" });
-    final List<String> trimedList = BatchParserCommon.trimStringListToLength(list, 100);
-
-    assertEquals(2, trimedList.size());
-    assertEquals("abc\r\n", trimedList.get(0));
-    assertEquals("123", trimedList.get(1));
+  public void testHeaderSperatedByComma() throws BatchException {
+    String[] messageRaw = new String[] {
+        "Content-Id: 1" + CRLF,
+        "Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11" + CRLF,
+        "content-type: Application/http" + CRLF,
+        "content-transfer-encoding: Binary" + CRLF
+      };
+    List<String> message = new ArrayList<String>();
+    message.addAll(Arrays.asList(messageRaw));
+    
+    
+    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    assertNotNull(header);
+    
+    final HeaderField upgradeHeader = header.get("upgrade");
+    assertNotNull(upgradeHeader);
+    assertEquals(4, upgradeHeader.getValues().size());
+    assertEquals("HTTP/2.0", upgradeHeader.getValues().get(0));
+    assertEquals("SHTTP/1.3", upgradeHeader.getValues().get(1));
+    assertEquals("IRC/6.9", upgradeHeader.getValues().get(2));
+    assertEquals("RTA/x11", upgradeHeader.getValues().get(3));
   }
-
+  
   @Test
-  public void testTrimListEmpty() {
-    final List<String> list = Arrays.asList(new String[0]);
-    final List<String> trimedList = BatchParserCommon.trimStringListToLength(list, 7);
-
-    assertEquals(0, trimedList.size());
+  public void testMultipleAcceptHeader() throws BatchException {
+    String[] messageRaw = new String[] {
+        "Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1" + CRLF,
+        "Accept: text/plain;q=0.3" + CRLF,
+        "Accept-Language:en-US,en;q=0.7,en-UK;q=0.9" + CRLF,
+        "content-type: Application/http" + CRLF,
+        "content-transfer-encoding: Binary" + CRLF
+      };
+    List<String> message = new ArrayList<String>();
+    message.addAll(Arrays.asList(messageRaw));
+    
+    
+    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    assertNotNull(header);
+    
+    final HeaderField acceptHeader = header.get(HttpHeaders.ACCEPT.toLowerCase());
+    assertNotNull(acceptHeader);
+    assertEquals(4, acceptHeader.getValues().size());
   }
-
+  
+  @Test
+  public void testMultipleAcceptHeaderSameValue() throws BatchException {
+    String[] messageRaw = new String[] {
+        "Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1" + CRLF,
+        "Accept: application/atomsvc+xml;q=0.8" + CRLF,
+        "Accept-Language:en-US,en;q=0.7,en-UK;q=0.9" + CRLF,
+        "content-type: Application/http" + CRLF,
+        "content-transfer-encoding: Binary" + CRLF
+      };
+    List<String> message = new ArrayList<String>();
+    message.addAll(Arrays.asList(messageRaw));
+    
+    
+    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    assertNotNull(header);
+    
+    final HeaderField acceptHeader = header.get(HttpHeaders.ACCEPT.toLowerCase());
+    assertNotNull(acceptHeader);
+    assertEquals(3, acceptHeader.getValues().size());
+  }
+  
+  @Test
+  public void testMultipleAccepLanguagetHeader() throws BatchException {
+    String[] messageRaw = new String[] {
+        "Accept-Language:en-US,en;q=0.7,en-UK;q=0.9" + CRLF,
+        "Accept-Language: de-DE;q=0.3" + CRLF,
+        "content-type: Application/http" + CRLF,
+        "content-transfer-encoding: Binary" + CRLF
+      };
+    List<String> message = new ArrayList<String>();
+    message.addAll(Arrays.asList(messageRaw));
+    
+    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    assertNotNull(header);
+    
+    final HeaderField acceptLanguageHeader = header.get(HttpHeaders.ACCEPT_LANGUAGE.toLowerCase());
+    assertNotNull(acceptLanguageHeader);
+    assertEquals(4, acceptLanguageHeader.getValues().size());
+  }
+  
+  @Test
+  public void testMultipleAccepLanguagetHeaderSameValue() throws BatchException {
+    String[] messageRaw = new String[] {
+        "Accept-Language:en-US,en;q=0.7,en-UK;q=0.9" + CRLF,
+        "Accept-Language:en-US,en;q=0.7" + CRLF,
+        "content-type: Application/http" + CRLF,
+        "content-transfer-encoding: Binary" + CRLF
+      };
+    List<String> message = new ArrayList<String>();
+    message.addAll(Arrays.asList(messageRaw));
+    
+    final Map<String, HeaderField> header = BatchParserCommon.consumeHeaders(message);
+    assertNotNull(header);
+    
+    final HeaderField acceptLanguageHeader = header.get(HttpHeaders.ACCEPT_LANGUAGE.toLowerCase());
+    assertNotNull(acceptLanguageHeader);
+    assertEquals(3, acceptLanguageHeader.getValues().size());
+  }
+  
   @Test
   public void testRemoveEndingCRLF() {
     String line = "Test\r\n";

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
index 7866004..4cd0b67 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
@@ -431,7 +431,7 @@ public class BatchRequestParserTest {
         + "--batch_8194-cf13-1f56--";
     parseInvalidBatchBody(batch);
   }
-  
+
   @Test(expected = BatchException.class)
   public void testMissingContentTransferEncoding() throws BatchException {
     String batch = "--batch_8194-cf13-1f56" + CRLF
@@ -439,7 +439,7 @@ public class BatchRequestParserTest {
         + CRLF
         + "--changeset_f980-1cb6-94dd" + CRLF
         + "Content-Type: application/http" + CRLF
-        //+ "Content-Transfer-Encoding: binary" + CRLF
+        // + "Content-Transfer-Encoding: binary" + CRLF
         + CRLF
         + "POST Employees('2') HTTP/1.1" + CRLF
         + "Content-Type: application/json;odata=verbose" + CRLF
@@ -449,14 +449,14 @@ public class BatchRequestParserTest {
         + "--batch_8194-cf13-1f56--";
     parseInvalidBatchBody(batch);
   }
-  
+
   @Test(expected = BatchException.class)
   public void testMissingContentType() throws BatchException {
     String batch = "--batch_8194-cf13-1f56" + CRLF
         + "Content-Type: multipart/mixed;boundary=changeset_f980-1cb6-94dd" + CRLF
         + CRLF
         + "--changeset_f980-1cb6-94dd" + CRLF
-        //+ "Content-Type: application/http" + CRLF
+        // + "Content-Type: application/http" + CRLF
         + "Content-Transfer-Encoding: binary" + CRLF
         + CRLF
         + "POST Employees('2') HTTP/1.1" + CRLF
@@ -467,7 +467,7 @@ public class BatchRequestParserTest {
         + "--batch_8194-cf13-1f56--";
     parseInvalidBatchBody(batch);
   }
-  
+
   @Test(expected = BatchException.class)
   public void testNoCloseDelimiter() throws BatchException {
     String batch = "--batch_8194-cf13-1f56" + CRLF
@@ -605,32 +605,33 @@ public class BatchRequestParserTest {
 
     }
   }
-  
+
   @SuppressWarnings("unused")
-  @Test(expected=BatchException.class)
+  @Test(expected = BatchException.class)
+  @Ignore("This header should not be validated")
   public void testNegativeContentLength() throws BatchException, IOException {
-      String batch = ""
-          + "--batch_8194-cf13-1f56" + CRLF
-          + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
-          + "Content-Length: -2" + CRLF
-          + CRLF
-          + "--changeset_f980-1cb6-94dd" + CRLF
-          + MIME_HEADERS
-          + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
-          + CRLF
-          + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
-          + "Content-Type: application/json;odata=verbose" + CRLF
-          + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
-          + CRLF
-          + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
-          + "--changeset_f980-1cb6-94dd--" + CRLF
-          + CRLF
-          + "--batch_8194-cf13-1f56--";
-      InputStream in = new ByteArrayInputStream(batch.getBytes());
-      BatchParser parser = new BatchParser(contentType, batchProperties, true);
-      List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
+    String batch = ""
+        + "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
+        + "Content-Length: -2" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + CRLF
+        + "--batch_8194-cf13-1f56--";
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
   }
-  
+
   @SuppressWarnings("unused")
   @Test
   public void testNegativeContentLengthChangeSet() throws BatchException, IOException {
@@ -655,9 +656,9 @@ public class BatchRequestParserTest {
     BatchParser parser = new BatchParser(contentType, batchProperties, true);
     List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
   }
-  
+
   @SuppressWarnings("unused")
-  @Test(expected=BatchException.class)
+  @Test(expected = BatchException.class)
   public void testNegativeContentLengthRequest() throws BatchException, IOException {
     String batch = ""
         + "--batch_8194-cf13-1f56" + CRLF
@@ -680,7 +681,7 @@ public class BatchRequestParserTest {
     BatchParser parser = new BatchParser(contentType, batchProperties, true);
     List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
   }
-  
+
   @Test
   public void testContentLengthGreatherThanBodyLength() throws BatchException, IOException {
     String batch = ""
@@ -746,6 +747,7 @@ public class BatchRequestParserTest {
   }
 
   @Test(expected = BatchException.class)
+  @Ignore("This header should not be validated")
   public void testCutChangeSetDelimiter() throws BatchException, IOException {
     String batch = ""
         + "--batch_8194-cf13-1f56" + CRLF
@@ -918,7 +920,7 @@ public class BatchRequestParserTest {
       }
     }
   }
-  
+
   @Test
   public void testNoContentId() throws BatchException {
     String batch = "--batch_8194-cf13-1f56" + CRLF
@@ -950,10 +952,10 @@ public class BatchRequestParserTest {
         + "--batch_8194-cf13-1f56--";
     InputStream in = new ByteArrayInputStream(batch.getBytes());
     BatchParser parser = new BatchParser(contentType, batchProperties, true);
-    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);  // No exception should be thrown
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in); // No exception should be thrown
     assertNotNull(batchRequestParts);
   }
-  
+
   @Test
   public void testPreamble() throws BatchException, IOException {
     String batch = ""
@@ -1017,6 +1019,60 @@ public class BatchRequestParserTest {
         inputStreamToString(changeSetPart.getRequests().get(1).getBody()));
   }
 
+  @SuppressWarnings("unused")
+  @Test
+  public void testContentTypeCaseInsensitive() throws BatchException, IOException {
+    String batch = ""
+        + "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: muLTiParT/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
+        + "Content-Length: -2" + CRLF
+        + CRLF
+        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + CRLF
+        + "--batch_8194-cf13-1f56--";
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
+  }
+
+  @Test
+  public void testContentTypeBoundaryCaseInsensitive() throws BatchException, IOException {
+    String batch = ""
+        + "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed; bOunDaRy=changeset_f980-1cb6-94dd" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
+        + "Content-Length: -2" + CRLF
+        + CRLF
+        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + CRLF
+        + "--batch_8194-cf13-1f56--";
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
+
+    assertNotNull(batchRequestParts);
+    assertEquals(1, batchRequestParts.size());
+    assertTrue(batchRequestParts.get(0).isChangeSet());
+    assertEquals(1, batchRequestParts.get(0).getRequests().size());
+  }
+
   @Test
   public void testEpilog() throws BatchException, IOException {
     String batch = ""

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f90b733/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
index a0ab9f4..a70d15a 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
@@ -26,7 +26,17 @@ public class BatchTransformatorCommonTest {
 
   @Test
   public void testValidateContentTypeMultipartMixed() throws BatchException {
-    List<String> contentTypeValues = Arrays.asList(new String[] { HttpContentType.MULTIPART_MIXED });
+    List<String> contentTypeValues =
+        Arrays.asList(new String[] { HttpContentType.MULTIPART_MIXED + "; boundary=batch_32332_32323_fdsf" });
+    Map<String, HeaderField> headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
+
+    BatchTransformatorCommon.validateContentType(headers);
+  }
+
+  @Test
+  public void testValidateContentTypeMultipartMixedCaseInsensitiv() throws BatchException {
+    List<String> contentTypeValues =
+        Arrays.asList(new String[] { "mulTiPart/MiXed; boundary=batch_32332_32323_fdsf" });
     Map<String, HeaderField> headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
 
     BatchTransformatorCommon.validateContentType(headers);


[02/19] Batch Parser

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
new file mode 100644
index 0000000..3626686
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * 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.odata2.core.batch.v2;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.batch.BatchParserResult;
+import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
+import org.apache.olingo.odata2.api.exception.MessageReference;
+import org.apache.olingo.odata2.api.processor.ODataRequest;
+import org.apache.olingo.odata2.api.processor.ODataRequest.ODataRequestBuilder;
+import org.apache.olingo.odata2.api.uri.PathInfo;
+import org.apache.olingo.odata2.core.batch.BatchHelper;
+import org.apache.olingo.odata2.core.batch.BatchRequestPartImpl;
+import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
+
+public class BatchRequestTransformator implements BatchTransformator {
+
+  private static final Set<String> HTTP_BATCH_METHODS = new HashSet<String>(Arrays.asList(new String[] { "GET" }));
+  private static final Set<String> HTTP_CHANGE_SET_METHODS = new HashSet<String>(Arrays.asList(new String[] { "POST",
+      "PUT", "DELETE", "MERGE", "PATCH" }));
+
+  @Override
+  public List<BatchParserResult> transform(final BatchBodyPart bodyPart, final PathInfo pathInfo, final String baseUri)
+      throws BatchException {
+
+    final List<ODataRequest> requests = new LinkedList<ODataRequest>();
+    final List<BatchParserResult> resultList = new ArrayList<BatchParserResult>();
+
+    BatchTransformatorCommon.parsePartSyntax(bodyPart);
+    validateBodyPartHeaders(bodyPart);
+
+    for (BatchQueryOperation queryOperation : bodyPart.getRequests()) {
+      requests.add(processQueryOperation(bodyPart, pathInfo, baseUri, queryOperation));
+    }
+
+    resultList.add(new BatchRequestPartImpl(bodyPart.isChangeSet(), requests));
+    return resultList;
+  }
+
+  private void validateBodyPartHeaders(final BatchBodyPart bodyPart) throws BatchException {
+    Map<String, HeaderField> headers = bodyPart.getHeaders();
+
+    BatchTransformatorCommon.validateContentType(headers);
+    BatchTransformatorCommon.validateContentTransferEncoding(headers, false);
+  }
+
+  private ODataRequest processQueryOperation(final BatchBodyPart bodyPart, final PathInfo pathInfo,
+      final String baseUri, final BatchQueryOperation queryOperation) throws BatchException {
+
+    if (bodyPart.isChangeSet()) {
+      BatchQueryOperation encapsulatedQueryOperation = ((BatchChangeSet) queryOperation).getRequest();
+      Map<String, HeaderField> headers = transformHeader(encapsulatedQueryOperation, queryOperation);
+      validateChangeSetMultipartMimeHeaders(queryOperation, encapsulatedQueryOperation);
+
+      return createRequest(queryOperation, headers, pathInfo, baseUri, bodyPart.isChangeSet());
+    } else {
+
+      Map<String, HeaderField> headers = transformHeader(queryOperation, bodyPart);
+      return createRequest(queryOperation, headers, pathInfo, baseUri, bodyPart.isChangeSet());
+    }
+  }
+
+  private void validateChangeSetMultipartMimeHeaders(final BatchQueryOperation queryOperation,
+      final BatchQueryOperation encapsulatedQueryOperation) throws BatchException {
+    BatchTransformatorCommon.validateContentType(queryOperation.getHeaders());
+    BatchTransformatorCommon.validateContentTransferEncoding(queryOperation.getHeaders(), true);
+  }
+
+  private ODataRequest createRequest(final BatchQueryOperation operation, final Map<String, HeaderField> headers,
+      final PathInfo pathInfo, final String baseUri, final boolean isChangeSet) throws BatchException {
+
+    ODataHttpMethod httpMethod = getHttpMethod(operation.getHttpMethod());
+    validateHttpMethod(httpMethod, isChangeSet);
+    validateBody(httpMethod, operation);
+    InputStream bodyStrean = getBodyStream(operation, headers, httpMethod);
+
+    ODataRequestBuilder requestBuilder = ODataRequest.method(httpMethod)
+        .acceptableLanguages(getAcceptLanguageHeaders(headers))
+        .acceptHeaders(getAcceptHeaders(headers))
+        .allQueryParameters(BatchParserCommon.parseQueryParameter(operation.getHttpMethod()))
+        .body(bodyStrean)
+        .requestHeaders(BatchParserCommon.headerFieldMapToMultiMap(headers))
+        .pathInfo(BatchParserCommon.parseRequestUri(operation.getHttpMethod(), pathInfo, baseUri));
+
+    addContentTypeHeader(requestBuilder, headers);
+
+    return requestBuilder.build();
+  }
+
+  private void validateBody(final ODataHttpMethod httpMethod, final BatchQueryOperation operation)
+      throws BatchException {
+    if (HTTP_BATCH_METHODS.contains(httpMethod.toString()) && isUnvalidGetRequestBody(operation)) {
+      throw new BatchException(BatchException.INVALID_REQUEST_LINE);
+    }
+  }
+
+  private boolean isUnvalidGetRequestBody(final BatchQueryOperation operation) {
+    return (operation.getBody().size() > 1)
+        || (operation.getBody().size() == 1 && !operation.getBody().get(0).trim().equals(""));
+  }
+
+  private InputStream getBodyStream(final BatchQueryOperation operation, final Map<String, HeaderField> headers,
+      final ODataHttpMethod httpMethod) throws BatchException {
+
+    if (HTTP_BATCH_METHODS.contains(httpMethod.toString())) {
+      return new ByteArrayInputStream(new byte[0]);
+    } else {
+      int contentLength = BatchTransformatorCommon.getContentLength(headers);
+      contentLength = (contentLength >= 0) ? contentLength : Integer.MAX_VALUE;
+
+      return BatchParserCommon.convertMessageToInputStream(operation.getBody(), contentLength);
+    }
+  }
+
+  private Map<String, HeaderField> transformHeader(final BatchPart operation, final BatchPart parentPart) {
+    final Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
+    final Map<String, HeaderField> operationHeader = operation.getHeaders();
+    final Map<String, HeaderField> parentHeaders = parentPart.getHeaders();
+
+    for (final String key : operation.getHeaders().keySet()) {
+      headers.put(key, operation.getHeaders().get(key).clone());
+    }
+
+    headers.remove(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH));
+
+    if (operationHeader.containsKey(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH))) {
+      HeaderField operationContentField = operationHeader.get(BatchHelper.HTTP_CONTENT_ID.toLowerCase());
+      headers.put(BatchHelper.REQUEST_HEADER_CONTENT_ID.toLowerCase(Locale.ENGLISH), new HeaderField(
+          BatchHelper.REQUEST_HEADER_CONTENT_ID, operationContentField.getValues()));
+    }
+
+    if (parentHeaders.containsKey(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH))) {
+      HeaderField parentContentField = parentHeaders.get(BatchHelper.HTTP_CONTENT_ID.toLowerCase());
+      headers.put(BatchHelper.MIME_HEADER_CONTENT_ID.toLowerCase(Locale.ENGLISH), new HeaderField(
+          BatchHelper.MIME_HEADER_CONTENT_ID, parentContentField.getValues()));
+    }
+
+    return headers;
+  }
+
+  private void validateHttpMethod(final ODataHttpMethod httpMethod, final boolean isChangeSet) throws BatchException {
+    Set<String> validMethods = (isChangeSet) ? HTTP_CHANGE_SET_METHODS : HTTP_BATCH_METHODS;
+
+    if (!validMethods.contains(httpMethod.toString())) {
+      MessageReference message =
+          (isChangeSet) ? BatchException.INVALID_CHANGESET_METHOD : BatchException.INVALID_QUERY_OPERATION_METHOD;
+      throw new BatchException(message);
+    }
+  }
+
+  private void addContentTypeHeader(final ODataRequestBuilder requestBuilder, final Map<String, HeaderField> header) {
+    String contentType = getContentTypeHeader(header);
+
+    if (contentType != null) {
+      requestBuilder.contentType(contentType);
+    }
+  }
+
+  private String getContentTypeHeader(final Map<String, HeaderField> headers) {
+    HeaderField contentTypeField = headers.get(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH));
+    String contentType = null;
+    if (contentTypeField != null) {
+      for (String requestContentType : contentTypeField.getValues()) {
+        contentType = contentType != null ? contentType + "," + requestContentType : requestContentType;
+      }
+    }
+
+    return contentType;
+  }
+
+  private List<String> getAcceptHeaders(final Map<String, HeaderField> headers) {
+    List<String> acceptHeaders = new ArrayList<String>();
+    HeaderField requestAcceptHeaderField = headers.get(HttpHeaders.ACCEPT.toLowerCase(Locale.ENGLISH));
+
+    if (requestAcceptHeaderField != null) {
+      acceptHeaders = requestAcceptHeaderField.getValues();
+    }
+
+    return acceptHeaders;
+  }
+
+  private List<Locale> getAcceptLanguageHeaders(final Map<String, HeaderField> headers) {
+    final HeaderField requestAcceptLanguageField = headers.get(HttpHeaders.ACCEPT_LANGUAGE.toLowerCase(Locale.ENGLISH));
+    List<Locale> acceptLanguages = new ArrayList<Locale>();
+
+    if (requestAcceptLanguageField != null) {
+      for (String acceptLanguage : requestAcceptLanguageField.getValues()) {
+        String[] part = acceptLanguage.split("-");
+        String language = part[0];
+        String country = "";
+        if (part.length == 2) {
+          country = part[part.length - 1];
+        }
+        Locale locale = new Locale(language, country);
+        acceptLanguages.add(locale);
+      }
+    }
+
+    return acceptLanguages;
+  }
+
+  private ODataHttpMethod getHttpMethod(final String httpRequest) throws BatchException {
+    ODataHttpMethod result = null;
+
+    if (httpRequest != null) {
+      String[] parts = httpRequest.split(" ");
+
+      if (parts.length == 3) {
+        try {
+          result = ODataHttpMethod.valueOf(parts[0]);
+        } catch (IllegalArgumentException e) {
+          throw new BatchException(BatchException.MISSING_METHOD, e);
+        }
+      } else {
+        throw new BatchException(BatchException.INVALID_REQUEST_LINE);
+      }
+    } else {
+      throw new BatchException(BatchException.INVALID_REQUEST_LINE);
+    }
+
+    return result;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
new file mode 100644
index 0000000..88f5064
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * 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.odata2.core.batch.v2;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.batch.BatchParserResult;
+import org.apache.olingo.odata2.api.client.batch.BatchSingleResponse;
+import org.apache.olingo.odata2.api.uri.PathInfo;
+import org.apache.olingo.odata2.core.batch.BatchHelper;
+import org.apache.olingo.odata2.core.batch.BatchSingleResponseImpl;
+import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
+
+public class BatchResponseTransformator implements BatchTransformator {
+
+  private static final String REG_EX_STATUS_LINE = "(?:HTTP/[0-9]\\.[0-9])\\s([0-9]{3})\\s([\\S ]+)\\s*";
+
+  public BatchResponseTransformator() {}
+
+  @Override
+  public List<BatchParserResult> transform(final BatchBodyPart bodyPart, final PathInfo pathInfo, final String baseUri)
+      throws BatchException {
+    return processQueryOperation(bodyPart, pathInfo, baseUri);
+  }
+
+  private List<BatchParserResult> processQueryOperation(final BatchBodyPart bodyPart,
+      final PathInfo pathInfo,
+      final String baseUri) throws BatchException {
+
+    List<BatchParserResult> resultList = new ArrayList<BatchParserResult>();
+
+    BatchTransformatorCommon.parsePartSyntax(bodyPart);
+    BatchTransformatorCommon.validateContentType(bodyPart.getHeaders());
+
+    resultList.addAll(handleBodyPart(bodyPart));
+
+    return resultList;
+  }
+
+  private List<BatchParserResult> handleBodyPart(final BatchBodyPart bodyPart) throws BatchException {
+    List<BatchParserResult> bodyPartResult = new ArrayList<BatchParserResult>();
+
+    if (bodyPart.isChangeSet()) {
+      for (BatchQueryOperation operation : bodyPart.getRequests()) {
+        bodyPartResult.add(transformChangeSet((BatchChangeSet) operation));
+      }
+    } else {
+      bodyPartResult.add(transformQueryOperation(bodyPart.getRequests().get(0), getContentId(bodyPart.getHeaders())));
+    }
+
+    return bodyPartResult;
+  }
+
+  private BatchSingleResponse transformChangeSet(final BatchChangeSet changeSet) throws BatchException {
+    BatchTransformatorCommon.validateContentTransferEncoding(changeSet.getHeaders(), true);
+
+    return transformQueryOperation(changeSet.getRequest(), getContentId(changeSet.getHeaders()));
+  }
+
+  private BatchSingleResponse transformQueryOperation(final BatchQueryOperation operation, final String contentId)
+      throws BatchException {
+    BatchSingleResponseImpl response = new BatchSingleResponseImpl();
+    response.setContentId(contentId);
+    response.setHeaders(BatchParserCommon.headerFieldMapToSingleMap(operation.getHeaders()));
+    response.setStatusCode(getStatusCode(operation.httpMethod));
+    response.setStatusInfo(getStatusInfo(operation.getHttpMethod()));
+    response.setBody(getBody(operation));
+
+    return response;
+  }
+
+  private String getContentId(final Map<String, HeaderField> headers) {
+    HeaderField contentIdField = headers.get(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH));
+
+    if (contentIdField != null) {
+      if (contentIdField.getValues().size() > 0) {
+        return contentIdField.getValues().get(0);
+      }
+    }
+
+    return null;
+  }
+
+  private String getBody(final BatchQueryOperation operation) throws BatchException {
+    int contentLength = BatchTransformatorCommon.getContentLength(operation.getHeaders());
+    List<String> body = BatchParserCommon.trimStringListToLength(operation.getBody(), contentLength);
+    return BatchParserCommon.stringListToString(body);
+  }
+
+  private String getStatusCode(final String httpMethod) throws BatchException {
+    Pattern regexPattern = Pattern.compile(REG_EX_STATUS_LINE);
+    Matcher matcher = regexPattern.matcher(httpMethod);
+
+    if (matcher.find()) {
+      return matcher.group(1);
+    } else {
+      throw new BatchException(BatchException.INVALID_STATUS_LINE);
+    }
+  }
+
+  private String getStatusInfo(final String httpMethod) throws BatchException {
+    Pattern regexPattern = Pattern.compile(REG_EX_STATUS_LINE);
+    Matcher matcher = regexPattern.matcher(httpMethod);
+
+    if (matcher.find()) {
+      return matcher.group(2);
+    } else {
+      throw new BatchException(BatchException.INVALID_STATUS_LINE);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformator.java
new file mode 100644
index 0000000..5dcddbf
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformator.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.odata2.core.batch.v2;
+
+import java.util.List;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.batch.BatchParserResult;
+import org.apache.olingo.odata2.api.uri.PathInfo;
+
+public interface BatchTransformator {
+  public List<BatchParserResult> transform(BatchBodyPart bodyPart, PathInfo pathInfo, String baseUri)
+      throws BatchException;
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
new file mode 100644
index 0000000..2098708
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
@@ -0,0 +1,84 @@
+package org.apache.olingo.odata2.core.batch.v2;
+
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.commons.HttpContentType;
+import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.core.batch.BatchHelper;
+import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
+
+public class BatchTransformatorCommon {
+
+  public static void validateContentType(final Map<String, HeaderField> headers) throws BatchException {
+    if (headers.containsKey(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH))) {
+      HeaderField contentTypeField = headers.get(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH));
+
+      if (contentTypeField.getValues().size() == 1) {
+        String contentType = contentTypeField.getValues().get(0);
+
+        if (!(HttpContentType.APPLICATION_HTTP.equalsIgnoreCase(contentType)
+        || contentType.contains(HttpContentType.MULTIPART_MIXED))) {
+
+          throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(HttpContentType.MULTIPART_MIXED
+              + " or " + HttpContentType.APPLICATION_HTTP));
+        }
+      } else if (contentTypeField.getValues().size() == 0) {
+        throw new BatchException(BatchException.MISSING_CONTENT_TYPE);
+      } else {
+        throw new BatchException(BatchException.INVALID_HEADER);
+      }
+    } else {
+      throw new BatchException(BatchException.MISSING_CONTENT_TYPE);
+    }
+  }
+
+  public static void validateContentTransferEncoding(final Map<String, HeaderField> headers, boolean isChangeRequest)
+      throws BatchException {
+    if (headers.containsKey(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING.toLowerCase(Locale.ENGLISH))) {
+      HeaderField encodingField = headers.get(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING.toLowerCase(Locale.ENGLISH));
+
+      if (encodingField.getValues().size() == 1) {
+        String encoding = encodingField.getValues().get(0);
+
+        if (!BatchHelper.BINARY_ENCODING.equalsIgnoreCase(encoding)) {
+          throw new BatchException(BatchException.INVALID_CONTENT_TRANSFER_ENCODING);
+        }
+      } else if (encodingField.getValues().size() == 0) {
+        throw new BatchException(BatchException.INVALID_CONTENT_TRANSFER_ENCODING);
+      } else {
+        throw new BatchException(BatchException.INVALID_HEADER);
+      }
+    } else {
+      if (isChangeRequest) {
+        throw new BatchException(BatchException.INVALID_CONTENT_TRANSFER_ENCODING);
+      }
+    }
+  }
+
+  public static void parsePartSyntax(final BatchBodyPart bodyPart) throws BatchException {
+    int contentLength = BatchTransformatorCommon.getContentLength(bodyPart.getHeaders());
+    bodyPart.parse(contentLength);
+  }
+
+  public static int getContentLength(final Map<String, HeaderField> headers) throws BatchException {
+
+    if (headers.containsKey(HttpHeaders.CONTENT_LENGTH.toLowerCase(Locale.ENGLISH))) {
+      try {
+        int contentLength =
+            Integer.parseInt(headers.get(HttpHeaders.CONTENT_LENGTH.toLowerCase(Locale.ENGLISH)).getValues().get(0));
+
+        if (contentLength < 0) {
+          throw new BatchException(BatchException.INVALID_HEADER);
+        }
+
+        return contentLength;
+      } catch (NumberFormatException e) {
+        throw new BatchException(BatchException.INVALID_HEADER, e);
+      }
+    }
+
+    return Integer.MAX_VALUE;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
new file mode 100644
index 0000000..5e411ff
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * 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.odata2.core.batch.v2;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+
+public class BufferedReaderIncludingLineEndings extends Reader {
+  private static final char CR = '\r';
+  private static final char LF = '\n';
+  private static final int EOF = -1;
+  private static final int BUFFER_SIZE = 1024;
+  private Reader reader;
+  private char[] buffer;
+  private int offset = 0;
+  private int limit = 0;
+
+  public BufferedReaderIncludingLineEndings(final Reader reader) {
+    this(reader, BUFFER_SIZE);
+  }
+
+  public BufferedReaderIncludingLineEndings(final Reader reader, final int bufferSize) {
+    if (bufferSize <= 0) {
+      throw new IllegalArgumentException("Buffer size must be greater than zero.");
+    }
+
+    this.reader = reader;
+    buffer = new char[bufferSize];
+  }
+
+  @Override
+  public int read(final char[] charBuffer, final int bufferOffset, final int length) throws IOException {
+    if ((bufferOffset + length) > charBuffer.length) {
+      throw new IndexOutOfBoundsException("Buffer is too small");
+    }
+
+    if (length < 0 || bufferOffset < 0) {
+      throw new IndexOutOfBoundsException("Offset and length must be grater than zero");
+    }
+
+    // Check if buffer is filled. Return if EOF is reached
+    if (isBufferReloadRequired() || isEOF()) {
+      fillBuffer();
+
+      if (isEOF()) {
+        return EOF;
+      }
+    }
+
+    int bytesRead = 0;
+    int bytesToRead = length;
+    int currentOutputOffset = bufferOffset;
+
+    while (bytesToRead != 0) {
+      if (isBufferReloadRequired()) {
+        fillBuffer();
+
+        if (isEOF()) {
+          bytesToRead = 0;
+        }
+      }
+
+      if (bytesToRead > 0) {
+        int readByte = Math.min(limit - offset, bytesToRead);
+        bytesRead += readByte;
+        bytesToRead -= readByte;
+
+        for (int i = 0; i < readByte; i++) {
+          charBuffer[currentOutputOffset++] = buffer[offset++];
+        }
+      }
+    }
+
+    return bytesRead;
+  }
+
+  public List<String> toList() throws IOException {
+    final List<String> result = new ArrayList<String>();
+    String currentLine;
+
+    while ((currentLine = readLine()) != null) {
+      result.add(currentLine);
+    }
+
+    return result;
+  }
+
+  public String readLine() throws IOException {
+    if (isEOF()) {
+      return null;
+    }
+
+    final StringBuilder stringBuffer = new StringBuilder();
+    boolean foundLineEnd = false; // EOF will be considered as line ending
+
+    while (!foundLineEnd) {
+      if (isBufferReloadRequired()) {
+        if (fillBuffer() == EOF) {
+          foundLineEnd = true;
+        }
+      }
+
+      if (!foundLineEnd) {
+        char currentChar = buffer[offset++];
+        stringBuffer.append(currentChar);
+
+        if (currentChar == LF) {
+          foundLineEnd = true;
+        } else if (currentChar == CR) {
+          foundLineEnd = true;
+
+          // Check next char. Consume \n if available
+          if (isBufferReloadRequired()) {
+            fillBuffer();
+          }
+
+          // Check if there is at least one character
+          if (!isEOF() && buffer[offset] == LF) {
+            stringBuffer.append(LF);
+            offset++;
+          }
+        }
+      }
+    }
+
+    return (stringBuffer.length() == 0) ? null : stringBuffer.toString();
+  }
+
+  @Override
+  public void close() throws IOException {
+    reader.close();
+  }
+
+  @Override
+  public boolean ready() throws IOException {
+    return !isEOF() && !isBufferReloadRequired();
+  }
+
+  @Override
+  public void reset() throws IOException {
+    throw new IOException("Reset is not supported");
+  }
+
+  @Override
+  public void mark(final int readAheadLimit) throws IOException {
+    throw new IOException("Mark is not supported");
+  }
+
+  @Override
+  public boolean markSupported() {
+    return false;
+  }
+
+  @Override
+  public long skip(final long n) throws IOException {
+    if (n == 0) {
+      return 0;
+    } else if (n < 0) {
+      throw new IllegalArgumentException("skip value is negative");
+    } else {
+      long charactersToSkip = n;
+      long charactersSkiped = 0;
+
+      while (charactersToSkip != 0) {
+        // Check if buffer is empty
+        if (isBufferReloadRequired()) {
+          fillBuffer();
+
+          if (isEOF()) {
+            charactersToSkip = 0;
+          }
+        }
+
+        // Check if more characters are available
+        if (!isEOF()) {
+          int skipChars = (int) Math.min(limit - offset, charactersToSkip);
+
+          charactersSkiped += skipChars;
+          charactersToSkip -= skipChars;
+          offset += skipChars;
+        }
+      }
+
+      return charactersSkiped;
+    }
+  }
+
+  private boolean isBufferReloadRequired() {
+    return limit == offset;
+  }
+
+  private boolean isEOF() {
+    return limit == EOF;
+  }
+
+  private int fillBuffer() throws IOException {
+    limit = reader.read(buffer, 0, buffer.length);
+    offset = 0;
+
+    return limit;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
index c76109b..4937e30 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
@@ -45,10 +45,9 @@ import org.apache.olingo.odata2.api.exception.ODataNotAcceptableException;
 import org.apache.olingo.odata2.api.processor.ODataErrorContext;
 import org.apache.olingo.odata2.api.processor.ODataResponse;
 import org.apache.olingo.odata2.api.servicedocument.ServiceDocument;
-import org.apache.olingo.odata2.core.batch.BatchRequestParser;
 import org.apache.olingo.odata2.core.batch.BatchRequestWriter;
-import org.apache.olingo.odata2.core.batch.BatchResponseParser;
 import org.apache.olingo.odata2.core.batch.BatchResponseWriter;
+import org.apache.olingo.odata2.core.batch.v2.BatchParser;
 import org.apache.olingo.odata2.core.commons.ContentType;
 import org.apache.olingo.odata2.core.edm.provider.EdmImplProv;
 import org.apache.olingo.odata2.core.edm.provider.EdmxProvider;
@@ -235,7 +234,7 @@ public class ProviderFacadeImpl implements EntityProviderInterface {
   @Override
   public List<BatchRequestPart> parseBatchRequest(final String contentType, final InputStream content,
       final EntityProviderBatchProperties properties) throws BatchException {
-    List<BatchRequestPart> batchParts = new BatchRequestParser(contentType, properties).parse(content);
+    List<BatchRequestPart> batchParts = new BatchParser(contentType, properties, true).parseBatchRequest(content);
     return batchParts;
   }
 
@@ -254,7 +253,7 @@ public class ProviderFacadeImpl implements EntityProviderInterface {
   @Override
   public List<BatchSingleResponse> parseBatchResponse(final String contentType, final InputStream content)
       throws BatchException {
-    List<BatchSingleResponse> responses = new BatchResponseParser(contentType).parse(content);
+    List<BatchSingleResponse> responses = new BatchParser(contentType, true).parseBatchResponse(content);
     return responses;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/resources/i18n.properties
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/resources/i18n.properties b/odata2-lib/odata-core/src/main/resources/i18n.properties
index 90b7045..a89c3e9 100644
--- a/odata2-lib/odata-core/src/main/resources/i18n.properties
+++ b/odata2-lib/odata-core/src/main/resources/i18n.properties
@@ -139,6 +139,7 @@ org.apache.olingo.odata2.api.batch.BatchException.INVALID_HEADER=Invalid header:
 org.apache.olingo.odata2.api.batch.BatchException.MISSING_BLANK_LINE=Expected empty line but was '%1$s': line '%2$s'  .
 org.apache.olingo.odata2.api.batch.BatchException.INVALID_PATHINFO=PathInfo should not be null.
 org.apache.olingo.odata2.api.batch.BatchException.MISSING_METHOD=Missing method in request line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.MISSING_MANDATORY_HEADER=Missing mandatory header '%1$s'.
 org.apache.olingo.odata2.api.batch.BatchException.INVALID_REQUEST_LINE=Invalid request line '%1$s' at line '%2$s'.
 org.apache.olingo.odata2.api.batch.BatchException.INVALID_REQUEST_LINE=Invalid status line '%1$s' at line '%2$s'.
 org.apache.olingo.odata2.api.batch.BatchException.TRUNCATED_BODY=Body is truncated: line '%1$s'.

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
new file mode 100644
index 0000000..c9e9a6b
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
@@ -0,0 +1,99 @@
+package org.apache.olingo.odata2.core.batch;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon;
+import org.junit.Test;
+
+public class BatchParserCommonTest {
+
+  @Test
+  public void testTrimList() {
+    final List<String> list = Arrays.asList(new String[] { "123\r\n", "abc", "a\n", "\r", "123" });
+    final List<String> trimedList = BatchParserCommon.trimStringListToLength(list, 7);
+
+    assertEquals(2, trimedList.size());
+    assertEquals("123\r\n", trimedList.get(0));
+    assertEquals("ab", trimedList.get(1));
+  }
+
+  @Test
+  public void testTrimListWithEmptyString() {
+    final List<String> list = Arrays.asList(new String[] { "123\r\n", "", "abc", "a\n", "\r", "123" });
+    final List<String> trimedList = BatchParserCommon.trimStringListToLength(list, 7);
+
+    assertEquals(3, trimedList.size());
+    assertEquals("123\r\n", trimedList.get(0));
+    assertEquals("", trimedList.get(1));
+    assertEquals("ab", trimedList.get(2));
+  }
+
+  @Test
+  public void testTrimListTryToReadMoreThanStringLength() {
+    final List<String> list = Arrays.asList(new String[] { "abc\r\n", "123" });
+    final List<String> trimedList = BatchParserCommon.trimStringListToLength(list, 100);
+
+    assertEquals(2, trimedList.size());
+    assertEquals("abc\r\n", trimedList.get(0));
+    assertEquals("123", trimedList.get(1));
+  }
+
+  @Test
+  public void testTrimListEmpty() {
+    final List<String> list = Arrays.asList(new String[0]);
+    final List<String> trimedList = BatchParserCommon.trimStringListToLength(list, 7);
+
+    assertEquals(0, trimedList.size());
+  }
+
+  @Test
+  public void testRemoveEndingCRLF() {
+    String line = "Test\r\n";
+    assertEquals("Test", BatchParserCommon.removeEndingCRLF(line));
+  }
+
+  @Test
+  public void testRemoveLastEndingCRLF() {
+    String line = "Test\r\n\r\n";
+    assertEquals("Test\r\n", BatchParserCommon.removeEndingCRLF(line));
+  }
+
+  @Test
+  public void testRemoveEndingCRLFWithWS() {
+    String line = "Test\r\n            ";
+    assertEquals("Test", BatchParserCommon.removeEndingCRLF(line));
+  }
+
+  @Test
+  public void testRemoveEndingCRLFNothingToRemove() {
+    String line = "Hallo\r\nBla";
+    assertEquals("Hallo\r\nBla", BatchParserCommon.removeEndingCRLF(line));
+  }
+
+  @Test
+  public void testRemoveEndingCRLFAll() {
+    String line = "\r\n";
+    assertEquals("", BatchParserCommon.removeEndingCRLF(line));
+  }
+
+  @Test
+  public void testRemoveEndingCRLFSpace() {
+    String line = "\r\n                      ";
+    assertEquals("", BatchParserCommon.removeEndingCRLF(line));
+  }
+
+  @Test
+  public void testRemoveLastEndingCRLFWithWS() {
+    String line = "Test            \r\n";
+    assertEquals("Test            ", BatchParserCommon.removeEndingCRLF(line));
+  }
+
+  @Test
+  public void testRemoveLastEndingCRLFWithWSLong() {
+    String line = "Test            \r\nTest2    \r\n";
+    assertEquals("Test            \r\nTest2    ", BatchParserCommon.removeEndingCRLF(line));
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
index f9b19b9..7866004 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
@@ -6,9 +6,9 @@
  * 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
@@ -38,13 +38,14 @@ import org.apache.olingo.odata2.api.ep.EntityProviderBatchProperties;
 import org.apache.olingo.odata2.api.processor.ODataRequest;
 import org.apache.olingo.odata2.core.ODataPathSegmentImpl;
 import org.apache.olingo.odata2.core.PathInfoImpl;
+import org.apache.olingo.odata2.core.batch.v2.BatchParser;
 import org.apache.olingo.odata2.testutil.helper.StringHelper;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 
 /**
- *  
+ *
  */
 public class BatchRequestParserTest {
 
@@ -67,7 +68,6 @@ public class BatchRequestParserTest {
     PathInfoImpl pathInfo = new PathInfoImpl();
     pathInfo.setServiceRoot(new URI(SERVICE_ROOT));
     batchProperties = EntityProviderBatchProperties.init().pathInfo(pathInfo).build();
-
   }
 
   @Test
@@ -78,8 +78,8 @@ public class BatchRequestParserTest {
       throw new IOException("Requested file '" + fileName + "' was not found.");
     }
 
-    BatchRequestParser parser = new BatchRequestParser(contentType, batchProperties);
-    List<BatchRequestPart> batchRequestParts = parser.parse(in);
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
     assertNotNull(batchRequestParts);
     assertEquals(false, batchRequestParts.isEmpty());
     for (BatchRequestPart object : batchRequestParts) {
@@ -169,7 +169,7 @@ public class BatchRequestParserTest {
         for (ODataRequest request : requests) {
           assertEquals(ODataHttpMethod.POST, request.getMethod());
           assertEquals("100000", request.getRequestHeaderValue(HttpHeaders.CONTENT_LENGTH.toLowerCase()));
-          assertEquals("1", request.getRequestHeaderValue(BatchHelper.MIME_HEADER_CONTENT_ID.toLowerCase()));
+          assertEquals("1", request.getRequestHeaderValue(BatchHelper.MIME_HEADER_CONTENT_ID));
           assertEquals("application/octet-stream", request.getContentType());
           InputStream body = request.getBody();
           assertEquals(content, StringHelper.inputStreamToString(body));
@@ -194,6 +194,7 @@ public class BatchRequestParserTest {
         + CRLF
         + "--changeset_f980-1cb6-94dd" + CRLF
         + MIME_HEADERS
+        + "Content-ID: changeRequest1" + CRLF
         + CRLF
         + "POST Employees('2') HTTP/1.1" + CRLF
         + "Content-Length: 100" + CRLF
@@ -225,8 +226,8 @@ public class BatchRequestParserTest {
         + GET_REQUEST
         + "--batch_1.2+34:2j)0?--";
     InputStream in = new ByteArrayInputStream(batch.getBytes());
-    BatchRequestParser parser = new BatchRequestParser(contentType, batchProperties);
-    List<BatchRequestPart> batchRequestParts = parser.parse(in);
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
     assertNotNull(batchRequestParts);
     assertEquals(false, batchRequestParts.isEmpty());
   }
@@ -239,8 +240,8 @@ public class BatchRequestParserTest {
         + GET_REQUEST
         + "--batch_1740-bb84-2f7f--";
     InputStream in = new ByteArrayInputStream(batch.getBytes());
-    BatchRequestParser parser = new BatchRequestParser(invalidContentType, batchProperties);
-    parser.parse(in);
+    BatchParser parser = new BatchParser(invalidContentType, batchProperties, true);
+    parser.parseBatchRequest(in);
   }
 
   @Test(expected = BatchException.class)
@@ -250,8 +251,8 @@ public class BatchRequestParserTest {
         + GET_REQUEST
         + "--batch_1740-bb84-2f7f--";
     InputStream in = new ByteArrayInputStream(batch.getBytes());
-    BatchRequestParser parser = new BatchRequestParser(invalidContentType, batchProperties);
-    parser.parse(in);
+    BatchParser parser = new BatchParser(invalidContentType, batchProperties, true);
+    parser.parseBatchRequest(in);
   }
 
   @Test(expected = BatchException.class)
@@ -261,8 +262,8 @@ public class BatchRequestParserTest {
         + GET_REQUEST
         + "--batch_1740-bb:84-2f7f--";
     InputStream in = new ByteArrayInputStream(batch.getBytes());
-    BatchRequestParser parser = new BatchRequestParser(invalidContentType, batchProperties);
-    parser.parse(in);
+    BatchParser parser = new BatchParser(invalidContentType, batchProperties, true);
+    parser.parseBatchRequest(in);
   }
 
   @Test(expected = BatchException.class)
@@ -290,6 +291,7 @@ public class BatchRequestParserTest {
         // + no boundary string
         + GET_REQUEST
         + "--batch_8194-cf13-1f56--";
+
     parseInvalidBatchBody(batch);
   }
 
@@ -372,6 +374,22 @@ public class BatchRequestParserTest {
   }
 
   @Test(expected = BatchException.class)
+  public void testNoBoundaryFound() throws BatchException {
+    String batch = "batch_8194-cf13-1f56" + CRLF
+        + MIME_HEADERS
+        + CRLF
+        + "POST Employees('1')/EmployeeName HTTP/1.1" + CRLF
+        + CRLF;
+    parseInvalidBatchBody(batch);
+  }
+
+  @Test(expected = BatchException.class)
+  public void testBadRequest() throws BatchException {
+    String batch = "This is a bad request. There is no syntax and also no semantic";
+    parseInvalidBatchBody(batch);
+  }
+
+  @Test(expected = BatchException.class)
   public void testNoMethod() throws BatchException {
     String batch = "--batch_8194-cf13-1f56" + CRLF
         + MIME_HEADERS
@@ -413,7 +431,43 @@ public class BatchRequestParserTest {
         + "--batch_8194-cf13-1f56--";
     parseInvalidBatchBody(batch);
   }
-
+  
+  @Test(expected = BatchException.class)
+  public void testMissingContentTransferEncoding() throws BatchException {
+    String batch = "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed;boundary=changeset_f980-1cb6-94dd" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + "Content-Type: application/http" + CRLF
+        //+ "Content-Transfer-Encoding: binary" + CRLF
+        + CRLF
+        + "POST Employees('2') HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "MaxDataServiceVersion: 2.0" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + "--batch_8194-cf13-1f56--";
+    parseInvalidBatchBody(batch);
+  }
+  
+  @Test(expected = BatchException.class)
+  public void testMissingContentType() throws BatchException {
+    String batch = "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed;boundary=changeset_f980-1cb6-94dd" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        //+ "Content-Type: application/http" + CRLF
+        + "Content-Transfer-Encoding: binary" + CRLF
+        + CRLF
+        + "POST Employees('2') HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "MaxDataServiceVersion: 2.0" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + "--batch_8194-cf13-1f56--";
+    parseInvalidBatchBody(batch);
+  }
+  
   @Test(expected = BatchException.class)
   public void testNoCloseDelimiter() throws BatchException {
     String batch = "--batch_8194-cf13-1f56" + CRLF
@@ -551,6 +605,259 @@ public class BatchRequestParserTest {
 
     }
   }
+  
+  @SuppressWarnings("unused")
+  @Test(expected=BatchException.class)
+  public void testNegativeContentLength() throws BatchException, IOException {
+      String batch = ""
+          + "--batch_8194-cf13-1f56" + CRLF
+          + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
+          + "Content-Length: -2" + CRLF
+          + CRLF
+          + "--changeset_f980-1cb6-94dd" + CRLF
+          + MIME_HEADERS
+          + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
+          + CRLF
+          + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+          + "Content-Type: application/json;odata=verbose" + CRLF
+          + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
+          + CRLF
+          + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+          + "--changeset_f980-1cb6-94dd--" + CRLF
+          + CRLF
+          + "--batch_8194-cf13-1f56--";
+      InputStream in = new ByteArrayInputStream(batch.getBytes());
+      BatchParser parser = new BatchParser(contentType, batchProperties, true);
+      List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
+  }
+  
+  @SuppressWarnings("unused")
+  @Test
+  public void testNegativeContentLengthChangeSet() throws BatchException, IOException {
+    String batch = ""
+        + "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
+        + "Content-Length: -2" + CRLF
+        + CRLF
+        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + CRLF
+        + "--batch_8194-cf13-1f56--";
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
+  }
+  
+  @SuppressWarnings("unused")
+  @Test(expected=BatchException.class)
+  public void testNegativeContentLengthRequest() throws BatchException, IOException {
+    String batch = ""
+        + "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
+        + "Content-Length: -2" + CRLF
+        + CRLF
+        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + CRLF
+        + "--batch_8194-cf13-1f56--";
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
+  }
+  
+  @Test
+  public void testContentLengthGreatherThanBodyLength() throws BatchException, IOException {
+    String batch = ""
+        + "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
+        + "Content-Length: 100000" + CRLF
+        + CRLF
+        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + CRLF
+        + "--batch_8194-cf13-1f56--";
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
+    assertNotNull(batchRequestParts);
+    for (BatchRequestPart multipart : batchRequestParts) {
+      if (multipart.isChangeSet()) {
+        assertEquals(1, multipart.getRequests().size());
+        ODataRequest request = multipart.getRequests().get(0);
+        assertEquals("{\"EmployeeName\":\"Peter Fall\"}", inputStreamToString(request.getBody()));
+      }
+    }
+  }
+
+  @Test
+  public void testContentLengthSmallerThanBodyLength() throws BatchException, IOException {
+    String batch = ""
+        + "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
+        + "Content-Length: 10" + CRLF
+        + CRLF
+        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + CRLF
+        + "--batch_8194-cf13-1f56--";
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
+    assertNotNull(batchRequestParts);
+    for (BatchRequestPart multipart : batchRequestParts) {
+      if (multipart.isChangeSet()) {
+        assertEquals(1, multipart.getRequests().size());
+        ODataRequest request = multipart.getRequests().get(0);
+        assertEquals("{\"Employee", inputStreamToString(request.getBody()));
+      }
+    }
+  }
+
+  @Test(expected = BatchException.class)
+  public void testCutChangeSetDelimiter() throws BatchException, IOException {
+    String batch = ""
+        + "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
+        + "Content-Length: 582" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
+        + "Content-Length: 10" + CRLF
+        + CRLF
+        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
+        + "Content-Length: 100000" + CRLF
+        + CRLF
+        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + CRLF
+        + "--batch_8194-cf13-1f56--";
+
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    parser.parseBatchRequest(in);
+  }
+
+  @Test(expected = BatchException.class)
+  public void testNonNumericContentLength() throws BatchException {
+    String batch = ""
+        + "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
+        + "Content-Length: 10abc" + CRLF
+        + CRLF
+        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + CRLF
+        + "--batch_8194-cf13-1f56--";
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    parser.parseBatchRequest(in);
+  }
+
+  @Test
+  public void testNonStrictParser() throws BatchException, IOException {
+    String batch = "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed;boundary=changeset_8194-cf13-1f56" + CRLF
+        + "--changeset_8194-cf13-1f56" + CRLF
+        + MIME_HEADERS
+        + "Content-ID: myRequest" + CRLF
+        + "PUT Employees('2')/EmployeeName HTTP/1.1" + CRLF
+        + "Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "MaxDataServiceVersion: 2.0" + CRLF
+        + "{\"EmployeeName\":\"Frederic Fall MODIFIED\"}" + CRLF
+        + "--changeset_8194-cf13-1f56--" + CRLF
+        + "--batch_8194-cf13-1f56--";
+
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, false);
+    List<BatchRequestPart> requests = parser.parseBatchRequest(in);
+    assertNotNull(requests);
+    assertEquals(1, requests.size());
+
+    BatchRequestPart part = requests.get(0);
+    assertTrue(part.isChangeSet());
+    assertNotNull(part.getRequests());
+    assertEquals(1, part.getRequests().size());
+
+    ODataRequest changeRequest = part.getRequests().get(0);
+    assertEquals("{\"EmployeeName\":\"Frederic Fall MODIFIED\"}", inputStreamToString(changeRequest.getBody()));
+    assertEquals("application/json;odata=verbose", changeRequest.getContentType());
+    assertEquals(ODataHttpMethod.PUT, changeRequest.getMethod());
+  }
+
+  @Test(expected = BatchException.class)
+  public void testNonStrictParserMoreCRLF() throws BatchException {
+    String batch = "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed;boundary=changeset_8194-cf13-1f56" + CRLF
+        + "--changeset_8194-cf13-1f56" + CRLF
+        + MIME_HEADERS
+        + CRLF
+        + CRLF // Only one CRLF allowed
+        + "PUT Employees('2')/EmployeeName HTTP/1.1" + CRLF
+        + "Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "MaxDataServiceVersion: 2.0" + CRLF
+        + "{\"EmployeeName\":\"Frederic Fall MODIFIED\"}" + CRLF
+        + "--changeset_8194-cf13-1f56--" + CRLF
+        + "--batch_8194-cf13-1f56--";
+
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, false);
+    parser.parseBatchRequest(in);
+  }
 
   @Test
   public void testContentId() throws BatchException {
@@ -586,8 +893,8 @@ public class BatchRequestParserTest {
         + CRLF
         + "--batch_8194-cf13-1f56--";
     InputStream in = new ByteArrayInputStream(batch.getBytes());
-    BatchRequestParser parser = new BatchRequestParser(contentType, batchProperties);
-    List<BatchRequestPart> batchRequestParts = parser.parse(in);
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
     assertNotNull(batchRequestParts);
     for (BatchRequestPart multipart : batchRequestParts) {
       if (!multipart.isChangeSet()) {
@@ -611,11 +918,175 @@ public class BatchRequestParserTest {
       }
     }
   }
+  
+  @Test
+  public void testNoContentId() throws BatchException {
+    String batch = "--batch_8194-cf13-1f56" + CRLF
+        + MIME_HEADERS
+        + CRLF
+        + "GET Employees HTTP/1.1" + CRLF
+        + "accept: */*,application/atom+xml,application/atomsvc+xml,application/xml" + CRLF
+        + CRLF + CRLF
+        + "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + CRLF
+        + "POST Employees HTTP/1.1" + CRLF
+        + "Content-type: application/octet-stream" + CRLF
+        + CRLF
+        + "/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAA" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + CRLF
+        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + CRLF
+        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + CRLF
+        + "--batch_8194-cf13-1f56--";
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);  // No exception should be thrown
+    assertNotNull(batchRequestParts);
+  }
+  
+  @Test
+  public void testPreamble() throws BatchException, IOException {
+    String batch = ""
+        + "This is a preamble and must be ignored" + CRLF
+        + CRLF
+        + CRLF
+        + "----1242"
+        + "--batch_8194-cf13-1f56" + CRLF
+        + MIME_HEADERS
+        + CRLF
+        + "GET Employees HTTP/1.1" + CRLF
+        + "accept: */*,application/atom+xml,application/atomsvc+xml,application/xml" + CRLF
+        + "Content-Id: BBB" + CRLF
+        + CRLF
+        + "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
+        + CRLF
+        + "This is a preamble and must be ignored" + CRLF
+        + CRLF
+        + CRLF
+        + "----1242"
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-Id: " + CONTENT_ID_REFERENCE + CRLF
+        + CRLF
+        + "POST Employees HTTP/1.1" + CRLF
+        + "Content-type: application/octet-stream" + CRLF
+        + CRLF
+        + "/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAA" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + CRLF
+        + "--batch_8194-cf13-1f56--";
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
+
+    assertNotNull(batchRequestParts);
+    assertEquals(2, batchRequestParts.size());
+
+    BatchRequestPart getRequestPart = batchRequestParts.get(0);
+    assertEquals(1, getRequestPart.getRequests().size());
+    ODataRequest getRequest = getRequestPart.getRequests().get(0);
+    assertEquals(ODataHttpMethod.GET, getRequest.getMethod());
+
+    BatchRequestPart changeSetPart = batchRequestParts.get(1);
+    assertEquals(2, changeSetPart.getRequests().size());
+    assertEquals("/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAA"
+        + CRLF,
+        inputStreamToString(changeSetPart.getRequests().get(0).getBody()));
+    assertEquals("{\"EmployeeName\":\"Peter Fall\"}",
+        inputStreamToString(changeSetPart.getRequests().get(1).getBody()));
+  }
+
+  @Test
+  public void testEpilog() throws BatchException, IOException {
+    String batch = ""
+        + "--batch_8194-cf13-1f56" + CRLF
+        + MIME_HEADERS
+        + CRLF
+        + "GET Employees HTTP/1.1" + CRLF
+        + "accept: */*,application/atom+xml,application/atomsvc+xml,application/xml" + CRLF
+        + "Content-Id: BBB" + CRLF
+        + CRLF
+        + "--batch_8194-cf13-1f56" + CRLF
+        + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-Id: " + CONTENT_ID_REFERENCE + CRLF
+        + CRLF
+        + "POST Employees HTTP/1.1" + CRLF
+        + "Content-type: application/octet-stream" + CRLF
+        + CRLF
+        + "/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAA" + CRLF
+        + CRLF
+        + "--changeset_f980-1cb6-94dd" + CRLF
+        + MIME_HEADERS
+        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
+        + "Content-Type: application/json;odata=verbose" + CRLF
+        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
+        + CRLF
+        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
+        + "--changeset_f980-1cb6-94dd--" + CRLF
+        + CRLF
+        + "This is an epilog and must be ignored" + CRLF
+        + CRLF
+        + CRLF
+        + "----1242"
+        + CRLF
+        + "--batch_8194-cf13-1f56--"
+        + CRLF
+        + "This is an epilog and must be ignored" + CRLF
+        + CRLF
+        + CRLF
+        + "----1242";
+
+    InputStream in = new ByteArrayInputStream(batch.getBytes());
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
+
+    assertNotNull(batchRequestParts);
+    assertEquals(2, batchRequestParts.size());
+
+    BatchRequestPart getRequestPart = batchRequestParts.get(0);
+    assertEquals(1, getRequestPart.getRequests().size());
+    ODataRequest getRequest = getRequestPart.getRequests().get(0);
+    assertEquals(ODataHttpMethod.GET, getRequest.getMethod());
+
+    BatchRequestPart changeSetPart = batchRequestParts.get(1);
+    assertEquals(2, changeSetPart.getRequests().size());
+    assertEquals("/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAA"
+        + CRLF,
+        inputStreamToString(changeSetPart.getRequests().get(0).getBody()));
+    assertEquals("{\"EmployeeName\":\"Peter Fall\"}",
+        inputStreamToString(changeSetPart.getRequests().get(1).getBody()));
+  }
 
   private List<BatchRequestPart> parse(final String batch) throws BatchException {
     InputStream in = new ByteArrayInputStream(batch.getBytes());
-    BatchRequestParser parser = new BatchRequestParser(contentType, batchProperties);
-    List<BatchRequestPart> batchRequestParts = parser.parse(in);
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
     assertNotNull(batchRequestParts);
     assertEquals(false, batchRequestParts.isEmpty());
     return batchRequestParts;
@@ -623,7 +1094,18 @@ public class BatchRequestParserTest {
 
   private void parseInvalidBatchBody(final String batch) throws BatchException {
     InputStream in = new ByteArrayInputStream(batch.getBytes());
-    BatchRequestParser parser = new BatchRequestParser(contentType, batchProperties);
-    parser.parse(in);
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    parser.parseBatchRequest(in);
+  }
+
+  private String inputStreamToString(final InputStream in) throws IOException {
+    int input;
+    final StringBuilder builder = new StringBuilder();
+
+    while ((input = in.read()) != -1) {
+      builder.append((char) input);
+    }
+
+    return builder.toString();
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
index ca6b655..6c604f8 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
@@ -39,7 +39,9 @@ import org.apache.olingo.odata2.api.client.batch.BatchPart;
 import org.apache.olingo.odata2.api.client.batch.BatchQueryPart;
 import org.apache.olingo.odata2.api.ep.EntityProviderBatchProperties;
 import org.apache.olingo.odata2.core.PathInfoImpl;
+import org.apache.olingo.odata2.core.batch.v2.BatchParser;
 import org.apache.olingo.odata2.testutil.helper.StringHelper;
+import org.junit.Ignore;
 import org.junit.Test;
 
 /**
@@ -88,8 +90,8 @@ public class BatchRequestTest {
     checkHeaders(headers, requestBody);
 
     String contentType = "multipart/mixed; boundary=" + BOUNDARY;
-    BatchRequestParser parser = new BatchRequestParser(contentType, parseProperties);
-    List<BatchRequestPart> parseResult = parser.parse(batchRequestStream.asStream());
+    BatchParser parser = new BatchParser(contentType, parseProperties, true);
+    List<BatchRequestPart> parseResult = parser.parseBatchRequest(batchRequestStream.asStream());
     assertEquals(1, parseResult.size());
   }
 
@@ -100,7 +102,7 @@ public class BatchRequestTest {
     headers.put("content-type", "application/json");
     BatchChangeSetPart request = BatchChangeSetPart.method(PUT)
         .uri("Employees('2')")
-        .body("{\"Возраст\":40}")
+        .body("{\"Возра�т\":40}")
         .headers(headers)
         .contentId("111")
         .build();
@@ -120,17 +122,32 @@ public class BatchRequestTest {
     assertTrue(requestBody.contains("--batch_"));
     assertTrue(requestBody.contains("--changeset_"));
     assertTrue(requestBody.contains("PUT Employees('2') HTTP/1.1"));
-    assertTrue(requestBody.contains("{\"Возраст\":40}"));
+    assertTrue(requestBody.contains("{\"Возра�т\":40}"));
     assertEquals(16, batchRequestStream.linesCount());
 
     String contentType = "multipart/mixed; boundary=" + BOUNDARY;
-    BatchRequestParser parser = new BatchRequestParser(contentType, parseProperties);
-    List<BatchRequestPart> parseResult = parser.parse(batchRequestStream.asStream());
+    BatchParser parser = new BatchParser(contentType, parseProperties, true);
+    List<BatchRequestPart> parseResult = parser.parseBatchRequest(batchRequestStream.asStream());
     assertEquals(1, parseResult.size());
   }
 
   @Test
-  public void testBatchWithGetAndPost() throws BatchException, IOException {
+  @Ignore
+  // TODO
+      /*
+       * --batch_123
+       * Content-Type: application/http
+       * Content-Transfer-Encoding: binary
+       * Content-Id: 000
+       * 
+       * GET Employees HTTP/1.1
+       * Accept: application/json <- Missing CRLF => Even ABAP can`t understand this request
+       * --batch_123
+       * ...
+       * ....
+       */
+      public
+      void testBatchWithGetAndPost() throws BatchException, IOException {
     List<BatchPart> batch = new ArrayList<BatchPart>();
     Map<String, String> headers = new HashMap<String, String>();
     headers.put("Accept", "application/json");
@@ -152,7 +169,6 @@ public class BatchRequestTest {
     BatchRequestWriter writer = new BatchRequestWriter();
     InputStream batchRequest = writer.writeBatchRequest(batch, BOUNDARY);
     assertNotNull(batchRequest);
-
     StringHelper.Stream batchRequestStream = StringHelper.toStream(batchRequest);
     String requestBody = batchRequestStream.asString();
     checkMimeHeaders(requestBody);
@@ -165,11 +181,11 @@ public class BatchRequestTest {
     assertEquals(23, batchRequestStream.linesCount());
 
     String contentType = "multipart/mixed; boundary=" + BOUNDARY;
-    BatchRequestParser parser = new BatchRequestParser(contentType, parseProperties);
-    List<BatchRequestPart> parseResult = parser.parse(batchRequestStream.asStream());
+    BatchParser parser = new BatchParser(contentType, parseProperties, true);
+    List<BatchRequestPart> parseResult = parser.parseBatchRequest(batchRequestStream.asStream());
     assertEquals(2, parseResult.size());
   }
-
+  
   @Test
   public void testChangeSetWithContentIdReferencing() throws BatchException, IOException {
     List<BatchPart> batch = new ArrayList<BatchPart>();
@@ -212,8 +228,8 @@ public class BatchRequestTest {
     assertTrue(requestBody.contains(body));
 
     String contentType = "multipart/mixed; boundary=" + BOUNDARY;
-    BatchRequestParser parser = new BatchRequestParser(contentType, parseProperties);
-    List<BatchRequestPart> parseResult = parser.parse(batchRequestStream.asStream());
+    BatchParser parser = new BatchParser(contentType, parseProperties, true);
+    List<BatchRequestPart> parseResult = parser.parseBatchRequest(batchRequestStream.asStream());
     assertEquals(1, parseResult.size());
   }
 
@@ -227,6 +243,7 @@ public class BatchRequestTest {
     String body = "/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEA";
     BatchChangeSetPart changeRequest = BatchChangeSetPart.method(POST)
         .uri("Employees")
+        .contentId("111request")
         .body(body)
         .headers(changeSetHeaders)
         .build();
@@ -239,6 +256,7 @@ public class BatchRequestTest {
     changeSetHeaders2.put("content-Id", "222");
     BatchChangeSetPart changeRequest2 = BatchChangeSetPart.method(PUT)
         .uri("Employees('2')/ManagerId")
+        .contentId("222request")
         .body("{\"ManagerId\":1}")
         .headers(changeSetHeaders2)
         .build();
@@ -260,8 +278,8 @@ public class BatchRequestTest {
     assertTrue(requestBody.contains(body));
 
     String contentType = "multipart/mixed; boundary=" + BOUNDARY;
-    BatchRequestParser parser = new BatchRequestParser(contentType, parseProperties);
-    List<BatchRequestPart> parseResult = parser.parse(batchRequestStream.asStream());
+    BatchParser parser = new BatchParser(contentType, parseProperties, true);
+    List<BatchRequestPart> parseResult = parser.parseBatchRequest(batchRequestStream.asStream());
     assertEquals(2, parseResult.size());
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java
index f7e4602..aa9143a 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java
@@ -31,6 +31,7 @@ import org.apache.olingo.odata2.api.client.batch.BatchSingleResponse;
 import org.apache.olingo.odata2.api.commons.HttpContentType;
 import org.apache.olingo.odata2.api.commons.HttpHeaders;
 import org.apache.olingo.odata2.api.ep.EntityProvider;
+import org.apache.olingo.odata2.core.batch.v2.BatchParser;
 import org.apache.olingo.odata2.testutil.helper.StringHelper;
 import org.junit.Test;
 
@@ -39,7 +40,6 @@ public class BatchResponseParserTest {
   private static final String CRLF = "\r\n";
   private static final String LF = "\n";
 
-
   @Test
   public void testSimpleBatchResponse() throws BatchException {
     String getResponse = "--batch_123" + CRLF
@@ -56,8 +56,8 @@ public class BatchResponseParserTest {
         + "--batch_123--";
 
     InputStream in = new ByteArrayInputStream(getResponse.getBytes());
-    BatchResponseParser parser = new BatchResponseParser("multipart/mixed;boundary=batch_123");
-    List<BatchSingleResponse> responses = parser.parse(in);
+    BatchParser parser = new BatchParser("multipart/mixed;boundary=batch_123", true);
+    List<BatchSingleResponse> responses = parser.parseBatchResponse(in);
     for (BatchSingleResponse response : responses) {
       assertEquals("200", response.getStatusCode());
       assertEquals("OK", response.getStatusInfo());
@@ -74,8 +74,9 @@ public class BatchResponseParserTest {
     if (in == null) {
       throw new IOException("Requested file '" + fileName + "' was not found.");
     }
-    BatchResponseParser parser = new BatchResponseParser("multipart/mixed;boundary=batch_123");
-    List<BatchSingleResponse> responses = parser.parse(StringHelper.toStream(in).asStreamWithLineSeparation("\r\n"));
+    BatchParser parser = new BatchParser("multipart/mixed;boundary=batch_123", true);
+    List<BatchSingleResponse> responses =
+        parser.parseBatchResponse(StringHelper.toStream(in).asStreamWithLineSeparation("\r\n"));
     for (BatchSingleResponse response : responses) {
       if ("1".equals(response.getContentId())) {
         assertEquals("204", response.getStatusCode());
@@ -106,8 +107,8 @@ public class BatchResponseParserTest {
         + "--batch_123--";
 
     InputStream in = new ByteArrayInputStream(putResponse.getBytes());
-    BatchResponseParser parser = new BatchResponseParser("multipart/mixed;boundary=batch_123");
-    List<BatchSingleResponse> responses = parser.parse(in);
+    BatchParser parser = new BatchParser("multipart/mixed;boundary=batch_123", true);
+    List<BatchSingleResponse> responses = parser.parseBatchResponse(in);
     for (BatchSingleResponse response : responses) {
       assertEquals("204", response.getStatusCode());
       assertEquals("No Content", response.getStatusInfo());
@@ -289,9 +290,9 @@ public class BatchResponseParserTest {
   public void parseWithAdditionalLineEndingAtTheEnd() throws Exception {
     String fileString = readFile("BatchResponseWithAdditionalLineEnding.batch");
     assertTrue(fileString.contains("\r\n--batch_123--"));
-    InputStream stream =new ByteArrayInputStream(fileString.getBytes());
+    InputStream stream = new ByteArrayInputStream(fileString.getBytes());
     BatchSingleResponse response =
-        EntityProvider.parseBatchResponse(stream , "multipart/mixed;boundary=batch_123").get(0);
+        EntityProvider.parseBatchResponse(stream, "multipart/mixed;boundary=batch_123").get(0);
     assertEquals("This is the body we need to parse. The trailing line ending is part of the body." + CRLF, response
         .getBody());
 
@@ -308,25 +309,24 @@ public class BatchResponseParserTest {
 
     assertEquals(body, response.getBody());
   }
-  
+
   @Test
   public void parseWithUnixLineEndingsInBody() throws Exception {
     String body =
         "This is the body we need to parse. The line spaces in the body " + LF + LF + LF + "are " + LF + LF
-        + "part of the body and must not be ignored or filtered.";
+            + "part of the body and must not be ignored or filtered.";
     String responseString = "--batch_123" + CRLF
         + "Content-Type: application/http" + CRLF
         + "Content-Length: 234" + CRLF
         + "content-transfer-encoding: binary" + CRLF
-        + CRLF 
+        + CRLF
         + "HTTP/1.1 500 Internal Server Error" + CRLF
         + "Content-Type: application/xml;charset=utf-8" + CRLF
         + "Content-Length: 125" + CRLF
         + CRLF
         + body
         + CRLF
-        + "--batch_123--"
-        ;
+        + "--batch_123--";
     InputStream stream = new ByteArrayInputStream(responseString.getBytes());
     BatchSingleResponse response =
         EntityProvider.parseBatchResponse(stream, "multipart/mixed;boundary=batch_123").get(0);
@@ -347,7 +347,7 @@ public class BatchResponseParserTest {
 
     return b.toString();
   }
-  
+
   private InputStream getFileAsStream(final String filename) throws IOException {
     InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename);
     if (in == null) {
@@ -358,7 +358,7 @@ public class BatchResponseParserTest {
 
   private void parseInvalidBatchResponseBody(final String putResponse) throws BatchException {
     InputStream in = new ByteArrayInputStream(putResponse.getBytes());
-    BatchResponseParser parser = new BatchResponseParser("multipart/mixed;boundary=batch_123");
-    parser.parse(in);
+    BatchParser parser = new BatchParser("multipart/mixed;boundary=batch_123", true);
+    parser.parseBatchResponse(in);
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java
index f5f05ff..2f8b7f8 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java
@@ -33,6 +33,7 @@ import org.apache.olingo.odata2.api.batch.BatchResponsePart;
 import org.apache.olingo.odata2.api.client.batch.BatchSingleResponse;
 import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
 import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.core.batch.v2.BatchParser;
 import org.apache.olingo.odata2.testutil.helper.StringHelper;
 import org.junit.Test;
 
@@ -75,8 +76,8 @@ public class BatchResponseTest {
     assertTrue(body.contains("HTTP/1.1 204 No Content"));
 
     String contentHeader = batchResponse.getContentHeader();
-    BatchResponseParser parser = new BatchResponseParser(contentHeader);
-    List<BatchSingleResponse> result = parser.parse(new ByteArrayInputStream(body.getBytes()));
+    BatchParser parser = new BatchParser(contentHeader, true);
+    List<BatchSingleResponse> result = parser.parseBatchResponse(new ByteArrayInputStream(body.getBytes()));
     assertEquals(2, result.size());
   }
 
@@ -104,8 +105,8 @@ public class BatchResponseTest {
     assertTrue(body.contains("Content-Type: multipart/mixed; boundary=changeset"));
 
     String contentHeader = batchResponse.getContentHeader();
-    BatchResponseParser parser = new BatchResponseParser(contentHeader);
-    List<BatchSingleResponse> result = parser.parse(new ByteArrayInputStream(body.getBytes()));
+    BatchParser parser = new BatchParser(contentHeader, true);
+    List<BatchSingleResponse> result = parser.parseBatchResponse(new ByteArrayInputStream(body.getBytes()));
     assertEquals(1, result.size());
   }
 
@@ -135,9 +136,9 @@ public class BatchResponseTest {
     assertTrue(body.contains("Content-Type: multipart/mixed; boundary=changeset"));
 
     String contentHeader = batchResponse.getContentHeader();
-    BatchResponseParser parser = new BatchResponseParser(contentHeader);
+    BatchParser parser = new BatchParser(contentHeader, true);
     StringHelper.Stream content = StringHelper.toStream(body);
-    List<BatchSingleResponse> result = parser.parse(content.asStream());
+    List<BatchSingleResponse> result = parser.parseBatchResponse(content.asStream());
     assertEquals(2, result.size());
     assertEquals("Failing content:\n" + content.asString(), 20, content.linesCount());
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseWriterTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseWriterTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseWriterTest.java
index ea7d2bb..cc58159 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseWriterTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseWriterTest.java
@@ -57,7 +57,7 @@ public class BatchResponseWriterTest {
     assertEquals(202, batchResponse.getStatus().getStatusCode());
     assertNotNull(batchResponse.getEntity());
     String body = (String) batchResponse.getEntity();
-
+    
     assertTrue(body.contains("--batch"));
     assertTrue(body.contains("--changeset"));
     assertTrue(body.contains("HTTP/1.1 200 OK"));

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
new file mode 100644
index 0000000..a0ab9f4
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
@@ -0,0 +1,95 @@
+package org.apache.olingo.odata2.core.batch;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.commons.HttpContentType;
+import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
+import org.apache.olingo.odata2.core.batch.v2.BatchTransformatorCommon;
+import org.junit.Test;
+
+public class BatchTransformatorCommonTest {
+
+  private static final String BASE64_ENCODING = "BASE64";
+
+  @Test
+  public void testValidateContentTypeApplicationHTTP() throws BatchException {
+    List<String> contentTypeValues = Arrays.asList(new String[] { HttpContentType.APPLICATION_HTTP });
+    Map<String, HeaderField> headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
+
+    BatchTransformatorCommon.validateContentType(headers);
+  }
+
+  @Test
+  public void testValidateContentTypeMultipartMixed() throws BatchException {
+    List<String> contentTypeValues = Arrays.asList(new String[] { HttpContentType.MULTIPART_MIXED });
+    Map<String, HeaderField> headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
+
+    BatchTransformatorCommon.validateContentType(headers);
+  }
+
+  @Test(expected = BatchException.class)
+  public void testValidateContentTypeNoValue() throws BatchException {
+    List<String> contentTypeValues = Arrays.asList(new String[] {});
+    Map<String, HeaderField> headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
+
+    BatchTransformatorCommon.validateContentType(headers);
+  }
+
+  @Test(expected = BatchException.class)
+  public void testValidateContentTypeMissingHeader() throws BatchException {
+    Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
+    BatchTransformatorCommon.validateContentType(headers);
+  }
+
+  @Test(expected = BatchException.class)
+  public void testValidateContentTypeMultipleValues() throws BatchException {
+    List<String> contentTypeValues =
+        Arrays.asList(new String[] { HttpContentType.APPLICATION_HTTP, HttpContentType.MULTIPART_MIXED });
+    Map<String, HeaderField> headers = makeHeaders(HttpHeaders.CONTENT_TYPE, contentTypeValues);
+
+    BatchTransformatorCommon.validateContentType(headers);
+  }
+
+  @Test
+  public void testValidateContentTransferEncoding() throws BatchException {
+    List<String> contentTransferEncoding = Arrays.asList(new String[] { BatchHelper.BINARY_ENCODING });
+    Map<String, HeaderField> headers = makeHeaders(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
+
+    BatchTransformatorCommon.validateContentTransferEncoding(headers, false);
+  }
+
+  @Test(expected = BatchException.class)
+  public void testValidateContentTransferEncodingMultipleValues() throws BatchException {
+    List<String> contentTransferEncoding = Arrays.asList(new String[] { BatchHelper.BINARY_ENCODING, BASE64_ENCODING });
+    Map<String, HeaderField> headers = makeHeaders(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
+
+    BatchTransformatorCommon.validateContentTransferEncoding(headers, false);
+  }
+
+  @Test(expected = BatchException.class)
+  public void testValidateContentTransferEncodingMissingHeader() throws BatchException {
+    Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
+    BatchTransformatorCommon.validateContentTransferEncoding(headers, true);
+  }
+
+  @Test(expected = BatchException.class)
+  public void testValidateContentTransferEncodingMissingValue() throws BatchException {
+    List<String> contentTransferEncoding = Arrays.asList(new String[] {});
+    Map<String, HeaderField> headers = makeHeaders(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
+
+    BatchTransformatorCommon.validateContentTransferEncoding(headers, false);
+  }
+
+  private Map<String, HeaderField> makeHeaders(final String headerName, final List<String> values) {
+    Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
+    headers.put(headerName.toLowerCase(), new HeaderField(headerName, values));
+
+    return headers;
+  }
+
+}


[03/19] git commit: Batch Parser

Posted by ch...@apache.org.
Batch Parser

Signed-off-by: Christian Amend <ch...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/6eca235e
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/6eca235e
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/6eca235e

Branch: refs/heads/master
Commit: 6eca235ea24a19dbd578109b6590f435fe16e2d4
Parents: 4966ebe
Author: Christian Holzer <c....@sap.com>
Authored: Wed Aug 20 17:53:10 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Tue Sep 23 14:47:37 2014 +0200

----------------------------------------------------------------------
 .../olingo/odata2/api/batch/BatchException.java |   6 +-
 .../odata2/api/batch/BatchParserResult.java     |   5 +
 .../odata2/api/batch/BatchRequestPart.java      |   2 +-
 .../odata2/api/batch/BatchResponsePart.java     |   2 +-
 .../api/client/batch/BatchSingleResponse.java   |   4 +-
 .../odata2/core/batch/BatchRequestParser.java   | 614 -------------------
 .../odata2/core/batch/BatchResponseParser.java  | 356 -----------
 .../odata2/core/batch/v2/BatchBodyPart.java     | 155 +++++
 .../odata2/core/batch/v2/BatchChangeSet.java    |  55 ++
 .../odata2/core/batch/v2/BatchParser.java       | 130 ++++
 .../odata2/core/batch/v2/BatchParserCommon.java | 414 +++++++++++++
 .../olingo/odata2/core/batch/v2/BatchPart.java  |  29 +
 .../core/batch/v2/BatchQueryOperation.java      |  82 +++
 .../batch/v2/BatchRequestTransformator.java     | 253 ++++++++
 .../batch/v2/BatchResponseTransformator.java    | 134 ++++
 .../core/batch/v2/BatchTransformator.java       |  30 +
 .../core/batch/v2/BatchTransformatorCommon.java |  84 +++
 .../v2/BufferedReaderIncludingLineEndings.java  | 220 +++++++
 .../odata2/core/ep/ProviderFacadeImpl.java      |   7 +-
 .../src/main/resources/i18n.properties          |   1 +
 .../core/batch/BatchParserCommonTest.java       |  99 +++
 .../core/batch/BatchRequestParserTest.java      | 526 +++++++++++++++-
 .../odata2/core/batch/BatchRequestTest.java     |  48 +-
 .../core/batch/BatchResponseParserTest.java     |  34 +-
 .../odata2/core/batch/BatchResponseTest.java    |  13 +-
 .../core/batch/BatchResponseWriterTest.java     |   2 +-
 .../batch/BatchTransformatorCommonTest.java     |  95 +++
 .../BufferedReaderIncludingLineEndingsTest.java | 452 ++++++++++++++
 .../src/test/resources/batchWithPost.batch      |   1 +
 .../odata2/fit/client/ClientBatchTest.java      |   2 +
 .../fit/client/ClientDeltaResponseTest.java     |   2 +
 .../src/test/resources/batchWithContentId.batch |   2 +
 .../resources/batchWithContentIdPart2.batch     |   6 +-
 .../src/test/resources/changeset.batch          |   2 +
 34 files changed, 2826 insertions(+), 1041 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchException.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchException.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchException.java
index 647b071..1171719 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchException.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchException.java
@@ -43,7 +43,11 @@ public class BatchException extends ODataMessageException {
   /** MISSING_CLOSE_DELIMITER requires 1 content value ('line number') */
   public static final MessageReference MISSING_CLOSE_DELIMITER = createMessageReference(BatchException.class,
       "MISSING_CLOSE_DELIMITER");
-
+  
+  /** MISSONG MANDATORY HEADER requires 1 content value ('header name') */
+  public static final MessageReference MISSING_MANDATORY_HEADER = createMessageReference(BatchException.class, 
+      "MISSING_MANDATORY_HEADER");
+  
   /** INVALID_QUERY_OPERATION_METHOD requires 1 content value ('line number') */
   public static final MessageReference INVALID_QUERY_OPERATION_METHOD = createMessageReference(BatchException.class,
       "INVALID_QUERY_OPERATION_METHOD");

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java
new file mode 100644
index 0000000..e11b69e
--- /dev/null
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchParserResult.java
@@ -0,0 +1,5 @@
+package org.apache.olingo.odata2.api.batch;
+
+public interface BatchParserResult {
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchRequestPart.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchRequestPart.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchRequestPart.java
index 5e3e2f2..5f76a36 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchRequestPart.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchRequestPart.java
@@ -26,7 +26,7 @@ import org.apache.olingo.odata2.api.processor.ODataRequest;
  * A BatchPart
  * <p> BatchPart represents a distinct MIME part of a Batch Request body. It can be ChangeSet or Query Operation
  */
-public interface BatchRequestPart {
+public interface BatchRequestPart extends BatchParserResult {
 
   /**
    * Get the info if a BatchPart is a ChangeSet

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchResponsePart.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchResponsePart.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchResponsePart.java
index dfafbdb..6133104 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchResponsePart.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchResponsePart.java
@@ -29,7 +29,7 @@ import org.apache.olingo.odata2.api.rt.RuntimeDelegate;
  * response to a retrieve request
  * 
  */
-public abstract class BatchResponsePart {
+public abstract class BatchResponsePart implements BatchParserResult {
 
   /**
    * Get responses. If a BatchResponsePart is a response to a retrieve request, the list consists of one response.

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/client/batch/BatchSingleResponse.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/client/batch/BatchSingleResponse.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/client/batch/BatchSingleResponse.java
index dc8c9b7..ddb3c02 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/client/batch/BatchSingleResponse.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/client/batch/BatchSingleResponse.java
@@ -21,12 +21,14 @@ package org.apache.olingo.odata2.api.client.batch;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.olingo.odata2.api.batch.BatchParserResult;
+
 /**
  * A BatchSingleResponse
  * <p> BatchSingleResponse represents a single response of a Batch Response body. It can be a response to a change
  * request of ChangeSet or a response to a retrieve request
  */
-public interface BatchSingleResponse {
+public interface BatchSingleResponse extends BatchParserResult {
   /**
    * @return a result code of the attempt to understand and satisfy the request
    */

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchRequestParser.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchRequestParser.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchRequestParser.java
deleted file mode 100644
index 6ac1445..0000000
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchRequestParser.java
+++ /dev/null
@@ -1,614 +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.odata2.core.batch;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.Set;
-import java.util.regex.MatchResult;
-import java.util.regex.Pattern;
-
-import org.apache.olingo.odata2.api.batch.BatchException;
-import org.apache.olingo.odata2.api.batch.BatchRequestPart;
-import org.apache.olingo.odata2.api.commons.HttpContentType;
-import org.apache.olingo.odata2.api.commons.HttpHeaders;
-import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
-import org.apache.olingo.odata2.api.ep.EntityProviderBatchProperties;
-import org.apache.olingo.odata2.api.processor.ODataRequest;
-import org.apache.olingo.odata2.api.processor.ODataRequest.ODataRequestBuilder;
-import org.apache.olingo.odata2.api.uri.PathInfo;
-import org.apache.olingo.odata2.api.uri.PathSegment;
-import org.apache.olingo.odata2.core.ODataPathSegmentImpl;
-import org.apache.olingo.odata2.core.PathInfoImpl;
-import org.apache.olingo.odata2.core.commons.Decoder;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-/**
- *  
- */
-public class BatchRequestParser {
-  private static final String LF = "\n";
-  private static final String REG_EX_OPTIONAL_WHITESPACE = "\\s?";
-  private static final String REG_EX_ZERO_OR_MORE_WHITESPACES = "\\s*";
-  private static final String ANY_CHARACTERS = ".*";
-
-  private static final Pattern REG_EX_BLANK_LINE = Pattern.compile("(|" + REG_EX_ZERO_OR_MORE_WHITESPACES + ")");
-  private static final Pattern REG_EX_HEADER = Pattern.compile("([a-zA-Z\\-]+):" + REG_EX_OPTIONAL_WHITESPACE + "(.*)"
-      + REG_EX_ZERO_OR_MORE_WHITESPACES);
-  private static final Pattern REG_EX_VERSION = Pattern.compile("(?:HTTP/[0-9]\\.[0-9])");
-  private static final Pattern REG_EX_ANY_BOUNDARY_STRING = Pattern.compile("--" + ANY_CHARACTERS
-      + REG_EX_ZERO_OR_MORE_WHITESPACES);
-  private static final Pattern REG_EX_REQUEST_LINE = Pattern.compile("(GET|POST|PUT|DELETE|MERGE|PATCH)\\s(.*)\\s?"
-      + REG_EX_VERSION + REG_EX_ZERO_OR_MORE_WHITESPACES);
-  private static final Pattern REG_EX_BOUNDARY_PARAMETER = Pattern.compile(REG_EX_OPTIONAL_WHITESPACE
-      + "boundary=(\".*\"|.*)" + REG_EX_ZERO_OR_MORE_WHITESPACES);
-  private static final Pattern REG_EX_CONTENT_TYPE = Pattern.compile(REG_EX_OPTIONAL_WHITESPACE
-      + HttpContentType.MULTIPART_MIXED);
-  private static final Pattern REG_EX_QUERY_PARAMETER = Pattern.compile("((?:\\$|)[^=]+)=([^=]+)");
-
-  private static final String REG_EX_BOUNDARY =
-      "([a-zA-Z0-9_\\-\\.'\\+]{1,70})|\"([a-zA-Z0-9_\\-\\.'\\+\\s\\" +
-          "(\\),/:=\\?]{1,69}[a-zA-Z0-9_\\-\\.'\\+\\(\\),/:=\\?])\""; // See RFC 2046
-
-  private String baseUri;
-  private PathInfo batchRequestPathInfo;
-  private String contentTypeMime;
-  private String boundary;
-  private String currentMimeHeaderContentId;
-  private int currentLineNumber = 0;
-  private final static Set<String> HTTP_CHANGESET_METHODS;
-  private final static Set<String> HTTP_BATCH_METHODS;
-
-  static {
-    HashSet<String> httpChangesetMethods = new HashSet<String>();
-    httpChangesetMethods.add("POST");
-    httpChangesetMethods.add("PUT");
-    httpChangesetMethods.add("DELETE");
-    httpChangesetMethods.add("MERGE");
-    httpChangesetMethods.add("PATCH");
-    HTTP_CHANGESET_METHODS = Collections.unmodifiableSet(httpChangesetMethods);
-
-    HashSet<String> httpBatchMethods = new HashSet<String>();
-    httpBatchMethods.add("GET");
-    HTTP_BATCH_METHODS = Collections.unmodifiableSet(httpBatchMethods);
-  }
-
-  public BatchRequestParser(final String contentType, final EntityProviderBatchProperties properties) {
-    contentTypeMime = contentType;
-    batchRequestPathInfo = properties.getPathInfo();
-  }
-
-  public List<BatchRequestPart> parse(final InputStream in) throws BatchException {
-    Scanner scanner = new Scanner(in, BatchHelper.DEFAULT_ENCODING);
-    scanner.useDelimiter(LF);
-    baseUri = getBaseUri();
-    List<BatchRequestPart> requestList;
-    try {
-      requestList = parseBatchRequest(scanner);
-    } finally {// NOPMD (suppress DoNotThrowExceptionInFinally)
-      scanner.close();
-      try {
-        in.close();
-      } catch (IOException e) {
-        throw new ODataRuntimeException(e);
-      }
-    }
-    return requestList;
-  }
-
-  private List<BatchRequestPart> parseBatchRequest(final Scanner scanner) throws BatchException {
-    List<BatchRequestPart> requests = new LinkedList<BatchRequestPart>();
-    if (contentTypeMime != null) {
-      boundary = getBoundary(contentTypeMime);
-      parsePreamble(scanner);
-      final String closeDelimiter = "--" + boundary + "--" + REG_EX_ZERO_OR_MORE_WHITESPACES;
-      while (scanner.hasNext() && !scanner.hasNext(closeDelimiter)) {
-        requests.add(parseMultipart(scanner, boundary, false));
-        parseOptionalLine(scanner);
-      }
-      if (scanner.hasNext(closeDelimiter)) {
-        scanner.next(closeDelimiter);
-        currentLineNumber++;
-      } else {
-        throw new BatchException(BatchException.MISSING_CLOSE_DELIMITER.addContent(currentLineNumber));
-      }
-    } else {
-      throw new BatchException(BatchException.MISSING_CONTENT_TYPE);
-    }
-    return requests;
-  }
-
-  // The method parses additional information prior to the first boundary delimiter line
-  private void parsePreamble(final Scanner scanner) {
-    while (scanner.hasNext() && !scanner.hasNext(REG_EX_ANY_BOUNDARY_STRING)) {
-      scanner.next();
-      currentLineNumber++;
-    }
-  }
-
-  private BatchRequestPart parseMultipart(final Scanner scanner, final String boundary, final boolean isChangeSet)
-      throws BatchException {
-
-    if (scanner.hasNext("--" + boundary + REG_EX_ZERO_OR_MORE_WHITESPACES)) {
-      scanner.next();
-      currentLineNumber++;
-      Map<String, String> mimeHeaders = parseHeaders(scanner);
-      currentMimeHeaderContentId = mimeHeaders.get(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH));
-
-      String contentType = mimeHeaders.get(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH));
-      if (contentType == null) {
-        throw new BatchException(BatchException.MISSING_CONTENT_TYPE);
-      }
-      if (isChangeSet) {
-        return parseBatchRequestPartInChangeset(scanner, boundary, mimeHeaders, contentType);
-      } else {
-        return parseBatchRequestPart(scanner, boundary, mimeHeaders, contentType);
-      }
-    } else if (scanner.hasNext(boundary + REG_EX_ZERO_OR_MORE_WHITESPACES)) {
-      currentLineNumber++;
-      throw new BatchException(BatchException.INVALID_BOUNDARY_DELIMITER.addContent(currentLineNumber));
-    } else if (scanner.hasNext(REG_EX_ANY_BOUNDARY_STRING)) {
-      currentLineNumber++;
-      throw new BatchException(BatchException.NO_MATCH_WITH_BOUNDARY_STRING.addContent(boundary).addContent(
-          currentLineNumber));
-    } else {
-      currentLineNumber++;
-      throw new BatchException(BatchException.MISSING_BOUNDARY_DELIMITER.addContent(currentLineNumber));
-    }
-  }
-
-  private BatchRequestPart parseBatchRequestPart(final Scanner scanner, final String boundary,
-      final Map<String, String> mimeHeaders,
-      final String contentType) throws BatchException {
-    if (HttpContentType.APPLICATION_HTTP.equalsIgnoreCase(contentType)) {
-      validateEncoding(mimeHeaders.get(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING.toLowerCase(Locale.ENGLISH)));
-      parseNewLine(scanner);// mandatory
-      List<ODataRequest> requests = new ArrayList<ODataRequest>(1);
-      requests.add(parseRequest(scanner, false, boundary));
-      return new BatchRequestPartImpl(false, requests);
-    } else if (contentType.matches(REG_EX_OPTIONAL_WHITESPACE + HttpContentType.MULTIPART_MIXED + ANY_CHARACTERS)) {
-      String changeSetBoundary = getBoundary(contentType);
-      if (boundary.equals(changeSetBoundary)) {
-        throw new BatchException(BatchException.INVALID_CHANGESET_BOUNDARY.addContent(currentLineNumber));
-      }
-      List<ODataRequest> changeSetRequests = new LinkedList<ODataRequest>();
-      parseNewLine(scanner);// mandatory
-      Pattern changeSetCloseDelimiter =
-          Pattern.compile("--" + changeSetBoundary + "--" + REG_EX_ZERO_OR_MORE_WHITESPACES);
-      while (!scanner.hasNext(changeSetCloseDelimiter)) {
-        BatchRequestPart part = parseMultipart(scanner, changeSetBoundary, true);
-        changeSetRequests.addAll(part.getRequests());
-      }
-      scanner.next(changeSetCloseDelimiter);
-      currentLineNumber++;
-      return new BatchRequestPartImpl(true, changeSetRequests);
-    } else {
-      throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(HttpContentType.MULTIPART_MIXED
-          + " or " + HttpContentType.APPLICATION_HTTP));
-    }
-  }
-
-  private BatchRequestPart parseBatchRequestPartInChangeset(final Scanner scanner, final String boundary,
-      final Map<String, String> mimeHeaders,
-      final String contentType) throws BatchException {
-    if (HttpContentType.APPLICATION_HTTP.equalsIgnoreCase(contentType)) {
-      validateEncoding(mimeHeaders.get(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING.toLowerCase(Locale.ENGLISH)));
-      parseNewLine(scanner);// mandatory
-      List<ODataRequest> requests = new ArrayList<ODataRequest>(1);
-      requests.add(parseRequest(scanner, true, boundary));
-      return new BatchRequestPartImpl(false, requests);
-    } else {
-      throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(HttpContentType.APPLICATION_HTTP));
-    }
-  }
-
-  private ODataRequest parseRequest(final Scanner scanner, final boolean isChangeSet, final String boundary)
-      throws BatchException {
-    if (scanner.hasNext(REG_EX_REQUEST_LINE)) {
-      scanner.next(REG_EX_REQUEST_LINE);
-      currentLineNumber++;
-      final String method;
-      final String uri;
-      MatchResult result = scanner.match();
-      if (result.groupCount() == 2) {
-        method = result.group(1);
-        uri = result.group(2).trim();
-      } else {
-        currentLineNumber++;
-        throw new BatchException(BatchException.INVALID_REQUEST_LINE.addContent(scanner.next()).addContent(
-            currentLineNumber));
-      }
-      PathInfo pathInfo = parseRequestUri(uri);
-      Map<String, String> queryParameters = parseQueryParameters(uri);
-      if (isChangeSet) {
-        if (!HTTP_CHANGESET_METHODS.contains(method)) {
-          throw new BatchException(BatchException.INVALID_CHANGESET_METHOD.addContent(currentLineNumber));
-        }
-      } else if (!HTTP_BATCH_METHODS.contains(method)) {
-        throw new BatchException(BatchException.INVALID_QUERY_OPERATION_METHOD.addContent(currentLineNumber));
-      }
-      ODataHttpMethod httpMethod = ODataHttpMethod.valueOf(method);
-      Map<String, List<String>> headers = parseRequestHeaders(scanner, boundary);
-      if (currentMimeHeaderContentId != null) {
-        List<String> headerList = new ArrayList<String>();
-        headerList.add(currentMimeHeaderContentId);
-        headers.put(BatchHelper.MIME_HEADER_CONTENT_ID.toLowerCase(Locale.ENGLISH), headerList);
-      }
-
-      String contentType = getContentTypeHeader(headers);
-      List<String> acceptHeaders = getAcceptHeader(headers);
-      List<Locale> acceptLanguages = getAcceptLanguageHeader(headers);
-      InputStream body = new ByteArrayInputStream(new byte[0]);
-      if (isChangeSet) {
-        body = parseBody(scanner);
-      }
-
-      ODataRequestBuilder requestBuilder = ODataRequest.method(httpMethod)
-          .queryParameters(queryParameters)
-          .requestHeaders(headers)
-          .pathInfo(pathInfo)
-          .acceptableLanguages(acceptLanguages)
-          .body(body)
-          .acceptHeaders(acceptHeaders);
-
-      if (contentType != null) {
-        requestBuilder = requestBuilder.contentType(contentType);
-      }
-      return requestBuilder.build();
-    } else {
-      currentLineNumber++;
-      throw new BatchException(BatchException.INVALID_REQUEST_LINE.addContent(scanner.next()).addContent(
-          currentLineNumber));
-    }
-
-  }
-
-  private Map<String, List<String>> parseRequestHeaders(final Scanner scanner, final String boundary)
-      throws BatchException {
-    Map<String, List<String>> headers = new HashMap<String, List<String>>();
-    while (scanner.hasNext()
-        && !scanner.hasNext(REG_EX_BLANK_LINE)
-        && !scanner.hasNext("--" + boundary + REG_EX_ZERO_OR_MORE_WHITESPACES)) {
-      if (scanner.hasNext(REG_EX_HEADER)) {
-        scanner.next(REG_EX_HEADER);
-        currentLineNumber++;
-        MatchResult result = scanner.match();
-        if (result.groupCount() == 2) {
-          String headerName = result.group(1).trim().toLowerCase(Locale.ENGLISH);
-          String headerValue = result.group(2).trim();
-          if (HttpHeaders.ACCEPT.equalsIgnoreCase(headerName)) {
-            List<String> acceptHeaders = parseAcceptHeaders(headerValue);
-            headers.put(headerName, acceptHeaders);
-          } else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(headerName)) {
-            List<String> acceptLanguageHeaders = parseAcceptableLanguages(headerValue);
-            headers.put(headerName, acceptLanguageHeaders);
-          } else if (!BatchHelper.HTTP_CONTENT_ID.equalsIgnoreCase(headerName)) {
-            if (headers.containsKey(headerName)) {
-              headers.get(headerName).add(headerValue);
-            } else {
-              List<String> headerList = new ArrayList<String>();
-              headerList.add(headerValue);
-              headers.put(headerName, headerList);
-            }
-          } else {
-            List<String> headerList = new ArrayList<String>();
-            headerList.add(headerValue);
-            headers.put(BatchHelper.REQUEST_HEADER_CONTENT_ID.toLowerCase(Locale.ENGLISH), headerList);
-          }
-        }
-      } else {
-        currentLineNumber++;
-        throw new BatchException(BatchException.INVALID_HEADER.addContent(scanner.next())
-            .addContent(currentLineNumber));
-      }
-    }
-    return headers;
-  }
-
-  private PathInfo parseRequestUri(final String uri) throws BatchException {
-    PathInfoImpl pathInfo = new PathInfoImpl();
-    pathInfo.setServiceRoot(batchRequestPathInfo.getServiceRoot());
-    pathInfo.setPrecedingPathSegment(batchRequestPathInfo.getPrecedingSegments());
-    final String odataPathSegmentsAsString;
-    final String queryParametersAsString;
-    try {
-      Scanner uriScanner = new Scanner(uri);
-      uriScanner.useDelimiter(LF);
-      URI uriObject = new URI(uri);
-      if (uriObject.isAbsolute()) {
-        Pattern regexRequestUri = Pattern.compile(baseUri + "/([^/][^?]*)(\\?.*)?");
-        if (uriScanner.hasNext(regexRequestUri)) {
-          uriScanner.next(regexRequestUri);
-          MatchResult result = uriScanner.match();
-          if (result.groupCount() == 2) {
-            odataPathSegmentsAsString = result.group(1);
-            queryParametersAsString = result.group(2) != null ? result.group(2) : "";
-          } else {
-            uriScanner.close();
-            throw new BatchException(BatchException.INVALID_URI.addContent(currentLineNumber));
-          }
-        } else {
-          uriScanner.close();
-          throw new BatchException(BatchException.INVALID_URI.addContent(currentLineNumber));
-        }
-      } else {
-        Pattern regexRequestUri = Pattern.compile("([^/][^?]*)(\\?.*)?");
-        if (uriScanner.hasNext(regexRequestUri)) {
-          uriScanner.next(regexRequestUri);
-          MatchResult result = uriScanner.match();
-          if (result.groupCount() == 2) {
-            odataPathSegmentsAsString = result.group(1);
-            queryParametersAsString = result.group(2) != null ? result.group(2) : "";
-          } else {
-            uriScanner.close();
-            throw new BatchException(BatchException.INVALID_URI.addContent(currentLineNumber));
-          }
-        } else if (uriScanner.hasNext("/(.*)")) {
-          uriScanner.close();
-          throw new BatchException(BatchException.UNSUPPORTED_ABSOLUTE_PATH.addContent(currentLineNumber));
-        } else {
-          uriScanner.close();
-          throw new BatchException(BatchException.INVALID_URI.addContent(currentLineNumber));
-        }
-
-      }
-      uriScanner.close();
-      pathInfo.setODataPathSegment(parseODataPathSegments(odataPathSegmentsAsString));
-      if (!odataPathSegmentsAsString.startsWith("$")) {
-        String requestUri = baseUri + "/" + odataPathSegmentsAsString + queryParametersAsString;
-        pathInfo.setRequestUri(new URI(requestUri));
-      }
-      return pathInfo;
-    } catch (URISyntaxException e) {
-      throw new BatchException(BatchException.INVALID_URI.addContent(currentLineNumber), e);
-    }
-
-  }
-
-  private Map<String, String> parseQueryParameters(final String uri) throws BatchException {
-    Scanner uriScanner = new Scanner(uri);
-    uriScanner.useDelimiter("\n");
-    Map<String, String> queryParametersMap = new HashMap<String, String>();
-    Pattern regex = Pattern.compile("(?:" + baseUri + "/)?" + "[^?]+" + "\\?(.*)");
-    if (uriScanner.hasNext(regex)) {
-      uriScanner.next(regex);
-      MatchResult uriResult = uriScanner.match();
-      if (uriResult.groupCount() == 1) {
-        String queryParams = uriResult.group(1);
-        Scanner queryParamsScanner = new Scanner(queryParams);
-        queryParamsScanner.useDelimiter("&");
-        while (queryParamsScanner.hasNext(REG_EX_QUERY_PARAMETER)) {
-          queryParamsScanner.next(REG_EX_QUERY_PARAMETER);
-          MatchResult result = queryParamsScanner.match();
-          if (result.groupCount() == 2) {
-            String systemQueryOption = result.group(1);
-            String value = result.group(2);
-            queryParametersMap.put(systemQueryOption, Decoder.decode(value));
-          } else {
-            queryParamsScanner.close();
-            throw new BatchException(BatchException.INVALID_QUERY_PARAMETER);
-          }
-        }
-        queryParamsScanner.close();
-
-      } else {
-        uriScanner.close();
-        throw new BatchException(BatchException.INVALID_URI.addContent(currentLineNumber));
-      }
-    }
-    uriScanner.close();
-    return queryParametersMap;
-  }
-
-  private List<PathSegment> parseODataPathSegments(final String odataPathSegmentsAsString) {
-    Scanner pathSegmentScanner = new Scanner(odataPathSegmentsAsString);
-    pathSegmentScanner.useDelimiter("/");
-    List<PathSegment> odataPathSegments = new ArrayList<PathSegment>();
-    while (pathSegmentScanner.hasNext()) {
-      odataPathSegments.add(new ODataPathSegmentImpl(pathSegmentScanner.next(), null));
-    }
-    pathSegmentScanner.close();
-    return odataPathSegments;
-  }
-
-  private List<String> parseAcceptHeaders(final String headerValue) throws BatchException {
-    return AcceptParser.parseAcceptHeaders(headerValue);
-  }
-
-  private List<String> parseAcceptableLanguages(final String headerValue) throws BatchException {
-    return AcceptParser.parseAcceptableLanguages(headerValue);
-  }
-
-  private InputStream parseBody(final Scanner scanner) {
-    StringBuilder body = null;
-    final InputStream requestBody;
-
-    while (scanner.hasNext() && !scanner.hasNext(REG_EX_ANY_BOUNDARY_STRING)) {
-      if (!scanner.hasNext(REG_EX_ZERO_OR_MORE_WHITESPACES)) {
-        if (body == null) {
-          body = new StringBuilder(scanner.next());
-        } else {
-          body.append(LF).append(scanner.next());
-        }
-      } else {
-        scanner.next();
-      }
-      currentLineNumber++;
-    }
-
-    if (body != null) {
-      requestBody = new ByteArrayInputStream(BatchHelper.getBytes(body.toString()));
-    } else {
-      requestBody = new ByteArrayInputStream(new byte[0]);
-    }
-    return requestBody;
-  }
-
-  private String getBoundary(final String contentType) throws BatchException {
-    Scanner contentTypeScanner = new Scanner(contentType);
-    contentTypeScanner.useDelimiter(";\\s?");
-    if (contentTypeScanner.hasNext(REG_EX_CONTENT_TYPE)) {
-      contentTypeScanner.next(REG_EX_CONTENT_TYPE);
-    } else {
-      contentTypeScanner.close();
-      throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(HttpContentType.MULTIPART_MIXED));
-    }
-    if (contentTypeScanner.hasNext(REG_EX_BOUNDARY_PARAMETER)) {
-      contentTypeScanner.next(REG_EX_BOUNDARY_PARAMETER);
-      MatchResult result = contentTypeScanner.match();
-      contentTypeScanner.close();
-      if (result.groupCount() == 1 && result.group(1).trim().matches(REG_EX_BOUNDARY)) {
-        return trimQuota(result.group(1).trim());
-      } else {
-        throw new BatchException(BatchException.INVALID_BOUNDARY);
-      }
-    } else {
-      contentTypeScanner.close();
-      throw new BatchException(BatchException.MISSING_PARAMETER_IN_CONTENT_TYPE);
-    }
-  }
-
-  private void validateEncoding(final String encoding) throws BatchException {
-    if (!BatchHelper.BINARY_ENCODING.equalsIgnoreCase(encoding)) {
-      throw new BatchException(BatchException.INVALID_CONTENT_TRANSFER_ENCODING);
-    }
-  }
-
-  private Map<String, String> parseHeaders(final Scanner scanner) throws BatchException {
-    Map<String, String> headers = new HashMap<String, String>();
-    while (scanner.hasNext() && !(scanner.hasNext(REG_EX_BLANK_LINE))) {
-      if (scanner.hasNext(REG_EX_HEADER)) {
-        scanner.next(REG_EX_HEADER);
-        currentLineNumber++;
-        MatchResult result = scanner.match();
-        if (result.groupCount() == 2) {
-          String headerName = result.group(1).trim().toLowerCase(Locale.ENGLISH);
-          String headerValue = result.group(2).trim();
-          headers.put(headerName, headerValue);
-        }
-      } else {
-        throw new BatchException(BatchException.INVALID_HEADER.addContent(scanner.next()));
-      }
-    }
-    return headers;
-  }
-
-  private void parseNewLine(final Scanner scanner) throws BatchException {
-    if (scanner.hasNext() && scanner.hasNext(REG_EX_BLANK_LINE)) {
-      scanner.next();
-      currentLineNumber++;
-    } else {
-      currentLineNumber++;
-      if (scanner.hasNext()) {
-        throw new BatchException(BatchException.MISSING_BLANK_LINE.addContent(scanner.next()).addContent(
-            currentLineNumber));
-      } else {
-        throw new BatchException(BatchException.TRUNCATED_BODY.addContent(currentLineNumber));
-
-      }
-    }
-  }
-
-  private void parseOptionalLine(final Scanner scanner) throws BatchException {
-    while (scanner.hasNext() && scanner.hasNext(REG_EX_BLANK_LINE)) {
-      scanner.next();
-      currentLineNumber++;
-    }
-  }
-
-  private String getBaseUri() throws BatchException {
-    if (batchRequestPathInfo != null) {
-      if (batchRequestPathInfo.getServiceRoot() != null) {
-        String baseUri = batchRequestPathInfo.getServiceRoot().toASCIIString();
-        if (baseUri.lastIndexOf('/') == baseUri.length() - 1) {
-          baseUri = baseUri.substring(0, baseUri.length() - 1);
-        }
-        for (PathSegment precedingPS : batchRequestPathInfo.getPrecedingSegments()) {
-          baseUri = baseUri + "/" + precedingPS.getPath();
-        }
-        return baseUri;
-      }
-    } else {
-      throw new BatchException(BatchException.INVALID_PATHINFO);
-    }
-    return null;
-  }
-
-  private String trimQuota(String boundary) {
-    if (boundary.matches("\".*\"")) {
-      boundary = boundary.replace("\"", "");
-    }
-    boundary = boundary.replaceAll("\\)", "\\\\)");
-    boundary = boundary.replaceAll("\\(", "\\\\(");
-    boundary = boundary.replaceAll("\\?", "\\\\?");
-    boundary = boundary.replaceAll("\\+", "\\\\+");
-    return boundary;
-  }
-
-  private List<String> getAcceptHeader(final Map<String, List<String>> headers) {
-    List<String> acceptHeaders = new ArrayList<String>();
-    List<String> requestAcceptHeaderList = headers.get(HttpHeaders.ACCEPT.toLowerCase(Locale.ENGLISH));
-
-    if (requestAcceptHeaderList != null) {
-      acceptHeaders = requestAcceptHeaderList;
-    }
-    return acceptHeaders;
-  }
-
-  private List<Locale> getAcceptLanguageHeader(final Map<String, List<String>> headers) {
-    List<String> requestAcceptLanguageList = headers.get(HttpHeaders.ACCEPT_LANGUAGE.toLowerCase(Locale.ENGLISH));
-    List<Locale> acceptLanguages = new ArrayList<Locale>();
-    if (requestAcceptLanguageList != null) {
-      for (String acceptLanguage : requestAcceptLanguageList) {
-        String[] part = acceptLanguage.split("-");
-        String language = part[0];
-        String country = "";
-        if (part.length == 2) {
-          country = part[part.length - 1];
-        }
-        Locale locale = new Locale(language, country);
-        acceptLanguages.add(locale);
-      }
-    }
-    return acceptLanguages;
-  }
-
-  private String getContentTypeHeader(final Map<String, List<String>> headers) {
-    List<String> requestContentTypeList = headers.get(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH));
-    String contentType = null;
-    if (requestContentTypeList != null) {
-      for (String requestContentType : requestContentTypeList) {
-        contentType = contentType != null ? contentType + "," + requestContentType : requestContentType;
-      }
-    }
-    return contentType;
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchResponseParser.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchResponseParser.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchResponseParser.java
deleted file mode 100644
index 239311b..0000000
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchResponseParser.java
+++ /dev/null
@@ -1,356 +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.odata2.core.batch;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.regex.MatchResult;
-import java.util.regex.Pattern;
-
-import org.apache.olingo.odata2.api.batch.BatchException;
-import org.apache.olingo.odata2.api.client.batch.BatchSingleResponse;
-import org.apache.olingo.odata2.api.commons.HttpContentType;
-import org.apache.olingo.odata2.api.commons.HttpHeaders;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-public class BatchResponseParser {
-
-  private static final String CRLF = "\r\n";
-  private static final String REG_EX_OPTIONAL_WHITESPACE = "\\s?";
-  private static final String REG_EX_ZERO_OR_MORE_WHITESPACES = "\\s*";
-  private static final String ANY_CHARACTERS = ".*";
-
-  private static final Pattern REG_EX_BLANK_LINE = Pattern.compile("(|" + REG_EX_ZERO_OR_MORE_WHITESPACES + ")");
-  private static final Pattern REG_EX_HEADER = Pattern.compile("([a-zA-Z\\-]+):" + REG_EX_OPTIONAL_WHITESPACE + "(.*)"
-      + REG_EX_ZERO_OR_MORE_WHITESPACES);
-  private static final Pattern REG_EX_VERSION = Pattern.compile("(?:HTTP/[0-9]\\.[0-9])");
-  private static final Pattern REG_EX_ANY_BOUNDARY_STRING = Pattern.compile("--" + ANY_CHARACTERS
-      + REG_EX_ZERO_OR_MORE_WHITESPACES);
-  private static final Pattern REG_EX_STATUS_LINE = Pattern.compile(REG_EX_VERSION + "\\s" + "([0-9]{3})\\s([\\S ]+)"
-      + REG_EX_ZERO_OR_MORE_WHITESPACES);
-  private static final Pattern REG_EX_BOUNDARY_PARAMETER = Pattern.compile(REG_EX_OPTIONAL_WHITESPACE
-      + "boundary=(\".*\"|.*)" + REG_EX_ZERO_OR_MORE_WHITESPACES);
-  private static final Pattern REG_EX_CONTENT_TYPE = Pattern.compile(REG_EX_OPTIONAL_WHITESPACE
-      + HttpContentType.MULTIPART_MIXED);
-
-  private static final String REG_EX_BOUNDARY =
-      "([a-zA-Z0-9_\\-\\.'\\+]{1,70})|\"([a-zA-Z0-9_\\-\\.'\\+ \\(\\)" +
-          ",/:=\\?]{1,69}[a-zA-Z0-9_\\-\\.'\\+\\(\\),/:=\\?])\""; // See RFC 2046
-
-  private String contentTypeMime;
-  private String boundary;
-  private String currentContentId;
-  private int currentLineNumber = 0;
-
-  public BatchResponseParser(final String contentType) {
-    contentTypeMime = contentType;
-  }
-
-  public List<BatchSingleResponse> parse(final InputStream in) throws BatchException {
-    Scanner scanner = new Scanner(in, BatchHelper.DEFAULT_ENCODING);
-    scanner.useDelimiter(CRLF);
-    List<BatchSingleResponse> responseList;
-    try {
-      responseList = Collections.unmodifiableList(parseBatchResponse(scanner));
-    } finally {// NOPMD (suppress DoNotThrowExceptionInFinally)
-      scanner.close();
-      try {
-        in.close();
-      } catch (IOException e) {
-        throw new ODataRuntimeException(e);
-      }
-    }
-    return responseList;
-  }
-
-  private List<BatchSingleResponse> parseBatchResponse(final Scanner scanner) throws BatchException {
-    List<BatchSingleResponse> responses = new ArrayList<BatchSingleResponse>();
-    if (contentTypeMime != null) {
-      boundary = getBoundary(contentTypeMime);
-      parsePreamble(scanner);
-      final String closeDelimiter = "--" + boundary + "--" + REG_EX_ZERO_OR_MORE_WHITESPACES;
-      while (scanner.hasNext() && !scanner.hasNext(closeDelimiter)) {
-        responses.addAll(parseMultipart(scanner, boundary, false));
-      }
-      if (scanner.hasNext(closeDelimiter)) {
-        scanner.next(closeDelimiter);
-        currentLineNumber++;
-      } else {
-        throw new BatchException(BatchException.MISSING_CLOSE_DELIMITER.addContent(currentLineNumber));
-      }
-    } else {
-      throw new BatchException(BatchException.MISSING_CONTENT_TYPE);
-    }
-    return responses;
-
-  }
-
-  // The method parses additional information prior to the first boundary delimiter line
-  private void parsePreamble(final Scanner scanner) {
-    while (scanner.hasNext() && !scanner.hasNext(REG_EX_ANY_BOUNDARY_STRING)) {
-      scanner.next();
-      currentLineNumber++;
-    }
-  }
-
-  private List<BatchSingleResponse> parseMultipart(final Scanner scanner, final String boundary,
-      final boolean isChangeSet) throws BatchException {
-    Map<String, String> mimeHeaders = new HashMap<String, String>();
-    List<BatchSingleResponse> responses = new ArrayList<BatchSingleResponse>();
-    if (scanner.hasNext("--" + boundary + REG_EX_ZERO_OR_MORE_WHITESPACES)) {
-      scanner.next();
-      currentLineNumber++;
-      mimeHeaders = parseMimeHeaders(scanner);
-      currentContentId = mimeHeaders.get(BatchHelper.HTTP_CONTENT_ID.toLowerCase(Locale.ENGLISH));
-
-      final String contentType = mimeHeaders.get(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH));
-      if (contentType == null) {
-        throw new BatchException(BatchException.MISSING_CONTENT_TYPE);
-      }
-      if (isChangeSet) {
-        if (HttpContentType.APPLICATION_HTTP.equalsIgnoreCase(contentType)) {
-          validateEncoding(mimeHeaders.get(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING.toLowerCase(Locale.ENGLISH)));
-          parseNewLine(scanner);// mandatory
-          BatchSingleResponseImpl response = parseResponse(scanner, isChangeSet);
-          responses.add(response);
-        } else {
-          throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(HttpContentType.APPLICATION_HTTP));
-        }
-      } else {
-        if (HttpContentType.APPLICATION_HTTP.equalsIgnoreCase(contentType)) {
-          validateEncoding(mimeHeaders.get(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING.toLowerCase(Locale.ENGLISH)));
-          parseNewLine(scanner);// mandatory
-          BatchSingleResponseImpl response = parseResponse(scanner, isChangeSet);
-          responses.add(response);
-        } else if (contentType.matches(REG_EX_OPTIONAL_WHITESPACE + HttpContentType.MULTIPART_MIXED + ANY_CHARACTERS)) {
-          String changeSetBoundary = getBoundary(contentType);
-          if (boundary.equals(changeSetBoundary)) {
-            throw new BatchException(BatchException.INVALID_CHANGESET_BOUNDARY.addContent(currentLineNumber));
-          }
-          parseNewLine(scanner);// mandatory
-          Pattern changeSetCloseDelimiter =
-              Pattern.compile("--" + changeSetBoundary + "--" + REG_EX_ZERO_OR_MORE_WHITESPACES);
-          while (!scanner.hasNext(changeSetCloseDelimiter)) {
-            responses.addAll(parseMultipart(scanner, changeSetBoundary, true));
-          }
-          scanner.next(changeSetCloseDelimiter);
-          currentLineNumber++;
-          parseOptionalEmptyLine(scanner);
-        } else {
-          throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(HttpContentType.MULTIPART_MIXED
-              + " or " + HttpContentType.APPLICATION_HTTP));
-        }
-      }
-    } else if (scanner.hasNext(boundary + REG_EX_ZERO_OR_MORE_WHITESPACES)) {
-      currentLineNumber++;
-      throw new BatchException(BatchException.INVALID_BOUNDARY_DELIMITER.addContent(currentLineNumber));
-    } else if (scanner.hasNext(REG_EX_ANY_BOUNDARY_STRING)) {
-      currentLineNumber++;
-      throw new BatchException(BatchException.NO_MATCH_WITH_BOUNDARY_STRING.addContent(boundary).addContent(
-          currentLineNumber));
-    } else {
-      currentLineNumber++;
-      throw new BatchException(BatchException.MISSING_BOUNDARY_DELIMITER.addContent(currentLineNumber));
-    }
-    return responses;
-
-  }
-
-  private BatchSingleResponseImpl parseResponse(final Scanner scanner, final boolean isChangeSet)
-      throws BatchException {
-    BatchSingleResponseImpl response = new BatchSingleResponseImpl();
-    if (scanner.hasNext(REG_EX_STATUS_LINE)) {
-      scanner.next(REG_EX_STATUS_LINE);
-      currentLineNumber++;
-      final String statusCode;
-      final String statusInfo;
-      MatchResult result = scanner.match();
-      if (result.groupCount() == 2) {
-        statusCode = result.group(1);
-        statusInfo = result.group(2);
-      } else {
-        currentLineNumber++;
-        throw new BatchException(BatchException.INVALID_STATUS_LINE.addContent(scanner.next()).addContent(
-            currentLineNumber));
-      }
-
-      Map<String, String> headers = parseResponseHeaders(scanner);
-      parseNewLine(scanner);
-      String body = parseBody(scanner);
-      String contentLengthHeader = getHeaderValue(headers, HttpHeaders.CONTENT_LENGTH);
-      if (contentLengthHeader != null) {
-        int contentLength = Integer.parseInt(contentLengthHeader);
-        if (contentLength < body.length()) {
-          body = body.substring(0, contentLength);
-        }
-      }
-      response.setStatusCode(statusCode);
-      response.setStatusInfo(statusInfo);
-      response.setHeaders(headers);
-      response.setContentId(currentContentId);
-      response.setBody(body);
-    } else {
-      currentLineNumber++;
-      throw new BatchException(BatchException.INVALID_STATUS_LINE.addContent(scanner.next()).addContent(
-          currentLineNumber));
-    }
-    return response;
-  }
-
-  private void validateEncoding(final String encoding) throws BatchException {
-    if (!BatchHelper.BINARY_ENCODING.equalsIgnoreCase(encoding)) {
-      throw new BatchException(BatchException.INVALID_CONTENT_TRANSFER_ENCODING);
-    }
-  }
-
-  private Map<String, String> parseMimeHeaders(final Scanner scanner) throws BatchException {
-    Map<String, String> headers = new HashMap<String, String>();
-    while (scanner.hasNext() && !(scanner.hasNext(REG_EX_BLANK_LINE))) {
-      if (scanner.hasNext(REG_EX_HEADER)) {
-        scanner.next(REG_EX_HEADER);
-        currentLineNumber++;
-        MatchResult result = scanner.match();
-        if (result.groupCount() == 2) {
-          String headerName = result.group(1).trim().toLowerCase(Locale.ENGLISH);
-          String headerValue = result.group(2).trim();
-          headers.put(headerName, headerValue);
-        }
-      } else {
-        throw new BatchException(BatchException.INVALID_HEADER.addContent(scanner.next()));
-      }
-    }
-    return headers;
-  }
-
-  private Map<String, String> parseResponseHeaders(final Scanner scanner) throws BatchException {
-    Map<String, String> headers = new HashMap<String, String>();
-    while (scanner.hasNext() && !scanner.hasNext(REG_EX_BLANK_LINE)) {
-      if (scanner.hasNext(REG_EX_HEADER)) {
-        scanner.next(REG_EX_HEADER);
-        currentLineNumber++;
-        MatchResult result = scanner.match();
-        if (result.groupCount() == 2) {
-          String headerName = result.group(1).trim();
-          String headerValue = result.group(2).trim();
-          if (BatchHelper.HTTP_CONTENT_ID.equalsIgnoreCase(headerName)) {
-            if (currentContentId == null) {
-              currentContentId = headerValue;
-            }
-          } else {
-            headers.put(headerName, headerValue);
-          }
-        }
-      } else {
-        currentLineNumber++;
-        throw new BatchException(BatchException.INVALID_HEADER.addContent(scanner.next())
-            .addContent(currentLineNumber));
-      }
-    }
-    return headers;
-  }
-
-  private String getHeaderValue(final Map<String, String> headers, final String headerName) {
-    for (Map.Entry<String, String> header : headers.entrySet()) {
-      if (headerName.equalsIgnoreCase(header.getKey())) {
-        return header.getValue();
-      }
-    }
-    return null;
-  }
-
-  private String parseBody(final Scanner scanner) {
-    StringBuilder body = null;
-    while (scanner.hasNext() && !scanner.hasNext(REG_EX_ANY_BOUNDARY_STRING)) {
-      if (body == null) {
-        body = new StringBuilder(scanner.next());
-      } else {
-        body.append(CRLF).append(scanner.next());
-      }
-      currentLineNumber++;
-    }
-    String responseBody = body != null ? body.toString() : null;
-    return responseBody;
-  }
-
-  private String getBoundary(final String contentType) throws BatchException {
-    Scanner contentTypeScanner = new Scanner(contentType);
-    contentTypeScanner.useDelimiter(";\\s?");
-    if (contentTypeScanner.hasNext(REG_EX_CONTENT_TYPE)) {
-      contentTypeScanner.next(REG_EX_CONTENT_TYPE);
-    } else {
-      contentTypeScanner.close();
-      throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(HttpContentType.MULTIPART_MIXED));
-    }
-    if (contentTypeScanner.hasNext(REG_EX_BOUNDARY_PARAMETER)) {
-      contentTypeScanner.next(REG_EX_BOUNDARY_PARAMETER);
-      MatchResult result = contentTypeScanner.match();
-      contentTypeScanner.close();
-      if (result.groupCount() == 1 && result.group(1).trim().matches(REG_EX_BOUNDARY)) {
-        return trimQuota(result.group(1).trim());
-      } else {
-        throw new BatchException(BatchException.INVALID_BOUNDARY);
-      }
-    } else {
-      contentTypeScanner.close();
-      throw new BatchException(BatchException.MISSING_PARAMETER_IN_CONTENT_TYPE);
-    }
-  }
-
-  private void parseNewLine(final Scanner scanner) throws BatchException {
-    if (scanner.hasNext() && scanner.hasNext(REG_EX_BLANK_LINE)) {
-      scanner.next();
-      currentLineNumber++;
-    } else {
-      currentLineNumber++;
-      if (scanner.hasNext()) {
-        throw new BatchException(BatchException.MISSING_BLANK_LINE.addContent(scanner.next()).addContent(
-            currentLineNumber));
-      } else {
-        throw new BatchException(BatchException.TRUNCATED_BODY.addContent(currentLineNumber));
-
-      }
-    }
-  }
-
-  private void parseOptionalEmptyLine(final Scanner scanner) {
-    if (scanner.hasNext() && scanner.hasNext(REG_EX_BLANK_LINE)) {
-      scanner.next();
-      currentLineNumber++;
-    }
-  }
-
-  private String trimQuota(String boundary) {
-    if (boundary.matches("\".*\"")) {
-      boundary = boundary.replace("\"", "");
-    }
-    boundary = boundary.replaceAll("\\)", "\\\\)");
-    boundary = boundary.replaceAll("\\(", "\\\\(");
-    boundary = boundary.replaceAll("\\?", "\\\\?");
-    boundary = boundary.replaceAll("\\+", "\\\\+");
-    return boundary;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
new file mode 100644
index 0000000..e355f84
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * 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.odata2.core.batch.v2;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.commons.HttpContentType;
+import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+public class BatchBodyPart implements BatchPart {
+  final private Map<String, HeaderField> headers;
+  final private String boundary;
+  final private boolean isChangeSet;
+  final private boolean isStrict;
+  final private List<String> body;
+  private boolean isParsed = false;
+  private List<BatchQueryOperation> requests;
+
+  public BatchBodyPart(final List<String> bodyPartMessage, final String boundary, final boolean isStrict)
+      throws BatchException {
+    this.boundary = boundary;
+    this.isStrict = isStrict;
+
+    List<String> remainingMessage = new LinkedList<String>();
+    remainingMessage.addAll(bodyPartMessage);
+
+    headers = BatchParserCommon.consumeHeaders(remainingMessage);
+    BatchParserCommon.consumeBlankLine(remainingMessage, isStrict);
+    isChangeSet = isChangeSet(headers);
+    body = remainingMessage;
+  }
+
+  public BatchBodyPart parse(final int contentLength) throws BatchException {
+    List<String> remainingMessage = BatchParserCommon.trimStringListToLength(body, contentLength);
+    requests = consumeRequest(remainingMessage);
+    isParsed = true;
+
+    return this;
+  }
+
+  private boolean isChangeSet(final Map<String, HeaderField> headers) throws BatchException {
+    final HeaderField contentTypeField = headers.get(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH));
+    boolean isChangeSet = false;
+
+    if (contentTypeField == null || contentTypeField.getValues().size() == 0) {
+      throw new BatchException(BatchException.MISSING_CONTENT_TYPE);
+    }
+
+    for (String contentType : contentTypeField.getValues()) {
+      if (isContentTypeMultiPartMixed(contentType)) {
+        isChangeSet = true;
+      }
+    }
+
+    return isChangeSet;
+  }
+
+  private boolean isContentTypeMultiPartMixed(final String contentType) {
+    return contentType.contains(HttpContentType.MULTIPART_MIXED);
+  }
+
+  private List<BatchQueryOperation> consumeRequest(final List<String> remainingMessage) throws BatchException {
+    if (isChangeSet) {
+      return consumeChangeSet(remainingMessage);
+    } else {
+      return consumeQueryOperation(remainingMessage);
+    }
+  }
+
+  private List<BatchQueryOperation> consumeChangeSet(final List<String> remainingMessage)
+      throws BatchException {
+    final List<List<String>> changeRequests = splitChangeSet(remainingMessage);
+    final List<BatchQueryOperation> requestList = new LinkedList<BatchQueryOperation>();
+
+    for (List<String> changeRequest : changeRequests) {
+      requestList.add(new BatchChangeSet(changeRequest, isStrict).parse());
+    }
+
+    return requestList;
+  }
+
+  private List<List<String>> splitChangeSet(final List<String> remainingMessage)
+      throws BatchException {
+
+    final String changeSetBoundary = BatchParserCommon.getBoundary(getContentType());
+    validateChangeSetBoundary(changeSetBoundary);
+
+    return BatchParserCommon.splitMessageByBoundary(remainingMessage, changeSetBoundary);
+  }
+
+  private List<BatchQueryOperation> consumeQueryOperation(final List<String> remainingMessage)
+      throws BatchException {
+    final List<BatchQueryOperation> requestList = new LinkedList<BatchQueryOperation>();
+    requestList.add(new BatchQueryOperation(remainingMessage, isStrict).parse());
+
+    return requestList;
+  }
+
+  private void validateChangeSetBoundary(final String changeSetBoundary) throws BatchException {
+    if (changeSetBoundary.equals(boundary)) {
+      throw new BatchException(BatchException.INVALID_BOUNDARY);
+    }
+  }
+
+  private String getContentType() {
+    HeaderField contentTypeField = headers.get(HttpHeaders.CONTENT_TYPE.toLowerCase(Locale.ENGLISH));
+
+    return (contentTypeField != null && contentTypeField.getValues().size() > 0) ? contentTypeField.getValues().get(0)
+        : "";
+  }
+
+  @Override
+  public Map<String, HeaderField> getHeaders() {
+    return headers;
+  }
+
+  @Override
+  public boolean isStrict() {
+    return isStrict;
+  }
+
+  public boolean isChangeSet() {
+    return isChangeSet;
+  }
+
+  public List<BatchQueryOperation> getRequests() {
+    if (!isParsed) {
+      throw new ODataRuntimeException("Batch part must be parsed first");
+    }
+
+    return requests;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSet.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSet.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSet.java
new file mode 100644
index 0000000..5331ff8
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSet.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.batch.v2;
+
+import java.util.List;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+
+public class BatchChangeSet extends BatchQueryOperation {
+  private BatchQueryOperation request;
+
+  public BatchChangeSet(final List<String> message, final boolean isStrict) throws BatchException {
+    super(message, isStrict);
+  }
+
+  @Override
+  public BatchChangeSet parse() throws BatchException {
+    headers = BatchParserCommon.consumeHeaders(message);
+    BatchParserCommon.consumeBlankLine(message, isStrict);
+
+    request = new BatchQueryOperation(message, isStrict).parse();
+
+    return this;
+  }
+
+  public BatchQueryOperation getRequest() {
+    return request;
+  }
+
+  @Override
+  public List<String> getBody() {
+    return request.getBody();
+  }
+
+  @Override
+  public String getHttpMethod() {
+    return request.getHttpMethod();
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
new file mode 100644
index 0000000..b64453b
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * 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.odata2.core.batch.v2;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.batch.BatchParserResult;
+import org.apache.olingo.odata2.api.batch.BatchRequestPart;
+import org.apache.olingo.odata2.api.client.batch.BatchSingleResponse;
+import org.apache.olingo.odata2.api.ep.EntityProviderBatchProperties;
+import org.apache.olingo.odata2.api.uri.PathInfo;
+import org.apache.olingo.odata2.api.uri.PathSegment;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+public class BatchParser {
+
+  private final PathInfo batchRequestPathInfo;
+  private final String contentTypeMime;
+  private final boolean isStrict;
+
+  public BatchParser(final String contentType, final boolean isStrict) {
+    this(contentType, null, isStrict);
+  }
+
+  public BatchParser(final String contentType, final EntityProviderBatchProperties properties, final boolean isStrict) {
+    contentTypeMime = contentType;
+    batchRequestPathInfo = (properties != null) ? properties.getPathInfo() : null;
+    this.isStrict = isStrict;
+  }
+
+  @SuppressWarnings("unchecked")
+  public List<BatchSingleResponse> parseBatchResponse(final InputStream in) throws BatchException {
+    return (List<BatchSingleResponse>) parse(in, new BatchResponseTransformator());
+  }
+
+  @SuppressWarnings("unchecked")
+  public List<BatchRequestPart> parseBatchRequest(final InputStream in) throws BatchException {
+    return (List<BatchRequestPart>) parse(in, new BatchRequestTransformator());
+  }
+
+  private List<? extends BatchParserResult> parse(final InputStream in, final BatchTransformator transformator)
+      throws BatchException {
+    try {
+      return parseBatch(in, transformator);
+    } catch (IOException e) {
+      throw new ODataRuntimeException(e);
+    } finally {
+      try {
+        in.close();
+      } catch (IOException e) {
+        throw new ODataRuntimeException(e);
+      }
+    }
+  }
+
+  private List<BatchParserResult> parseBatch(final InputStream in,
+      final BatchTransformator transformator) throws BatchException, IOException {
+
+    final String baseUri = getBaseUri();
+    final String boundary = BatchParserCommon.getBoundary(contentTypeMime);
+    final List<BatchParserResult> resultList = new LinkedList<BatchParserResult>();
+    final List<List<String>> bodyPartStrings = splitBodyParts(in, boundary);
+
+    for (List<String> bodyPartString : bodyPartStrings) {
+      BatchBodyPart bodyPart = new BatchBodyPart(bodyPartString, boundary, isStrict);
+      resultList.addAll(transformator.transform(bodyPart, batchRequestPathInfo, baseUri));
+    }
+
+    return resultList;
+  }
+
+  private List<List<String>> splitBodyParts(final InputStream in, final String boundary)
+      throws IOException, BatchException {
+
+    final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
+    final List<String> message = reader.toList();
+    reader.close();
+
+    return BatchParserCommon.splitMessageByBoundary(message, boundary);
+  }
+
+  private String getBaseUri() throws BatchException {
+    String baseUri = "";
+
+    if (batchRequestPathInfo != null && batchRequestPathInfo.getServiceRoot() != null) {
+      final String uri = batchRequestPathInfo.getServiceRoot().toASCIIString();
+
+      baseUri = addPathSegements(removeLastSlash(uri));
+    }
+
+    return baseUri;
+  }
+
+  private String addPathSegements(String baseUri) {
+    for (PathSegment precedingPS : batchRequestPathInfo.getPrecedingSegments()) {
+      baseUri = baseUri + "/" + precedingPS.getPath();
+    }
+
+    return baseUri;
+  }
+
+  private String removeLastSlash(String baseUri) {
+    if (baseUri.lastIndexOf('/') == baseUri.length() - 1) {
+      baseUri = baseUri.substring(0, baseUri.length() - 1);
+    }
+
+    return baseUri;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
new file mode 100644
index 0000000..51314dd
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
@@ -0,0 +1,414 @@
+/*******************************************************************************
+ * 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.odata2.core.batch.v2;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.commons.HttpContentType;
+import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.api.uri.PathInfo;
+import org.apache.olingo.odata2.api.uri.PathSegment;
+import org.apache.olingo.odata2.core.ODataPathSegmentImpl;
+import org.apache.olingo.odata2.core.PathInfoImpl;
+import org.apache.olingo.odata2.core.batch.AcceptParser;
+import org.apache.olingo.odata2.core.commons.Decoder;
+
+public class BatchParserCommon {
+  private static final String BOUNDARY_IDENTIFIER = "boundary=";
+  private static final String REG_EX_BOUNDARY =
+      "([a-zA-Z0-9_\\-\\.'\\+]{1,70})|\"([a-zA-Z0-9_\\-\\.'\\+\\s\\" +
+          "(\\),/:=\\?]{1,69}[a-zA-Z0-9_\\-\\.'\\+\\(\\),/:=\\?])\""; // See RFC 2046
+
+  private static final Pattern REG_EX_HEADER = Pattern.compile("([a-zA-Z\\-]+):\\s?(.*)\\s*");
+
+  public static List<String> trimStringListToLength(final List<String> list, final int length) {
+    final Iterator<String> iter = list.iterator();
+    final List<String> result = new ArrayList<String>();
+    boolean isEndReached = false;
+    int currentLength = 0;
+
+    while (!isEndReached && iter.hasNext()) {
+      String currentLine = iter.next();
+
+      if (currentLength + currentLine.length() <= length) {
+        result.add(currentLine);
+        currentLength += currentLine.length();
+      } else {
+        result.add(currentLine.substring(0, length - currentLength));
+        isEndReached = true;
+      }
+    }
+
+    return result;
+  }
+
+  public static String stringListToString(final List<String> list) {
+    StringBuilder builder = new StringBuilder();
+
+    for (String currentLine : list) {
+      builder.append(currentLine);
+    }
+
+    return builder.toString();
+  }
+
+  public static InputStream convertMessageToInputStream(final List<String> message, final int contentLength)
+      throws BatchException {
+    List<String> shortenedMessage = BatchParserCommon.trimStringListToLength(message, contentLength);
+
+    return new ByteArrayInputStream(BatchParserCommon.stringListToString(shortenedMessage).getBytes());
+  }
+
+  static List<List<String>> splitMessageByBoundary(final List<String> message, final String boundary)
+      throws BatchException {
+    final List<List<String>> messageParts = new LinkedList<List<String>>();
+    List<String> currentPart = new ArrayList<String>();
+    boolean isEndReached = false;
+
+    for (String currentLine : message) {
+      if (currentLine.contains("--" + boundary + "--")) {
+        removeEndingCRLFFromList(currentPart);
+        messageParts.add(currentPart);
+        isEndReached = true;
+      } else if (currentLine.contains("--" + boundary)) {
+        removeEndingCRLFFromList(currentPart);
+        messageParts.add(currentPart);
+        currentPart = new LinkedList<String>();
+      } else {
+        currentPart.add(currentLine);
+      }
+
+      if (isEndReached) {
+        break;
+      }
+    }
+
+    // Remove preamble
+    if (messageParts.size() > 0) {
+      messageParts.remove(0);
+    } else {
+      throw new BatchException(BatchException.MISSING_BOUNDARY_DELIMITER);
+    }
+
+    if (messageParts.size() == 0) {
+      throw new BatchException(BatchException.NO_MATCH_WITH_BOUNDARY_STRING);
+    }
+
+    if (!isEndReached) {
+      throw new BatchException(BatchException.MISSING_CLOSE_DELIMITER);
+    }
+
+    return messageParts;
+  }
+
+  private static void removeEndingCRLFFromList(final List<String> list) {
+    if (list.size() > 0) {
+      String lastLine = list.remove(list.size() - 1);
+      list.add(removeEndingCRLF(lastLine));
+    }
+  }
+
+  public static String removeEndingCRLF(final String line) {
+    Pattern pattern = Pattern.compile("(.*)(\r\n){1}( *)", Pattern.DOTALL);
+    Matcher matcher = pattern.matcher(line);
+
+    if (matcher.matches()) {
+      return matcher.group(1);
+    } else {
+      return line;
+    }
+  }
+
+  static Map<String, HeaderField> consumeHeaders(final List<String> remainingMessage) throws BatchException {
+    final Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
+    boolean isHeader = true;
+    String currentLine;
+    Iterator<String> iter = remainingMessage.iterator();
+
+    while (iter.hasNext() && isHeader) {
+      currentLine = iter.next();
+      Matcher headerMatcher = REG_EX_HEADER.matcher(currentLine);
+
+      if (headerMatcher.matches() && headerMatcher.groupCount() == 2) {
+        iter.remove();
+
+        String headerName = headerMatcher.group(1).trim();
+        String headerNameLowerCase = headerName.toLowerCase(Locale.ENGLISH);
+        String headerValue = headerMatcher.group(2).trim();
+
+        if (HttpHeaders.ACCEPT.equalsIgnoreCase(headerNameLowerCase)) {
+          List<String> acceptHeaders = AcceptParser.parseAcceptHeaders(headerValue);
+          headers.put(headerNameLowerCase, new HeaderField(headerName, acceptHeaders));
+        } else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(headerNameLowerCase)) {
+          List<String> acceptLanguageHeaders = AcceptParser.parseAcceptableLanguages(headerValue);
+          headers.put(headerNameLowerCase, new HeaderField(headerName, acceptLanguageHeaders));
+        } else {
+          HeaderField headerField = headers.get(headerNameLowerCase);
+          headerField = headerField == null ? new HeaderField(headerName) : headerField;
+          headers.put(headerNameLowerCase, headerField);
+          headerField.getValues().add(headerValue);
+        }
+      } else {
+        isHeader = false;
+      }
+    }
+
+    return Collections.unmodifiableMap(headers);
+  }
+
+  static void consumeBlankLine(final List<String> remainingMessage, final boolean isStrict) throws BatchException {
+    if (remainingMessage.size() > 0 && "".equals(remainingMessage.get(0).trim())) {
+      remainingMessage.remove(0);
+    } else {
+      if (isStrict) {
+        throw new BatchException(BatchException.MISSING_BLANK_LINE);
+      }
+    }
+  }
+
+  static void consumeLastBlankLine(final List<String> message, final boolean isStrict) throws BatchException {
+    if (message.size() > 0 && "".equals(message.get(message.size() - 1).trim())) {
+      message.remove(message.size() - 1);
+    } else {
+      if (isStrict) {
+        throw new BatchException(BatchException.MISSING_BLANK_LINE);
+      }
+    }
+  }
+
+  static String getBoundary(final String contentType) throws BatchException {
+    if (contentType.contains(HttpContentType.MULTIPART_MIXED)) {
+      String[] parts = contentType.split(BOUNDARY_IDENTIFIER);
+
+      if (parts.length == 2) {
+        if (parts[1].matches(REG_EX_BOUNDARY)) {
+          return trimQuota(parts[1].trim());
+        } else {
+          throw new BatchException(BatchException.INVALID_BOUNDARY);
+        }
+      } else {
+        throw new BatchException(BatchException.MISSING_PARAMETER_IN_CONTENT_TYPE);
+      }
+    } else {
+      throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(HttpContentType.MULTIPART_MIXED));
+    }
+  }
+
+  static Map<String, List<String>> parseQueryParameter(final String httpRequest) {
+    Map<String, List<String>> queryParameter = new HashMap<String, List<String>>();
+
+    String[] requestParts = httpRequest.split(" ");
+    if (requestParts.length == 3) {
+
+      String[] parts = requestParts[1].split("\\?");
+      if (parts.length == 2) {
+        String[] parameters = parts[1].split("&");
+
+        for (String parameter : parameters) {
+          String[] parameterParts = parameter.split("=");
+          String parameterName = parameterParts[0].toLowerCase(Locale.ENGLISH);
+
+          if (parameterParts.length == 2) {
+            List<String> valueList = queryParameter.get(parameterName);
+            valueList = valueList == null ? new LinkedList<String>() : valueList;
+            queryParameter.put(parameterName, valueList);
+
+            String[] valueParts = parameterParts[1].split(",");
+            for (String value : valueParts) {
+              valueList.add(Decoder.decode(value));
+            }
+          }
+        }
+      }
+    }
+
+    return queryParameter;
+  }
+
+  public static PathInfo parseRequestUri(final String httpRequest, final PathInfo batchRequestPathInfo,
+      final String baseUri)
+      throws BatchException {
+
+    final String odataPathSegmentsAsString;
+    final String queryParametersAsString;
+
+    PathInfoImpl pathInfo = new PathInfoImpl();
+    pathInfo.setServiceRoot(batchRequestPathInfo.getServiceRoot());
+    pathInfo.setPrecedingPathSegment(batchRequestPathInfo.getPrecedingSegments());
+
+    String[] requestParts = httpRequest.split(" ");
+    if (requestParts.length == 3) {
+      String uri = requestParts[1];
+      Pattern regexRequestUri;
+
+      try {
+        URI uriObject = new URI(uri);
+        if (uriObject.isAbsolute()) {
+          regexRequestUri = Pattern.compile(baseUri + "/([^/][^?]*)(\\?.*)?");
+        } else {
+          regexRequestUri = Pattern.compile("([^/][^?]*)(\\?.*)?");
+
+        }
+
+        Matcher uriParts = regexRequestUri.matcher(uri);
+
+        if (uriParts.lookingAt() && uriParts.groupCount() == 2) {
+          odataPathSegmentsAsString = uriParts.group(1);
+          queryParametersAsString = uriParts.group(2) != null ? uriParts.group(2) : "";
+
+          pathInfo.setODataPathSegment(parseODataPathSegments(odataPathSegmentsAsString));
+          if (!odataPathSegmentsAsString.startsWith("$")) {
+            String requestUri = baseUri + "/" + odataPathSegmentsAsString + queryParametersAsString;
+            pathInfo.setRequestUri(new URI(requestUri));
+          }
+
+        } else {
+          throw new BatchException(BatchException.INVALID_URI);
+        }
+
+      } catch (URISyntaxException e) {
+        throw new BatchException(BatchException.INVALID_URI, e);
+      }
+    } else {
+      throw new BatchException(BatchException.INVALID_REQUEST_LINE);
+    }
+
+    return pathInfo;
+  }
+
+  public static List<PathSegment> parseODataPathSegments(final String odataPathSegmentsAsString) {
+    final List<PathSegment> odataPathSegments = new ArrayList<PathSegment>();
+    final String[] pathParts = odataPathSegmentsAsString.split("/");
+
+    for (final String pathSegment : pathParts) {
+      odataPathSegments.add(new ODataPathSegmentImpl(pathSegment, null));
+    }
+
+    return odataPathSegments;
+  }
+
+  private static String trimQuota(String boundary) {
+    if (boundary.matches("\".*\"")) {
+      boundary = boundary.replace("\"", "");
+    }
+
+    return boundary;
+  }
+
+  public static Map<String, String> headerFieldMapToSingleMap(final Map<String, HeaderField> headers) {
+    final Map<String, String> singleMap = new HashMap<String, String>();
+
+    for (final String key : headers.keySet()) {
+      HeaderField field = headers.get(key);
+      String value = field.getValues().size() > 0 ? field.getValues().get(0) : "";
+      singleMap.put(field.getFieldName(), value);
+    }
+
+    return singleMap;
+  }
+
+  public static Map<String, List<String>> headerFieldMapToMultiMap(final Map<String, HeaderField> headers) {
+    final Map<String, List<String>> singleMap = new HashMap<String, List<String>>();
+
+    for (final String key : headers.keySet()) {
+      HeaderField field = headers.get(key);
+      singleMap.put(field.getFieldName(), field.getValues());
+    }
+
+    return singleMap;
+  }
+
+  public static class HeaderField implements Cloneable {
+    private String fieldName;
+    private List<String> values;
+
+    public HeaderField(final String fieldName) {
+      this(fieldName, new ArrayList<String>());
+    }
+
+    public HeaderField(final String fieldName, final List<String> values) {
+      this.fieldName = fieldName;
+      this.values = values;
+    }
+
+    public String getFieldName() {
+      return fieldName;
+    }
+
+    public List<String> getValues() {
+      return values;
+    }
+
+    public void setValues(final List<String> values) {
+      this.values = values;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((fieldName == null) ? 0 : fieldName.hashCode());
+      return result;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+      if (this == obj) {
+        return true;
+      }
+      if (obj == null) {
+        return false;
+      }
+      if (getClass() != obj.getClass()) {
+        return false;
+      }
+      HeaderField other = (HeaderField) obj;
+      if (fieldName == null) {
+        if (other.fieldName != null) {
+          return false;
+        }
+      } else if (!fieldName.equals(other.fieldName)) {
+        return false;
+      }
+      return true;
+    }
+
+    @Override
+    public HeaderField clone() {
+      List<String> newValues = new ArrayList<String>();
+      newValues.addAll(values);
+
+      return new HeaderField(fieldName, newValues);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchPart.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchPart.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchPart.java
new file mode 100644
index 0000000..258f48a
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchPart.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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.odata2.core.batch.v2;
+
+import java.util.Map;
+
+import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
+
+public interface BatchPart {
+  public Map<String, HeaderField> getHeaders();
+
+  public boolean isStrict();
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6eca235e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
new file mode 100644
index 0000000..179fffb
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.batch.v2;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon.HeaderField;
+
+public class BatchQueryOperation implements BatchPart {
+
+  protected final boolean isStrict;
+  protected String httpMethod;
+  protected Map<String, HeaderField> headers;
+  protected List<String> body;
+  protected int bodySize;
+  protected List<String> message;
+
+  public BatchQueryOperation(final List<String> message, final boolean isStrict) {
+    this.isStrict = isStrict;
+    this.message = message;
+  }
+
+  public BatchQueryOperation parse() throws BatchException {
+    httpMethod = consumeHttpMethod(message);
+    headers = BatchParserCommon.consumeHeaders(message);
+    BatchParserCommon.consumeBlankLine(message, isStrict);
+    body = message;
+
+    return this;
+  }
+
+  protected String consumeHttpMethod(final List<String> message) throws BatchException {
+    if (message.size() > 0 && !message.get(0).trim().equals("")) {
+      String method = message.get(0);
+      message.remove(0);
+
+      return method;
+    } else {
+      throw new BatchException(BatchException.INVALID_QUERY_OPERATION_METHOD);
+    }
+  }
+
+  public String getHttpMethod() {
+    return httpMethod;
+  }
+
+  public List<String> getBody() {
+    return body;
+  }
+
+  public int getBodySize() {
+    return bodySize;
+  }
+
+  @Override
+  public Map<String, HeaderField> getHeaders() {
+    return headers;
+  }
+
+  @Override
+  public boolean isStrict() {
+    return isStrict;
+  }
+}


[07/19] Line number tracking and exception messages

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/test/resources/batchLarge.batch
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/batchLarge.batch b/odata2-lib/odata-core/src/test/resources/batchLarge.batch
new file mode 100644
index 0000000..3be0982
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/batchLarge.batch
@@ -0,0 +1,2505 @@
+--batch_8194-cf13-1f56
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+GET Employees HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Accept: application/atom+xml
+MaxDataServiceVersion: 2.0
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+DataServiceVersion: 2.0
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+
+--batch_8194-cf13-1f56
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+GET Employees HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Accept: application/atom+xml
+MaxDataServiceVersion: 2.0
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+DataServiceVersion: 2.0
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+
+--batch_8194-cf13-1f56
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+GET Employees HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Accept: application/atom+xml
+MaxDataServiceVersion: 2.0
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+DataServiceVersion: 2.0
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+
+--batch_8194-cf13-1f56
+Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd
+
+--changeset_f980-1cb6-94dd
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-ID: 1
+
+POST Employees HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Content-Length: 1117
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept: */*
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+<entry xmlns="http://www.w3.org/2005/Atom"
+  xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+  xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+  xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/"
+  m:etag="W/2">
+  <id>
+    http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Rooms('2')
+  </id>
+  <title type="text">Room 2</title>
+  <updated>2013-04-03T10:53:26.021+02:00</updated>
+  <category term="RefScenario.Room"
+    scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+  <link href="Rooms('2')" rel="edit" title="Room" />
+  <link href="Rooms('2')/nr_Employees"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Employees"
+    title="nr_Employees" type="application/atom+xml; type=feed">
+    <m:inline>
+      <feed xmlns="http://www.w3.org/2005/Atom"
+        xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+        xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+        xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/">
+        <id>
+          http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees
+        </id>
+        <title type="text">Employees</title>
+        <updated>2013-04-03T10:53:26.024+02:00</updated>
+        <author>
+          <name />
+        </author>
+        <link href="Employees" rel="self" title="Employees" />
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('2')
+          </id>
+          <title type="text">Frederic Fall</title>
+          <updated>2003-07-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('2')" rel="edit" title="Employee" />
+          <link href="Employees('2')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('2')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('2')/$value" />
+          <m:properties>
+            <d:EmployeeId>2</d:EmployeeId>
+            <d:EmployeeName>Frederic Fall</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>32</d:Age>
+            <d:EntryDate>2003-07-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('2')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('3')
+          </id>
+          <title type="text">Jonathan Smith</title>
+          <updated>2013-04-03T10:53:26.025+02:00</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('3')" rel="edit" title="Employee" />
+          <link href="Employees('3')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('3')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('3')/$value" />
+          <m:properties>
+            <d:EmployeeId>3</d:EmployeeId>
+            <d:EmployeeName>Jonathan Smith</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>56</d:Age>
+            <d:EntryDate m:null="true" />
+            <d:ImageUrl>Employees('3')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('4')
+          </id>
+          <title type="text">Peter Burke</title>
+          <updated>2004-09-12T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('4')" rel="edit" title="Employee" />
+          <link href="Employees('4')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('4')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('4')/$value" />
+          <m:properties>
+            <d:EmployeeId>4</d:EmployeeId>
+            <d:EmployeeName>Peter Burke</d:EmployeeName>
+            <d:ManagerId>3</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>2</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>39</d:Age>
+            <d:EntryDate>2004-09-12T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('4')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('6')
+          </id>
+          <title type="text">Susan Bay</title>
+          <updated>2010-12-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('6')" rel="edit" title="Employee" />
+          <link href="Employees('6')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('6')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('6')/$value" />
+          <m:properties>
+            <d:EmployeeId>6</d:EmployeeId>
+            <d:EmployeeName>Susan Bay</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>3</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>29</d:Age>
+            <d:EntryDate>2010-12-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('6')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+      </feed>
+    </m:inline>
+  </link>
+  <link href="Rooms('2')/nr_Building"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Building"
+    title="nr_Building" type="application/atom+xml; type=entry" />
+  <content type="application/xml">
+    <m:properties>
+      <d:Id>2</d:Id>
+      <d:Name>Room 2</d:Name>
+      <d:Seats>5</d:Seats>
+      <d:Version>2</d:Version>
+    </m:properties>
+  </content>
+</entry>
+
+--changeset_f980-1cb6-94dd
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-ID: 1
+
+POST Employees HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Content-Length: 1117
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept: */*
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+<entry xmlns="http://www.w3.org/2005/Atom"
+  xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+  xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+  xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/"
+  m:etag="W/2">
+  <id>
+    http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Rooms('2')
+  </id>
+  <title type="text">Room 2</title>
+  <updated>2013-04-03T10:53:26.021+02:00</updated>
+  <category term="RefScenario.Room"
+    scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+  <link href="Rooms('2')" rel="edit" title="Room" />
+  <link href="Rooms('2')/nr_Employees"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Employees"
+    title="nr_Employees" type="application/atom+xml; type=feed">
+    <m:inline>
+      <feed xmlns="http://www.w3.org/2005/Atom"
+        xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+        xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+        xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/">
+        <id>
+          http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees
+        </id>
+        <title type="text">Employees</title>
+        <updated>2013-04-03T10:53:26.024+02:00</updated>
+        <author>
+          <name />
+        </author>
+        <link href="Employees" rel="self" title="Employees" />
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('2')
+          </id>
+          <title type="text">Frederic Fall</title>
+          <updated>2003-07-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('2')" rel="edit" title="Employee" />
+          <link href="Employees('2')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('2')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('2')/$value" />
+          <m:properties>
+            <d:EmployeeId>2</d:EmployeeId>
+            <d:EmployeeName>Frederic Fall</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>32</d:Age>
+            <d:EntryDate>2003-07-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('2')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('3')
+          </id>
+          <title type="text">Jonathan Smith</title>
+          <updated>2013-04-03T10:53:26.025+02:00</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('3')" rel="edit" title="Employee" />
+          <link href="Employees('3')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('3')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('3')/$value" />
+          <m:properties>
+            <d:EmployeeId>3</d:EmployeeId>
+            <d:EmployeeName>Jonathan Smith</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>56</d:Age>
+            <d:EntryDate m:null="true" />
+            <d:ImageUrl>Employees('3')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('4')
+          </id>
+          <title type="text">Peter Burke</title>
+          <updated>2004-09-12T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('4')" rel="edit" title="Employee" />
+          <link href="Employees('4')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('4')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('4')/$value" />
+          <m:properties>
+            <d:EmployeeId>4</d:EmployeeId>
+            <d:EmployeeName>Peter Burke</d:EmployeeName>
+            <d:ManagerId>3</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>2</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>39</d:Age>
+            <d:EntryDate>2004-09-12T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('4')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('6')
+          </id>
+          <title type="text">Susan Bay</title>
+          <updated>2010-12-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('6')" rel="edit" title="Employee" />
+          <link href="Employees('6')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('6')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('6')/$value" />
+          <m:properties>
+            <d:EmployeeId>6</d:EmployeeId>
+            <d:EmployeeName>Susan Bay</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>3</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>29</d:Age>
+            <d:EntryDate>2010-12-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('6')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+      </feed>
+    </m:inline>
+  </link>
+  <link href="Rooms('2')/nr_Building"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Building"
+    title="nr_Building" type="application/atom+xml; type=entry" />
+  <content type="application/xml">
+    <m:properties>
+      <d:Id>2</d:Id>
+      <d:Name>Room 2</d:Name>
+      <d:Seats>5</d:Seats>
+      <d:Version>2</d:Version>
+    </m:properties>
+  </content>
+</entry>
+
+--changeset_f980-1cb6-94dd
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-ID: 1
+
+PUT Employees('1') HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Content-Length: 1117
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept: */*
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+<?xml version='1.0' encoding='utf-8'?>
+<entry xmlns="http://www.w3.org/2005/Atom"
+  xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+  xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+  xml:base="http://localhost:19000/abc/EntryXmlChangeTest/">
+  <id>http://localhost:19000/abc/EntryXmlChangeTest/Employees('9')</id>
+  <title type="text">Mister X</title>
+  <updated m:null='true'>Z</updated>
+  <category term="RefScenario.Employee"
+    scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+  <content type="image/jpeg" src="Employees('1')/$value" />
+  <m:properties>
+    <d:EmployeeId>1</d:EmployeeId>
+    <d:EmployeeName>Mister X</d:EmployeeName>
+    <d:ManagerId>1</d:ManagerId>
+    <d:RoomId>2</d:RoomId>
+    <d:TeamId>1</d:TeamId>
+    <d:Location m:type="RefScenario.c_Location">
+      <d:City m:type="RefScenario.c_City">
+        <d:PostalCode>69190</d:PostalCode>
+        <d:CityName>Walldorf</d:CityName>
+      </d:City>
+      <d:Country>Germany</d:Country>
+    </d:Location>
+    <d:EntryDate m:null='true'></d:EntryDate>
+    <d:ImageUrl>Employees('1')/$value</d:ImageUrl>
+  </m:properties>
+</entry>
+--changeset_f980-1cb6-94dd--
+--batch_8194-cf13-1f56
+Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd
+
+--changeset_f980-1cb6-94dd
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-ID: 1
+
+POST Employees HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Content-Length: 1117
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept: */*
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+<entry xmlns="http://www.w3.org/2005/Atom"
+  xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+  xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+  xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/"
+  m:etag="W/2">
+  <id>
+    http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Rooms('2')
+  </id>
+  <title type="text">Room 2</title>
+  <updated>2013-04-03T10:53:26.021+02:00</updated>
+  <category term="RefScenario.Room"
+    scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+  <link href="Rooms('2')" rel="edit" title="Room" />
+  <link href="Rooms('2')/nr_Employees"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Employees"
+    title="nr_Employees" type="application/atom+xml; type=feed">
+    <m:inline>
+      <feed xmlns="http://www.w3.org/2005/Atom"
+        xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+        xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+        xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/">
+        <id>
+          http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees
+        </id>
+        <title type="text">Employees</title>
+        <updated>2013-04-03T10:53:26.024+02:00</updated>
+        <author>
+          <name />
+        </author>
+        <link href="Employees" rel="self" title="Employees" />
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('2')
+          </id>
+          <title type="text">Frederic Fall</title>
+          <updated>2003-07-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('2')" rel="edit" title="Employee" />
+          <link href="Employees('2')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('2')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('2')/$value" />
+          <m:properties>
+            <d:EmployeeId>2</d:EmployeeId>
+            <d:EmployeeName>Frederic Fall</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>32</d:Age>
+            <d:EntryDate>2003-07-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('2')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('3')
+          </id>
+          <title type="text">Jonathan Smith</title>
+          <updated>2013-04-03T10:53:26.025+02:00</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('3')" rel="edit" title="Employee" />
+          <link href="Employees('3')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('3')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('3')/$value" />
+          <m:properties>
+            <d:EmployeeId>3</d:EmployeeId>
+            <d:EmployeeName>Jonathan Smith</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>56</d:Age>
+            <d:EntryDate m:null="true" />
+            <d:ImageUrl>Employees('3')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('4')
+          </id>
+          <title type="text">Peter Burke</title>
+          <updated>2004-09-12T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('4')" rel="edit" title="Employee" />
+          <link href="Employees('4')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('4')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('4')/$value" />
+          <m:properties>
+            <d:EmployeeId>4</d:EmployeeId>
+            <d:EmployeeName>Peter Burke</d:EmployeeName>
+            <d:ManagerId>3</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>2</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>39</d:Age>
+            <d:EntryDate>2004-09-12T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('4')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('6')
+          </id>
+          <title type="text">Susan Bay</title>
+          <updated>2010-12-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('6')" rel="edit" title="Employee" />
+          <link href="Employees('6')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('6')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('6')/$value" />
+          <m:properties>
+            <d:EmployeeId>6</d:EmployeeId>
+            <d:EmployeeName>Susan Bay</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>3</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>29</d:Age>
+            <d:EntryDate>2010-12-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('6')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+      </feed>
+    </m:inline>
+  </link>
+  <link href="Rooms('2')/nr_Building"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Building"
+    title="nr_Building" type="application/atom+xml; type=entry" />
+  <content type="application/xml">
+    <m:properties>
+      <d:Id>2</d:Id>
+      <d:Name>Room 2</d:Name>
+      <d:Seats>5</d:Seats>
+      <d:Version>2</d:Version>
+    </m:properties>
+  </content>
+</entry>
+
+--changeset_f980-1cb6-94dd
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-ID: 1
+
+POST Employees HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Content-Length: 1117
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept: */*
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+<entry xmlns="http://www.w3.org/2005/Atom"
+  xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+  xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+  xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/"
+  m:etag="W/2">
+  <id>
+    http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Rooms('2')
+  </id>
+  <title type="text">Room 2</title>
+  <updated>2013-04-03T10:53:26.021+02:00</updated>
+  <category term="RefScenario.Room"
+    scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+  <link href="Rooms('2')" rel="edit" title="Room" />
+  <link href="Rooms('2')/nr_Employees"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Employees"
+    title="nr_Employees" type="application/atom+xml; type=feed">
+    <m:inline>
+      <feed xmlns="http://www.w3.org/2005/Atom"
+        xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+        xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+        xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/">
+        <id>
+          http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees
+        </id>
+        <title type="text">Employees</title>
+        <updated>2013-04-03T10:53:26.024+02:00</updated>
+        <author>
+          <name />
+        </author>
+        <link href="Employees" rel="self" title="Employees" />
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('2')
+          </id>
+          <title type="text">Frederic Fall</title>
+          <updated>2003-07-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('2')" rel="edit" title="Employee" />
+          <link href="Employees('2')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('2')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('2')/$value" />
+          <m:properties>
+            <d:EmployeeId>2</d:EmployeeId>
+            <d:EmployeeName>Frederic Fall</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>32</d:Age>
+            <d:EntryDate>2003-07-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('2')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('3')
+          </id>
+          <title type="text">Jonathan Smith</title>
+          <updated>2013-04-03T10:53:26.025+02:00</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('3')" rel="edit" title="Employee" />
+          <link href="Employees('3')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('3')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('3')/$value" />
+          <m:properties>
+            <d:EmployeeId>3</d:EmployeeId>
+            <d:EmployeeName>Jonathan Smith</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>56</d:Age>
+            <d:EntryDate m:null="true" />
+            <d:ImageUrl>Employees('3')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('4')
+          </id>
+          <title type="text">Peter Burke</title>
+          <updated>2004-09-12T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('4')" rel="edit" title="Employee" />
+          <link href="Employees('4')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('4')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('4')/$value" />
+          <m:properties>
+            <d:EmployeeId>4</d:EmployeeId>
+            <d:EmployeeName>Peter Burke</d:EmployeeName>
+            <d:ManagerId>3</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>2</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>39</d:Age>
+            <d:EntryDate>2004-09-12T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('4')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('6')
+          </id>
+          <title type="text">Susan Bay</title>
+          <updated>2010-12-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('6')" rel="edit" title="Employee" />
+          <link href="Employees('6')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('6')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('6')/$value" />
+          <m:properties>
+            <d:EmployeeId>6</d:EmployeeId>
+            <d:EmployeeName>Susan Bay</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>3</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>29</d:Age>
+            <d:EntryDate>2010-12-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('6')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+      </feed>
+    </m:inline>
+  </link>
+  <link href="Rooms('2')/nr_Building"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Building"
+    title="nr_Building" type="application/atom+xml; type=entry" />
+  <content type="application/xml">
+    <m:properties>
+      <d:Id>2</d:Id>
+      <d:Name>Room 2</d:Name>
+      <d:Seats>5</d:Seats>
+      <d:Version>2</d:Version>
+    </m:properties>
+  </content>
+</entry>
+
+--changeset_f980-1cb6-94dd
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-ID: 1
+
+PUT Employees('1') HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Content-Length: 1117
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept: */*
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+<?xml version='1.0' encoding='utf-8'?>
+<entry xmlns="http://www.w3.org/2005/Atom"
+  xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+  xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+  xml:base="http://localhost:19000/abc/EntryXmlChangeTest/">
+  <id>http://localhost:19000/abc/EntryXmlChangeTest/Employees('9')</id>
+  <title type="text">Mister X</title>
+  <updated m:null='true'>Z</updated>
+  <category term="RefScenario.Employee"
+    scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+  <content type="image/jpeg" src="Employees('1')/$value" />
+  <m:properties>
+    <d:EmployeeId>1</d:EmployeeId>
+    <d:EmployeeName>Mister X</d:EmployeeName>
+    <d:ManagerId>1</d:ManagerId>
+    <d:RoomId>2</d:RoomId>
+    <d:TeamId>1</d:TeamId>
+    <d:Location m:type="RefScenario.c_Location">
+      <d:City m:type="RefScenario.c_City">
+        <d:PostalCode>69190</d:PostalCode>
+        <d:CityName>Walldorf</d:CityName>
+      </d:City>
+      <d:Country>Germany</d:Country>
+    </d:Location>
+    <d:EntryDate m:null='true'></d:EntryDate>
+    <d:ImageUrl>Employees('1')/$value</d:ImageUrl>
+  </m:properties>
+</entry>
+--changeset_f980-1cb6-94dd--
+--batch_8194-cf13-1f56
+Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd
+
+--changeset_f980-1cb6-94dd
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-ID: 1
+
+POST Employees HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Content-Length: 1117
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept: */*
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+<entry xmlns="http://www.w3.org/2005/Atom"
+  xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+  xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+  xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/"
+  m:etag="W/2">
+  <id>
+    http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Rooms('2')
+  </id>
+  <title type="text">Room 2</title>
+  <updated>2013-04-03T10:53:26.021+02:00</updated>
+  <category term="RefScenario.Room"
+    scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+  <link href="Rooms('2')" rel="edit" title="Room" />
+  <link href="Rooms('2')/nr_Employees"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Employees"
+    title="nr_Employees" type="application/atom+xml; type=feed">
+    <m:inline>
+      <feed xmlns="http://www.w3.org/2005/Atom"
+        xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+        xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+        xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/">
+        <id>
+          http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees
+        </id>
+        <title type="text">Employees</title>
+        <updated>2013-04-03T10:53:26.024+02:00</updated>
+        <author>
+          <name />
+        </author>
+        <link href="Employees" rel="self" title="Employees" />
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('2')
+          </id>
+          <title type="text">Frederic Fall</title>
+          <updated>2003-07-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('2')" rel="edit" title="Employee" />
+          <link href="Employees('2')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('2')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('2')/$value" />
+          <m:properties>
+            <d:EmployeeId>2</d:EmployeeId>
+            <d:EmployeeName>Frederic Fall</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>32</d:Age>
+            <d:EntryDate>2003-07-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('2')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('3')
+          </id>
+          <title type="text">Jonathan Smith</title>
+          <updated>2013-04-03T10:53:26.025+02:00</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('3')" rel="edit" title="Employee" />
+          <link href="Employees('3')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('3')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('3')/$value" />
+          <m:properties>
+            <d:EmployeeId>3</d:EmployeeId>
+            <d:EmployeeName>Jonathan Smith</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>56</d:Age>
+            <d:EntryDate m:null="true" />
+            <d:ImageUrl>Employees('3')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('4')
+          </id>
+          <title type="text">Peter Burke</title>
+          <updated>2004-09-12T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('4')" rel="edit" title="Employee" />
+          <link href="Employees('4')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('4')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('4')/$value" />
+          <m:properties>
+            <d:EmployeeId>4</d:EmployeeId>
+            <d:EmployeeName>Peter Burke</d:EmployeeName>
+            <d:ManagerId>3</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>2</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>39</d:Age>
+            <d:EntryDate>2004-09-12T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('4')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('6')
+          </id>
+          <title type="text">Susan Bay</title>
+          <updated>2010-12-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('6')" rel="edit" title="Employee" />
+          <link href="Employees('6')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('6')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('6')/$value" />
+          <m:properties>
+            <d:EmployeeId>6</d:EmployeeId>
+            <d:EmployeeName>Susan Bay</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>3</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>29</d:Age>
+            <d:EntryDate>2010-12-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('6')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+      </feed>
+    </m:inline>
+  </link>
+  <link href="Rooms('2')/nr_Building"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Building"
+    title="nr_Building" type="application/atom+xml; type=entry" />
+  <content type="application/xml">
+    <m:properties>
+      <d:Id>2</d:Id>
+      <d:Name>Room 2</d:Name>
+      <d:Seats>5</d:Seats>
+      <d:Version>2</d:Version>
+    </m:properties>
+  </content>
+</entry>
+
+--changeset_f980-1cb6-94dd
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-ID: 1
+
+POST Employees HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Content-Length: 1117
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept: */*
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+<entry xmlns="http://www.w3.org/2005/Atom"
+  xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+  xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+  xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/"
+  m:etag="W/2">
+  <id>
+    http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Rooms('2')
+  </id>
+  <title type="text">Room 2</title>
+  <updated>2013-04-03T10:53:26.021+02:00</updated>
+  <category term="RefScenario.Room"
+    scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+  <link href="Rooms('2')" rel="edit" title="Room" />
+  <link href="Rooms('2')/nr_Employees"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Employees"
+    title="nr_Employees" type="application/atom+xml; type=feed">
+    <m:inline>
+      <feed xmlns="http://www.w3.org/2005/Atom"
+        xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+        xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+        xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/">
+        <id>
+          http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees
+        </id>
+        <title type="text">Employees</title>
+        <updated>2013-04-03T10:53:26.024+02:00</updated>
+        <author>
+          <name />
+        </author>
+        <link href="Employees" rel="self" title="Employees" />
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('2')
+          </id>
+          <title type="text">Frederic Fall</title>
+          <updated>2003-07-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('2')" rel="edit" title="Employee" />
+          <link href="Employees('2')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('2')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('2')/$value" />
+          <m:properties>
+            <d:EmployeeId>2</d:EmployeeId>
+            <d:EmployeeName>Frederic Fall</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>32</d:Age>
+            <d:EntryDate>2003-07-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('2')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('3')
+          </id>
+          <title type="text">Jonathan Smith</title>
+          <updated>2013-04-03T10:53:26.025+02:00</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('3')" rel="edit" title="Employee" />
+          <link href="Employees('3')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('3')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('3')/$value" />
+          <m:properties>
+            <d:EmployeeId>3</d:EmployeeId>
+            <d:EmployeeName>Jonathan Smith</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>56</d:Age>
+            <d:EntryDate m:null="true" />
+            <d:ImageUrl>Employees('3')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('4')
+          </id>
+          <title type="text">Peter Burke</title>
+          <updated>2004-09-12T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('4')" rel="edit" title="Employee" />
+          <link href="Employees('4')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('4')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('4')/$value" />
+          <m:properties>
+            <d:EmployeeId>4</d:EmployeeId>
+            <d:EmployeeName>Peter Burke</d:EmployeeName>
+            <d:ManagerId>3</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>2</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>39</d:Age>
+            <d:EntryDate>2004-09-12T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('4')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('6')
+          </id>
+          <title type="text">Susan Bay</title>
+          <updated>2010-12-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('6')" rel="edit" title="Employee" />
+          <link href="Employees('6')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('6')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('6')/$value" />
+          <m:properties>
+            <d:EmployeeId>6</d:EmployeeId>
+            <d:EmployeeName>Susan Bay</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>3</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>29</d:Age>
+            <d:EntryDate>2010-12-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('6')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+      </feed>
+    </m:inline>
+  </link>
+  <link href="Rooms('2')/nr_Building"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Building"
+    title="nr_Building" type="application/atom+xml; type=entry" />
+  <content type="application/xml">
+    <m:properties>
+      <d:Id>2</d:Id>
+      <d:Name>Room 2</d:Name>
+      <d:Seats>5</d:Seats>
+      <d:Version>2</d:Version>
+    </m:properties>
+  </content>
+</entry>
+
+--changeset_f980-1cb6-94dd
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-ID: 1
+
+PUT Employees('1') HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Content-Length: 1117
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept: */*
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+<?xml version='1.0' encoding='utf-8'?>
+<entry xmlns="http://www.w3.org/2005/Atom"
+  xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+  xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+  xml:base="http://localhost:19000/abc/EntryXmlChangeTest/">
+  <id>http://localhost:19000/abc/EntryXmlChangeTest/Employees('9')</id>
+  <title type="text">Mister X</title>
+  <updated m:null='true'>Z</updated>
+  <category term="RefScenario.Employee"
+    scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+  <content type="image/jpeg" src="Employees('1')/$value" />
+  <m:properties>
+    <d:EmployeeId>1</d:EmployeeId>
+    <d:EmployeeName>Mister X</d:EmployeeName>
+    <d:ManagerId>1</d:ManagerId>
+    <d:RoomId>2</d:RoomId>
+    <d:TeamId>1</d:TeamId>
+    <d:Location m:type="RefScenario.c_Location">
+      <d:City m:type="RefScenario.c_City">
+        <d:PostalCode>69190</d:PostalCode>
+        <d:CityName>Walldorf</d:CityName>
+      </d:City>
+      <d:Country>Germany</d:Country>
+    </d:Location>
+    <d:EntryDate m:null='true'></d:EntryDate>
+    <d:ImageUrl>Employees('1')/$value</d:ImageUrl>
+  </m:properties>
+</entry>
+--changeset_f980-1cb6-94dd--
+--batch_8194-cf13-1f56
+Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd
+
+--changeset_f980-1cb6-94dd
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-ID: 1
+
+POST Employees HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Content-Length: 1117
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept: */*
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+<entry xmlns="http://www.w3.org/2005/Atom"
+  xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+  xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+  xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/"
+  m:etag="W/2">
+  <id>
+    http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Rooms('2')
+  </id>
+  <title type="text">Room 2</title>
+  <updated>2013-04-03T10:53:26.021+02:00</updated>
+  <category term="RefScenario.Room"
+    scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+  <link href="Rooms('2')" rel="edit" title="Room" />
+  <link href="Rooms('2')/nr_Employees"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Employees"
+    title="nr_Employees" type="application/atom+xml; type=feed">
+    <m:inline>
+      <feed xmlns="http://www.w3.org/2005/Atom"
+        xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+        xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+        xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/">
+        <id>
+          http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees
+        </id>
+        <title type="text">Employees</title>
+        <updated>2013-04-03T10:53:26.024+02:00</updated>
+        <author>
+          <name />
+        </author>
+        <link href="Employees" rel="self" title="Employees" />
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('2')
+          </id>
+          <title type="text">Frederic Fall</title>
+          <updated>2003-07-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('2')" rel="edit" title="Employee" />
+          <link href="Employees('2')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('2')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('2')/$value" />
+          <m:properties>
+            <d:EmployeeId>2</d:EmployeeId>
+            <d:EmployeeName>Frederic Fall</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>32</d:Age>
+            <d:EntryDate>2003-07-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('2')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('3')
+          </id>
+          <title type="text">Jonathan Smith</title>
+          <updated>2013-04-03T10:53:26.025+02:00</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('3')" rel="edit" title="Employee" />
+          <link href="Employees('3')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('3')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('3')/$value" />
+          <m:properties>
+            <d:EmployeeId>3</d:EmployeeId>
+            <d:EmployeeName>Jonathan Smith</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>56</d:Age>
+            <d:EntryDate m:null="true" />
+            <d:ImageUrl>Employees('3')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('4')
+          </id>
+          <title type="text">Peter Burke</title>
+          <updated>2004-09-12T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('4')" rel="edit" title="Employee" />
+          <link href="Employees('4')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('4')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('4')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('4')/$value" />
+          <m:properties>
+            <d:EmployeeId>4</d:EmployeeId>
+            <d:EmployeeName>Peter Burke</d:EmployeeName>
+            <d:ManagerId>3</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>2</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>39</d:Age>
+            <d:EntryDate>2004-09-12T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('4')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('6')
+          </id>
+          <title type="text">Susan Bay</title>
+          <updated>2010-12-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('6')" rel="edit" title="Employee" />
+          <link href="Employees('6')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('6')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('6')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('6')/$value" />
+          <m:properties>
+            <d:EmployeeId>6</d:EmployeeId>
+            <d:EmployeeName>Susan Bay</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>3</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>29</d:Age>
+            <d:EntryDate>2010-12-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('6')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+      </feed>
+    </m:inline>
+  </link>
+  <link href="Rooms('2')/nr_Building"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Building"
+    title="nr_Building" type="application/atom+xml; type=entry" />
+  <content type="application/xml">
+    <m:properties>
+      <d:Id>2</d:Id>
+      <d:Name>Room 2</d:Name>
+      <d:Seats>5</d:Seats>
+      <d:Version>2</d:Version>
+    </m:properties>
+  </content>
+</entry>
+
+--changeset_f980-1cb6-94dd
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-ID: 1
+
+POST Employees HTTP/1.1
+Host: http://localhost/odata
+Connection: keep-alive
+Content-Length: 1117
+Authorization: Basic YW56ZWlnZXI6ZGlzcGxheQ==
+Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
+X-CSRF-Token: P6no0PBwygp1ie0Gz-YbEg==
+User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
+Content-Type: application/atom+xml
+Accept: */*
+Accept-Encoding: gzip,deflate
+Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
+
+<entry xmlns="http://www.w3.org/2005/Atom"
+  xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+  xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+  xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/"
+  m:etag="W/2">
+  <id>
+    http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Rooms('2')
+  </id>
+  <title type="text">Room 2</title>
+  <updated>2013-04-03T10:53:26.021+02:00</updated>
+  <category term="RefScenario.Room"
+    scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+  <link href="Rooms('2')" rel="edit" title="Room" />
+  <link href="Rooms('2')/nr_Employees"
+    rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Employees"
+    title="nr_Employees" type="application/atom+xml; type=feed">
+    <m:inline>
+      <feed xmlns="http://www.w3.org/2005/Atom"
+        xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+        xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+        xml:base="http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/">
+        <id>
+          http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees
+        </id>
+        <title type="text">Employees</title>
+        <updated>2013-04-03T10:53:26.024+02:00</updated>
+        <author>
+          <name />
+        </author>
+        <link href="Employees" rel="self" title="Employees" />
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('2')
+          </id>
+          <title type="text">Frederic Fall</title>
+          <updated>2003-07-01T00:00:00Z</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('2')" rel="edit" title="Employee" />
+          <link href="Employees('2')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('2')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('2')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('2')/$value" />
+          <m:properties>
+            <d:EmployeeId>2</d:EmployeeId>
+            <d:EmployeeName>Frederic Fall</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>32</d:Age>
+            <d:EntryDate>2003-07-01T00:00:00</d:EntryDate>
+            <d:ImageUrl>Employees('2')/$value</d:ImageUrl>
+          </m:properties>
+        </entry>
+        <entry>
+          <id>
+            http://localhost:8080/org.apache.olingo.odata2.ref.web/ReferenceScenario.svc/Employees('3')
+          </id>
+          <title type="text">Jonathan Smith</title>
+          <updated>2013-04-03T10:53:26.025+02:00</updated>
+          <category term="RefScenario.Employee"
+            scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+          <link href="Employees('3')" rel="edit" title="Employee" />
+          <link href="Employees('3')/$value" rel="edit-media"
+            type="application/octet-stream" />
+          <link href="Employees('3')/ne_Manager"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager"
+            title="ne_Manager" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Team"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team"
+            title="ne_Team" type="application/atom+xml; type=entry" />
+          <link href="Employees('3')/ne_Room"
+            rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room"
+            title="ne_Room" type="application/atom+xml; type=entry" />
+          <content type="application/octet-stream" src="Employees('3')/$value" />
+          <m:properties>
+            <d:EmployeeId>3</d:EmployeeId>
+            <d:EmployeeName>Jonathan Smith</d:EmployeeName>
+            <d:ManagerId>1</d:ManagerId>
+            <d:RoomId>2</d:RoomId>
+            <d:TeamId>1</d:TeamId>
+            <d:Location m:type="RefScenario.c_Location">
+              <d:City m:type="RefScenario.c_City">
+                <d:PostalCode>69190</d:PostalCode>
+                <d:CityName>Walldorf</d:CityName>
+              </d:City>
+              <d:Country>Germany</d:Country>
+            </d:Location>
+            <d:Age>56</d:Age>
+            <d:EntryDate m:null="true" />
+            <d:Im

<TRUNCATED>

[04/19] git commit: Line ending issue

Posted by ch...@apache.org.
Line ending issue


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

Branch: refs/heads/master
Commit: ffb21db2dce53add1f6b98e796a5ac13a18a61ab
Parents: 6eca235
Author: Christian Amend <ch...@apache.org>
Authored: Mon Oct 6 13:15:32 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Mon Oct 6 13:15:32 2014 +0200

----------------------------------------------------------------------
 .../src/main/resources/SQL_Cleanup.properties   |  42 +-
 .../resources/SQL_Insert_Category.properties    |  42 +-
 .../main/resources/SQL_Insert_Config.properties |  42 +-
 .../resources/SQL_Insert_Customer.properties    |  44 +-
 .../resources/SQL_Insert_Material.properties    |  58 +-
 .../SQL_Insert_SalesOrderHeader.properties      |  58 +-
 .../SQL_Insert_SalesOrderItem.properties        |  60 +-
 .../main/resources/SQL_Insert_Store.properties  |  58 +-
 .../src/main/resources/serviceConfig.properties |  36 +-
 .../jpa-web/src/main/webapp/WEB-INF/web.xml     |  54 +-
 .../jpa-web/src/main/webapp/index.jsp           | 664 +++++++++----------
 odata2-lib/odata-annotation/.gitignore          |  16 +-
 .../src/main/java/META-INF/MANIFEST.MF          |   6 +-
 13 files changed, 590 insertions(+), 590 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ffb21db2/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Cleanup.properties
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Cleanup.properties b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Cleanup.properties
index 19f859d..27c4f3d 100644
--- a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Cleanup.properties
+++ b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Cleanup.properties
@@ -1,22 +1,22 @@
-#-------------------------------------------------------------------------------
-# 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.
-#-------------------------------------------------------------------------------
-
-#Config file for deleting the entities. They are deleted in the order provided in the below comma-separated string. 
-#It is mandatory due to referential constaints.
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
+
+#Config file for deleting the entities. They are deleted in the order provided in the below comma-separated string. 
+#It is mandatory due to referential constaints.
 delete_queries = DELETE FROM T_NOTE,DELETE FROM T_SALESORDERITEM,DELETE FROM T_MATERIAL_T_STORE,DELETE FROM T_MATERIAL,DELETE FROM T_STORE,DELETE FROM T_SALESORDERHEADER
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ffb21db2/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Category.properties
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Category.properties b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Category.properties
index d9b44e6..6bda640 100644
--- a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Category.properties
+++ b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Category.properties
@@ -1,22 +1,22 @@
-#-------------------------------------------------------------------------------
-# 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.
-#-------------------------------------------------------------------------------
-query_1 = INSERT INTO T_CATEGORY (CODE,ID,DESC) VALUES('P1',1,'Pen');
-query_2 = INSERT INTO T_CATEGORY (CODE,ID,DESC) VALUES('P2',1,'Pencil');
-query_3 = INSERT INTO T_CATEGORY (CODE,ID,DESC) VALUES('S1',2,'Sharpner');
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
+query_1 = INSERT INTO T_CATEGORY (CODE,ID,DESC) VALUES('P1',1,'Pen');
+query_2 = INSERT INTO T_CATEGORY (CODE,ID,DESC) VALUES('P2',1,'Pencil');
+query_3 = INSERT INTO T_CATEGORY (CODE,ID,DESC) VALUES('S1',2,'Sharpner');
 query_4 = INSERT INTO T_CATEGORY (CODE,ID,DESC) VALUES('E1',3,'Eraser');
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ffb21db2/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Config.properties
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Config.properties b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Config.properties
index 5910123..6a55bab 100644
--- a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Config.properties
+++ b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Config.properties
@@ -1,22 +1,22 @@
-#-------------------------------------------------------------------------------
-# 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.
-#-------------------------------------------------------------------------------
-
-#This file contains names of file which will contain the SQL statements to be executed by Data generator. Add a file name here and it will be picked up by Generator
-#You need to put the file names in order you want to get them called. First Entry will be inserted first.
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
+
+#This file contains names of file which will contain the SQL statements to be executed by Data generator. Add a file name here and it will be picked up by Generator
+#You need to put the file names in order you want to get them called. First Entry will be inserted first.
 insert_file_names = SQL_Insert_Customer,SQL_Insert_Category,SQL_Insert_SalesOrderHeader,SQL_Insert_Store,SQL_Insert_Material,SQL_Insert_SalesOrderItem,SQL_Insert_Note
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ffb21db2/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Customer.properties
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Customer.properties b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Customer.properties
index fe52d68..a42f23e 100644
--- a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Customer.properties
+++ b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Customer.properties
@@ -1,23 +1,23 @@
-#-------------------------------------------------------------------------------
-# 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.
-#-------------------------------------------------------------------------------
-query_1 = INSERT INTO T_CUSTOMER (ID , NAME, HOUSE_NUMBER , STREET_NAME, CITY, COUNTRY, PINCODE,CREATED_AT) VALUES(100,'Bob Bryan',7,'5 cross Street', 'London', 'UK',  'E7','2012-11-01 00:01:00');
-query_2 = INSERT INTO T_CUSTOMER (ID , NAME, HOUSE_NUMBER , STREET_NAME, CITY, COUNTRY, PINCODE,CREATED_AT) VALUES(200,'Mike Bryan',7,'8 cross Street', 'New York', 'USA',  '10011','2012-11-01 00:01:00');
-query_3 = INSERT INTO T_CUSTOMER (ID , NAME, HOUSE_NUMBER , STREET_NAME, CITY, COUNTRY, PINCODE,CREATED_AT) VALUES(201,'Steve Roger',7,'9 cross Street', 'Mumbai', 'India', '200101','2012-11-01 00:01:00');
-query_4 = INSERT INTO T_CUSTOMER (ID , NAME, HOUSE_NUMBER , STREET_NAME, CITY, COUNTRY, PINCODE,CREATED_AT) VALUES(101,'Pac Man',7,'25 cross Street', 'Frankfurt', 'Germany',  '60001','2012-11-01 00:01:00');
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
+query_1 = INSERT INTO T_CUSTOMER (ID , NAME, HOUSE_NUMBER , STREET_NAME, CITY, COUNTRY, PINCODE,CREATED_AT) VALUES(100,'Bob Bryan',7,'5 cross Street', 'London', 'UK',  'E7','2012-11-01 00:01:00');
+query_2 = INSERT INTO T_CUSTOMER (ID , NAME, HOUSE_NUMBER , STREET_NAME, CITY, COUNTRY, PINCODE,CREATED_AT) VALUES(200,'Mike Bryan',7,'8 cross Street', 'New York', 'USA',  '10011','2012-11-01 00:01:00');
+query_3 = INSERT INTO T_CUSTOMER (ID , NAME, HOUSE_NUMBER , STREET_NAME, CITY, COUNTRY, PINCODE,CREATED_AT) VALUES(201,'Steve Roger',7,'9 cross Street', 'Mumbai', 'India', '200101','2012-11-01 00:01:00');
+query_4 = INSERT INTO T_CUSTOMER (ID , NAME, HOUSE_NUMBER , STREET_NAME, CITY, COUNTRY, PINCODE,CREATED_AT) VALUES(101,'Pac Man',7,'25 cross Street', 'Frankfurt', 'Germany',  '60001','2012-11-01 00:01:00');
 query_5 = INSERT INTO T_CUSTOMER (ID , NAME, HOUSE_NUMBER , STREET_NAME, CITY, COUNTRY, PINCODE,CREATED_AT) VALUES(202,'Bolt Man',7,'25 cross Street', 'Toronto', 'Canada',  'NE','2012-11-01 00:01:00');
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ffb21db2/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Material.properties
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Material.properties b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Material.properties
index 653fafd..7c64d36 100644
--- a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Material.properties
+++ b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Material.properties
@@ -1,30 +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.
-#-------------------------------------------------------------------------------
-
-material_query_1 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(111, 'My Pen', 'P1', 1, 111.1, 'Piece');
-material_query_2 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(112, 'My Great Pen', 'P1', 1, 112.1, 'Piece');
-material_query_3 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(113, 'Super Pen', 'P1', 1, 113.1, 'Piece');
-material_query_4 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(114, 'Marvel Pen', 'P1', 1, 114.1, 'Piece');
-material_query_5 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(115, 'Smooth', 'P2', 1, 115.1, 'Piece');
-material_query_6 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(116, 'Silver Line', 'P2', 1, 116.1, 'Piece');
-material_query_7 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(117, 'Dark Line', 'P2', 1, 117.1, 'Piece');
-material_query_8 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(118, 'Sharp', 'S1', 2, 118.1, 'Piece');
-material_query_9 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(119, 'Cut Sharp', 'S1', 2, 119.1, 'Piece');
-material_query_10 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(120, 'Thin line', 'S1', 2, 120.1, 'Piece');
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
+
+material_query_1 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(111, 'My Pen', 'P1', 1, 111.1, 'Piece');
+material_query_2 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(112, 'My Great Pen', 'P1', 1, 112.1, 'Piece');
+material_query_3 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(113, 'Super Pen', 'P1', 1, 113.1, 'Piece');
+material_query_4 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(114, 'Marvel Pen', 'P1', 1, 114.1, 'Piece');
+material_query_5 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(115, 'Smooth', 'P2', 1, 115.1, 'Piece');
+material_query_6 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(116, 'Silver Line', 'P2', 1, 116.1, 'Piece');
+material_query_7 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(117, 'Dark Line', 'P2', 1, 117.1, 'Piece');
+material_query_8 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(118, 'Sharp', 'S1', 2, 118.1, 'Piece');
+material_query_9 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(119, 'Cut Sharp', 'S1', 2, 119.1, 'Piece');
+material_query_10 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(120, 'Thin line', 'S1', 2, 120.1, 'Piece');
 material_query_11 = insert into T_MATERIAL (MATERIAL_ID , MATERIAL_NAME, TYPE_CODE, CAT_ID, PRICE, MEASUREMENT_UNIT) values(121, 'Clean', 'E1', 3, 121.1, 'Piece');
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ffb21db2/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_SalesOrderHeader.properties
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_SalesOrderHeader.properties b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_SalesOrderHeader.properties
index 8b519bf..f27abd4 100644
--- a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_SalesOrderHeader.properties
+++ b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_SalesOrderHeader.properties
@@ -1,30 +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.
-#-------------------------------------------------------------------------------
-
-query1 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(1, 100, 'INR', '01', '2012-11-01 00:01:00');
-query2 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(2, 100, 'USD', '01', '2013-01-02 00:00:00');
-query3 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(3, 100, 'USD', '02', '2013-01-01 14:00:00');
-query4 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(4, 200, 'INR', '01', '2013-01-02 00:00:00');
-query5 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(5, 201, 'INR', '02', '2013-01-01 14:14:14');
-query6 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(6, 101, 'EUR', '01', '2013-01-02 00:00:00');
-query7 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(7, 201, 'EUR', '02', '2013-01-01 14:14:00');
-query8 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(8, 201, 'GBR', '01', '2013-01-02 00:00:00');
-query9 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(9, 101, 'GBR', '02', '2013-01-01 00:00:00');
-query10 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(10, 100, 'AUD', '01', '2013-01-01 00:00:00');
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
+
+query1 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(1, 100, 'INR', '01', '2012-11-01 00:01:00');
+query2 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(2, 100, 'USD', '01', '2013-01-02 00:00:00');
+query3 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(3, 100, 'USD', '02', '2013-01-01 14:00:00');
+query4 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(4, 200, 'INR', '01', '2013-01-02 00:00:00');
+query5 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(5, 201, 'INR', '02', '2013-01-01 14:14:14');
+query6 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(6, 101, 'EUR', '01', '2013-01-02 00:00:00');
+query7 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(7, 201, 'EUR', '02', '2013-01-01 14:14:00');
+query8 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(8, 201, 'GBR', '01', '2013-01-02 00:00:00');
+query9 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(9, 101, 'GBR', '02', '2013-01-01 00:00:00');
+query10 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(10, 100, 'AUD', '01', '2013-01-01 00:00:00');
 query11 = insert into T_SALESORDERHEADER (SO_ID, customer_ID, CURRENCY_CODE, DELIVERY_STATUS, creationDate) values(11, 202, 'AUD', '02', '2013-01-02 00:00:00');
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ffb21db2/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_SalesOrderItem.properties
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_SalesOrderItem.properties b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_SalesOrderItem.properties
index 0cc7669..3c0b221 100644
--- a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_SalesOrderItem.properties
+++ b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_SalesOrderItem.properties
@@ -1,30 +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.
-#-------------------------------------------------------------------------------
-
-line_item_query1 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(111, 1, 10.1, 1.11, 3, 11,true);
-line_item_query2 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(112, 1, 111.1, 1.12, 2, 10,true);
-line_item_query3 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(113, 1, 211.1, 1.13, 3, 9,false);
-line_item_query4 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(114, 1, 221.1, 1.14, 4, 8,false);
-line_item_query5 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(115, 1, 651.1, 1.15, 5, 7,true);
-line_item_query6 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(116, 1, 653.21, 1.16, 6, 6,true);
-line_item_query7 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(117, 1, 57.11, 1.17, 7, 5,true);
-line_item_query8 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(118, 1, 52.98, 1.18, 8, 4,false);
-line_item_query9 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(119, 1, 78.99, 1.19, 9, 3,false);
-line_item_query10 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(120, 1,69.23, 1.20, 10, 2,true);
-line_item_query11 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id , delivered) values(121, 1, 356.65, 1.21, 3, 1,true);
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
+
+line_item_query1 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(111, 1, 10.1, 1.11, 3, 11,true);
+line_item_query2 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(112, 1, 111.1, 1.12, 2, 10,true);
+line_item_query3 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(113, 1, 211.1, 1.13, 3, 9,false);
+line_item_query4 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(114, 1, 221.1, 1.14, 4, 8,false);
+line_item_query5 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(115, 1, 651.1, 1.15, 5, 7,true);
+line_item_query6 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(116, 1, 653.21, 1.16, 6, 6,true);
+line_item_query7 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(117, 1, 57.11, 1.17, 7, 5,true);
+line_item_query8 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(118, 1, 52.98, 1.18, 8, 4,false);
+line_item_query9 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(119, 1, 78.99, 1.19, 9, 3,false);
+line_item_query10 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id, delivered ) values(120, 1,69.23, 1.20, 10, 2,true);
+line_item_query11 = insert into T_SALESORDERITEM (Material_Id , quantity , amount , discount , Sales_Order_Id , Sales_Order_Item_Id , delivered) values(121, 1, 356.65, 1.21, 3, 1,true);

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ffb21db2/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Store.properties
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Store.properties b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Store.properties
index 20860f2..24d1bce 100644
--- a/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Store.properties
+++ b/odata2-jpa-processor/jpa-web/src/main/resources/SQL_Insert_Store.properties
@@ -1,30 +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.
-#-------------------------------------------------------------------------------
-
-store_query_1 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(131, 'Store New York', 11, 'New York Street', 'New York', 'USA','10001');
-store_query_2 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(132, 'Store Bengaluru', 21, 'Whitefield', 'Bengaluru', 'India','560037');
-store_query_3 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(133, 'Store Toronto', 31, 'Toronto Street', 'Toronto', 'Canada','M4J');
-store_query_4 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(134, 'Store Chicago', 41, 'Chicago Street', 'Chicago', 'USA','60625');
-store_query_5 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(135, 'Store Chennai', 51, 'Park Street', 'Chennai', 'India','600021');
-store_query_6 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(136, 'Store Frankfurt', 61, 'Frankfurt Street', 'Frankfurt', 'Germany','60001');
-store_query_7 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(137, 'Store Berlin', 71, 'Berlin Street', 'Berlin', 'Germany','10115');
-store_query_8 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(138, 'Store Hamburg', 81, 'Hamburg Street', 'Hamburg', 'Germany','20001');
-store_query_9 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(139, 'Store New Delhi', 91, 'New Delhi Street', 'New Delhi', 'India','110001');
-store_query_10 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(140, 'Store Ottawa', 100, 'Ottawa Street', 'Ottawa', 'Canada','K0A');
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
+
+store_query_1 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(131, 'Store New York', 11, 'New York Street', 'New York', 'USA','10001');
+store_query_2 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(132, 'Store Bengaluru', 21, 'Whitefield', 'Bengaluru', 'India','560037');
+store_query_3 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(133, 'Store Toronto', 31, 'Toronto Street', 'Toronto', 'Canada','M4J');
+store_query_4 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(134, 'Store Chicago', 41, 'Chicago Street', 'Chicago', 'USA','60625');
+store_query_5 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(135, 'Store Chennai', 51, 'Park Street', 'Chennai', 'India','600021');
+store_query_6 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(136, 'Store Frankfurt', 61, 'Frankfurt Street', 'Frankfurt', 'Germany','60001');
+store_query_7 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(137, 'Store Berlin', 71, 'Berlin Street', 'Berlin', 'Germany','10115');
+store_query_8 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(138, 'Store Hamburg', 81, 'Hamburg Street', 'Hamburg', 'Germany','20001');
+store_query_9 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(139, 'Store New Delhi', 91, 'New Delhi Street', 'New Delhi', 'India','110001');
+store_query_10 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(140, 'Store Ottawa', 100, 'Ottawa Street', 'Ottawa', 'Canada','K0A');
 store_query_11 = insert into T_STORE (STORE_ID , STORE_NAME, HOUSE_NUMBER, STREET_NAME, CITY, COUNTRY, PINCODE) values(141, 'Store Kolkata', 101, 'Kolkata Street', 'Kolkata', 'India','310001');
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ffb21db2/odata2-jpa-processor/jpa-web/src/main/resources/serviceConfig.properties
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/resources/serviceConfig.properties b/odata2-jpa-processor/jpa-web/src/main/resources/serviceConfig.properties
index 747277e..774b83a 100644
--- a/odata2-jpa-processor/jpa-web/src/main/resources/serviceConfig.properties
+++ b/odata2-jpa-processor/jpa-web/src/main/resources/serviceConfig.properties
@@ -1,19 +1,19 @@
-#-------------------------------------------------------------------------------
-# 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.
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
 showDetailError=true
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ffb21db2/odata2-jpa-processor/jpa-web/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/webapp/WEB-INF/web.xml b/odata2-jpa-processor/jpa-web/src/main/webapp/WEB-INF/web.xml
index df2bba0..cffa37e 100644
--- a/odata2-jpa-processor/jpa-web/src/main/webapp/WEB-INF/web.xml
+++ b/odata2-jpa-processor/jpa-web/src/main/webapp/WEB-INF/web.xml
@@ -18,30 +18,30 @@
   under the License.
 -->
 
-<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
-	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
-	id="WebApp_ID" version="2.5">
-	<display-name>OData - JPA Reference</display-name>
-	<welcome-file-list>
-		<welcome-file>index.jsp</welcome-file>
-	</welcome-file-list>
-
-	<servlet>
-		<servlet-name>JPARefScenarioServlet</servlet-name>
-		<servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
-		<init-param>
-			<param-name>javax.ws.rs.Application</param-name>
-			<param-value>org.apache.olingo.odata2.core.rest.app.ODataApplication</param-value>
-		</init-param>
-		<init-param>
-			<param-name>org.apache.olingo.odata2.service.factory</param-name>
-			<param-value>org.apache.olingo.odata2.jpa.processor.ref.web.JPAReferenceServiceFactory</param-value>
-		</init-param>
-		<load-on-startup>1</load-on-startup>
-	</servlet>
-	<servlet-mapping>
-		<servlet-name>JPARefScenarioServlet</servlet-name>
-		<url-pattern>/SalesOrderProcessing.svc/*</url-pattern>
-	</servlet-mapping>
-</web-app>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+	id="WebApp_ID" version="2.5">
+	<display-name>OData - JPA Reference</display-name>
+	<welcome-file-list>
+		<welcome-file>index.jsp</welcome-file>
+	</welcome-file-list>
+
+	<servlet>
+		<servlet-name>JPARefScenarioServlet</servlet-name>
+		<servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
+		<init-param>
+			<param-name>javax.ws.rs.Application</param-name>
+			<param-value>org.apache.olingo.odata2.core.rest.app.ODataApplication</param-value>
+		</init-param>
+		<init-param>
+			<param-name>org.apache.olingo.odata2.service.factory</param-name>
+			<param-value>org.apache.olingo.odata2.jpa.processor.ref.web.JPAReferenceServiceFactory</param-value>
+		</init-param>
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+	<servlet-mapping>
+		<servlet-name>JPARefScenarioServlet</servlet-name>
+		<url-pattern>/SalesOrderProcessing.svc/*</url-pattern>
+	</servlet-mapping>
+</web-app>

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ffb21db2/odata2-jpa-processor/jpa-web/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/webapp/index.jsp b/odata2-jpa-processor/jpa-web/src/main/webapp/index.jsp
index db37577..0885ad0 100644
--- a/odata2-jpa-processor/jpa-web/src/main/webapp/index.jsp
+++ b/odata2-jpa-processor/jpa-web/src/main/webapp/index.jsp
@@ -1,332 +1,332 @@
-<!--
-  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.
--->
-<%@page
-	import="org.apache.olingo.odata2.jpa.processor.ref.factory.JPAEntityManagerFactory"%>
-<%@page import="java.util.List"%>
-<%@page import="javax.persistence.EntityManager"%>
-<%@page import="javax.persistence.EntityManagerFactory"%>
-<%@page import="javax.persistence.Persistence"%>
-<%@page import="javax.persistence.Query"%>
-<%@page
-	import="org.apache.olingo.odata2.jpa.processor.ref.web.JPAReferenceServiceFactory"%>
-<%@page
-	import="org.apache.olingo.odata2.jpa.processor.ref.util.DataGenerator"%>
-
-<%@ page language="java" contentType="text/html; charset=UTF-8"
-	pageEncoding="UTF-8"%>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<title>Apache Olingo - OData2 JPA Processor Library</title>
-<style type="text/css">
-body {
-	font-family: Arial, sans-serif;
-	font-size: 13px;
-	line-height: 18px;
-	color: blue;
-	background-color: #ffffff;
-}
-
-a {
-	color: blue;
-	text-decoration: none;
-}
-
-a:focus {
-	outline: thin dotted #4076cb;
-	outline-offset: -1px;
-}
-
-a:hover,a:active {
-	outline: 0;
-}
-
-a:hover {
-	color: #404a7e;
-	text-decoration: underline;
-}
-
-h1,h2,h3,h4,h5,h6 {
-	margin: 9px 0;
-	font-family: inherit;
-	font-weight: bold;
-	line-height: 1;
-	color: blue;
-}
-
-h1 {
-	font-size: 36px;
-	line-height: 40px;
-}
-
-h2 {
-	font-size: 30px;
-	line-height: 40px;
-}
-
-h3 {
-	font-size: 24px;
-	line-height: 40px;
-}
-
-h4 {
-	font-size: 18px;
-	line-height: 20px;
-}
-
-h5 {
-	font-size: 14px;
-	line-height: 20px;
-}
-
-h6 {
-	font-size: 12px;
-	line-height: 20px;
-}
-
-.logo {
-	float: right;
-}
-
-ul {
-	padding: 0;
-	margin: 0 0 9px 25px;
-}
-
-ul ul {
-	margin-bottom: 0;
-}
-
-li {
-	line-height: 18px;
-}
-
-hr {
-	margin: 18px 0;
-	border: 0;
-	border-top: 1px solid #cccccc;
-	border-bottom: 1px solid #ffffff;
-}
-
-table {
-	border-collapse: collapse;
-	border-spacing: 10px;
-	border: 0px;
-}
-
-th,td {
-	border: 0px solid;
-	padding: 20px;
-}
-
-.code {
-	font-family: "Courier New", monospace;
-	font-size: 13px;
-	line-height: 18px;
-}
-</style>
-</head>
-<body>
-	<h1>Apache Olingo - OData2 JPA Processor Library</h1>
-	<hr />
-	<table width=100% cellspacing="1" cellpadding="1">
-		<tr>
-			<td width=50%><h2>Reference Scenario</h2></td>
-			<td width="50%">
-				<table cellspacing="1" cellpadding="1">
-					<tr align="center">
-						<td align="right" width="80%"><font color="green"><small>
-									<%
-									  EntityManagerFactory entityManagerFactory =
-									      JPAEntityManagerFactory.getEntityManagerFactory("salesorderprocessing");
-									  EntityManager entityManager = entityManagerFactory
-									      .createEntityManager();
-									  System.out.println("Data Gen " + entityManager.hashCode());
-									  DataGenerator dataGenerator = new DataGenerator(entityManager);
-
-									  Number result1 = null;
-									  Number existingCount = null;
-
-									  String msg = null;
-									  if (request.getParameter("button") != null) {
-									    if (request.getParameter("button").equalsIgnoreCase("Generate")) {
-									      Query q = entityManager
-									          .createQuery("SELECT COUNT(x) FROM SalesOrderHeader x");
-									      existingCount = (Number) q.getSingleResult();
-									      if (existingCount.intValue() < 10) { // Generate only if no data!
-									        dataGenerator.generate();
-									        result1 = (Number) q.getSingleResult();
-									        System.out
-									            .println("Data not existing earlier.... Generated number of Items - "
-									                + result1);
-									        msg = result1 + " items generated. ";
-
-									      } else {
-									        System.err
-									            .println("Data already existing.... No Item generated by Data Generator !!");
-									        msg = "Data exists. No Item generated !!";
-									      }
-									    } else { //Clean
-
-									      // Check if data already exists
-									      Query q = entityManager
-									          .createQuery("SELECT COUNT(x) FROM SalesOrderHeader x");
-									      Number result = (Number) q.getSingleResult();
-									      if (result.intValue() > 0) { // Generate only if no data!
-									        dataGenerator.clean();
-									        msg = "Data Cleaned. " + result + " items cleaned.";
-									      } else {
-									        msg = " Nothing to clean!!";
-									      }
-									    }
-									%> <%=(msg)%>
-							</small> </font></td>
-						<%
-						  }
-						%>
-						<td width="10%">
-							<form name="form1" method="get">
-								<input type="hidden" name="button" value="Generate"> <input
-									type="submit" value="Generate Data" width="100%">
-							</form>
-						</td>
-						<td width="10%">
-
-							<form name="form2" method="get">
-								<input type="hidden" name="button" value="Clean"> <input
-									type="submit" value="   Clean Data  " width="100%">
-							</form>
-						</td>
-					</tr>
-				</table>
-			</td>
-		</tr>
-	</table>
-	<table width=100%>
-		<tr>
-			<td valign="top">
-				<h3>Service Document and Metadata</h3>
-				<ul>
-					<li><a href="SalesOrderProcessing.svc?_wadl" target="_blank">wadl</a></li>
-					<li><a href="SalesOrderProcessing.svc/" target="_blank">service
-							document</a></li>
-					<li><a href="SalesOrderProcessing.svc/$metadata"
-						target="_blank">metadata</a></li>
-				</ul>
-				<h3>EntitySets</h3>
-				<ul>
-					<li><a href="SalesOrderProcessing.svc/SalesOrders"
-						target="_blank">SalesOrders</a></li>
-					<li><a href="SalesOrderProcessing.svc/SalesOrderLineItems"
-						target="_blank">SalesOrderLineItems</a></li>
-					<li><a href="SalesOrderProcessing.svc/Materials"
-						target="_blank">Materials</a></li>
-					<li><a href="SalesOrderProcessing.svc/Stores" target="_blank">Stores</a></li>
-				</ul>
-				<h3>Entities</h3>
-				<ul>
-					<li><a href="SalesOrderProcessing.svc/SalesOrders(2L)"
-						target="_blank">SalesOrders(2L)</a></li>
-					<li><a
-						href="SalesOrderProcessing.svc/SalesOrderLineItems(LiId=10L,SoId=2L)"
-						target="_blank">SalesOrderLineItems(LiId=10L,SoId=2L)</a></li>
-					<li><a href="SalesOrderProcessing.svc/Materials(111L)"
-						target="_blank">Materials(111L)</a></li>
-					<li><a href="SalesOrderProcessing.svc/Stores(131L)"
-						target="_blank">Stores(131L)</a></li>
-
-				</ul>
-				<h3>Navigation</h3>
-				<ul>
-					<li><a
-						href="SalesOrderProcessing.svc/SalesOrders(2L)/SalesOrderLineItemDetails"
-						target="_blank">SalesOrders(2L)/SalesOrderLineItemDetails</a></li>
-					<li><a
-						href="SalesOrderProcessing.svc/SalesOrders(2L)/SalesOrderLineItemDetails"
-						target="_blank">SalesOrders(2L)/SalesOrderLineItemDetails</a></li>
-					<li><a
-						href="SalesOrderProcessing.svc/SalesOrderLineItems(LiId=10L,SoId=2L)/MaterialDetails"
-						target="_blank">SalesOrderLineItems(LiId=10L,SoId=2L)/MaterialDetails</a></li>
-					<li><a
-						href="SalesOrderProcessing.svc/Materials(112L)/StoreDetails"
-						target="_blank">Materials(112L)/StoreDetails</a></li>
-
-				</ul>
-				<h3>$expand</h3>
-				<ul>
-					<li><a
-						href="SalesOrderProcessing.svc/SalesOrders?$expand=SalesOrderLineItemDetails"
-						target="_blank">SalesOrders?$expand=SalesOrderLineItemDetails</a></li>
-					<li><a
-						href="SalesOrderProcessing.svc/SalesOrders(2L)?$expand=SalesOrderLineItemDetails"
-						target="_blank">SalesOrders(2L)?$expand=SalesOrderLineItemDetails</a></li>
-					<li><a
-						href="SalesOrderProcessing.svc/SalesOrders?$expand=SalesOrderLineItemDetails/MaterialDetails,SalesOrderLineItemDetails/MaterialDetails/StoreDetails,NotesDetails"
-						target="_blank">SalesOrders?$expand=SalesOrderLineItemDetails/MaterialDetails,SalesOrderLineItemDetails/MaterialDetails/StoreDetails,NotesDetails</a></li>
-					<li><a
-						href="SalesOrderProcessing.svc/SalesOrders(2L)?$expand=SalesOrderLineItemDetails/MaterialDetails,SalesOrderLineItemDetails/MaterialDetails/StoreDetails,NotesDetails"
-						target="_blank">SalesOrders(2L)?$expand=SalesOrderLineItemDetails/MaterialDetails,SalesOrderLineItemDetails/MaterialDetails/StoreDetails,NotesDetails</a></li>
-
-				</ul>
-				<h3>Function Imports</h3>
-				<ul>
-					<li><a
-						href="SalesOrderProcessing.svc/FindAllSalesOrders?DeliveryStatusCode='01'"
-						target="_blank">SalesOrderProcessing.svc/FindAllSalesOrders?DeliveryStatusCode='01'</a></li>
-					<li><a href="SalesOrderProcessing.svc/orderValue?SoId=2L"
-						target="_blank">SalesOrderProcessing.svc/orderValue?SoId=2L</a></li>
-				</ul>
-				<h3>Paging</h3>
-				<ul>
-					<li><a
-						href="SalesOrderProcessing.svc/SalesOrders?$top=1&$inlinecount=allpages"
-						target="_blank">SalesOrderProcessing.svc/SalesOrders?$top=1&$inlinecount=allpages"</a></li>
-					<li><a
-						href="SalesOrderProcessing.svc/SalesOrders?$top=1&$inlinecount=allpages&$skiptoken=5"
-						target="_blank">SalesOrderProcessing.svc/SalesOrders?$top=1&$inlinecount=allpages&$skiptoken=5</a></li>
-					<li><a
-						href="SalesOrderProcessing.svc/SalesOrders?$top=1&$skip=4&$inlinecount=allpages&$skiptoken=5"
-						target="_blank">SalesOrderProcessing.svc/SalesOrders?$top=1&$skip=4&$inlinecount=allpages&$skiptoken=5</a></li>
-				</ul>
-			</td>
-			<td valign="top">&nbsp;</td>
-			<td valign="bottom">
-				<div class="code">
-					<%
-					  String version = "gen/version.html";
-					%>
-					<%
-					  try {
-					%>
-					<jsp:include page='<%=version%>' />
-					<%
-					  } catch (Exception e) {
-					%>
-					<p>IDE Build</p>
-					<%
-					  }
-					%>
-				</div>
-			</td>
-		</tr>
-	</table>
-</body>
-</html>
-
+<!--
+  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.
+-->
+<%@page
+	import="org.apache.olingo.odata2.jpa.processor.ref.factory.JPAEntityManagerFactory"%>
+<%@page import="java.util.List"%>
+<%@page import="javax.persistence.EntityManager"%>
+<%@page import="javax.persistence.EntityManagerFactory"%>
+<%@page import="javax.persistence.Persistence"%>
+<%@page import="javax.persistence.Query"%>
+<%@page
+	import="org.apache.olingo.odata2.jpa.processor.ref.web.JPAReferenceServiceFactory"%>
+<%@page
+	import="org.apache.olingo.odata2.jpa.processor.ref.util.DataGenerator"%>
+
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8"%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<title>Apache Olingo - OData2 JPA Processor Library</title>
+<style type="text/css">
+body {
+	font-family: Arial, sans-serif;
+	font-size: 13px;
+	line-height: 18px;
+	color: blue;
+	background-color: #ffffff;
+}
+
+a {
+	color: blue;
+	text-decoration: none;
+}
+
+a:focus {
+	outline: thin dotted #4076cb;
+	outline-offset: -1px;
+}
+
+a:hover,a:active {
+	outline: 0;
+}
+
+a:hover {
+	color: #404a7e;
+	text-decoration: underline;
+}
+
+h1,h2,h3,h4,h5,h6 {
+	margin: 9px 0;
+	font-family: inherit;
+	font-weight: bold;
+	line-height: 1;
+	color: blue;
+}
+
+h1 {
+	font-size: 36px;
+	line-height: 40px;
+}
+
+h2 {
+	font-size: 30px;
+	line-height: 40px;
+}
+
+h3 {
+	font-size: 24px;
+	line-height: 40px;
+}
+
+h4 {
+	font-size: 18px;
+	line-height: 20px;
+}
+
+h5 {
+	font-size: 14px;
+	line-height: 20px;
+}
+
+h6 {
+	font-size: 12px;
+	line-height: 20px;
+}
+
+.logo {
+	float: right;
+}
+
+ul {
+	padding: 0;
+	margin: 0 0 9px 25px;
+}
+
+ul ul {
+	margin-bottom: 0;
+}
+
+li {
+	line-height: 18px;
+}
+
+hr {
+	margin: 18px 0;
+	border: 0;
+	border-top: 1px solid #cccccc;
+	border-bottom: 1px solid #ffffff;
+}
+
+table {
+	border-collapse: collapse;
+	border-spacing: 10px;
+	border: 0px;
+}
+
+th,td {
+	border: 0px solid;
+	padding: 20px;
+}
+
+.code {
+	font-family: "Courier New", monospace;
+	font-size: 13px;
+	line-height: 18px;
+}
+</style>
+</head>
+<body>
+	<h1>Apache Olingo - OData2 JPA Processor Library</h1>
+	<hr />
+	<table width=100% cellspacing="1" cellpadding="1">
+		<tr>
+			<td width=50%><h2>Reference Scenario</h2></td>
+			<td width="50%">
+				<table cellspacing="1" cellpadding="1">
+					<tr align="center">
+						<td align="right" width="80%"><font color="green"><small>
+									<%
+									  EntityManagerFactory entityManagerFactory =
+									      JPAEntityManagerFactory.getEntityManagerFactory("salesorderprocessing");
+									  EntityManager entityManager = entityManagerFactory
+									      .createEntityManager();
+									  System.out.println("Data Gen " + entityManager.hashCode());
+									  DataGenerator dataGenerator = new DataGenerator(entityManager);
+
+									  Number result1 = null;
+									  Number existingCount = null;
+
+									  String msg = null;
+									  if (request.getParameter("button") != null) {
+									    if (request.getParameter("button").equalsIgnoreCase("Generate")) {
+									      Query q = entityManager
+									          .createQuery("SELECT COUNT(x) FROM SalesOrderHeader x");
+									      existingCount = (Number) q.getSingleResult();
+									      if (existingCount.intValue() < 10) { // Generate only if no data!
+									        dataGenerator.generate();
+									        result1 = (Number) q.getSingleResult();
+									        System.out
+									            .println("Data not existing earlier.... Generated number of Items - "
+									                + result1);
+									        msg = result1 + " items generated. ";
+
+									      } else {
+									        System.err
+									            .println("Data already existing.... No Item generated by Data Generator !!");
+									        msg = "Data exists. No Item generated !!";
+									      }
+									    } else { //Clean
+
+									      // Check if data already exists
+									      Query q = entityManager
+									          .createQuery("SELECT COUNT(x) FROM SalesOrderHeader x");
+									      Number result = (Number) q.getSingleResult();
+									      if (result.intValue() > 0) { // Generate only if no data!
+									        dataGenerator.clean();
+									        msg = "Data Cleaned. " + result + " items cleaned.";
+									      } else {
+									        msg = " Nothing to clean!!";
+									      }
+									    }
+									%> <%=(msg)%>
+							</small> </font></td>
+						<%
+						  }
+						%>
+						<td width="10%">
+							<form name="form1" method="get">
+								<input type="hidden" name="button" value="Generate"> <input
+									type="submit" value="Generate Data" width="100%">
+							</form>
+						</td>
+						<td width="10%">
+
+							<form name="form2" method="get">
+								<input type="hidden" name="button" value="Clean"> <input
+									type="submit" value="   Clean Data  " width="100%">
+							</form>
+						</td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	</table>
+	<table width=100%>
+		<tr>
+			<td valign="top">
+				<h3>Service Document and Metadata</h3>
+				<ul>
+					<li><a href="SalesOrderProcessing.svc?_wadl" target="_blank">wadl</a></li>
+					<li><a href="SalesOrderProcessing.svc/" target="_blank">service
+							document</a></li>
+					<li><a href="SalesOrderProcessing.svc/$metadata"
+						target="_blank">metadata</a></li>
+				</ul>
+				<h3>EntitySets</h3>
+				<ul>
+					<li><a href="SalesOrderProcessing.svc/SalesOrders"
+						target="_blank">SalesOrders</a></li>
+					<li><a href="SalesOrderProcessing.svc/SalesOrderLineItems"
+						target="_blank">SalesOrderLineItems</a></li>
+					<li><a href="SalesOrderProcessing.svc/Materials"
+						target="_blank">Materials</a></li>
+					<li><a href="SalesOrderProcessing.svc/Stores" target="_blank">Stores</a></li>
+				</ul>
+				<h3>Entities</h3>
+				<ul>
+					<li><a href="SalesOrderProcessing.svc/SalesOrders(2L)"
+						target="_blank">SalesOrders(2L)</a></li>
+					<li><a
+						href="SalesOrderProcessing.svc/SalesOrderLineItems(LiId=10L,SoId=2L)"
+						target="_blank">SalesOrderLineItems(LiId=10L,SoId=2L)</a></li>
+					<li><a href="SalesOrderProcessing.svc/Materials(111L)"
+						target="_blank">Materials(111L)</a></li>
+					<li><a href="SalesOrderProcessing.svc/Stores(131L)"
+						target="_blank">Stores(131L)</a></li>
+
+				</ul>
+				<h3>Navigation</h3>
+				<ul>
+					<li><a
+						href="SalesOrderProcessing.svc/SalesOrders(2L)/SalesOrderLineItemDetails"
+						target="_blank">SalesOrders(2L)/SalesOrderLineItemDetails</a></li>
+					<li><a
+						href="SalesOrderProcessing.svc/SalesOrders(2L)/SalesOrderLineItemDetails"
+						target="_blank">SalesOrders(2L)/SalesOrderLineItemDetails</a></li>
+					<li><a
+						href="SalesOrderProcessing.svc/SalesOrderLineItems(LiId=10L,SoId=2L)/MaterialDetails"
+						target="_blank">SalesOrderLineItems(LiId=10L,SoId=2L)/MaterialDetails</a></li>
+					<li><a
+						href="SalesOrderProcessing.svc/Materials(112L)/StoreDetails"
+						target="_blank">Materials(112L)/StoreDetails</a></li>
+
+				</ul>
+				<h3>$expand</h3>
+				<ul>
+					<li><a
+						href="SalesOrderProcessing.svc/SalesOrders?$expand=SalesOrderLineItemDetails"
+						target="_blank">SalesOrders?$expand=SalesOrderLineItemDetails</a></li>
+					<li><a
+						href="SalesOrderProcessing.svc/SalesOrders(2L)?$expand=SalesOrderLineItemDetails"
+						target="_blank">SalesOrders(2L)?$expand=SalesOrderLineItemDetails</a></li>
+					<li><a
+						href="SalesOrderProcessing.svc/SalesOrders?$expand=SalesOrderLineItemDetails/MaterialDetails,SalesOrderLineItemDetails/MaterialDetails/StoreDetails,NotesDetails"
+						target="_blank">SalesOrders?$expand=SalesOrderLineItemDetails/MaterialDetails,SalesOrderLineItemDetails/MaterialDetails/StoreDetails,NotesDetails</a></li>
+					<li><a
+						href="SalesOrderProcessing.svc/SalesOrders(2L)?$expand=SalesOrderLineItemDetails/MaterialDetails,SalesOrderLineItemDetails/MaterialDetails/StoreDetails,NotesDetails"
+						target="_blank">SalesOrders(2L)?$expand=SalesOrderLineItemDetails/MaterialDetails,SalesOrderLineItemDetails/MaterialDetails/StoreDetails,NotesDetails</a></li>
+
+				</ul>
+				<h3>Function Imports</h3>
+				<ul>
+					<li><a
+						href="SalesOrderProcessing.svc/FindAllSalesOrders?DeliveryStatusCode='01'"
+						target="_blank">SalesOrderProcessing.svc/FindAllSalesOrders?DeliveryStatusCode='01'</a></li>
+					<li><a href="SalesOrderProcessing.svc/orderValue?SoId=2L"
+						target="_blank">SalesOrderProcessing.svc/orderValue?SoId=2L</a></li>
+				</ul>
+				<h3>Paging</h3>
+				<ul>
+					<li><a
+						href="SalesOrderProcessing.svc/SalesOrders?$top=1&$inlinecount=allpages"
+						target="_blank">SalesOrderProcessing.svc/SalesOrders?$top=1&$inlinecount=allpages"</a></li>
+					<li><a
+						href="SalesOrderProcessing.svc/SalesOrders?$top=1&$inlinecount=allpages&$skiptoken=5"
+						target="_blank">SalesOrderProcessing.svc/SalesOrders?$top=1&$inlinecount=allpages&$skiptoken=5</a></li>
+					<li><a
+						href="SalesOrderProcessing.svc/SalesOrders?$top=1&$skip=4&$inlinecount=allpages&$skiptoken=5"
+						target="_blank">SalesOrderProcessing.svc/SalesOrders?$top=1&$skip=4&$inlinecount=allpages&$skiptoken=5</a></li>
+				</ul>
+			</td>
+			<td valign="top">&nbsp;</td>
+			<td valign="bottom">
+				<div class="code">
+					<%
+					  String version = "gen/version.html";
+					%>
+					<%
+					  try {
+					%>
+					<jsp:include page='<%=version%>' />
+					<%
+					  } catch (Exception e) {
+					%>
+					<p>IDE Build</p>
+					<%
+					  }
+					%>
+				</div>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ffb21db2/odata2-lib/odata-annotation/.gitignore
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-annotation/.gitignore b/odata2-lib/odata-annotation/.gitignore
index 8b3fd61..29be3de 100644
--- a/odata2-lib/odata-annotation/.gitignore
+++ b/odata2-lib/odata-annotation/.gitignore
@@ -1,8 +1,8 @@
-.project
-.classpath
-.settings
-target
-bin
-*.bak
-classes
-.DS_Store
+.project
+.classpath
+.settings
+target
+bin
+*.bak
+classes
+.DS_Store

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ffb21db2/odata2-lib/odata-annotation/src/main/java/META-INF/MANIFEST.MF
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-annotation/src/main/java/META-INF/MANIFEST.MF b/odata2-lib/odata-annotation/src/main/java/META-INF/MANIFEST.MF
index 5e94951..254272e 100644
--- a/odata2-lib/odata-annotation/src/main/java/META-INF/MANIFEST.MF
+++ b/odata2-lib/odata-annotation/src/main/java/META-INF/MANIFEST.MF
@@ -1,3 +1,3 @@
-Manifest-Version: 1.0
-Class-Path: 
-
+Manifest-Version: 1.0
+Class-Path: 
+


[08/19] git commit: Line number tracking and exception messages

Posted by ch...@apache.org.
Line number tracking and exception messages

Signed-off-by: Christian Amend <ch...@apache.org>


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

Branch: refs/heads/master
Commit: f0dc0f74593a3184c84dbf43337b23ec52f57abb
Parents: 05d20c1
Author: Christian Holzer <c....@sap.com>
Authored: Mon Oct 6 13:01:40 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Mon Oct 6 13:54:39 2014 +0200

----------------------------------------------------------------------
 .../olingo/odata2/api/batch/BatchException.java |    2 +-
 .../odata2/core/batch/v2/BatchBodyPart.java     |   31 +-
 .../core/batch/v2/BatchChangeSetPart.java       |    7 +-
 .../odata2/core/batch/v2/BatchParser.java       |   11 +-
 .../odata2/core/batch/v2/BatchParserCommon.java |  101 +-
 .../core/batch/v2/BatchQueryOperation.java      |   22 +-
 .../batch/v2/BatchRequestTransformator.java     |   74 +-
 .../batch/v2/BatchResponseTransformator.java    |   10 +-
 .../core/batch/v2/BatchTransformatorCommon.java |   31 +-
 .../v2/BufferedReaderIncludingLineEndings.java  |   60 +-
 .../olingo/odata2/core/batch/v2/Header.java     |  142 +-
 .../src/main/resources/i18n.properties          |   37 +-
 .../core/batch/BatchParserCommonTest.java       |   55 +-
 .../core/batch/BatchRequestParserTest.java      |   82 +-
 .../odata2/core/batch/BatchRequestTest.java     |    5 +-
 .../batch/BatchTransformatorCommonTest.java     |    8 +-
 .../BufferedReaderIncludingLineEndingsTest.java |   25 +-
 .../olingo/odata2/core/batch/HeaderTest.java    |   54 +-
 .../src/test/resources/batchLarge.batch         | 2505 ++++++++++++++++++
 19 files changed, 2911 insertions(+), 351 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchException.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchException.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchException.java
index 1171719..96aa4dd 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchException.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/batch/BatchException.java
@@ -94,7 +94,7 @@ public class BatchException extends ODataMessageException {
   public static final MessageReference INVALID_ACCEPT_LANGUAGE_HEADER = createMessageReference(BatchException.class,
       "INVALID_ACCEPT_LANGUAGE_HEADER");
 
-  /** INVALID_CONTENT_TRANSFER_ENCODING requires no content value */
+  /** INVALID_CONTENT_TRANSFER_ENCODING requires 1 content value */
   public static final MessageReference INVALID_CONTENT_TRANSFER_ENCODING = createMessageReference(BatchException.class,
       "INVALID_CONTENT_TRANSFER_ENCODING");
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
index f74ea85..288ca1c 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchBodyPart.java
@@ -23,17 +23,19 @@ import java.util.List;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
 import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings.Line;
+import org.apache.olingo.odata2.core.batch.v2.Header.HeaderField;
 
 public class BatchBodyPart implements BatchPart {
   final private String boundary;
   final private boolean isStrict;
-  final List<String> remainingMessage = new LinkedList<String>();
+  final List<Line> remainingMessage = new LinkedList<Line>();
 
   private Header headers;
   private boolean isChangeSet;
   private List<BatchQueryOperation> requests;
 
-  public BatchBodyPart(final List<String> bodyPartMessage, final String boundary, final boolean isStrict)
+  public BatchBodyPart(final List<Line> bodyPartMessage, final String boundary, final boolean isStrict)
       throws BatchException {
     this.boundary = boundary;
     this.isStrict = isStrict;
@@ -55,7 +57,7 @@ public class BatchBodyPart implements BatchPart {
     boolean isChangeSet = false;
 
     if (contentTypes.size() == 0) {
-      throw new BatchException(BatchException.MISSING_CONTENT_TYPE);
+      throw new BatchException(BatchException.MISSING_CONTENT_TYPE.addContent(headers.getLineNumber()));
     }
 
     for (String contentType : contentTypes) {
@@ -71,7 +73,7 @@ public class BatchBodyPart implements BatchPart {
     return BatchParserCommon.PATTERN_MULTIPART_BOUNDARY.matcher(contentType).matches();
   }
 
-  private List<BatchQueryOperation> consumeRequest(final List<String> remainingMessage) throws BatchException {
+  private List<BatchQueryOperation> consumeRequest(final List<Line> remainingMessage) throws BatchException {
     if (isChangeSet) {
       return consumeChangeSet(remainingMessage);
     } else {
@@ -79,28 +81,30 @@ public class BatchBodyPart implements BatchPart {
     }
   }
 
-  private List<BatchQueryOperation> consumeChangeSet(final List<String> remainingMessage)
+  private List<BatchQueryOperation> consumeChangeSet(final List<Line> remainingMessage)
       throws BatchException {
-    final List<List<String>> changeRequests = splitChangeSet(remainingMessage);
+    final List<List<Line>> changeRequests = splitChangeSet(remainingMessage);
     final List<BatchQueryOperation> requestList = new LinkedList<BatchQueryOperation>();
 
-    for (List<String> changeRequest : changeRequests) {
+    for (List<Line> changeRequest : changeRequests) {
       requestList.add(new BatchChangeSetPart(changeRequest, isStrict).parse());
     }
 
     return requestList;
   }
 
-  private List<List<String>> splitChangeSet(final List<String> remainingMessage)
+  private List<List<Line>> splitChangeSet(final List<Line> remainingMessage)
       throws BatchException {
 
-    final String changeSetBoundary = BatchParserCommon.getBoundary(headers.getHeaderNotNull(HttpHeaders.CONTENT_TYPE));
-    validateChangeSetBoundary(changeSetBoundary);
+    final HeaderField contentTypeField = headers.getHeaderField(HttpHeaders.CONTENT_TYPE);
+    final String changeSetBoundary =
+        BatchParserCommon.getBoundary(contentTypeField.getValueNotNull(), contentTypeField.getLineNumber());
+    validateChangeSetBoundary(changeSetBoundary, headers);
 
     return BatchParserCommon.splitMessageByBoundary(remainingMessage, changeSetBoundary);
   }
 
-  private List<BatchQueryOperation> consumeQueryOperation(final List<String> remainingMessage)
+  private List<BatchQueryOperation> consumeQueryOperation(final List<Line> remainingMessage)
       throws BatchException {
     final List<BatchQueryOperation> requestList = new LinkedList<BatchQueryOperation>();
     requestList.add(new BatchQueryOperation(remainingMessage, isStrict).parse());
@@ -108,9 +112,10 @@ public class BatchBodyPart implements BatchPart {
     return requestList;
   }
 
-  private void validateChangeSetBoundary(final String changeSetBoundary) throws BatchException {
+  private void validateChangeSetBoundary(final String changeSetBoundary, Header header) throws BatchException {
     if (changeSetBoundary.equals(boundary)) {
-      throw new BatchException(BatchException.INVALID_BOUNDARY);
+      throw new BatchException(BatchException.INVALID_BOUNDARY.addContent(header.getHeaderField(
+          HttpHeaders.CONTENT_TYPE).getLineNumber()));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSetPart.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSetPart.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSetPart.java
index 746c368..f3b0699 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSetPart.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchChangeSetPart.java
@@ -21,11 +21,12 @@ package org.apache.olingo.odata2.core.batch.v2;
 import java.util.List;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings.Line;
 
 public class BatchChangeSetPart extends BatchQueryOperation {
   private BatchQueryOperation request;
 
-  public BatchChangeSetPart(final List<String> message, final boolean isStrict) throws BatchException {
+  public BatchChangeSetPart(final List<Line> message, final boolean isStrict) throws BatchException {
     super(message, isStrict);
   }
 
@@ -44,12 +45,12 @@ public class BatchChangeSetPart extends BatchQueryOperation {
   }
 
   @Override
-  public List<String> getBody() {
+  public List<Line> getBody() {
     return request.getBody();
   }
 
   @Override
-  public String getHttpStatusLine() {
+  public Line getHttpStatusLine() {
     return request.getHttpStatusLine();
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
index 6fb7dbd..00a1f2a 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
@@ -31,6 +31,7 @@ import org.apache.olingo.odata2.api.client.batch.BatchSingleResponse;
 import org.apache.olingo.odata2.api.ep.EntityProviderBatchProperties;
 import org.apache.olingo.odata2.api.uri.PathInfo;
 import org.apache.olingo.odata2.api.uri.PathSegment;
+import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings.Line;
 import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
 
 public class BatchParser {
@@ -78,11 +79,11 @@ public class BatchParser {
       final BatchTransformator transformator) throws BatchException, IOException {
 
     final String baseUri = getBaseUri();
-    final String boundary = BatchParserCommon.getBoundary(contentTypeMime);
+    final String boundary = BatchParserCommon.getBoundary(contentTypeMime, 1);
     final List<BatchParserResult> resultList = new LinkedList<BatchParserResult>();
-    final List<List<String>> bodyPartStrings = splitBodyParts(in, boundary);
+    final List<List<Line>> bodyPartStrings = splitBodyParts(in, boundary);
 
-    for (List<String> bodyPartString : bodyPartStrings) {
+    for (List<Line> bodyPartString : bodyPartStrings) {
       BatchBodyPart bodyPart = new BatchBodyPart(bodyPartString, boundary, isStrict).parse();
       resultList.addAll(transformator.transform(bodyPart, batchRequestPathInfo, baseUri));
     }
@@ -90,11 +91,11 @@ public class BatchParser {
     return resultList;
   }
 
-  private List<List<String>> splitBodyParts(final InputStream in, final String boundary)
+  private List<List<Line>> splitBodyParts(final InputStream in, final String boundary)
       throws IOException, BatchException {
 
     final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
-    final List<String> message = reader.toList();
+    final List<Line> message = reader.toList();
     reader.close();
 
     return BatchParserCommon.splitMessageByBoundary(message, boundary);

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
index df62994..b028759 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
@@ -40,6 +40,7 @@ import org.apache.olingo.odata2.api.uri.PathSegment;
 import org.apache.olingo.odata2.core.ODataPathSegmentImpl;
 import org.apache.olingo.odata2.core.PathInfoImpl;
 import org.apache.olingo.odata2.core.batch.AcceptParser;
+import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings.Line;
 import org.apache.olingo.odata2.core.commons.Decoder;
 
 public class BatchParserCommon {
@@ -55,53 +56,52 @@ public class BatchParserCommon {
   public static final Pattern PATTERN_CONTENT_TYPE_APPLICATION_HTTP = Pattern.compile(REG_EX_APPLICATION_HTTP,
       Pattern.CASE_INSENSITIVE);
 
-  public static String trimStringListToStringLength(final List<String> list, final int length) {
+  public static String trimLineListToLength(final List<Line> list, final int length) {
     final String message = stringListToString(list);
     final int lastIndex = Math.min(length, message.length());
 
     return (lastIndex > 0) ? message.substring(0, lastIndex) : "";
   }
 
-  public static String stringListToString(final List<String> list) {
+  public static String stringListToString(final List<Line> list) {
     StringBuilder builder = new StringBuilder();
 
-    for (String currentLine : list) {
-      builder.append(currentLine);
+    for (Line currentLine : list) {
+      builder.append(currentLine.toString());
     }
 
     return builder.toString();
   }
 
-  public static InputStream convertMessageToInputStream(final List<String> messageList, final int contentLength)
+  public static InputStream convertMessageToInputStream(final List<Line> messageList, final int contentLength)
       throws BatchException {
-    final String message = trimStringListToStringLength(messageList, contentLength);
+    final String message = trimLineListToLength(messageList, contentLength);
 
     return new ByteArrayInputStream(message.getBytes());
   }
 
-  public static InputStream convertMessageToInputStream(final List<String> messageList)
+  public static InputStream convertMessageToInputStream(final List<Line> messageList)
       throws BatchException {
     final String message = stringListToString(messageList);
 
     return new ByteArrayInputStream(message.getBytes());
   }
 
-  // TODO Splitten von InputStream, sodass nur eine Iteration erfolgen muss
-  static List<List<String>> splitMessageByBoundary(final List<String> message, final String boundary)
+  static List<List<Line>> splitMessageByBoundary(final List<Line> message, final String boundary)
       throws BatchException {
-    final List<List<String>> messageParts = new LinkedList<List<String>>();
-    List<String> currentPart = new ArrayList<String>();
+    final List<List<Line>> messageParts = new LinkedList<List<Line>>();
+    List<Line> currentPart = new ArrayList<Line>();
     boolean isEndReached = false;
 
-    for (String currentLine : message) {
-      if (currentLine.contains("--" + boundary + "--")) {
+    for (Line currentLine : message) {
+      if (currentLine.toString().contains("--" + boundary + "--")) {
         removeEndingCRLFFromList(currentPart);
         messageParts.add(currentPart);
         isEndReached = true;
-      } else if (currentLine.contains("--" + boundary)) {
+      } else if (currentLine.toString().contains("--" + boundary)) {
         removeEndingCRLFFromList(currentPart);
         messageParts.add(currentPart);
-        currentPart = new LinkedList<String>();
+        currentPart = new LinkedList<Line>();
       } else {
         currentPart.add(currentLine);
       }
@@ -111,52 +111,57 @@ public class BatchParserCommon {
       }
     }
 
+    final int lineNumer = (message.size() > 0) ? message.get(0).getLineNumber() : 0;
     // Remove preamble
     if (messageParts.size() > 0) {
       messageParts.remove(0);
     } else {
-      throw new BatchException(BatchException.MISSING_BOUNDARY_DELIMITER);
-    }
 
-    if (messageParts.size() == 0) {
-      throw new BatchException(BatchException.NO_MATCH_WITH_BOUNDARY_STRING);
+      throw new BatchException(BatchException.MISSING_BOUNDARY_DELIMITER.addContent(lineNumer));
     }
 
     if (!isEndReached) {
-      throw new BatchException(BatchException.MISSING_CLOSE_DELIMITER);
+      throw new BatchException(BatchException.MISSING_CLOSE_DELIMITER.addContent(lineNumer));
+    }
+
+    if (messageParts.size() == 0) {
+      throw new BatchException(BatchException.NO_MATCH_WITH_BOUNDARY_STRING.addContent(boundary).addContent(lineNumer));
     }
 
     return messageParts;
   }
 
-  private static void removeEndingCRLFFromList(final List<String> list) {
+  private static void removeEndingCRLFFromList(final List<Line> list) {
     if (list.size() > 0) {
-      String lastLine = list.remove(list.size() - 1);
+      Line lastLine = list.remove(list.size() - 1);
       list.add(removeEndingCRLF(lastLine));
     }
   }
 
-  public static String removeEndingCRLF(final String line) {
+  public static Line removeEndingCRLF(final Line line) {
     Pattern pattern = Pattern.compile("(.*)(\r\n){1}( *)", Pattern.DOTALL);
-    Matcher matcher = pattern.matcher(line);
+    Matcher matcher = pattern.matcher(line.toString());
 
     if (matcher.matches()) {
-      return matcher.group(1);
+      return new Line(matcher.group(1), line.getLineNumber());
     } else {
       return line;
     }
   }
 
-  public static Header consumeHeaders(final List<String> remainingMessage) throws BatchException {
-    final Header headers = new Header();
+  public static Header consumeHeaders(final List<Line> remainingMessage) throws BatchException {
+    final int lineNumberOfHeader = remainingMessage.size() != 0 ? remainingMessage.get(0).getLineNumber() : 0;
+    final Header headers = new Header(lineNumberOfHeader);
     boolean isHeader = true;
-    final Iterator<String> iter = remainingMessage.iterator();
+    final Iterator<Line> iter = remainingMessage.iterator();
     final AcceptParser acceptParser = new AcceptParser();
-    String currentLine;
+    Line currentLine;
+    int acceptLineNumber = 0;
+    int acceptLanguageLineNumber = 0;
 
     while (iter.hasNext() && isHeader) {
       currentLine = iter.next();
-      final Matcher headerMatcher = PATTERN_HEADER_LINE.matcher(currentLine);
+      final Matcher headerMatcher = PATTERN_HEADER_LINE.matcher(currentLine.toString());
 
       if (headerMatcher.matches() && headerMatcher.groupCount() == 2) {
         iter.remove();
@@ -166,34 +171,37 @@ public class BatchParserCommon {
 
         if (HttpHeaders.ACCEPT.equalsIgnoreCase(headerName)) {
           acceptParser.addAcceptHeaderValue(headerValue);
+          acceptLineNumber = currentLine.getLineNumber();
         } else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(headerName)) {
           acceptParser.addAcceptLanguageHeaderValue(headerValue);
+          acceptLanguageLineNumber = currentLine.getLineNumber();
         } else {
-          headers.addHeader(headerName, Header.splitValuesByComma(headerValue));
+          headers.addHeader(headerName, Header.splitValuesByComma(headerValue), currentLine.getLineNumber());
         }
       } else {
         isHeader = false;
       }
     }
 
-    headers.addHeader(HttpHeaders.ACCEPT, acceptParser.parseAcceptHeaders());
-    headers.addHeader(HttpHeaders.ACCEPT_LANGUAGE, acceptParser.parseAcceptableLanguages());
+    headers.addHeader(HttpHeaders.ACCEPT, acceptParser.parseAcceptHeaders(), acceptLineNumber);
+    headers.addHeader(HttpHeaders.ACCEPT_LANGUAGE, acceptParser.parseAcceptableLanguages(), acceptLanguageLineNumber);
 
     return headers;
   }
 
-  public static void consumeBlankLine(final List<String> remainingMessage, final boolean isStrict)
+  public static void consumeBlankLine(final List<Line> remainingMessage, final boolean isStrict)
       throws BatchException {
-    if (remainingMessage.size() > 0 && "".equals(remainingMessage.get(0).trim())) {
+    if (remainingMessage.size() > 0 && "".equals(remainingMessage.get(0).toString().trim())) {
       remainingMessage.remove(0);
     } else {
       if (isStrict) {
-        throw new BatchException(BatchException.MISSING_BLANK_LINE);
+        final int lineNumber = (remainingMessage.size() > 0) ? remainingMessage.get(0).getLineNumber() : 0;
+        throw new BatchException(BatchException.MISSING_BLANK_LINE.addContent("[None]").addContent(lineNumber));
       }
     }
   }
 
-  public static String getBoundary(final String contentType) throws BatchException {
+  public static String getBoundary(final String contentType, final int line) throws BatchException {
     final Matcher boundaryMatcher = PATTERN_MULTIPART_BOUNDARY.matcher(contentType);
 
     if (boundaryMatcher.matches()) {
@@ -201,17 +209,17 @@ public class BatchParserCommon {
       if (boundary.matches(REG_EX_BOUNDARY)) {
         return trimQuota(boundary);
       } else {
-        throw new BatchException(BatchException.INVALID_BOUNDARY);
+        throw new BatchException(BatchException.INVALID_BOUNDARY.addContent(line));
       }
     } else {
       throw new BatchException(BatchException.INVALID_CONTENT_TYPE.addContent(HttpContentType.MULTIPART_MIXED));
     }
   }
 
-  public static Map<String, List<String>> parseQueryParameter(final String httpRequest) {
+  public static Map<String, List<String>> parseQueryParameter(final Line httpRequest) {
     Map<String, List<String>> queryParameter = new HashMap<String, List<String>>();
 
-    String[] requestParts = httpRequest.split(" ");
+    String[] requestParts = httpRequest.toString().split(" ");
     if (requestParts.length == 3) {
 
       String[] parts = requestParts[1].split("\\?");
@@ -239,8 +247,8 @@ public class BatchParserCommon {
     return queryParameter;
   }
 
-  public static PathInfo parseRequestUri(final String httpRequest, final PathInfo batchRequestPathInfo,
-      final String baseUri)
+  public static PathInfo parseRequestUri(final Line httpStatusLine, final PathInfo batchRequestPathInfo,
+      final String baseUri, final int line)
       throws BatchException {
 
     final String odataPathSegmentsAsString;
@@ -250,7 +258,7 @@ public class BatchParserCommon {
     pathInfo.setServiceRoot(batchRequestPathInfo.getServiceRoot());
     pathInfo.setPrecedingPathSegment(batchRequestPathInfo.getPrecedingSegments());
 
-    String[] requestParts = httpRequest.split(" ");
+    String[] requestParts = httpStatusLine.toString().split(" ");
     if (requestParts.length == 3) {
       String uri = requestParts[1];
       Pattern regexRequestUri;
@@ -277,14 +285,15 @@ public class BatchParserCommon {
           }
 
         } else {
-          throw new BatchException(BatchException.INVALID_URI);
+          throw new BatchException(BatchException.INVALID_URI.addContent(httpStatusLine.getLineNumber()));
         }
 
       } catch (URISyntaxException e) {
-        throw new BatchException(BatchException.INVALID_URI, e);
+        throw new BatchException(BatchException.INVALID_URI.addContent(line), e);
       }
     } else {
-      throw new BatchException(BatchException.INVALID_REQUEST_LINE);
+      throw new BatchException(BatchException.INVALID_REQUEST_LINE.addContent(httpStatusLine.toString())
+          .addContent(line));
     }
 
     return pathInfo;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
index 87dcb23..9bbd019 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchQueryOperation.java
@@ -21,17 +21,18 @@ package org.apache.olingo.odata2.core.batch.v2;
 import java.util.List;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings.Line;
 
 public class BatchQueryOperation implements BatchPart {
 
   protected final boolean isStrict;
-  protected String httpStatusLine;
+  protected Line httpStatusLine;
   protected Header headers;
-  protected List<String> body;
+  protected List<Line> body;
   protected int bodySize;
-  protected List<String> message;
+  protected List<Line> message;
 
-  public BatchQueryOperation(final List<String> message, final boolean isStrict) {
+  public BatchQueryOperation(final List<Line> message, final boolean isStrict) {
     this.isStrict = isStrict;
     this.message = message;
   }
@@ -45,22 +46,23 @@ public class BatchQueryOperation implements BatchPart {
     return this;
   }
 
-  protected String consumeHttpStatusLine(final List<String> message) throws BatchException {
-    if (message.size() > 0 && !message.get(0).trim().equals("")) {
-      String method = message.get(0);
+  protected Line consumeHttpStatusLine(final List<Line> message) throws BatchException {
+    if (message.size() > 0 && !message.get(0).toString().trim().equals("")) {
+      final Line method = message.get(0);
       message.remove(0);
 
       return method;
     } else {
-      throw new BatchException(BatchException.INVALID_QUERY_OPERATION_METHOD);
+      final int line = (message.size() > 0) ? message.get(0).getLineNumber() : 0;
+      throw new BatchException(BatchException.MISSING_METHOD.addContent(line));
     }
   }
 
-  public String getHttpStatusLine() {
+  public Line getHttpStatusLine() {
     return httpStatusLine;
   }
 
-  public List<String> getBody() {
+  public List<Line> getBody() {
     return body;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
index a49a2e5..c7ffa88 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchRequestTransformator.java
@@ -32,12 +32,13 @@ import org.apache.olingo.odata2.api.batch.BatchException;
 import org.apache.olingo.odata2.api.batch.BatchParserResult;
 import org.apache.olingo.odata2.api.commons.HttpHeaders;
 import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
-import org.apache.olingo.odata2.api.exception.MessageReference;
 import org.apache.olingo.odata2.api.processor.ODataRequest;
 import org.apache.olingo.odata2.api.processor.ODataRequest.ODataRequestBuilder;
 import org.apache.olingo.odata2.api.uri.PathInfo;
 import org.apache.olingo.odata2.core.batch.BatchHelper;
 import org.apache.olingo.odata2.core.batch.BatchRequestPartImpl;
+import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings.Line;
+import org.apache.olingo.odata2.core.batch.v2.Header.HeaderField;
 
 public class BatchRequestTransformator implements BatchTransformator {
 
@@ -88,9 +89,10 @@ public class BatchRequestTransformator implements BatchTransformator {
   private ODataRequest createRequest(final BatchQueryOperation operation, final Header headers,
       final PathInfo pathInfo, final String baseUri, final boolean isChangeSet) throws BatchException {
 
+    final int httpLineNumber = operation.getHttpStatusLine().getLineNumber();
     ODataHttpMethod httpMethod = getHttpMethod(operation.getHttpStatusLine());
-    validateHttpMethod(httpMethod, isChangeSet);
-    validateBody(httpMethod, operation);
+    validateHttpMethod(httpMethod, isChangeSet, httpLineNumber);
+    validateBody(httpMethod, operation, httpLineNumber);
     InputStream bodyStrean = getBodyStream(operation, headers, httpMethod);
 
     ODataRequestBuilder requestBuilder = ODataRequest.method(httpMethod)
@@ -99,27 +101,26 @@ public class BatchRequestTransformator implements BatchTransformator {
         .allQueryParameters(BatchParserCommon.parseQueryParameter(operation.getHttpStatusLine()))
         .body(bodyStrean)
         .requestHeaders(headers.toMultiMap())
-        .pathInfo(BatchParserCommon.parseRequestUri(operation.getHttpStatusLine(), pathInfo, baseUri));
-    
-    final String contentType =headers.getHeader(HttpHeaders.CONTENT_TYPE);
-    if(contentType != null) {
+        .pathInfo(BatchParserCommon.parseRequestUri(operation.getHttpStatusLine(), pathInfo, baseUri, 0));
+
+    final String contentType = headers.getHeader(HttpHeaders.CONTENT_TYPE);
+    if (contentType != null) {
       requestBuilder.contentType(contentType);
     }
-      
-    
+
     return requestBuilder.build();
   }
 
-  private void validateBody(final ODataHttpMethod httpMethod, final BatchQueryOperation operation)
+  private void validateBody(final ODataHttpMethod httpStatusLine, final BatchQueryOperation operation, final int line)
       throws BatchException {
-    if (HTTP_BATCH_METHODS.contains(httpMethod.toString()) && isUnvalidGetRequestBody(operation)) {
-      throw new BatchException(BatchException.INVALID_REQUEST_LINE);
+    if (HTTP_BATCH_METHODS.contains(httpStatusLine.toString()) && isUnvalidGetRequestBody(operation)) {
+      throw new BatchException(BatchException.INVALID_REQUEST_LINE.addContent(httpStatusLine).addContent(line));
     }
   }
 
   private boolean isUnvalidGetRequestBody(final BatchQueryOperation operation) {
     return (operation.getBody().size() > 1)
-        || (operation.getBody().size() == 1 && !operation.getBody().get(0).trim().equals(""));
+        || (operation.getBody().size() == 1 && !operation.getBody().get(0).toString().trim().equals(""));
   }
 
   private InputStream getBodyStream(final BatchQueryOperation operation, Header headers,
@@ -140,28 +141,32 @@ public class BatchRequestTransformator implements BatchTransformator {
 
   private Header transformHeader(final BatchPart operation, final BatchPart parentPart) {
     final Header headers = operation.getHeaders().clone();
-    headers.removeHeaders(BatchHelper.HTTP_CONTENT_ID);
-    final List<String> operationContentIds = operation.getHeaders().getHeaders(BatchHelper.HTTP_CONTENT_ID);
-    final List<String> parentContentIds = parentPart.getHeaders().getHeaders(BatchHelper.HTTP_CONTENT_ID);
+    headers.removeHeader(BatchHelper.HTTP_CONTENT_ID);
+    final HeaderField operationHeader = operation.getHeaders().getHeaderField(BatchHelper.HTTP_CONTENT_ID);
+    final HeaderField parentHeader = parentPart.getHeaders().getHeaderField(BatchHelper.HTTP_CONTENT_ID);
 
-    if (operationContentIds.size() != 0) {
-      headers.addHeader(BatchHelper.REQUEST_HEADER_CONTENT_ID, operationContentIds);
+    if (operationHeader != null && operationHeader.getValues().size() != 0) {
+      headers.addHeader(BatchHelper.REQUEST_HEADER_CONTENT_ID, operationHeader.getValues(), operationHeader
+          .getLineNumber());
     }
 
-    if (parentContentIds.size() != 0) {
-      headers.addHeader(BatchHelper.MIME_HEADER_CONTENT_ID, parentContentIds);
+    if (parentHeader != null && parentHeader.getValues().size() != 0) {
+      headers.addHeader(BatchHelper.MIME_HEADER_CONTENT_ID, parentHeader.getValues(), parentHeader.getLineNumber());
     }
 
     return headers;
   }
 
-  private void validateHttpMethod(final ODataHttpMethod httpMethod, final boolean isChangeSet) throws BatchException {
+  private void validateHttpMethod(final ODataHttpMethod httpMethod, final boolean isChangeSet, final int line)
+      throws BatchException {
     Set<String> validMethods = (isChangeSet) ? HTTP_CHANGE_SET_METHODS : HTTP_BATCH_METHODS;
 
     if (!validMethods.contains(httpMethod.toString())) {
-      MessageReference message =
-          (isChangeSet) ? BatchException.INVALID_CHANGESET_METHOD : BatchException.INVALID_QUERY_OPERATION_METHOD;
-      throw new BatchException(message);
+      if (isChangeSet) {
+        throw new BatchException(BatchException.INVALID_CHANGESET_METHOD.addContent(line));
+      } else {
+        throw new BatchException(BatchException.INVALID_QUERY_OPERATION_METHOD.addContent(line));
+      }
     }
   }
 
@@ -183,23 +188,20 @@ public class BatchRequestTransformator implements BatchTransformator {
     return acceptLanguages;
   }
 
-  private ODataHttpMethod getHttpMethod(final String httpRequest) throws BatchException {
+  private ODataHttpMethod getHttpMethod(final Line httpRequest) throws BatchException {
     ODataHttpMethod result = null;
 
-    if (httpRequest != null) {
-      String[] parts = httpRequest.split(" ");
+    String[] parts = httpRequest.toString().split(" ");
 
-      if (parts.length == 3) {
-        try {
-          result = ODataHttpMethod.valueOf(parts[0]);
-        } catch (IllegalArgumentException e) {
-          throw new BatchException(BatchException.MISSING_METHOD, e);
-        }
-      } else {
-        throw new BatchException(BatchException.INVALID_REQUEST_LINE);
+    if (parts.length == 3) {
+      try {
+        result = ODataHttpMethod.valueOf(parts[0]);
+      } catch (IllegalArgumentException e) {
+        throw new BatchException(BatchException.MISSING_METHOD.addContent(httpRequest.getLineNumber()), e);
       }
     } else {
-      throw new BatchException(BatchException.INVALID_REQUEST_LINE);
+      throw new BatchException(BatchException.INVALID_REQUEST_LINE.addContent(httpRequest.toString()).addContent(
+          httpRequest.getLineNumber()));
     }
 
     return result;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
index ab983ac..e800673 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchResponseTransformator.java
@@ -29,6 +29,7 @@ import org.apache.olingo.odata2.api.client.batch.BatchSingleResponse;
 import org.apache.olingo.odata2.api.uri.PathInfo;
 import org.apache.olingo.odata2.core.batch.BatchHelper;
 import org.apache.olingo.odata2.core.batch.BatchSingleResponseImpl;
+import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings.Line;
 
 public class BatchResponseTransformator implements BatchTransformator {
 
@@ -92,14 +93,15 @@ public class BatchResponseTransformator implements BatchTransformator {
     return response;
   }
 
-  private Matcher prepareStatusLineMatcher(String httpStatusLine) throws BatchException {
+  private Matcher prepareStatusLineMatcher(final Line httpStatusLine) throws BatchException {
     final Pattern regexPattern = Pattern.compile(REG_EX_STATUS_LINE);
-    final Matcher matcher = regexPattern.matcher(httpStatusLine);
+    final Matcher matcher = regexPattern.matcher(httpStatusLine.toString());
 
     if (matcher.find()) {
       return matcher;
     } else {
-      throw new BatchException(BatchException.INVALID_STATUS_LINE);
+      throw new BatchException(BatchException.INVALID_STATUS_LINE.addContent(httpStatusLine.toString())
+          .addContent(httpStatusLine.getLineNumber()));
     }
   }
 
@@ -109,7 +111,7 @@ public class BatchResponseTransformator implements BatchTransformator {
     if (contentLength == -1) {
       return BatchParserCommon.stringListToString(operation.getBody());
     } else {
-      return BatchParserCommon.trimStringListToStringLength(operation.getBody(), contentLength);
+      return BatchParserCommon.trimLineListToLength(operation.getBody(), contentLength);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
index 9c67f49..498dd2d 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchTransformatorCommon.java
@@ -6,6 +6,7 @@ import org.apache.olingo.odata2.api.batch.BatchException;
 import org.apache.olingo.odata2.api.commons.HttpContentType;
 import org.apache.olingo.odata2.api.commons.HttpHeaders;
 import org.apache.olingo.odata2.core.batch.BatchHelper;
+import org.apache.olingo.odata2.core.batch.v2.Header.HeaderField;
 
 public class BatchTransformatorCommon {
 
@@ -24,39 +25,45 @@ public class BatchTransformatorCommon {
 
   public static void validateContentTransferEncoding(final Header headers, final boolean isChangeRequest)
       throws BatchException {
-    final List<String> contentTransferEncodings = headers.getHeaders(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING);
+    final HeaderField contentTransferField = headers.getHeaderField(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING);
 
-    if (contentTransferEncodings.size() != 0) {
-      if (contentTransferEncodings.size() == 1) {
-        String encoding = contentTransferEncodings.get(0);
+    if (contentTransferField != null) {
+      final List<String> contentTransferValues = contentTransferField.getValues();
+      if (contentTransferValues.size() == 1) {
+        String encoding = contentTransferValues.get(0);
 
         if (!BatchHelper.BINARY_ENCODING.equalsIgnoreCase(encoding)) {
-          throw new BatchException(BatchException.INVALID_CONTENT_TRANSFER_ENCODING);
+          throw new BatchException(
+              BatchException.INVALID_CONTENT_TRANSFER_ENCODING.addContent(contentTransferField.getLineNumber()));
         }
       } else {
-        throw new BatchException(BatchException.INVALID_HEADER);
+        throw new BatchException(BatchException.INVALID_HEADER.addContent(contentTransferField.getLineNumber()));
       }
     } else {
       if (isChangeRequest) {
-        throw new BatchException(BatchException.INVALID_CONTENT_TRANSFER_ENCODING);
+        throw new BatchException(BatchException.INVALID_CONTENT_TRANSFER_ENCODING.addContent(headers.getLineNumber()));
       }
     }
   }
 
   public static int getContentLength(final Header headers) throws BatchException {
-    final List<String> contentLengths = headers.getHeaders(HttpHeaders.CONTENT_LENGTH);
+    final HeaderField contentLengthField = headers.getHeaderField(HttpHeaders.CONTENT_LENGTH);
+
+    if (contentLengthField != null && contentLengthField.getValues().size() == 1) {
+      final List<String> contentLengthValues = contentLengthField.getValues();
 
-    if (contentLengths.size() == 1) {
       try {
-        int contentLength = Integer.parseInt(contentLengths.get(0));
+        int contentLength = Integer.parseInt(contentLengthValues.get(0));
 
         if (contentLength < 0) {
-          throw new BatchException(BatchException.INVALID_HEADER);
+          throw new BatchException(BatchException.INVALID_HEADER.addContent(contentLengthField.getValue()).addContent(
+              contentLengthField.getLineNumber()));
         }
 
         return contentLength;
       } catch (NumberFormatException e) {
-        throw new BatchException(BatchException.INVALID_HEADER, e);
+        throw new BatchException(BatchException.INVALID_HEADER.addContent(contentLengthField.getValue()).addContent(
+            contentLengthField.getLineNumber()), e);
       }
     }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
index 5e411ff..295f4c6 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
@@ -92,12 +92,13 @@ public class BufferedReaderIncludingLineEndings extends Reader {
     return bytesRead;
   }
 
-  public List<String> toList() throws IOException {
-    final List<String> result = new ArrayList<String>();
+  public List<Line> toList() throws IOException {
+    final List<Line> result = new ArrayList<Line>();
     String currentLine;
+    int counter = 1;
 
     while ((currentLine = readLine()) != null) {
-      result.add(currentLine);
+      result.add(new Line(currentLine, counter++));
     }
 
     return result;
@@ -217,4 +218,57 @@ public class BufferedReaderIncludingLineEndings extends Reader {
 
     return limit;
   }
+
+  public static class Line {
+    private final int lineNumber;
+    private final String content;
+
+    public Line(final String content, final int lineNumber) {
+      this.content = content;
+      this.lineNumber = lineNumber;
+    }
+
+    public int getLineNumber() {
+      return lineNumber;
+    }
+
+    @Override
+    public String toString() {
+      return content;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((content == null) ? 0 : content.hashCode());
+      result = prime * result + lineNumber;
+      return result;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+      if (this == obj) {
+        return true;
+      }
+      if (obj == null) {
+        return false;
+      }
+      if (getClass() != obj.getClass()) {
+        return false;
+      }
+      Line other = (Line) obj;
+      if (content == null) {
+        if (other.content != null) {
+          return false;
+        }
+      } else if (!content.equals(other.content)) {
+        return false;
+      }
+      if (lineNumber != other.lineNumber) {
+        return false;
+      }
+      return true;
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
index 7901b7b..c9daa6a 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
@@ -10,20 +10,14 @@ import java.util.regex.Pattern;
 public class Header implements Cloneable {
 
   private final Map<String, HeaderField> headers = new HashMap<String, HeaderField>();
+  private int lineNumber;
   
-  public static List<String> splitValuesByComma(final String headerValue) {
-    final List<String> singleValues = new ArrayList<String>();
-
-    String[] parts = headerValue.split(",");
-    for (final String value : parts) {
-      singleValues.add(value.trim());
-    }
-
-    return singleValues;
+  public Header(int lineNumer) {
+    this.lineNumber = lineNumer;
   }
   
-  public void addHeader(final String name, final String value) {
-    final HeaderField headerField = getHeaderFieldOrDefault(name);
+  public void addHeader(final String name, final String value, final int lineNumber) {
+    final HeaderField headerField = getHeaderFieldOrDefault(name, lineNumber);
     final List<String> headerValues = headerField.getValues();
 
     if (!headerValues.contains(value)) {
@@ -31,8 +25,8 @@ public class Header implements Cloneable {
     }
   }
 
-  public void addHeader(final String name, final List<String> values) {
-    final HeaderField headerField = getHeaderFieldOrDefault(name);
+  public void addHeader(final String name, final List<String> values, final int lineNumber) {
+    final HeaderField headerField = getHeaderFieldOrDefault(name, lineNumber);
     final List<String> headerValues = headerField.getValues();
 
     for (final String value : values) {
@@ -41,45 +35,29 @@ public class Header implements Cloneable {
       }
     }
   }
-  
+
   public boolean isHeaderMatching(final String name, final Pattern pattern) {
-    if(getHeaders(name).size() != 1 ) {
+    if (getHeaders(name).size() != 1) {
       return false;
     } else {
       return pattern.matcher(getHeaders(name).get(0)).matches();
     }
   }
-  
-  public void removeHeaders(final String name) {
+
+  public void removeHeader(final String name) {
     headers.remove(name.toLowerCase(Locale.ENGLISH));
   }
 
   public String getHeader(final String name) {
     final HeaderField headerField = getHeaderField(name);
-
-    if (headerField == null) {
-      return null;
-    } else {
-      final List<String> headerValues = headerField.getValues();
-      final StringBuilder result = new StringBuilder();
-
-      for (final String value : headerValues) {
-        result.append(value);
-        result.append(", ");
-      }
-      
-      if(result.length()>0) {
-        result.delete(result.length() - 2, result.length());
-      }
-      
-      return result.toString();
-    }
+    
+    return (headerField == null) ? null : headerField.getValue();
   }
 
   public String getHeaderNotNull(final String name) {
-    final String value = getHeader(name);
-
-    return (value == null) ? "" : value;
+    final HeaderField headerField = getHeaderField(name);
+    
+    return (headerField == null) ? "" : headerField.getValueNotNull();
   }
 
   public List<String> getHeaders(final String name) {
@@ -91,7 +69,11 @@ public class Header implements Cloneable {
   public HeaderField getHeaderField(final String name) {
     return headers.get(name.toLowerCase(Locale.ENGLISH));
   }
-
+  
+  public int getLineNumber() {
+    return lineNumber;
+  }
+  
   public Map<String, String> toSingleMap() {
     final Map<String, String> singleMap = new HashMap<String, String>();
 
@@ -114,11 +96,11 @@ public class Header implements Cloneable {
     return singleMap;
   }
 
-  private HeaderField getHeaderFieldOrDefault(final String name) {
+  private HeaderField getHeaderFieldOrDefault(final String name, final int lineNumber) {
     HeaderField headerField = headers.get(name.toLowerCase(Locale.ENGLISH));
 
     if (headerField == null) {
-      headerField = new HeaderField(name);
+      headerField = new HeaderField(name, lineNumber);
       headers.put(name.toLowerCase(Locale.ENGLISH), headerField);
     }
 
@@ -127,7 +109,7 @@ public class Header implements Cloneable {
 
   @Override
   public Header clone() {
-    final Header newInstance = new Header();
+    final Header newInstance = new Header(lineNumber);
 
     for (final String key : headers.keySet()) {
       newInstance.headers.put(key, headers.get(key).clone());
@@ -136,17 +118,30 @@ public class Header implements Cloneable {
     return newInstance;
   }
 
+  public static List<String> splitValuesByComma(final String headerValue) {
+    final List<String> singleValues = new ArrayList<String>();
+
+    String[] parts = headerValue.split(",");
+    for (final String value : parts) {
+      singleValues.add(value.trim());
+    }
+
+    return singleValues;
+  }
+
   public static class HeaderField implements Cloneable {
-    private String fieldName;
-    private List<String> values;
+    private final String fieldName;
+    private final List<String> values;
+    private final int lineNumber;
 
-    public HeaderField(final String fieldName) {
-      this(fieldName, new ArrayList<String>());
+    public HeaderField(final String fieldName, final int lineNumber) {
+      this(fieldName, new ArrayList<String>(), lineNumber);
     }
 
-    public HeaderField(final String fieldName, final List<String> values) {
+    public HeaderField(final String fieldName, final List<String> values, final int lineNumber) {
       this.fieldName = fieldName;
       this.values = values;
+      this.lineNumber = lineNumber;
     }
 
     public String getFieldName() {
@@ -157,8 +152,37 @@ public class Header implements Cloneable {
       return values;
     }
 
-    public void setValues(final List<String> values) {
-      this.values = values;
+    public String getValue() {
+      final StringBuilder result = new StringBuilder();
+
+      for (final String value : values) {
+        result.append(value);
+        result.append(", ");
+      }
+
+      if (result.length() > 0) {
+        result.delete(result.length() - 2, result.length());
+      }
+
+      return result.toString();
+    }
+
+    public String getValueNotNull() {
+      final String value = getValue();
+
+      return (value == null) ? "" : value;
+    }
+
+    @Override
+    public HeaderField clone() {
+      List<String> newValues = new ArrayList<String>();
+      newValues.addAll(values);
+
+      return new HeaderField(fieldName, newValues, lineNumber);
+    }
+
+    public int getLineNumber() {
+      return lineNumber;
     }
 
     @Override
@@ -166,6 +190,8 @@ public class Header implements Cloneable {
       final int prime = 31;
       int result = 1;
       result = prime * result + ((fieldName == null) ? 0 : fieldName.hashCode());
+      result = prime * result + lineNumber;
+      result = prime * result + ((values == null) ? 0 : values.hashCode());
       return result;
     }
 
@@ -188,15 +214,17 @@ public class Header implements Cloneable {
       } else if (!fieldName.equals(other.fieldName)) {
         return false;
       }
+      if (lineNumber != other.lineNumber) {
+        return false;
+      }
+      if (values == null) {
+        if (other.values != null) {
+          return false;
+        }
+      } else if (!values.equals(other.values)) {
+        return false;
+      }
       return true;
     }
-
-    @Override
-    public HeaderField clone() {
-      List<String> newValues = new ArrayList<String>();
-      newValues.addAll(values);
-
-      return new HeaderField(fieldName, newValues);
-    }
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/main/resources/i18n.properties
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/resources/i18n.properties b/odata2-lib/odata-core/src/main/resources/i18n.properties
index a89c3e9..47e50a2 100644
--- a/odata2-lib/odata-core/src/main/resources/i18n.properties
+++ b/odata2-lib/odata-core/src/main/resources/i18n.properties
@@ -118,31 +118,30 @@ org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_DELETED_ENTRY_ME
 ##################################
 # BatchParserexceptions
 ##################################
-org.apache.olingo.odata2.api.batch.BatchException.INVALID_CHANGESET_BOUNDARY=The boundary of the ChangeSet should be different from that used by the Batch: line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_ACCEPT_LANGUAGE_HEADER=Invalid Accept-Language: '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_ACCEPT_HEADER=Invalid Accept header: '%1$s'.
 org.apache.olingo.odata2.api.batch.BatchException.INVALID_BOUNDARY_DELIMITER=The boundary delimiter must begin with two hyphen characters: line '%1$s'.
-org.apache.olingo.odata2.api.batch.BatchException.MISSING_BOUNDARY_DELIMITER=Missing boundary delimiter at line '%1$s'.
-org.apache.olingo.odata2.api.batch.BatchException.MISSING_CLOSE_DELIMITER=Missing close delimiter at line '%1$s'.
-org.apache.olingo.odata2.api.batch.BatchException.INVALID_QUERY_OPERATION_METHOD=Invalid method: a Query Operation cannot contain insert, update or delete requests at line '%1$s'.
-org.apache.olingo.odata2.api.batch.BatchException.INVALID_CHANGESET_METHOD= Invalid method: a ChangeSet cannot contain retrieve requests at line '%1$s'.
-org.apache.olingo.odata2.api.batch.BatchException.INVALID_QUERY_PARAMETER=Invalid query parameters.
-org.apache.olingo.odata2.api.batch.BatchException.INVALID_URI=Invalid URI: line '%1$s'.
-org.apache.olingo.odata2.api.batch.BatchException.UNSUPPORTED_ABSOLUTE_PATH = An absolute-path in request line is not supported: line '%1$s'.
 org.apache.olingo.odata2.api.batch.BatchException.INVALID_BOUNDARY=Invalid boundary at line '%1$s'.
-org.apache.olingo.odata2.api.batch.BatchException.NO_MATCH_WITH_BOUNDARY_STRING=The boundary string does not match the boundary from the Content-Type header field '%1$s': line '%2$s'.
-org.apache.olingo.odata2.api.batch.BatchException.MISSING_CONTENT_TYPE=No Content-Type field for MIME-header is present.
-org.apache.olingo.odata2.api.batch.BatchException.INVALID_CONTENT_TYPE=Content-Type should be '%1$s'.
-org.apache.olingo.odata2.api.batch.BatchException.MISSING_PARAMETER_IN_CONTENT_TYPE=The Content-Type field for multipart entities requires boundary parameter.
-org.apache.olingo.odata2.api.batch.BatchException.INVALID_CONTENT_TRANSFER_ENCODING=The Content-Transfer-Encoding should be binary.
-org.apache.olingo.odata2.api.batch.BatchException.INVALID_ACCEPT_HEADER=Invalid Accept header: '%1$s'.
-org.apache.olingo.odata2.api.batch.BatchException.INVALID_ACCEPT_LANGUAGE_HEADER=Invalid Accept-Language: '%1$s'.
 org.apache.olingo.odata2.api.batch.BatchException.INVALID_HEADER=Invalid header: '%1$s' at line '%2$s'.
-org.apache.olingo.odata2.api.batch.BatchException.MISSING_BLANK_LINE=Expected empty line but was '%1$s': line '%2$s'  .
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_CONTENT_TRANSFER_ENCODING=The Content-Transfer-Encoding should be binary: line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_CONTENT_TYPE=Content-Type should be '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_CHANGESET_BOUNDARY=The boundary of the ChangeSet should be different from that used by the Batch: line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_CHANGESET_METHOD= Invalid method: a ChangeSet cannot contain retrieve requests at line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_REQUEST_LINE=Invalid request line '%1$s' at line '%2$s'.
 org.apache.olingo.odata2.api.batch.BatchException.INVALID_PATHINFO=PathInfo should not be null.
-org.apache.olingo.odata2.api.batch.BatchException.MISSING_METHOD=Missing method in request line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_URI=Invalid URI: line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_QUERY_OPERATION_METHOD=Invalid method: a Query Operation cannot contain insert, update or delete requests at line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_QUERY_PARAMETER=Invalid query parameters.
+org.apache.olingo.odata2.api.batch.BatchException.MISSING_BLANK_LINE=Expected empty line but was '%1$s': line '%2$s'  .
+org.apache.olingo.odata2.api.batch.BatchException.MISSING_BOUNDARY_DELIMITER=Missing boundary delimiter at line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.MISSING_CONTENT_TYPE=No Content-Type field for MIME-header is present.
+org.apache.olingo.odata2.api.batch.BatchException.MISSING_CLOSE_DELIMITER=Missing close delimiter at line '%1$s'.
 org.apache.olingo.odata2.api.batch.BatchException.MISSING_MANDATORY_HEADER=Missing mandatory header '%1$s'.
-org.apache.olingo.odata2.api.batch.BatchException.INVALID_REQUEST_LINE=Invalid request line '%1$s' at line '%2$s'.
-org.apache.olingo.odata2.api.batch.BatchException.INVALID_REQUEST_LINE=Invalid status line '%1$s' at line '%2$s'.
+org.apache.olingo.odata2.api.batch.BatchException.MISSING_METHOD=Missing method in request line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.MISSING_PARAMETER_IN_CONTENT_TYPE=The Content-Type field for multipart entities requires boundary parameter.
+org.apache.olingo.odata2.api.batch.BatchException.NO_MATCH_WITH_BOUNDARY_STRING=The boundary string does not match the boundary from the Content-Type header field '%1$s': line '%2$s'.
 org.apache.olingo.odata2.api.batch.BatchException.TRUNCATED_BODY=Body is truncated: line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.UNSUPPORTED_ABSOLUTE_PATH = An absolute-path in request line is not supported: line '%1$s'.
 
 ##################################
 # HttpExceptions

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
index 56cbeeb..4369c1e 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchParserCommonTest.java
@@ -3,12 +3,12 @@ package org.apache.olingo.odata2.core.batch;
 import static org.junit.Assert.*;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
 import org.apache.olingo.odata2.api.commons.HttpHeaders;
 import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon;
+import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings.Line;
 import org.apache.olingo.odata2.core.batch.v2.Header;
 import org.junit.Test;
 
@@ -24,9 +24,7 @@ public class BatchParserCommonTest {
         "content-type: Application/http" + CRLF,
         "content-transfer-encoding: Binary" + CRLF
       };
-    List<String> message = new ArrayList<String>();
-    message.addAll(Arrays.asList(messageRaw));
-    
+    List<Line> message = toLineList(messageRaw);
     
     final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
@@ -46,9 +44,7 @@ public class BatchParserCommonTest {
         "content-type: Application/http" + CRLF,
         "content-transfer-encoding: Binary" + CRLF
       };
-    List<String> message = new ArrayList<String>();
-    message.addAll(Arrays.asList(messageRaw));
-    
+    List<Line> message = toLineList(messageRaw);
     
     final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
@@ -67,9 +63,7 @@ public class BatchParserCommonTest {
         "content-type: Application/http" + CRLF,
         "content-transfer-encoding: Binary" + CRLF
       };
-    List<String> message = new ArrayList<String>();
-    message.addAll(Arrays.asList(messageRaw));
-    
+    List<Line> message = toLineList(messageRaw);
     
     final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
@@ -92,9 +86,7 @@ public class BatchParserCommonTest {
         "content-type: Application/http" + CRLF,
         "content-transfer-encoding: Binary" + CRLF
       };
-    List<String> message = new ArrayList<String>();
-    message.addAll(Arrays.asList(messageRaw));
-    
+    List<Line> message = toLineList(messageRaw);
     
     final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
@@ -113,9 +105,7 @@ public class BatchParserCommonTest {
         "content-type: Application/http" + CRLF,
         "content-transfer-encoding: Binary" + CRLF
       };
-    List<String> message = new ArrayList<String>();
-    message.addAll(Arrays.asList(messageRaw));
-    
+    List<Line> message = toLineList(messageRaw);
     
     final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
@@ -133,8 +123,7 @@ public class BatchParserCommonTest {
         "content-type: Application/http" + CRLF,
         "content-transfer-encoding: Binary" + CRLF
       };
-    List<String> message = new ArrayList<String>();
-    message.addAll(Arrays.asList(messageRaw));
+    List<Line> message = toLineList(messageRaw);
     
     final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
@@ -152,8 +141,7 @@ public class BatchParserCommonTest {
         "content-type: Application/http" + CRLF,
         "content-transfer-encoding: Binary" + CRLF
       };
-    List<String> message = new ArrayList<String>();
-    message.addAll(Arrays.asList(messageRaw));
+    List<Line> message = toLineList(messageRaw);
     
     final Header header = BatchParserCommon.consumeHeaders(message);
     assertNotNull(header);
@@ -166,48 +154,59 @@ public class BatchParserCommonTest {
   @Test
   public void testRemoveEndingCRLF() {
     String line = "Test\r\n";
-    assertEquals("Test", BatchParserCommon.removeEndingCRLF(line));
+    assertEquals("Test", BatchParserCommon.removeEndingCRLF(new Line(line,1)).toString());
   }
 
   @Test
   public void testRemoveLastEndingCRLF() {
     String line = "Test\r\n\r\n";
-    assertEquals("Test\r\n", BatchParserCommon.removeEndingCRLF(line));
+    assertEquals("Test\r\n", BatchParserCommon.removeEndingCRLF(new Line(line,1)).toString());
   }
 
   @Test
   public void testRemoveEndingCRLFWithWS() {
     String line = "Test\r\n            ";
-    assertEquals("Test", BatchParserCommon.removeEndingCRLF(line));
+    assertEquals("Test", BatchParserCommon.removeEndingCRLF(new Line(line,1)).toString());
   }
 
   @Test
   public void testRemoveEndingCRLFNothingToRemove() {
     String line = "Hallo\r\nBla";
-    assertEquals("Hallo\r\nBla", BatchParserCommon.removeEndingCRLF(line));
+    assertEquals("Hallo\r\nBla", BatchParserCommon.removeEndingCRLF(new Line(line,1)).toString());
   }
 
   @Test
   public void testRemoveEndingCRLFAll() {
     String line = "\r\n";
-    assertEquals("", BatchParserCommon.removeEndingCRLF(line));
+    assertEquals("", BatchParserCommon.removeEndingCRLF(new Line(line,1)).toString());
   }
 
   @Test
   public void testRemoveEndingCRLFSpace() {
     String line = "\r\n                      ";
-    assertEquals("", BatchParserCommon.removeEndingCRLF(line));
+    assertEquals("", BatchParserCommon.removeEndingCRLF(new Line(line,1)).toString());
   }
 
   @Test
   public void testRemoveLastEndingCRLFWithWS() {
     String line = "Test            \r\n";
-    assertEquals("Test            ", BatchParserCommon.removeEndingCRLF(line));
+    assertEquals("Test            ", BatchParserCommon.removeEndingCRLF(new Line(line,1)).toString());
   }
 
   @Test
   public void testRemoveLastEndingCRLFWithWSLong() {
     String line = "Test            \r\nTest2    \r\n";
-    assertEquals("Test            \r\nTest2    ", BatchParserCommon.removeEndingCRLF(line));
+    assertEquals("Test            \r\nTest2    ", BatchParserCommon.removeEndingCRLF(new Line(line,1)).toString());
+  }
+  
+  private List<Line> toLineList(String[] messageRaw) {
+    final List<Line> lineList = new ArrayList<Line>();
+    int counter = 1;
+    
+    for(final String currentLine : messageRaw) {
+      lineList.add(new Line(currentLine, counter++));
+    }
+    
+    return lineList;
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
index 4cd0b67..142d355 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
@@ -44,9 +44,6 @@ import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 
-/**
- *
- */
 public class BatchRequestParserTest {
 
   private static final String CRLF = "\r\n";
@@ -257,7 +254,7 @@ public class BatchRequestParserTest {
 
   @Test(expected = BatchException.class)
   public void testBoundaryParameterWithoutQuota() throws BatchException {
-    String invalidContentType = "multipart;boundary=batch_1740-bb:84-2f7f";
+    String invalidContentType = "multipart/mixed;boundary=batch_1740-bb:84-2f7f";
     String batch = "--batch_1740-bb:84-2f7f" + CRLF
         + GET_REQUEST
         + "--batch_1740-bb:84-2f7f--";
@@ -607,32 +604,6 @@ public class BatchRequestParserTest {
   }
 
   @SuppressWarnings("unused")
-  @Test(expected = BatchException.class)
-  @Ignore("This header should not be validated")
-  public void testNegativeContentLength() throws BatchException, IOException {
-    String batch = ""
-        + "--batch_8194-cf13-1f56" + CRLF
-        + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
-        + "Content-Length: -2" + CRLF
-        + CRLF
-        + "--changeset_f980-1cb6-94dd" + CRLF
-        + MIME_HEADERS
-        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
-        + CRLF
-        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
-        + "Content-Type: application/json;odata=verbose" + CRLF
-        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
-        + CRLF
-        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
-        + "--changeset_f980-1cb6-94dd--" + CRLF
-        + CRLF
-        + "--batch_8194-cf13-1f56--";
-    InputStream in = new ByteArrayInputStream(batch.getBytes());
-    BatchParser parser = new BatchParser(contentType, batchProperties, true);
-    List<BatchRequestPart> batchRequestParts = parser.parseBatchRequest(in);
-  }
-
-  @SuppressWarnings("unused")
   @Test
   public void testNegativeContentLengthChangeSet() throws BatchException, IOException {
     String batch = ""
@@ -747,44 +718,6 @@ public class BatchRequestParserTest {
   }
 
   @Test(expected = BatchException.class)
-  @Ignore("This header should not be validated")
-  public void testCutChangeSetDelimiter() throws BatchException, IOException {
-    String batch = ""
-        + "--batch_8194-cf13-1f56" + CRLF
-        + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + CRLF
-        + "Content-Length: 582" + CRLF
-        + CRLF
-        + "--changeset_f980-1cb6-94dd" + CRLF
-        + MIME_HEADERS
-        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
-        + CRLF
-        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
-        + "Content-Type: application/json;odata=verbose" + CRLF
-        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
-        + "Content-Length: 10" + CRLF
-        + CRLF
-        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
-        + CRLF
-        + "--changeset_f980-1cb6-94dd" + CRLF
-        + MIME_HEADERS
-        + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + CRLF
-        + CRLF
-        + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + CRLF
-        + "Content-Type: application/json;odata=verbose" + CRLF
-        + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + CRLF
-        + "Content-Length: 100000" + CRLF
-        + CRLF
-        + "{\"EmployeeName\":\"Peter Fall\"}" + CRLF
-        + "--changeset_f980-1cb6-94dd--" + CRLF
-        + CRLF
-        + "--batch_8194-cf13-1f56--";
-
-    InputStream in = new ByteArrayInputStream(batch.getBytes());
-    BatchParser parser = new BatchParser(contentType, batchProperties, true);
-    parser.parseBatchRequest(in);
-  }
-
-  @Test(expected = BatchException.class)
   public void testNonNumericContentLength() throws BatchException {
     String batch = ""
         + "--batch_8194-cf13-1f56" + CRLF
@@ -1138,7 +1071,20 @@ public class BatchRequestParserTest {
     assertEquals("{\"EmployeeName\":\"Peter Fall\"}",
         inputStreamToString(changeSetPart.getRequests().get(1).getBody()));
   }
+  
+  @Test
+  public void testLargeBatch() throws BatchException, IOException {
+    String fileName = "/batchLarge.batch";
+    InputStream in = ClassLoader.class.getResourceAsStream(fileName);
+    if (in == null) {
+      throw new IOException("Requested file '" + fileName + "' was not found.");
+    }
+    
+    BatchParser parser = new BatchParser(contentType, batchProperties, true);
+    parser.parseBatchRequest(in);
+  }
 
+  
   private List<BatchRequestPart> parse(final String batch) throws BatchException {
     InputStream in = new ByteArrayInputStream(batch.getBytes());
     BatchParser parser = new BatchParser(contentType, batchProperties, true);

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
index 6c604f8..bcf13e4 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestTest.java
@@ -132,7 +132,6 @@ public class BatchRequestTest {
   }
 
   @Test
-  @Ignore
   // TODO
       /*
        * --batch_123
@@ -146,8 +145,8 @@ public class BatchRequestTest {
        * ...
        * ....
        */
-      public
-      void testBatchWithGetAndPost() throws BatchException, IOException {
+  @Ignore
+  public void testBatchWithGetAndPost() throws BatchException, IOException {
     List<BatchPart> batch = new ArrayList<BatchPart>();
     Map<String, String> headers = new HashMap<String, String>();
     headers.put("Accept", "application/json");

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
index e98a295..7437caf 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchTransformatorCommonTest.java
@@ -50,7 +50,7 @@ public class BatchTransformatorCommonTest {
 
   @Test(expected = BatchException.class)
   public void testValidateContentTypeMissingHeader() throws BatchException {
-    final Header headers = new Header();
+    final Header headers = new Header(1);
     
     BatchTransformatorCommon.validateContentType(headers);
   }
@@ -82,7 +82,7 @@ public class BatchTransformatorCommonTest {
 
   @Test(expected = BatchException.class)
   public void testValidateContentTransferEncodingMissingHeader() throws BatchException {
-    final Header headers = new Header();
+    final Header headers = new Header(1);
     
     BatchTransformatorCommon.validateContentTransferEncoding(headers, true);
   }
@@ -96,8 +96,8 @@ public class BatchTransformatorCommonTest {
   }
 
   private Header makeHeaders(final String headerName, final List<String> values) {
-    final Header headers = new Header();
-    headers.addHeader(headerName, values);
+    final Header headers = new Header(1);
+    headers.addHeader(headerName, values, 1);
 
     return headers;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
index bd3607a..482dc3b 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BufferedReaderIncludingLineEndingsTest.java
@@ -9,6 +9,7 @@ import java.io.UnsupportedEncodingException;
 import java.util.List;
 
 import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings;
+import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings.Line;
 import org.junit.Test;
 
 public class BufferedReaderIncludingLineEndingsTest {
@@ -422,20 +423,20 @@ public class BufferedReaderIncludingLineEndingsTest {
   @Test
   public void testToList() throws IOException {
     BufferedReaderIncludingLineEndings reader = create(TEXT_COMBINED);
-    List<String> stringList = reader.toList();
+    List<Line> stringList = reader.toList();
 
     assertEquals(11, stringList.size());
-    assertEquals("Test\r", stringList.get(0));
-    assertEquals("Test2\r\n", stringList.get(1));
-    assertEquals("Test3\n", stringList.get(2));
-    assertEquals("Test4\r", stringList.get(3));
-    assertEquals("\r", stringList.get(4));
-    assertEquals("\r\n", stringList.get(5));
-    assertEquals("\r\n", stringList.get(6));
-    assertEquals("Test5\n", stringList.get(7));
-    assertEquals("Test6\r\n", stringList.get(8));
-    assertEquals("Test7\n", stringList.get(9));
-    assertEquals("\n", stringList.get(10));
+    assertEquals("Test\r", stringList.get(0).toString());
+    assertEquals("Test2\r\n", stringList.get(1).toString());
+    assertEquals("Test3\n", stringList.get(2).toString());
+    assertEquals("Test4\r", stringList.get(3).toString());
+    assertEquals("\r", stringList.get(4).toString());
+    assertEquals("\r\n", stringList.get(5).toString());
+    assertEquals("\r\n", stringList.get(6).toString());
+    assertEquals("Test5\n", stringList.get(7).toString());
+    assertEquals("Test6\r\n", stringList.get(8).toString());
+    assertEquals("Test7\n", stringList.get(9).toString());
+    assertEquals("\n", stringList.get(10).toString());
     reader.close();
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f0dc0f74/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java
index 128aa2e..bfe7b24 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/HeaderTest.java
@@ -15,8 +15,8 @@ public class HeaderTest {
 
   @Test
   public void test() {
-    Header header = new Header();
-    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
+    Header header = new Header(1);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED, 1);
 
     assertEquals(HttpContentType.MULTIPART_MIXED, header.getHeader(HttpHeaders.CONTENT_TYPE));
     assertEquals(1, header.getHeaders(HttpHeaders.CONTENT_TYPE).size());
@@ -25,7 +25,7 @@ public class HeaderTest {
 
   @Test
   public void testNotAvailable() {
-    Header header = new Header();
+    Header header = new Header(1);
 
     assertNull(header.getHeader(HttpHeaders.CONTENT_TYPE));
     assertEquals(0, header.getHeaders(HttpHeaders.CONTENT_TYPE).size());
@@ -34,8 +34,8 @@ public class HeaderTest {
 
   @Test
   public void testCaseInsensitive() {
-    Header header = new Header();
-    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
+    Header header = new Header(1);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED, 1);
 
     assertEquals(HttpContentType.MULTIPART_MIXED, header.getHeader("cOnTenT-TyPE"));
     assertEquals(1, header.getHeaders("cOnTenT-TyPE").size());
@@ -44,9 +44,9 @@ public class HeaderTest {
 
   @Test
   public void testDuplicatedAdd() {
-    Header header = new Header();
-    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
-    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
+    Header header = new Header(1);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED, 1);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED, 2);
 
     assertEquals(HttpContentType.MULTIPART_MIXED, header.getHeader(HttpHeaders.CONTENT_TYPE));
     assertEquals(1, header.getHeaders(HttpHeaders.CONTENT_TYPE).size());
@@ -55,16 +55,16 @@ public class HeaderTest {
 
   @Test
   public void testMatcher() {
-    Header header = new Header();
-    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED + ";boundary=123");
+    Header header = new Header(1);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED + ";boundary=123", 1);
 
     assertTrue(header.isHeaderMatching(HttpHeaders.CONTENT_TYPE, BatchParserCommon.PATTERN_MULTIPART_BOUNDARY));
   }
 
   @Test
   public void testFieldName() {
-    Header header = new Header();
-    header.addHeader("MyFieldNamE", "myValue");
+    Header header = new Header(0);
+    header.addHeader("MyFieldNamE", "myValue", 1);
 
     assertEquals("MyFieldNamE", header.getHeaderField("myfieldname").getFieldName());
     assertEquals("MyFieldNamE", header.toSingleMap().keySet().toArray(new String[0])[0]);
@@ -76,8 +76,8 @@ public class HeaderTest {
 
   @Test
   public void testDeepCopy() {
-    Header header = new Header();
-    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED + ";boundary=123");
+    Header header = new Header(1);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED + ";boundary=123", 1);
 
     Header copy = header.clone();
     assertEquals(header.getHeaders(HttpHeaders.CONTENT_TYPE), copy.getHeaders(HttpHeaders.CONTENT_TYPE));
@@ -90,25 +90,25 @@ public class HeaderTest {
 
   @Test
   public void testMatcherNoHeader() {
-    Header header = new Header();
+    Header header = new Header(1);
 
     assertFalse(header.isHeaderMatching(HttpHeaders.CONTENT_TYPE, BatchParserCommon.PATTERN_MULTIPART_BOUNDARY));
   }
 
   @Test
   public void testMatcherFail() {
-    Header header = new Header();
-    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED + ";boundary=123");
+    Header header = new Header(1);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED + ";boundary=123", 1);
 
     assertFalse(header.isHeaderMatching(HttpHeaders.CONTENT_TYPE, BatchParserCommon.PATTERN_HEADER_LINE));
   }
 
   @Test
   public void testDuplicatedAddList() {
-    Header header = new Header();
-    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
+    Header header = new Header(1);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED, 1);
     header.addHeader(HttpHeaders.CONTENT_TYPE, Arrays.asList(new String[] { HttpContentType.MULTIPART_MIXED,
-        HttpContentType.APPLICATION_ATOM_SVC }));
+        HttpContentType.APPLICATION_ATOM_SVC }), 2);
 
     assertEquals(HttpContentType.MULTIPART_MIXED + ", " + HttpContentType.APPLICATION_ATOM_SVC, header
         .getHeader(HttpHeaders.CONTENT_TYPE));
@@ -119,9 +119,9 @@ public class HeaderTest {
 
   @Test
   public void testRemove() {
-    Header header = new Header();
-    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
-    header.removeHeaders(HttpHeaders.CONTENT_TYPE);
+    Header header = new Header(1);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED, 1);
+    header.removeHeader(HttpHeaders.CONTENT_TYPE);
 
     assertNull(header.getHeader(HttpHeaders.CONTENT_TYPE));
     assertEquals(0, header.getHeaders(HttpHeaders.CONTENT_TYPE).size());
@@ -129,10 +129,10 @@ public class HeaderTest {
 
   @Test
   public void testMultipleValues() {
-    Header header = new Header();
-    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED);
-    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.APPLICATION_ATOM_SVC);
-    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.APPLICATION_ATOM_XML);
+    Header header = new Header(1);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED, 1);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.APPLICATION_ATOM_SVC, 2);
+    header.addHeader(HttpHeaders.CONTENT_TYPE, HttpContentType.APPLICATION_ATOM_XML, 3);
 
     final String fullHeaderString =
         HttpContentType.MULTIPART_MIXED + ", " + HttpContentType.APPLICATION_ATOM_SVC + ", "


[15/19] git commit: Performance Refactoring

Posted by ch...@apache.org.
Performance Refactoring

Signed-off-by: Christian Amend <ch...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/1f76b210
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/1f76b210
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/1f76b210

Branch: refs/heads/master
Commit: 1f76b2103d75fe8cd5077538bb84ad1b0bba28e3
Parents: b155bda
Author: Christian Holzer <c....@sap.com>
Authored: Tue Oct 7 14:42:41 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Oct 9 16:45:26 2014 +0200

----------------------------------------------------------------------
 .../olingo/odata2/core/batch/AcceptParser.java  | 143 ++++++-------------
 .../odata2/core/batch/v2/BatchParser.java       |  24 ++--
 .../odata2/core/batch/v2/BatchParserCommon.java |  74 +++++++++-
 .../v2/BufferedReaderIncludingLineEndings.java  |  10 +-
 .../olingo/odata2/core/batch/v2/Header.java     |   2 +-
 .../core/batch/BatchRequestParserTest.java      |  37 +++--
 6 files changed, 158 insertions(+), 132 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f76b210/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/AcceptParser.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/AcceptParser.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/AcceptParser.java
index 48bfb1b..5c8811c 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/AcceptParser.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/AcceptParser.java
@@ -19,23 +19,19 @@
 package org.apache.olingo.odata2.core.batch;
 
 import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
-import java.util.Scanner;
 import java.util.TreeSet;
-import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.exception.MessageReference;
 
 /**
  *
  */
 public class AcceptParser {
 
-  private static final String COMMA = ",";
   private static final String BAD_REQUEST = "400";
   private static final String ALL = "*";
   private static final String REG_EX_QUALITY_FACTOR = "q=((?:1\\.0{0,3})|(?:0\\.[0-9]{0,2}[1-9]))";
@@ -54,42 +50,53 @@ public class AcceptParser {
   private List<String> acceptLanguageHeaderValues = new ArrayList<String>();
 
   public List<String> parseAcceptHeaders() throws BatchException {
-    final String headerValue = concatenateHeaderLines(acceptHeaderValues);
-    final TreeSet<Accept> acceptTree = getAcceptTree();
+    return parseQualifiedHeader(acceptHeaderValues,
+        REG_EX_ACCEPT_WITH_Q_FACTOR,
+        BatchException.INVALID_ACCEPT_HEADER);
+  }
+
+  public List<String> parseAcceptableLanguages() throws BatchException {
+    return parseQualifiedHeader(acceptLanguageHeaderValues,
+        REG_EX_ACCEPT_LANGUAGES_WITH_Q_FACTOR,
+        BatchException.INVALID_ACCEPT_LANGUAGE_HEADER);
+  }
+
+  private List<String> parseQualifiedHeader(List<String> headerValues, Pattern regEx, MessageReference exectionMessage)
+      throws BatchException {
+    final TreeSet<Accept> acceptTree = new TreeSet<AcceptParser.Accept>();
     final List<String> acceptHeaders = new ArrayList<String>();
-    final Scanner acceptHeaderScanner = new Scanner(headerValue);
-
-    acceptHeaderScanner.useDelimiter(",\\s?");
-    while (acceptHeaderScanner.hasNext()) {
-      if (acceptHeaderScanner.hasNext(REG_EX_ACCEPT_WITH_Q_FACTOR)) {
-        acceptHeaderScanner.next(REG_EX_ACCEPT_WITH_Q_FACTOR);
-        MatchResult result = acceptHeaderScanner.match();
-        if (result.groupCount() == 2) {
-          String acceptHeaderValue = result.group(1);
-          double qualityFactor = result.group(2) != null ? Double.parseDouble(result.group(2)) : 1d;
-          qualityFactor = getQualityFactor(acceptHeaderValue, qualityFactor);
-          Accept acceptHeader = new Accept().setQuality(qualityFactor).setValue(acceptHeaderValue);
+
+    for (final String headerValue : headerValues) {
+      final String[] acceptParts = headerValue.split(",");
+
+      for (final String part : acceptParts) {
+        final Matcher matcher = regEx.matcher(part.trim());
+
+        if (matcher.matches() && matcher.groupCount() == 2) {
+          final Accept acceptHeader = getQualifiedHeader(matcher);
           acceptTree.add(acceptHeader);
         } else {
-          String header = acceptHeaderScanner.next();
-          acceptHeaderScanner.close();
-          throw new BatchException(BatchException.INVALID_ACCEPT_HEADER.addContent(header), BAD_REQUEST);
+          throw new BatchException(exectionMessage.addContent(part), BAD_REQUEST);
         }
-      } else {
-        String header = acceptHeaderScanner.next();
-        acceptHeaderScanner.close();
-        throw new BatchException(BatchException.INVALID_ACCEPT_HEADER.addContent(header), BAD_REQUEST);
       }
     }
+
     for (Accept accept : acceptTree) {
       if (!acceptHeaders.contains(accept.getValue())) {
         acceptHeaders.add(accept.getValue());
       }
     }
-    acceptHeaderScanner.close();
     return acceptHeaders;
   }
 
+  private Accept getQualifiedHeader(final Matcher matcher) {
+    final String acceptHeaderValue = matcher.group(1);
+    double qualityFactor = matcher.group(2) != null ? Double.parseDouble(matcher.group(2)) : 1d;
+    qualityFactor = getQualityFactor(acceptHeaderValue, qualityFactor);
+
+    return new Accept().setQuality(qualityFactor).setValue(acceptHeaderValue);
+  }
+  
   private double getQualityFactor(final String acceptHeaderValue, double qualityFactor) {
     int paramNumber = 0;
     double typeFactor = 0.0;
@@ -115,57 +122,7 @@ public class AcceptParser {
     qualityFactor = qualityFactor + paramNumber * QUALITY_PARAM_FACTOR + typeFactor + subtypeFactor;
     return qualityFactor;
   }
-
-  public List<String> parseAcceptableLanguages() throws BatchException {
-    final String headerValue = concatenateHeaderLines(acceptLanguageHeaderValues);
-    final List<String> acceptLanguages = new LinkedList<String>();
-    final TreeSet<Accept> acceptTree = getAcceptTree();
-    Scanner acceptLanguageScanner = new Scanner(headerValue);
-    acceptLanguageScanner.useDelimiter(",\\s?");
-
-    while (acceptLanguageScanner.hasNext()) {
-      if (acceptLanguageScanner.hasNext(REG_EX_ACCEPT_LANGUAGES_WITH_Q_FACTOR)) {
-        acceptLanguageScanner.next(REG_EX_ACCEPT_LANGUAGES_WITH_Q_FACTOR);
-        MatchResult result = acceptLanguageScanner.match();
-        if (result.groupCount() == 2) {
-          String languagerange = result.group(1);
-          double qualityFactor = result.group(2) != null ? Double.parseDouble(result.group(2)) : 1d;
-          acceptTree.add(new Accept().setQuality(qualityFactor).setValue(languagerange));
-        } else {
-          String acceptLanguage = acceptLanguageScanner.next();
-          acceptLanguageScanner.close();
-          throw new BatchException(BatchException.INVALID_ACCEPT_LANGUAGE_HEADER.addContent(acceptLanguage),
-              BAD_REQUEST);
-        }
-      } else {
-        String acceptLanguage = acceptLanguageScanner.next();
-        acceptLanguageScanner.close();
-        throw new BatchException(BatchException.INVALID_ACCEPT_LANGUAGE_HEADER.addContent(acceptLanguage), BAD_REQUEST);
-      }
-    }
-    for (Accept accept : acceptTree) {
-      if (!acceptLanguages.contains(accept.getValue())) {
-        acceptLanguages.add(accept.getValue());
-      }
-    }
-    acceptLanguageScanner.close();
-    return acceptLanguages;
-  }
-
-  private String concatenateHeaderLines(final List<String> headerValues) {
-    final StringBuilder builder = new StringBuilder();
-    final Iterator<String> iter = headerValues.iterator();
-
-    while (iter.hasNext()) {
-      builder.append(iter.next());
-      if (iter.hasNext()) {
-        builder.append(COMMA);
-      }
-    }
-
-    return builder.toString();
-  }
-
+  
   public void addAcceptHeaderValue(final String headerValue) {
     acceptHeaderValues.add(headerValue);
   }
@@ -174,21 +131,7 @@ public class AcceptParser {
     acceptLanguageHeaderValues.add(headerValue);
   }
 
-  private TreeSet<Accept> getAcceptTree() {
-    TreeSet<Accept> treeSet = new TreeSet<Accept>(new Comparator<Accept>() {
-      @Override
-      public int compare(final Accept o1, final Accept o2) {
-        if (o1.getQuality() <= o2.getQuality()) {
-          return 1;
-        } else {
-          return -1;
-        }
-      }
-    });
-    return treeSet;
-  }
-
-  private static class Accept {
+  private static class Accept implements Comparable<Accept> {
     private double quality;
     private String value;
 
@@ -201,14 +144,18 @@ public class AcceptParser {
       return this;
     }
 
-    public double getQuality() {
-      return quality;
-    }
-
     public Accept setQuality(final double quality) {
       this.quality = quality;
       return this;
     }
 
+    @Override
+    public int compareTo(Accept o) {
+      if (quality <= o.quality) {
+        return 1;
+      } else {
+        return -1;
+      }
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f76b210/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
index 00a1f2a..76b5215 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParser.java
@@ -20,7 +20,6 @@ package org.apache.olingo.odata2.core.batch.v2;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -81,7 +80,7 @@ public class BatchParser {
     final String baseUri = getBaseUri();
     final String boundary = BatchParserCommon.getBoundary(contentTypeMime, 1);
     final List<BatchParserResult> resultList = new LinkedList<BatchParserResult>();
-    final List<List<Line>> bodyPartStrings = splitBodyParts(in, boundary);
+    final List<List<Line>> bodyPartStrings = BatchParserCommon.splitRequestByBoundary(in, boundary);
 
     for (List<Line> bodyPartString : bodyPartStrings) {
       BatchBodyPart bodyPart = new BatchBodyPart(bodyPartString, boundary, isStrict).parse();
@@ -90,16 +89,17 @@ public class BatchParser {
 
     return resultList;
   }
-
-  private List<List<Line>> splitBodyParts(final InputStream in, final String boundary)
-      throws IOException, BatchException {
-
-    final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
-    final List<Line> message = reader.toList();
-    reader.close();
-
-    return BatchParserCommon.splitMessageByBoundary(message, boundary);
-  }
+  
+  //TODO remove
+//  private List<List<Line>> splitBodyParts(final InputStream in, final String boundary)
+//      throws IOException, BatchException {
+//
+//    final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
+//    final List<Line> message = reader.toList();
+//    reader.close();
+//
+//    return BatchParserCommon.splitMessageByBoundary(message, boundary);
+//  }
 
   private String getBaseUri() throws BatchException {
     String baseUri = "";

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f76b210/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
index b028759..3592688 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java
@@ -19,7 +19,9 @@
 package org.apache.olingo.odata2.core.batch.v2;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
@@ -44,6 +46,9 @@ import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings
 import org.apache.olingo.odata2.core.commons.Decoder;
 
 public class BatchParserCommon {
+
+  private static final Pattern PATTERN_LAST_CRLF = Pattern.compile("(.*)(\r\n){1}( *)", Pattern.DOTALL);
+
   private static final String REG_EX_BOUNDARY =
       "([a-zA-Z0-9_\\-\\.'\\+]{1,70})|\"([a-zA-Z0-9_\\-\\.'\\+\\s\\" +
           "(\\),/:=\\?]{1,69}[a-zA-Z0-9_\\-\\.'\\+\\(\\),/:=\\?])\""; // See RFC 2046
@@ -55,6 +60,7 @@ public class BatchParserCommon {
   public static final Pattern PATTERN_HEADER_LINE = Pattern.compile("([a-zA-Z\\-]+):\\s?(.*)\\s*");
   public static final Pattern PATTERN_CONTENT_TYPE_APPLICATION_HTTP = Pattern.compile(REG_EX_APPLICATION_HTTP,
       Pattern.CASE_INSENSITIVE);
+  private static final Pattern PATTERN_RELATIVE_URI = Pattern.compile("([^/][^?]*)(\\?.*)?");
 
   public static String trimLineListToLength(final List<Line> list, final int length) {
     final String message = stringListToString(list);
@@ -86,19 +92,77 @@ public class BatchParserCommon {
 
     return new ByteArrayInputStream(message.getBytes());
   }
+  
+  static List<List<Line>> splitRequestByBoundary(final InputStream in, final String boundary)
+      throws BatchException, IOException {
+    final List<List<Line>> messageParts = new LinkedList<List<Line>>();
+    List<Line> currentPart = new ArrayList<Line>();
+    boolean isEndReached = false;
+    //32ms
+    final String quotedBoundary = Pattern.quote(boundary);
+    final Pattern boundaryDelimiterPattern = Pattern.compile("--" + quotedBoundary +  "--[\\s ]*");
+    final Pattern boundaryPattern = Pattern.compile("--" + quotedBoundary + "[\\s ]*");
+    
+    final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
+    String currentLine;
+    int lineNumber = 1;
+    
+    while((currentLine = reader.readLine()) != null) {
+      if (boundaryDelimiterPattern.matcher(currentLine.toString()).matches()) {
+        removeEndingCRLFFromList(currentPart);
+        messageParts.add(currentPart);
+        isEndReached = true;
+      } else if (boundaryPattern.matcher(currentLine.toString()).matches()) {
+        removeEndingCRLFFromList(currentPart);
+        messageParts.add(currentPart);
+        currentPart = new LinkedList<Line>();
+      } else {
+        currentPart.add(new Line(currentLine, lineNumber));
+      }
 
+      if (isEndReached) {
+        break;
+      }
+
+      lineNumber++;
+    }
+    reader.close();
+
+    // Remove preamble
+    if (messageParts.size() > 0) {
+      messageParts.remove(0);
+    } else {
+
+      throw new BatchException(BatchException.MISSING_BOUNDARY_DELIMITER.addContent(1));
+    }
+
+    if (!isEndReached) {
+      throw new BatchException(BatchException.MISSING_CLOSE_DELIMITER.addContent(1));
+    }
+
+    if (messageParts.size() == 0) {
+      throw new BatchException(BatchException.NO_MATCH_WITH_BOUNDARY_STRING.addContent(boundary).addContent(0));
+    }
+
+    return messageParts;
+  }
+  
   static List<List<Line>> splitMessageByBoundary(final List<Line> message, final String boundary)
       throws BatchException {
     final List<List<Line>> messageParts = new LinkedList<List<Line>>();
     List<Line> currentPart = new ArrayList<Line>();
     boolean isEndReached = false;
-
+    
+    final String quotedBoundary = Pattern.quote(boundary);
+    final Pattern boundaryDelimiterPattern = Pattern.compile("--" + quotedBoundary +  "--[\\s ]*");
+    final Pattern boundaryPattern = Pattern.compile("--" + quotedBoundary + "[\\s ]*");
+    
     for (Line currentLine : message) {
-      if (currentLine.toString().contains("--" + boundary + "--")) {
+      if (boundaryDelimiterPattern.matcher(currentLine.toString()).matches()) {
         removeEndingCRLFFromList(currentPart);
         messageParts.add(currentPart);
         isEndReached = true;
-      } else if (currentLine.toString().contains("--" + boundary)) {
+      } else if (boundaryPattern.matcher(currentLine.toString()).matches()) {
         removeEndingCRLFFromList(currentPart);
         messageParts.add(currentPart);
         currentPart = new LinkedList<Line>();
@@ -139,7 +203,7 @@ public class BatchParserCommon {
   }
 
   public static Line removeEndingCRLF(final Line line) {
-    Pattern pattern = Pattern.compile("(.*)(\r\n){1}( *)", Pattern.DOTALL);
+    Pattern pattern = PATTERN_LAST_CRLF;
     Matcher matcher = pattern.matcher(line.toString());
 
     if (matcher.matches()) {
@@ -268,7 +332,7 @@ public class BatchParserCommon {
         if (uriObject.isAbsolute()) {
           regexRequestUri = Pattern.compile(baseUri + "/([^/][^?]*)(\\?.*)?");
         } else {
-          regexRequestUri = Pattern.compile("([^/][^?]*)(\\?.*)?");
+          regexRequestUri = PATTERN_RELATIVE_URI;
 
         }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f76b210/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
index 295f4c6..7b81dc8 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BufferedReaderIncludingLineEndings.java
@@ -27,7 +27,7 @@ public class BufferedReaderIncludingLineEndings extends Reader {
   private static final char CR = '\r';
   private static final char LF = '\n';
   private static final int EOF = -1;
-  private static final int BUFFER_SIZE = 1024;
+  private static final int BUFFER_SIZE = 8192;
   private Reader reader;
   private char[] buffer;
   private int offset = 0;
@@ -105,7 +105,7 @@ public class BufferedReaderIncludingLineEndings extends Reader {
   }
 
   public String readLine() throws IOException {
-    if (isEOF()) {
+    if (limit == EOF) {
       return null;
     }
 
@@ -113,7 +113,7 @@ public class BufferedReaderIncludingLineEndings extends Reader {
     boolean foundLineEnd = false; // EOF will be considered as line ending
 
     while (!foundLineEnd) {
-      if (isBufferReloadRequired()) {
+      if (limit == offset) {
         if (fillBuffer() == EOF) {
           foundLineEnd = true;
         }
@@ -129,12 +129,12 @@ public class BufferedReaderIncludingLineEndings extends Reader {
           foundLineEnd = true;
 
           // Check next char. Consume \n if available
-          if (isBufferReloadRequired()) {
+          if (limit == offset) {
             fillBuffer();
           }
 
           // Check if there is at least one character
-          if (!isEOF() && buffer[offset] == LF) {
+          if (limit != EOF && buffer[offset] == LF) {
             stringBuffer.append(LF);
             offset++;
           }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f76b210/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
index c9daa6a..6c90e02 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/Header.java
@@ -87,7 +87,7 @@ public class Header implements Cloneable {
 
   public Map<String, List<String>> toMultiMap() {
     final Map<String, List<String>> singleMap = new HashMap<String, List<String>>();
-
+    
     for (final String key : headers.keySet()) {
       HeaderField field = headers.get(key);
       singleMap.put(field.getFieldName(), field.getValues());

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f76b210/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
index 142d355..f9287b5 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
@@ -29,6 +29,7 @@ import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.List;
+import java.util.Random;
 
 import org.apache.olingo.odata2.api.batch.BatchException;
 import org.apache.olingo.odata2.api.batch.BatchRequestPart;
@@ -895,7 +896,7 @@ public class BatchRequestParserTest {
         + "This is a preamble and must be ignored" + CRLF
         + CRLF
         + CRLF
-        + "----1242"
+        + "----1242" + CRLF
         + "--batch_8194-cf13-1f56" + CRLF
         + MIME_HEADERS
         + CRLF
@@ -909,7 +910,7 @@ public class BatchRequestParserTest {
         + "This is a preamble and must be ignored" + CRLF
         + CRLF
         + CRLF
-        + "----1242"
+        + "----1242" + CRLF
         + "--changeset_f980-1cb6-94dd" + CRLF
         + MIME_HEADERS
         + "Content-Id: " + CONTENT_ID_REFERENCE + CRLF
@@ -1071,20 +1072,34 @@ public class BatchRequestParserTest {
     assertEquals("{\"EmployeeName\":\"Peter Fall\"}",
         inputStreamToString(changeSetPart.getRequests().get(1).getBody()));
   }
-  
+
   @Test
   public void testLargeBatch() throws BatchException, IOException {
-    String fileName = "/batchLarge.batch";
-    InputStream in = ClassLoader.class.getResourceAsStream(fileName);
-    if (in == null) {
-      throw new IOException("Requested file '" + fileName + "' was not found.");
+    for (int j = 0; j < 200; j++) {
+      String fileName = "/batchLarge.batch";
+      InputStream in = ClassLoader.class.getResourceAsStream(fileName);
+      if (in == null) {
+        throw new IOException("Requested file '" + fileName + "' was not found.");
+      }
+
+      StringBuilder builder = new StringBuilder();
+      Random rnd = new Random();
+      for (int i = 0; i < 300; i++) {
+        builder.append((char) ('A' + rnd.nextInt('Z' - 'A')));
+      }
+
+      // String request = builder.toString() + CRLF + inputStreamToString(in);
+      String request = inputStreamToString(in).replace("Walldorf", builder.toString());
+      in.close();
+      InputStream requestStream = new ByteArrayInputStream(request.getBytes());
+
+      long start = System.currentTimeMillis();
+      BatchParser parser = new BatchParser(contentType, batchProperties, true);
+      parser.parseBatchRequest(requestStream);
+      System.out.println(System.currentTimeMillis() - start);
     }
-    
-    BatchParser parser = new BatchParser(contentType, batchProperties, true);
-    parser.parseBatchRequest(in);
   }
 
-  
   private List<BatchRequestPart> parse(final String batch) throws BatchException {
     InputStream in = new ByteArrayInputStream(batch.getBytes());
     BatchParser parser = new BatchParser(contentType, batchProperties, true);


[18/19] git commit: Merge branch 'olingo436BatchRefactoring'

Posted by ch...@apache.org.
Merge branch 'olingo436BatchRefactoring'


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

Branch: refs/heads/master
Commit: d82220ea09a57f7ef555daa216f5950bfedf6fb4
Parents: 14c6dd5 8dfd515
Author: Christian Amend <ch...@apache.org>
Authored: Thu Oct 9 16:52:21 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Thu Oct 9 16:52:21 2014 +0200

----------------------------------------------------------------------
 .../olingo/odata2/api/batch/BatchException.java |    8 +-
 .../odata2/api/batch/BatchParserResult.java     |    5 +
 .../odata2/api/batch/BatchRequestPart.java      |    2 +-
 .../odata2/api/batch/BatchResponsePart.java     |    2 +-
 .../api/client/batch/BatchSingleResponse.java   |    4 +-
 .../olingo/odata2/core/batch/AcceptParser.java  |  143 +-
 .../odata2/core/batch/BatchRequestParser.java   |  614 -----
 .../odata2/core/batch/BatchResponseParser.java  |  356 ---
 .../odata2/core/batch/v2/BatchBodyPart.java     |  139 +
 .../core/batch/v2/BatchChangeSetPart.java       |   56 +
 .../odata2/core/batch/v2/BatchParser.java       |  132 +
 .../odata2/core/batch/v2/BatchParserCommon.java |  328 +++
 .../olingo/odata2/core/batch/v2/BatchPart.java  |   25 +
 .../core/batch/v2/BatchQueryOperation.java      |   82 +
 .../batch/v2/BatchRequestTransformator.java     |  210 ++
 .../batch/v2/BatchResponseTransformator.java    |  126 +
 .../core/batch/v2/BatchTransformator.java       |   30 +
 .../core/batch/v2/BatchTransformatorCommon.java |   72 +
 .../v2/BufferedReaderIncludingLineEndings.java  |  275 ++
 .../olingo/odata2/core/batch/v2/Header.java     |  230 ++
 .../odata2/core/ep/ProviderFacadeImpl.java      |    7 +-
 .../src/main/resources/i18n.properties          |   36 +-
 .../odata2/core/batch/AcceptParserTest.java     |   77 +-
 .../core/batch/BatchParserCommonTest.java       |  212 ++
 .../core/batch/BatchRequestParserTest.java      |  530 +++-
 .../odata2/core/batch/BatchRequestTest.java     |   45 +-
 .../core/batch/BatchResponseParserTest.java     |   34 +-
 .../odata2/core/batch/BatchResponseTest.java    |   13 +-
 .../core/batch/BatchResponseWriterTest.java     |    2 +-
 .../batch/BatchTransformatorCommonTest.java     |  105 +
 .../BufferedReaderIncludingLineEndingsTest.java |  453 ++++
 .../olingo/odata2/core/batch/HeaderTest.java    |  161 ++
 .../src/test/resources/batchLarge.batch         | 2419 ++++++++++++++++++
 .../src/test/resources/batchWithPost.batch      |    1 +
 .../odata2/fit/client/ClientBatchTest.java      |    2 +
 .../fit/client/ClientDeltaResponseTest.java     |    2 +
 .../src/test/resources/batchWithContentId.batch |    2 +
 .../resources/batchWithContentIdPart2.batch     |    6 +-
 .../src/test/resources/changeset.batch          |    2 +
 39 files changed, 5786 insertions(+), 1162 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/d82220ea/odata2-lib/odata-core/src/main/resources/i18n.properties
----------------------------------------------------------------------