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 2015/08/04 16:25:47 UTC

[07/18] olingo-odata4 git commit: [OLINGO-731] Added html as debug output and refactored structure

[OLINGO-731] Added html as debug output and refactored structure


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

Branch: refs/heads/OLINGO-640
Commit: 3dae763f359b27c4c2d13dd95193dc4f76e778ab
Parents: 010d94f
Author: Christian Amend <ch...@sap.com>
Authored: Fri Jul 24 16:11:13 2015 +0200
Committer: Christian Amend <ch...@sap.com>
Committed: Fri Jul 24 16:12:01 2015 +0200

----------------------------------------------------------------------
 .../apache/olingo/server/api/ODataResponse.java |   2 +-
 .../server/api/debug/DebugInformation.java      | 118 ++++++++++
 .../server/api/debug/DebugResponseHelper.java   |   7 +-
 .../olingo/server/api/debug/DebugSupport.java   |  10 +-
 .../server/api/debug/DefaultDebugSupport.java   |  17 +-
 .../apache/olingo/server/core/ODataHandler.java |  10 +-
 .../server/core/ODataHttpHandlerImpl.java       |  89 ++-----
 .../olingo/server/core/debug/DebugInfo.java     |  50 ----
 .../olingo/server/core/debug/DebugInfoBody.java | 150 ------------
 .../server/core/debug/DebugInfoException.java   | 142 ------------
 .../server/core/debug/DebugInfoRequest.java     | 112 ---------
 .../server/core/debug/DebugInfoResponse.java    |  87 -------
 .../server/core/debug/DebugInfoRuntime.java     | 186 ---------------
 .../server/core/debug/DebugInfoServer.java      |  87 -------
 .../olingo/server/core/debug/DebugInfoUri.java  | 231 ------------------
 .../core/debug/DebugResponseHelperImpl.java     | 229 +++++++++---------
 .../olingo/server/core/debug/DebugTab.java      |  50 ++++
 .../olingo/server/core/debug/DebugTabBody.java  | 149 ++++++++++++
 .../server/core/debug/DebugTabException.java    | 136 +++++++++++
 .../server/core/debug/DebugTabRequest.java      | 115 +++++++++
 .../server/core/debug/DebugTabResponse.java     |  89 +++++++
 .../server/core/debug/DebugTabRuntime.java      | 181 +++++++++++++++
 .../server/core/debug/DebugTabServer.java       |  57 +++++
 .../olingo/server/core/debug/DebugTabUri.java   | 232 +++++++++++++++++++
 .../server/core/debug/ServerCoreDebugger.java   | 137 +++++++++++
 .../olingo/server/tecsvc/TechnicalServlet.java  |   1 -
 .../olingo/server/core/ODataHandlerTest.java    |  10 +-
 27 files changed, 1423 insertions(+), 1261 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java
index 493e794..7b9e9c9 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java
@@ -31,7 +31,7 @@ import org.apache.olingo.commons.api.http.HttpStatusCode;
 public class ODataResponse {
 
   private int statusCode = HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode();
-  private Map<String, String> headers = new HashMap<String, String>();
+  private final Map<String, String> headers = new HashMap<String, String>();
   private InputStream content;
 
   /**

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugInformation.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugInformation.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugInformation.java
new file mode 100644
index 0000000..9198c6b
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugInformation.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.api.debug;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.uri.UriInfo;
+
+/**
+ * This class contains all information necessary to construct a debug response.
+ */
+public class DebugInformation {
+
+  private ODataRequest request;
+  private ODataResponse applicationResponse;
+  private UriInfo uriInfo;
+  private Exception exception;
+  private Map<String, String> serverEnvironmentVaribles;
+  private List<RuntimeMeasurement> runtimeInformation;
+
+  /**
+   * This method will return the ODataRequest the library created. This request will never be null but might be filled
+   * incompletely if there has been an exception during the request parsing.
+   * @return the ODataRequest the library built
+   */
+  public ODataRequest getRequest() {
+    return request;
+  }
+
+  public void setRequest(ODataRequest request) {
+    this.request = request;
+  }
+
+  /**
+   * This method will return the ODataResponse which was filled by the Application or the library in an exception case.
+   * The response might be null or might not be filled completely.
+   * @return the response filled by the application
+   */
+  public ODataResponse getApplicationResponse() {
+    return applicationResponse;
+  }
+
+  public void setApplicationResponse(ODataResponse applicationResponse) {
+    this.applicationResponse = applicationResponse;
+  }
+
+  /**
+   * The URI Info object the library created during URI parsing. Might be null if there was an exception during URI
+   * parsing.
+   * @return the URI Info Object
+   */
+  public UriInfo getUriInfo() {
+    return uriInfo;
+  }
+
+  public void setUriInfo(UriInfo uriInfo) {
+    this.uriInfo = uriInfo;
+  }
+
+  /**
+   * This method will return any exception that was thrown from the application or library. Will be null if there was no
+   * exception.
+   * @return an exception if thrown.
+   */
+  public Exception getException() {
+    return exception;
+  }
+
+  public void setException(Exception exception) {
+    this.exception = exception;
+  }
+
+  /**
+   * A map containing information about the runtime environment. Depending on the servlet or webserver used this map
+   * might contain different information. Will never be null but might be empty.
+   * @return environment variables
+   */
+  public Map<String, String> getServerEnvironmentVaribles() {
+    return serverEnvironmentVaribles;
+  }
+
+  public void setServerEnvironmentVaribles(Map<String, String> serverEnvironmentVaribles) {
+    this.serverEnvironmentVaribles = serverEnvironmentVaribles;
+  }
+
+  /**
+   * This method will return all runtime information which was collected inside the library. Might be null if no data
+   * could be collected.
+   * @return runtime information collected by the library
+   */
+  public List<RuntimeMeasurement> getRuntimeInformation() {
+    return runtimeInformation;
+  }
+
+  public void setRuntimeInformation(List<RuntimeMeasurement> runtimeInformation) {
+    this.runtimeInformation = runtimeInformation;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java
index bf6fc56..e2f6933 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java
@@ -18,10 +18,6 @@
  */
 package org.apache.olingo.server.api.debug;
 
-import java.util.List;
-import java.util.Map;
-
-import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
 
 /**
@@ -38,6 +34,5 @@ public interface DebugResponseHelper {
    * @param runtimeInformation
    * @return the debug response or the raw application response in case an exception occurred.
    */
-  ODataResponse createDebugResponse(ODataRequest request, ODataResponse applicationResponse, Exception exception,
-      Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation);
+  ODataResponse createDebugResponse(DebugInformation debugInfo);
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java
index 995ba34..7a94c44 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java
@@ -18,11 +18,7 @@
  */
 package org.apache.olingo.server.api.debug;
 
-import java.util.List;
-import java.util.Map;
-
 import org.apache.olingo.server.api.OData;
-import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
 
 /**
@@ -35,8 +31,11 @@ public interface DebugSupport {
   public static final String ODATA_DEBUG_HTML = "html";
   public static final String ODATA_DEBUG_DOWNLOAD = "download";
 
+  //TODO:JavaDoc
   void init(OData odata);
 
+  boolean isUserAuthorized();
+  
   /**
    * This method should create a debug response and deliver it back to the Olingo library. This method MUST NEVER throw
    * an exception.
@@ -46,7 +45,6 @@ public interface DebugSupport {
    * @param exception which has been thrown. Might be null in case there was no exception
    * @return a new debug response which will be send to the client
    */
-  ODataResponse createDebugResponse(String debugFormat, ODataRequest request, ODataResponse response,
-      Exception exception, Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation);
+  ODataResponse createDebugResponse(String debugFormat, DebugInformation debugInfo);
 
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java
index cca537f..7079e76 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java
@@ -18,11 +18,7 @@
  */
 package org.apache.olingo.server.api.debug;
 
-import java.util.List;
-import java.util.Map;
-
 import org.apache.olingo.server.api.OData;
-import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
 
 /**
@@ -38,18 +34,21 @@ public class DefaultDebugSupport implements DebugSupport {
   }
 
   @Override
-  public ODataResponse createDebugResponse(String debugFormat, ODataRequest request, ODataResponse applicationResponse,
-      Exception exception, Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation) {
+  public boolean isUserAuthorized() {
+    return true;
+  }
+
+  @Override
+  public ODataResponse createDebugResponse(String debugFormat, DebugInformation debugInfo) {
     // Check if debugFormat is supported by the library
     if (DebugSupport.ODATA_DEBUG_JSON.equalsIgnoreCase(debugFormat)
         || DebugSupport.ODATA_DEBUG_HTML.equalsIgnoreCase(debugFormat)
         || DebugSupport.ODATA_DEBUG_DOWNLOAD.equalsIgnoreCase(debugFormat)) {
-      return odata.createDebugResponseHelper(debugFormat).createDebugResponse(request, applicationResponse, exception,
-          serverEnvironmentVaribles, runtimeInformation);
+      return odata.createDebugResponseHelper(debugFormat).createDebugResponse(debugInfo);
     } else {
       // Debug format is not supported by the library by default so in order to avoid an exception we will just give
       // back the original response from the application.
-      return applicationResponse;
+      return debugInfo.getApplicationResponse();
     }
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
index 1a0df8d..1d1b270 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
@@ -42,6 +42,7 @@ import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
 import org.apache.olingo.server.api.serializer.RepresentationType;
 import org.apache.olingo.server.api.serializer.SerializerException;
 import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.core.debug.ServerCoreDebugger;
 import org.apache.olingo.server.core.uri.parser.Parser;
 import org.apache.olingo.server.core.uri.parser.UriParserException;
 import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;
@@ -54,15 +55,18 @@ public class ODataHandler {
   private final OData odata;
   private final ServiceMetadata serviceMetadata;
   private final List<Processor> processors = new LinkedList<Processor>();
+  private final ServerCoreDebugger debugger;
+
   private CustomContentTypeSupport customContentTypeSupport;
   private CustomETagSupport customETagSupport;
 
   private UriInfo uriInfo;
   private Exception lastThrownException;
 
-  public ODataHandler(final OData server, final ServiceMetadata serviceMetadata) {
+  public ODataHandler(final OData server, final ServiceMetadata serviceMetadata, ServerCoreDebugger debugger) {
     odata = server;
     this.serviceMetadata = serviceMetadata;
+    this.debugger = debugger;
 
     register(new DefaultRedirectProcessor());
     register(new DefaultProcessor());
@@ -192,4 +196,8 @@ public class ODataHandler {
   public Exception getLastThrownException() {
     return lastThrownException;
   }
+  
+  public UriInfo getUriInfo(){
+    return uriInfo;
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
index 2bab186..e443591 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
@@ -35,19 +35,19 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.olingo.commons.api.ODataRuntimeException;
 import org.apache.olingo.commons.api.http.HttpHeader;
 import org.apache.olingo.commons.api.http.HttpMethod;
-import org.apache.olingo.server.api.ODataServerError;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.ODataHttpHandler;
+import org.apache.olingo.server.api.ODataLibraryException;
 import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.ODataLibraryException;
+import org.apache.olingo.server.api.ODataServerError;
 import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.debug.DebugSupport;
-import org.apache.olingo.server.api.debug.RuntimeMeasurement;
 import org.apache.olingo.server.api.etag.CustomETagSupport;
 import org.apache.olingo.server.api.processor.Processor;
 import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
 import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.core.debug.ServerCoreDebugger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -56,99 +56,52 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
   private static final Logger LOG = LoggerFactory.getLogger(ODataHttpHandlerImpl.class);
 
   private final ODataHandler handler;
-  private final OData odata;
-  private int split = 0;
+  private final ServerCoreDebugger debugger;
 
-  // debug stuff
-  private final List<RuntimeMeasurement> runtimeInformation = new ArrayList<RuntimeMeasurement>();
-  private DebugSupport debugSupport;
-  private String debugFormat;
-  private boolean isDebugMode = false;
+  private int split = 0;
 
   public ODataHttpHandlerImpl(final OData odata, final ServiceMetadata serviceMetadata) {
-    this.odata = odata;
-    handler = new ODataHandler(odata, serviceMetadata);
+    debugger = new ServerCoreDebugger(odata);
+    handler = new ODataHandler(odata, serviceMetadata, debugger);
   }
 
   @Override
   public void process(final HttpServletRequest request, final HttpServletResponse response) {
+    ODataRequest odRequest = new ODataRequest();
     Exception exception = null;
-    ODataRequest odRequest = null;
     ODataResponse odResponse;
-    resolveDebugMode(request);
-    int processMethodHandel = startRuntimeMeasurement("ODataHttpHandlerImpl", "process");
+    debugger.resolveDebugMode(request);
 
+    int processMethodHandel = debugger.startRuntimeMeasurement("ODataHttpHandlerImpl", "process");
     try {
-      odRequest = new ODataRequest();
-      int requestHandel = startRuntimeMeasurement("ODataHttpHandlerImpl", "fillODataRequest");
+      int requestHandel = debugger.startRuntimeMeasurement("ODataHttpHandlerImpl", "fillODataRequest");
       fillODataRequest(odRequest, request, split);
-      stopRuntimeMeasurement(requestHandel);
-      
-      int responseHandel = startRuntimeMeasurement("ODataHandler", "process");
+      debugger.stopRuntimeMeasurement(requestHandel);
+
+      int responseHandel = debugger.startRuntimeMeasurement("ODataHandler", "process");
       odResponse = handler.process(odRequest);
-      stopRuntimeMeasurement(responseHandel);
+      debugger.stopRuntimeMeasurement(responseHandel);
       // ALL future methods after process must not throw exceptions!
     } catch (Exception e) {
       exception = e;
       odResponse = handleException(odRequest, e);
     }
-    stopRuntimeMeasurement(processMethodHandel);
+    debugger.stopRuntimeMeasurement(processMethodHandel);
 
-    if (isDebugMode) {
-      debugSupport.init(odata);
-      // TODO: Should we be more careful here with response assignement in order to not loose the original response?
-      // TODO: How should we react to exceptions here?
+    if (debugger.isDebugMode()) {
+      Map<String, String> serverEnvironmentVaribles = createEnvironmentVariablesMap(request);
       if (exception == null) {
         // This is to ensure that we have access to the thrown OData Exception
-        // TODO: Should we make this hack
         exception = handler.getLastThrownException();
       }
-      Map<String, String> serverEnvironmentVaribles = createEnvironmentVariablesMap(request);
-
       odResponse =
-          debugSupport.createDebugResponse(debugFormat, odRequest, odResponse, exception, serverEnvironmentVaribles,
-              runtimeInformation);
+          debugger.createDebugResponse(request, exception, odRequest, odResponse, handler.getUriInfo(),
+              serverEnvironmentVaribles);
     }
 
     convertToHttp(response, odResponse);
   }
 
-  private void resolveDebugMode(HttpServletRequest request) {
-    if (debugSupport != null) {
-      // Should we read the parameter from the servlet here and ignore multiple parameters?
-      debugFormat = request.getParameter(DebugSupport.ODATA_DEBUG_QUERY_PARAMETER);
-      // Debug format is present and we have a debug support processor registered so we are in debug mode
-      isDebugMode = debugFormat != null;
-    }
-  }
-
-  public int startRuntimeMeasurement(final String className, final String methodName) {
-    if (isDebugMode) {
-      int handleId = runtimeInformation.size();
-
-      final RuntimeMeasurement measurement = new RuntimeMeasurement();
-      measurement.setTimeStarted(System.nanoTime());
-      measurement.setClassName(className);
-      measurement.setMethodName(methodName);
-
-      runtimeInformation.add(measurement);
-
-      return handleId;
-    } else {
-      return 0;
-    }
-  }
-
-  public void stopRuntimeMeasurement(final int handle) {
-    if (isDebugMode && handle < runtimeInformation.size()) {
-        long stopTime = System.nanoTime();
-        RuntimeMeasurement runtimeMeasurement = runtimeInformation.get(handle);
-        if (runtimeMeasurement != null) {
-          runtimeMeasurement.setTimeStopped(stopTime);
-        }
-      }
-  }
-
   private Map<String, String> createEnvironmentVariablesMap(HttpServletRequest request) {
     LinkedHashMap<String, String> environment = new LinkedHashMap<String, String>();
     environment.put("authType", request.getAuthType());
@@ -350,6 +303,6 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
 
   @Override
   public void register(final DebugSupport debugSupport) {
-    this.debugSupport = debugSupport;
+    debugger.setDebugSupportProcessor(debugSupport);
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfo.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfo.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfo.java
deleted file mode 100644
index 9c5a1d4..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfo.java
+++ /dev/null
@@ -1,50 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-
-/**
- * Debug information.
- */
-public interface DebugInfo {
-
-  /**
-   * Gets the name of this debug information part, useful as title.
-   * @return the name
-   */
-  public String getName();
-
-  /**
-   * Appends the content of this debug information part
-   * to the given JSON stream writer.
-   * @param jsonGenerator a JSON generator
-   */
-  public void appendJson(JsonGenerator jsonGenerator) throws IOException;
-
-  /**
-   * Appends the content of this debug information part to the given writer.
-   * @param writer a {@link Writer}
-   */
-  public void appendHtml(Writer writer) throws IOException;
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoBody.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoBody.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoBody.java
deleted file mode 100644
index e266aae..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoBody.java
+++ /dev/null
@@ -1,150 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.olingo.commons.api.http.HttpHeader;
-import org.apache.olingo.server.api.ODataResponse;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-/**
- * Response body debug information.
- */
-public class DebugInfoBody implements DebugInfo {
-
-  private static enum ResponseContent {JSON, XML, TEXT, IMAGE};
-  
-  private final ODataResponse response;
-  private final ResponseContent responseContent;
-  
-  //private final String serviceRoot;
-//  private final boolean isXml;
-//  private final boolean isJson;
-//  private final boolean isText;
-//  private final boolean isImage;
-
-  public DebugInfoBody(final ODataResponse response, final String serviceRoot) {
-    this.response = response;
-    // TODO: make header case insensitive
-    final String contentType = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
-    //TODO: Differentiate better
-    if (contentType != null) {
-      responseContent = ResponseContent.JSON;
-    } else {
-      responseContent = ResponseContent.TEXT;
-    }
-//    isXml = contentType.contains("xml");
-//    isJson = !isXml && contentType.startsWith(HttpContentType.APPLICATION_JSON);
-//    isText = isXml || isJson || contentType.startsWith("text/")
-//        || contentType.startsWith(HttpContentType.APPLICATION_HTTP)
-//        || contentType.startsWith(HttpContentType.MULTIPART_MIXED);
-//    isImage = !isText && contentType.startsWith("image/");
-  }
-
-  @Override
-  public String getName() {
-    return "Body";
-  }
-
-//
-  @Override
-  public void appendJson(final JsonGenerator gen) throws IOException {
-    gen.writeString(getContentString());
-  }
-
-  private String getContentString() {
-    try {
-      String contentString;
-      switch (responseContent) {
-      case IMAGE:
-        //TODO: DecodeString as base 64
-        contentString = "Currently not supported";
-        break;
-      case JSON:
-      case XML:
-      case TEXT:
-      default:
-        // TODO: Remove IOUtils from core dependency
-        contentString = IOUtils.toString(response.getContent(), "UTF-8");
-        break;
-      }
-      return contentString;
-    } catch (IOException e) {
-      return "Could not parse Body for Debug Output";
-    }
-  }
-
-//
-//  @Override
-//  public void appendHtml(final Writer writer) throws IOException {
-//    final String body = getContentString();
-//    if (isImage) {
-//      writer.append("<img src=\"data:").append(response.getContentHeader()).append(";base64,")
-//          .append(body)
-//          .append("\" />\n");
-//    } else {
-//      writer.append("<pre class=\"code").append(isXml ? " xml" : isJson ? " json" : "").append("\">\n")
-//          .append(isXml || isJson ?
-//              addLinks(ODataDebugResponseWrapper.escapeHtml(isXml ? formatXml(body) : formatJson(body)), isXml) :
-//              ODataDebugResponseWrapper.escapeHtml(body))
-//          .append("</pre>\n");
-//    }
-//  }
-//
-//  private String formatXml(final String xml) throws IOException {
-//    try {
-//      Transformer transformer = TransformerFactory.newInstance().newTransformer();
-//      transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-//      transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
-//      StreamResult outputTarget = new StreamResult(new StringWriter());
-//      transformer.transform(new StreamSource(new StringReader(xml)), outputTarget);
-//      return outputTarget.getWriter().toString();
-//    } catch (final TransformerException e) {
-//      return xml;
-//    }
-//  }
-//
-//  private String formatJson(final String json) {
-//    return new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create().toJson(new JsonParser().parse(json));
-//  }
-//
-//  private String addLinks(final String source, final boolean isXml) {
-//    final String debugOption = ODataDebugResponseWrapper.ODATA_DEBUG_QUERY_PARAMETER + "="
-//        + ODataDebugResponseWrapper.ODATA_DEBUG_HTML;
-//    final String urlPattern = "("
-//        + (isXml ? "(?:href|src|base)=" : "\"(?:uri|media_src|edit_media|__next)\":\\p{Space}*")
-//        + "\")(.+?)\"";
-//    return (isXml ? source.replaceAll("(xmlns(?::\\p{Alnum}+)?=\")(.+?)\"", "$1<span class=\"ns\">$2</span>\"") :
-//        source)
-//        .replaceAll(urlPattern, "$1<a href=\"" + serviceRoot + "$2?" + debugOption + "\">$2</a>\"")
-//        .replaceAll("(<a href=\"" + Pattern.quote(serviceRoot) + ')' + Pattern.quote(serviceRoot), "$1")
-//        .replaceAll("<a href=\"(.+?)\\?(.+?)\\?" + debugOption, "<a href=\"$1?$2&amp;" + debugOption)
-//        .replaceAll("&amp;amp;", "&amp;");
-//  }
-
-  @Override
-  public void appendHtml(Writer writer) throws IOException {
-    // TODO Auto-generated method stub
-
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoException.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoException.java
deleted file mode 100644
index b19252f..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoException.java
+++ /dev/null
@@ -1,142 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.olingo.server.api.ODataLibraryException;
-import org.apache.olingo.server.api.ODataLibraryException.ODataErrorMessage;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-/**
- * Exception debug information.
- */
-public class DebugInfoException implements DebugInfo {
-
-  private final Exception exception;
-
-  public DebugInfoException(final Exception exception) {
-    this.exception = exception;
-  }
-
-  @Override
-  public String getName() {
-    return "Stacktrace";
-  }
-
-  @Override
-  public void appendJson(final JsonGenerator gen) throws IOException {
-    gen.writeStartObject();
-    gen.writeFieldName("exceptions");
-    gen.writeStartArray();
-    Throwable throwable = exception;
-    while (throwable != null) {
-      gen.writeStartObject();
-      gen.writeStringField("class", throwable.getClass().getCanonicalName());
-      gen.writeStringField("message", getMessage(throwable));
-      gen.writeFieldName("invocation");
-      appendJsonStackTraceElement(gen, throwable.getStackTrace()[0]);
-      gen.writeEndObject();
-
-      // Get next exception in the cause list
-      throwable = throwable.getCause();
-    }
-    gen.writeEndArray();
-
-    gen.writeFieldName("stacktrace");
-    gen.writeStartArray();
-    for (final StackTraceElement stackTraceElement : exception.getStackTrace()) {
-      appendJsonStackTraceElement(gen, stackTraceElement);
-    }
-    gen.writeEndArray();
-
-    gen.writeEndObject();
-  }
-
-  private String getMessage(final Throwable throwable) {
-    String message;
-    if (throwable instanceof ODataLibraryException) {
-      ODataLibraryException ex = (ODataLibraryException) throwable;
-      // We use the default locale
-      ODataErrorMessage translatedMessage = ex.getTranslatedMessage(null);
-      // We provide the best message we can
-      message = translatedMessage.getMessage() == null ? ex.getMessage() : translatedMessage.getMessage();
-    } else {
-      message = throwable.getMessage();
-    }
-    return message;
-  }
-
-  private void appendJsonStackTraceElement(final JsonGenerator gen, final StackTraceElement element)
-      throws IOException {
-    gen.writeStartObject();
-    gen.writeStringField("class", element.getClassName());
-    gen.writeStringField("method", element.getMethodName());
-    gen.writeStringField("line", Integer.toString(element.getLineNumber()));
-    gen.writeEndObject();
-  }
-
-  @Override
-  public void appendHtml(Writer writer) throws IOException {
-    // TODO Auto-generated method stub
-
-  }
-//
-//  @Override
-//  public void appendHtml(final Writer writer) throws IOException {
-//    appendException(exception, writer);
-//    writer.append("<h2>Stacktrace</h2>\n");
-//    int count = 0;
-//    for (final StackTraceElement stackTraceElement : exception.getStackTrace()) {
-//      appendStackTraceElement(stackTraceElement, ++count == 1, count == exception.getStackTrace().length, writer);
-//    }
-//  }
-//
-//  private void appendException(final Throwable throwable, final Writer writer) throws IOException {
-//    if (throwable.getCause() != null) {
-//      appendException(throwable.getCause(), writer);
-//    }
-//    final StackTraceElement details = throwable.getStackTrace()[0];
-//    writer.append("<h2>").append(throwable.getClass().getCanonicalName()).append("</h2>\n")
-//        .append("<p>")
-//        .append(ODataDebugResponseWrapper.escapeHtml(getMessageText(throwable)))
-//        .append("</p>\n");
-//    appendStackTraceElement(details, true, true, writer);
-//  }
-//
-//  private void appendStackTraceElement(final StackTraceElement stackTraceElement,
-//      final boolean isFirst, final boolean isLast, final Writer writer) throws IOException {
-//    if (isFirst) {
-//      writer.append("<table>\n<thead>\n")
-//          .append("<tr>\n<th class=\"name\">Class</th>\n")
-//          .append("<th class=\"name\">Method</th>\n")
-//          .append("<th class=\"value\">Line number in class</th>\n</tr>\n")
-//          .append("</thead>\n<tbody>\n");
-//    }
-//    writer.append("<tr>\n<td class=\"name\">").append(stackTraceElement.getClassName()).append("</td>\n")
-//        .append("<td class=\"name\">").append(stackTraceElement.getMethodName()).append("</td>\n")
-//        .append("<td class=\"value\">").append(Integer.toString(stackTraceElement.getLineNumber()))
-//        .append("</td>\n</tr>\n");
-//    if (isLast) {
-//      writer.append("</tbody>\n</table>\n");
-//    }
-//  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRequest.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRequest.java
deleted file mode 100644
index e28bbb9..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRequest.java
+++ /dev/null
@@ -1,112 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.olingo.server.api.ODataRequest;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-/**
- * Request debug information.
- */
-public class DebugInfoRequest implements DebugInfo {
-
-  private final String method;
-  private final String uri;
-  private final String protocol;
-  private final Map<String, String> headers;
-
-  public DebugInfoRequest(ODataRequest request) {
-    method = request.getMethod() == null ? "unkown" : request.getMethod().toString();
-    uri = request.getRawRequestUri() == null ? "unkown" : request.getRawRequestUri();
-    protocol = request.getProtocol() == null ? "unkown" : request.getProtocol();
-    // TODO: Should we really wrap the headers here or keep the original structure?
-    headers = wrapHeaders(request.getAllHeaders());
-  }
-
-  private Map<String, String> wrapHeaders(Map<String, List<String>> allHeaders) {
-    Map<String, String> localHeaders = new HashMap<String, String>();
-    for (Map.Entry<String, List<String>> entry : allHeaders.entrySet()) {
-      String value = null;
-      if (entry.getValue() != null) {
-        value = "";
-        boolean first = true;
-        for (String valuePart : entry.getValue()) {
-          if (!first) {
-            value = value + ", ";
-          }
-          value = value + valuePart;
-        }
-      }
-    }
-    return localHeaders;
-  }
-
-  @Override
-  public void appendHtml(final Writer writer) throws IOException {
-//    writer.append("<h2>Request Method</h2>\n")
-//        .append("<p>").append(method).append("</p>\n")
-//        .append("<h2>Request URI</h2>\n")
-//        .append("<p>").append(DebugResponseHelperImpl.escapeHtml(uri.toString())).append("</p>\n")
-//        .append("<h2>Request Protocol</h2>\n")
-//        .append("<p>").append(protocol).append("</p>\n");
-//    writer.append("<h2>Request Headers</h2>\n")
-//        .append("<table>\n<thead>\n")
-//        .append("<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n")
-//        .append("</thead>\n<tbody>\n");
-//    for (final String name : headers.keySet()) {
-//      for (final String value : headers.get(name)) {
-//        if (value != null) {
-//          writer.append("<tr><td class=\"name\">").append(name).append("</td>")
-//              .append("<td class=\"value\">").append(DebugResponseHelperImpl.escapeHtml(value))
-//              .append("</td></tr>\n");
-//        }
-//      }
-//    }
-//    writer.append("</tbody>\n</table>\n");
-  }
-
-  @Override
-  public String getName() {
-    return "Request";
-  }
-
-  @Override
-  public void appendJson(JsonGenerator gen) throws IOException {
-    gen.writeStartObject();
-    gen.writeStringField("method", method);
-
-    gen.writeStringField("uri", uri);
-
-    gen.writeStringField("protocol", protocol);
-
-    if (!headers.isEmpty()) {
-      gen.writeFieldName("headers");
-      DebugResponseHelperImpl.appendJsonTable(gen, headers);
-    }
-
-    gen.writeEndObject();
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoResponse.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoResponse.java
deleted file mode 100644
index 0781d50..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoResponse.java
+++ /dev/null
@@ -1,87 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Map;
-
-import org.apache.olingo.commons.api.http.HttpStatusCode;
-import org.apache.olingo.server.api.ODataResponse;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-/**
- * Response debug information.
- */
-public class DebugInfoResponse implements DebugInfo {
-
-  private final ODataResponse response;
-  private final String serviceRoot;
-  private final HttpStatusCode status;
-  private final Map<String, String> headers;
-
-  public DebugInfoResponse(final ODataResponse applicationResponse, final String serviceRoot) {
-    this.response = applicationResponse;
-    this.serviceRoot = serviceRoot;
-    status = HttpStatusCode.fromStatusCode(response.getStatusCode());
-    headers = response.getHeaders();
-  }
-
-  @Override
-  public String getName() {
-    return "Response";
-  }
-
-  @Override
-  public void appendJson(final JsonGenerator gen) throws IOException {
-    gen.writeStartObject();
-
-    if (status != null) {
-      gen.writeFieldName("status");
-      gen.writeStartObject();
-      gen.writeStringField("code", Integer.toString(status.getStatusCode()));
-      gen.writeStringField("info", status.getInfo());
-      gen.writeEndObject();
-    }
-
-    if (headers != null && !headers.isEmpty()) {
-      gen.writeFieldName("headers");
-      DebugResponseHelperImpl.appendJsonTable(gen, headers);
-    }
-
-    gen.writeFieldName("body");
-    new DebugInfoBody(response, serviceRoot).appendJson(gen);
-
-    gen.writeEndObject();
-  }
-
-  @Override
-  public void appendHtml(final Writer writer) throws IOException {
-//    writer.append("<h2>Status Code</h2>\n")
-//        .append("<p>").append(Integer.toString(status.getStatusCode())).append(' ')
-//        .append(status.getInfo()).append("</p>\n")
-//        .append("<h2>Response Headers</h2>\n");
-//    ODataDebugResponseWrapper.appendHtmlTable(writer, headers);
-//    if (response.getContentHeader() != null && response.getEntity() != null) {
-//      writer.append("<h2>Response Body</h2>\n");
-//      new DebugInfoBody(response, serviceRoot).appendHtml(writer);
-//    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRuntime.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRuntime.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRuntime.java
deleted file mode 100644
index 2465ce4..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRuntime.java
+++ /dev/null
@@ -1,186 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.olingo.server.api.debug.RuntimeMeasurement;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-/**
- * Runtime debug information.
- */
-public class DebugInfoRuntime implements DebugInfo {
-
-  private final RuntimeNode rootNode;
-
-  public DebugInfoRuntime(List<RuntimeMeasurement> runtimeInformation) {
-    rootNode = new RuntimeNode();
-    for (final RuntimeMeasurement runtimeMeasurement : runtimeInformation) {
-      rootNode.add(runtimeMeasurement);
-    }
-    rootNode.combineRuntimeMeasurements();
-  }
-
-  @Override
-  public String getName() {
-    return "Runtime";
-  }
-
-  @Override
-  public void appendJson(JsonGenerator gen) throws IOException {
-    appendJsonChildren(gen, rootNode);
-  }
-
-  private void appendJsonChildren(JsonGenerator gen, RuntimeNode node) throws IOException {
-    gen.writeStartArray();
-    for (RuntimeNode child : node.children) {
-      appendJsonNode(gen, child);
-    }
-    gen.writeEndArray();
-  }
-
-  private void appendJsonNode(JsonGenerator gen, RuntimeNode node) throws IOException {
-    gen.writeStartObject();
-    gen.writeStringField("class", node.className);
-    gen.writeStringField("method ", node.methodName);
-
-    if (node.timeStopped == 0) {
-      gen.writeNullField("duration");
-    } else {
-      gen.writeStringField("duration", Long.toString((node.timeStopped - node.timeStarted) / 1000));
-      gen.writeStringField("unit", "µs");
-    }
-
-    if (!node.children.isEmpty()) {
-      gen.writeFieldName("children");
-      appendJsonChildren(gen, node);
-    }
-
-    gen.writeEndObject();
-  }
-
-  @Override
-  public void appendHtml(Writer writer) throws IOException {
-    // TODO Auto-generated method stub
-    //
-//  @Override
-//  public void appendHtml(final Writer writer) throws IOException {
-//    appendRuntimeNode(rootNode, "", true, writer);
-//  }
-//
-//  private void appendRuntimeNode(final RuntimeNode node, final String draw, final boolean isLast, final Writer writer)
-//      throws IOException {
-//    if (node.className != null) {
-//      writer.append("<li>")
-//          .append("<span class=\"code\">")
-//          .append("<span class=\"draw\">").append(draw)
-//          .append(isLast ? "&#x2514;" : "&#x251C;").append("&#x2500;&nbsp;</span>")
-//          .append("<span class=\"class\">").append(node.className).append("</span>.")
-//          .append("<span class=\"method\">").append(node.methodName).append("(&hellip;)")
-//          .append("</span></span>");
-//      long time = node.timeStopped == 0 ? 0 : (node.timeStopped - node.timeStarted) / 1000;
-//      writer.append("<span class=\"").append(time == 0 ? "null" : "numeric")
-//          .append("\" title=\"").append(time == 0 ? "Stop time missing" : "Gross duration")
-//          .append("\">").append(time == 0 ? "unfinished" : Long.toString(time) + "&nbsp;&micro;s")
-//          .append("</span>\n");
-//    }
-//    if (!node.children.isEmpty()) {
-//      writer.append("<ol class=\"tree\">\n");
-//      for (final RuntimeNode childNode : node.children) {
-//        appendRuntimeNode(childNode,
-//            node.className == null ? draw : draw + (isLast ? "&nbsp;" : "&#x2502;") + "&nbsp;&nbsp;",
-//            node.children.indexOf(childNode) == node.children.size() - 1,
-//            writer);
-//      }
-//      writer.append("</ol>\n");
-//    }
-//    if (node.className != null) {
-//      writer.append("</li>\n");
-//    }
-//  }
-  }
-
-  private class RuntimeNode {
-
-    protected String className;
-    protected String methodName;
-    protected long timeStarted;
-    protected long timeStopped;
-    protected List<RuntimeNode> children = new ArrayList<RuntimeNode>();
-
-    protected RuntimeNode() {
-      timeStarted = 0;
-      timeStopped = Long.MAX_VALUE;
-    }
-
-    private RuntimeNode(final RuntimeMeasurement runtimeMeasurement) {
-      className = runtimeMeasurement.getClassName();
-      methodName = runtimeMeasurement.getMethodName();
-      timeStarted = runtimeMeasurement.getTimeStarted();
-      timeStopped = runtimeMeasurement.getTimeStopped();
-    }
-
-    protected boolean add(final RuntimeMeasurement runtimeMeasurement) {
-      if (timeStarted <= runtimeMeasurement.getTimeStarted()
-          && timeStopped != 0 && timeStopped >= runtimeMeasurement.getTimeStopped()) {
-        for (RuntimeNode candidate : children) {
-          if (candidate.add(runtimeMeasurement)) {
-            return true;
-          }
-        }
-        children.add(new RuntimeNode(runtimeMeasurement));
-        return true;
-      } else {
-        return false;
-      }
-    }
-
-    /**
-     * Combines runtime measurements with identical class names and method
-     * names into one measurement, assuming that they originate from a loop
-     * or a similar construct where a summary measurement has been intended.
-     */
-    protected void combineRuntimeMeasurements() {
-      RuntimeNode preceding = null;
-      for (Iterator<RuntimeNode> iterator = children.iterator(); iterator.hasNext();) {
-        final RuntimeNode child = iterator.next();
-        if (preceding != null
-            && preceding.timeStopped != 0 && child.timeStopped != 0
-            && preceding.timeStopped <= child.timeStarted
-            && preceding.children.isEmpty() && child.children.isEmpty()
-            && preceding.methodName.equals(child.methodName)
-            && preceding.className.equals(child.className)) {
-          preceding.timeStarted = child.timeStarted - (preceding.timeStopped - preceding.timeStarted);
-          preceding.timeStopped = child.timeStopped;
-
-          iterator.remove();
-        } else {
-          preceding = child;
-          child.combineRuntimeMeasurements();
-        }
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoServer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoServer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoServer.java
deleted file mode 100644
index e974d03..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoServer.java
+++ /dev/null
@@ -1,87 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Map;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-/**
- * Server debug information.
- */
-public class DebugInfoServer implements DebugInfo {
-
-  private final Map<String, String> serverEnvironmentVaribles;
-
-  public DebugInfoServer(Map<String, String> serverEnvironmentVaribles) {
-    this.serverEnvironmentVaribles = serverEnvironmentVaribles;
-  }
-
-  @Override
-  public String getName() {
-    return "Environment";
-  }
-
-  @Override
-  public void appendJson(JsonGenerator gen) throws IOException {
-    DebugResponseHelperImpl.appendJsonTable(gen, serverEnvironmentVaribles);
-  }
-
-  @Override
-  public void appendHtml(Writer writer) throws IOException {
-    // TODO Auto-generated method stub
-
-  }
-
-//  private final Map<String, String> environment;
-//
-//  public DebugInfoServer(final HttpServletRequest httpServletRequest) {
-//    environment = new TreeMap<String, String>();
-//    environment.put("authType", httpServletRequest.getAuthType());
-//    environment.put("localAddr", httpServletRequest.getLocalAddr());
-//    environment.put("localName", httpServletRequest.getLocalName());
-//    addInt("localPort", httpServletRequest.getLocalPort());
-//    environment.put("pathInfo", httpServletRequest.getPathInfo());
-//    environment.put("pathTranslated", httpServletRequest.getPathTranslated());
-//    environment.put("remoteAddr", httpServletRequest.getRemoteAddr());
-//    environment.put("remoteHost", httpServletRequest.getRemoteHost());
-//    addInt("remotePort", httpServletRequest.getRemotePort());
-//    environment.put("remoteUser", httpServletRequest.getRemoteUser());
-//    environment.put("scheme", httpServletRequest.getScheme());
-//    environment.put("serverName", httpServletRequest.getServerName());
-//    addInt("serverPort", httpServletRequest.getServerPort());
-//    environment.put("servletPath", httpServletRequest.getServletPath());
-//  }
-
-//  @Override
-//  public void appendHtml(final Writer writer) throws IOException {
-//    final Package pack = ODataDebugResponseWrapper.class.getPackage();
-//    writer.append("<h2>Library Version</h2>\n")
-//        .append("<p>").append(pack.getImplementationTitle())
-//        .append(" Version ").append(pack.getImplementationVersion()).append("</p>\n")
-//        .append("<h2>Server Environment</h2>\n");
-//    ODataDebugResponseWrapper.appendHtmlTable(writer, environment);
-//  }
-//
-//  private void addInt(final String name, final int number) {
-//    environment.put(name, number == 0 ? null : Integer.toString(number));
-//  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoUri.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoUri.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoUri.java
deleted file mode 100644
index 2ddeb07..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoUri.java
+++ /dev/null
@@ -1,231 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-
-/**
- * URI parser debug information.
- */
-public class DebugInfoUri implements DebugInfo {
-
-  @Override
-  public String getName() {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public void appendJson(JsonGenerator jsonGenerator) throws IOException {
-    // TODO Auto-generated method stub
-    
-  }
-
-  @Override
-  public void appendHtml(Writer writer) throws IOException {
-    // TODO Auto-generated method stub
-    
-  }
-
-//  private final UriInfo uriInfo;
-//  private final FilterExpression filter;
-//  private final OrderByExpression orderBy;
-//  private final ExpandSelectTreeNodeImpl expandSelectTree;
-//  private final ExpressionParserException exception;
-//
-//  public DebugInfoUri(final UriInfo uriInfo, final ExpressionParserException exception) {
-//    this.uriInfo = uriInfo;
-//    filter = uriInfo == null ? null : uriInfo.getFilter();
-//    orderBy = uriInfo == null ? null : uriInfo.getOrderBy();
-//    expandSelectTree = uriInfo == null ? null : getExpandSelect();
-//    this.exception = exception;
-//  }
-//
-//  private ExpandSelectTreeNodeImpl getExpandSelect() {
-//    try {
-//      return uriInfo.getExpand().isEmpty() && uriInfo.getSelect().isEmpty() ? null :
-//          new ExpandSelectTreeCreator(uriInfo.getSelect(), uriInfo.getExpand()).create();
-//    } catch (final EdmException e) {
-//      return null;
-//    }
-//  }
-//
-//  @Override
-//  public String getName() {
-//    return "URI";
-//  }
-//
-//  @Override
-//  public void appendJson(final JsonStreamWriter jsonStreamWriter) throws IOException {
-//    jsonStreamWriter.beginObject();
-//
-//    if (exception != null && exception.getFilterTree() != null) {
-//      jsonStreamWriter.name("error")
-//          .beginObject()
-//          .namedStringValue("expression", exception.getFilterTree().getUriLiteral())
-//          .endObject();
-//      if (filter != null || orderBy != null || expandSelectTree != null) {
-//        jsonStreamWriter.separator();
-//      }
-//    }
-//
-//    if (filter != null) {
-//      String filterString;
-//      try {
-//        filterString = (String) filter.accept(new JsonVisitor());
-//      } catch (final ExceptionVisitExpression e) {
-//        filterString = null;
-//      } catch (final ODataApplicationException e) {
-//        filterString = null;
-//      }
-//      jsonStreamWriter.name("filter").unquotedValue(filterString);
-//      if (orderBy != null || expandSelectTree != null) {
-//        jsonStreamWriter.separator();
-//      }
-//    }
-//
-//    if (orderBy != null) {
-//      String orderByString;
-//      try {
-//        orderByString = (String) orderBy.accept(new JsonVisitor());
-//      } catch (final ExceptionVisitExpression e) {
-//        orderByString = null;
-//      } catch (final ODataApplicationException e) {
-//        orderByString = null;
-//      }
-//      jsonStreamWriter.name("orderby").unquotedValue(orderByString);
-//      if (expandSelectTree != null) {
-//        jsonStreamWriter.separator();
-//      }
-//    }
-//
-//    if (expandSelectTree != null) {
-//      jsonStreamWriter.name("expandSelect").unquotedValue(expandSelectTree.toJsonString());
-//    }
-//
-//    jsonStreamWriter.endObject();
-//  }
-//
-//  @Override
-//  public void appendHtml(final Writer writer) throws IOException {
-//    if (exception != null && exception.getFilterTree() != null) {
-//      writer.append("<h2>Expression Information</h2>\n")
-//          .append("<pre class=\"code\">").append(exception.getFilterTree().getUriLiteral())
-//          .append("</pre>\n");
-//      // TODO: filter error position, filter tokens, filter tree
-//    }
-//    if (filter != null) {
-//      writer.append("<h2>Filter</h2>\n")
-//          .append("<ul class=\"expr\"><li>");
-//      appendExpression(filter.getExpression(), writer);
-//      writer.append("</li></ul>\n");
-//    }
-//    if (orderBy != null) {
-//      writer.append("<h2>Orderby</h2>\n")
-//          .append(orderBy.getOrdersCount() == 1 ? "<ul" : "<ol").append(" class=\"expr\">\n");
-//      for (final OrderExpression order : orderBy.getOrders()) {
-//        writer.append("<li>");
-//        appendExpression(order.getExpression(), writer);
-//        final ExpressionKind kind = order.getExpression().getKind();
-//        if (kind == ExpressionKind.PROPERTY || kind == ExpressionKind.LITERAL) {
-//          writer.append("<br />");
-//        }
-//        writer.append("<span class=\"order\">")
-//            .append(order.getSortOrder().toString())
-//            .append("</span></li>\n");
-//      }
-//      writer.append(orderBy.getOrdersCount() == 1 ? "</ul" : "</ol").append(">\n");
-//    }
-//    if (expandSelectTree != null) {
-//      writer.append("<h2>Expand/Select</h2>\n");
-//      appendExpandSelect(expandSelectTree, writer);
-//    }
-//  }
-//
-//  private void appendExpression(final CommonExpression expression, final Writer writer) throws IOException {
-//    final ExpressionKind kind = expression.getKind();
-//    writer.append("<span class=\"kind\">")
-//        .append(kind.toString())
-//        .append("</span> <span class=\"literal\">")
-//        .append(kind == ExpressionKind.MEMBER ? ((MemberExpression) expression).getProperty().getUriLiteral() :
-//            expression.getUriLiteral())
-//        .append("</span>, type <span class=\"type\">")
-//        .append(expression.getEdmType().toString())
-//        .append("</span>");
-//    if (kind == ExpressionKind.UNARY) {
-//      writer.append("<ul class=\"expr\"><li>");
-//      appendExpression(((UnaryExpression) expression).getOperand(), writer);
-//      writer.append("</li></ul>");
-//    } else if (kind == ExpressionKind.BINARY) {
-//      writer.append("<ol class=\"expr\"><li>");
-//      appendExpression(((BinaryExpression) expression).getLeftOperand(), writer);
-//      writer.append("</li><li>");
-//      appendExpression(((BinaryExpression) expression).getRightOperand(), writer);
-//      writer.append("</li></ol>");
-//    } else if (kind == ExpressionKind.METHOD) {
-//      final MethodExpression methodExpression = (MethodExpression) expression;
-//      if (methodExpression.getParameterCount() > 0) {
-//        writer.append("<ol class=\"expr\">");
-//        for (final CommonExpression parameter : methodExpression.getParameters()) {
-//          writer.append("<li>");
-//          appendExpression(parameter, writer);
-//          writer.append("</li>");
-//        }
-//        writer.append("</ol>");
-//      }
-//    } else if (kind == ExpressionKind.MEMBER) {
-//      writer.append("<ul class=\"expr\"><li>");
-//      appendExpression(((MemberExpression) expression).getPath(), writer);
-//      writer.append("</li></ul>");
-//    }
-//  }
-//
-//  private void appendExpandSelect(final ExpandSelectTreeNode expandSelect, final Writer writer) throws IOException {
-//    writer.append("<ul class=\"expand\">\n")
-//        .append("<li>");
-//    if (expandSelect.isAll()) {
-//      writer.append("all properties");
-//    } else {
-//      for (final EdmProperty property : expandSelect.getProperties()) {
-//        try {
-//          writer.append("property <span class=\"prop\">")
-//              .append(property.getName())
-//              .append("</span><br />");
-//        } catch (final EdmException e) {}
-//      }
-//    }
-//    writer.append("</li>\n");
-//    if (!expandSelect.getLinks().isEmpty()) {
-//      for (final String name : expandSelect.getLinks().keySet()) {
-//        writer.append("<li>link <span class=\"link\">").append(name).append("</span>");
-//        final ExpandSelectTreeNode link = expandSelect.getLinks().get(name);
-//        if (link != null) {
-//          writer.append('\n');
-//          appendExpandSelect(link, writer);
-//        }
-//        writer.append("</li>\n");
-//      }
-//    }
-//    writer.append("</ul>\n");
-//  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
index 6952018..d99dd4c 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
@@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.StringWriter;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -32,8 +33,8 @@ import org.apache.olingo.commons.api.ODataRuntimeException;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.api.http.HttpHeader;
 import org.apache.olingo.commons.api.http.HttpStatusCode;
-import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.debug.DebugInformation;
 import org.apache.olingo.server.api.debug.DebugResponseHelper;
 import org.apache.olingo.server.api.debug.DebugSupport;
 import org.apache.olingo.server.api.debug.RuntimeMeasurement;
@@ -62,13 +63,10 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
   }
 
   @Override
-  public ODataResponse createDebugResponse(ODataRequest request, ODataResponse applicationResponse,
-      Exception exception, Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation) {
-
+  public ODataResponse createDebugResponse(DebugInformation debugInfo) {
     try {
-      final List<DebugInfo> parts =
-          createParts(request, applicationResponse, exception, serverEnvironmentVaribles, runtimeInformation);
-      
+      final List<DebugTab> parts = createParts(debugInfo);
+
       ODataResponse response = new ODataResponse();
       String contentTypeString;
       InputStream body;
@@ -78,7 +76,9 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
             + new Date().toString().replace(' ', '_').replace(':', '.') + ".html");
         // Download is the same as html except for the above header
       case HTML:
-        body = wrapInHtml(parts);
+        String title = debugInfo.getRequest() == null ? 
+            "V4 Service" : "V4 Service: " + debugInfo.getRequest().getRawODataPath();
+        body = wrapInHtml(parts, title);
         contentTypeString = ContentType.TEXT_HTML.toContentTypeString();
         break;
       case JSON:
@@ -93,65 +93,58 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
 
       return response;
     } catch (IOException e) {
-      // Should not happen
-      // TODO: Check what we can do here.
+      // Should not happen. In case it does the library will deliver a default response. So no handling here.
       throw new ODataRuntimeException(e);
     }
   }
 
-  private List<DebugInfo> createParts(ODataRequest request, ODataResponse applicationResponse, Exception exception,
-      Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation) {
-    List<DebugInfo> parts = new ArrayList<DebugInfo>();
+  private List<DebugTab> createParts(DebugInformation debugInfo) {
+    List<DebugTab> parts = new ArrayList<DebugTab>();
 
     // request
-    parts.add(new DebugInfoRequest(request));
+    parts.add(new DebugTabRequest(debugInfo.getRequest()));
 
     // response
-    // TODO: Check service URI
-    parts.add(new DebugInfoResponse(applicationResponse, request.getRawBaseUri()));
+    parts.add(new DebugTabResponse(debugInfo.getApplicationResponse(), debugInfo.getRequest().getRawBaseUri()));
 
     // server
+    Map<String, String> serverEnvironmentVaribles = debugInfo.getServerEnvironmentVaribles();
     if (serverEnvironmentVaribles != null && !serverEnvironmentVaribles.isEmpty()) {
-      parts.add(new DebugInfoServer(serverEnvironmentVaribles));
+      parts.add(new DebugTabServer(serverEnvironmentVaribles));
     }
 
-//    // URI
-//    Throwable candidate = exception;
-//    while (candidate != null && !(candidate instanceof ExpressionParserException)) {
-//      candidate = candidate.getCause();
+    // TODO:Enable URIDebugInfo
+    // URI
+//    if (uriInfo != null && (uriInfo.getFilterOption() != null || uriInfo.getOrderByOption() != null
+//        || uriInfo.getExpandOption() != null || uriInfo.getSelectOption() != null)) {
+//      parts.add(new DebugInfoUri(uriInfo));
 //    }
-//    final ExpressionParserException expressionParserException = (ExpressionParserException) candidate;
-//    if (uriInfo != null
-//        && (uriInfo.getFilter() != null || uriInfo.getOrderBy() != null
-//            || !uriInfo.getExpand().isEmpty() || !uriInfo.getSelect().isEmpty())
-//        || expressionParserException != null && expressionParserException.getFilterTree() != null) {
-//      parts.add(new DebugInfoUri(uriInfo, expressionParserException));
-//    }
-//
-//    // runtime measurements
+
+    // runtime measurements
+    List<RuntimeMeasurement> runtimeInformation = debugInfo.getRuntimeInformation();
     if (runtimeInformation != null && !runtimeInformation.isEmpty()) {
-      parts.add(new DebugInfoRuntime(runtimeInformation));
+      parts.add(new DebugTabRuntime(runtimeInformation));
     }
-//
-//    // exceptions
-    if (exception != null) {
-      parts.add(new DebugInfoException(exception));
+
+    // exceptions
+    if (debugInfo.getException() != null) {
+      parts.add(new DebugTabException(debugInfo.getException()));
     }
 
     return parts;
   }
 
-  private InputStream wrapInJson(final List<DebugInfo> parts) throws IOException {
+  private InputStream wrapInJson(final List<DebugTab> parts) throws IOException {
     CircleStreamBuffer csb = new CircleStreamBuffer();
     JsonGenerator gen = new JsonFactory().createGenerator(csb.getOutputStream(), JsonEncoding.UTF8);
 
     gen.writeStartObject();
-    DebugInfo requestInfo = parts.get(0);
+    DebugTab requestInfo = parts.get(0);
     // TODO: Should we really translate to lower case here?
     gen.writeFieldName(requestInfo.getName().toLowerCase(Locale.ROOT));
     requestInfo.appendJson(gen);
 
-    DebugInfo responseInfo = parts.get(1);
+    DebugTab responseInfo = parts.get(1);
     gen.writeFieldName(responseInfo.getName().toLowerCase(Locale.ROOT));
     responseInfo.appendJson(gen);
 
@@ -163,7 +156,7 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
     } else {
       gen.writeNullField("version");
     }
-    for (DebugInfo part : parts.subList(2, parts.size())) {
+    for (DebugTab part : parts.subList(2, parts.size())) {
       gen.writeFieldName(part.getName().toLowerCase(Locale.ROOT));
       part.appendJson(gen);
     }
@@ -171,76 +164,72 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
 
     gen.writeEndObject();
     gen.close();
+    csb.close();
 
     return csb.getInputStream();
   }
 
-  private InputStream wrapInHtml(final List<DebugInfo> parts) throws IOException {
+  private InputStream wrapInHtml(final List<DebugTab> parts, String title) throws IOException {
     StringWriter writer = new StringWriter();
-//    PathInfo pathInfo = null;
-//    try {
-//      pathInfo = context.getPathInfo();
-//    } catch (final ODataException e) {}
-//
-//    writer.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n")
-//        .append("  \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n")
-//        .append("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n")
-//        .append("<head>\n")
-//        .append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n")
-//        .append("<title>")
-//        .append(pathInfo == null ? "" :
-//            escapeHtml(pathInfo.getServiceRoot().relativize(pathInfo.getRequestUri()).getPath()))
-//        .append("</title>\n")
-//        .append("<style type=\"text/css\">\n")
-//        .append("body { font-family: Arial, sans-serif; font-size: 13px;\n")
-//        .append("       line-height: 16px; margin: 0;\n")
-//        .append("       background-color: #eeeeee; color: #333333; }\n")
-//        .append(".header { float: left; }\n")
-//        .append(".header a { line-height: 22px; padding: 10px 18px;\n")
-//        .append("            text-decoration: none; color: #333333; }\n")
-//        .append(":target, .header:nth-last-child(2) { background-color: #cccccc; }\n")
-//        .append(":target ~ .header:nth-last-child(2) { background-color: inherit; }\n")
-//        .append(".header:focus, .header:hover,\n")
-//        .append("  .header:nth-last-child(2):focus, .header:nth-last-child(2):hover\n")
-//        .append("    { background-color: #999999; }\n")
-//        .append(".section { position: absolute; top: 42px; min-width: 100%;\n")
-//        .append("           padding-top: 18px; border-top: 1px solid #dddddd; }\n")
-//        .append(".section > * { margin-left: 18px; }\n")
-//        .append(":target + .section, .section:last-child { display: block; }\n")
-//        .append(".section, :target + .section ~ .section { display: none; }\n")
-//        .append("h1 { font-size: 18px; font-weight: normal; margin: 10px 0; }\n")
-//        .append("h2 { font-size: 15px; }\n")
-//        .append("h2:not(:first-child) { margin-top: 2em; }\n")
-//        .append("table { border-collapse: collapse; border-spacing: 0;\n")
-//        .append("        margin-top: 1.5em; }\n")
-//        .append("table, thead { border-width: 1px 0; border-style: solid;\n")
-//        .append("               border-color: #dddddd; text-align: left; }\n")
-//        .append("th.name, td.name { padding: 1ex 2em 1ex 0; }\n")
-//        .append("tbody > tr:hover { background-color: #cccccc; }\n")
-//        .append(".code { font-family: \"Courier New\", monospace; }\n")
-//        .append(".code, .tree li { line-height: 15px; }\n")
-//        .append(".code a { text-decoration: underline; color: #666666; }\n")
-//        .append(".xml .ns { font-style: italic; color: #999999; }\n")
-//        .append("ul, .tree { list-style-type: none; }\n")
-//        .append("div > ul.expr, div > .expand, .tree { padding-left: 0; }\n")
-//        .append(".expr, .expand, .null, .numeric { padding-left: 1.5em; }\n")
-//        .append("</style>\n")
-//        .append("</head>\n")
-//        .append("<body>\n");
-//    char count = '0';
-//    for (final DebugInfo part : parts) {
-//      writer.append("<div class=\"header\" id=\"sec").append(++count).append("\">\n")
-//          .append("<h1><a href=\"#sec").append(count).append("\">")
-//          .append(part.getName())
-//          .append("</a></h1>\n")
-//          .append("</div>\n")
-//          .append("<div class=\"section\">\n");
-//      part.appendHtml(writer);
-//      writer.append("</div>\n");
-//    }
-//    writer.append("</body>\n")
-//        .append("</html>\n")
-//        .close();
+
+    writer.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n")
+        .append("  \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n")
+        .append("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n")
+        .append("<head>\n")
+        .append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n")
+        .append("<title>")
+        .append(escapeHtml(title))
+        .append("</title>\n")
+        .append("<style type=\"text/css\">\n")
+        .append("body { font-family: Arial, sans-serif; font-size: 13px;\n")
+        .append("       line-height: 16px; margin: 0;\n")
+        .append("       background-color: #eeeeee; color: #333333; }\n")
+        .append(".header { float: left; }\n")
+        .append(".header a { line-height: 22px; padding: 10px 18px;\n")
+        .append("            text-decoration: none; color: #333333; }\n")
+        .append(":target, .header:nth-last-child(2) { background-color: #cccccc; }\n")
+        .append(":target ~ .header:nth-last-child(2) { background-color: inherit; }\n")
+        .append(".header:focus, .header:hover,\n")
+        .append("  .header:nth-last-child(2):focus, .header:nth-last-child(2):hover\n")
+        .append("    { background-color: #999999; }\n")
+        .append(".section { position: absolute; top: 42px; min-width: 100%;\n")
+        .append("           padding-top: 18px; border-top: 1px solid #dddddd; }\n")
+        .append(".section > * { margin-left: 18px; }\n")
+        .append(":target + .section, .section:last-child { display: block; }\n")
+        .append(".section, :target + .section ~ .section { display: none; }\n")
+        .append("h1 { font-size: 18px; font-weight: normal; margin: 10px 0; }\n")
+        .append("h2 { font-size: 15px; }\n")
+        .append("h2:not(:first-child) { margin-top: 2em; }\n")
+        .append("table { border-collapse: collapse; border-spacing: 0;\n")
+        .append("        margin-top: 1.5em; }\n")
+        .append("table, thead { border-width: 1px 0; border-style: solid;\n")
+        .append("               border-color: #dddddd; text-align: left; }\n")
+        .append("th.name, td.name { padding: 1ex 2em 1ex 0; }\n")
+        .append("tbody > tr:hover { background-color: #cccccc; }\n")
+        .append(".code { font-family: \"Courier New\", monospace; }\n")
+        .append(".code, .tree li { line-height: 15px; }\n")
+        .append(".code a { text-decoration: underline; color: #666666; }\n")
+        .append(".xml .ns { font-style: italic; color: #999999; }\n")
+        .append("ul, .tree { list-style-type: none; }\n")
+        .append("div > ul.expr, div > .expand, .tree { padding-left: 0; }\n")
+        .append(".expr, .expand, .null, .numeric { padding-left: 1.5em; }\n")
+        .append("</style>\n")
+        .append("</head>\n")
+        .append("<body>\n");
+    char count = '0';
+    for (final DebugTab part : parts) {
+      writer.append("<div class=\"header\" id=\"sec").append(++count).append("\">\n")
+          .append("<h1><a href=\"#sec").append(count).append("\">")
+          .append(part.getName())
+          .append("</a></h1>\n")
+          .append("</div>\n")
+          .append("<div class=\"section\">\n");
+      part.appendHtml(writer);
+      writer.append("</div>\n");
+    }
+    writer.append("</body>\n")
+        .append("</html>\n")
+        .close();
     byte[] bytes = writer.toString().getBytes("UTF-8");
     return new ByteArrayInputStream(bytes);
   }
@@ -262,21 +251,21 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
     }
     gen.writeEndObject();
   }
-//
-//  protected static void appendHtmlTable(final Writer writer, final Map<String, String> entries) throws IOException {
-//    writer.append("<table>\n<thead>\n")
-//        .append("<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n")
-//        .append("</thead>\n<tbody>\n");
-//    for (final String name : entries.keySet()) {
-//      final String value = entries.get(name);
-//      if (value != null) {
-//        writer.append("<tr><td class=\"name\">").append(name).append("</td>")
-//            .append("<td class=\"value\">")
-//            .append(ODataDebugResponseWrapper.escapeHtml(value))
-//            .append("</td></tr>\n");
-//      }
-//    }
-//    writer.append("</tbody>\n</table>\n");
-//  }
+
+  protected static void appendHtmlTable(final Writer writer, final Map<String, String> entries) throws IOException {
+    writer.append("<table>\n<thead>\n")
+        .append("<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n")
+        .append("</thead>\n<tbody>\n");
+    for (final String name : entries.keySet()) {
+      final String value = entries.get(name);
+      if (value != null) {
+        writer.append("<tr><td class=\"name\">").append(name).append("</td>")
+            .append("<td class=\"value\">")
+            .append(escapeHtml(value))
+            .append("</td></tr>\n");
+      }
+    }
+    writer.append("</tbody>\n</table>\n");
+  }
 
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTab.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTab.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTab.java
new file mode 100644
index 0000000..8847e33
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTab.java
@@ -0,0 +1,50 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+
+/**
+ * Debug information.
+ */
+public interface DebugTab {
+
+  /**
+   * Gets the name of this debug information part, useful as title.
+   * @return the name
+   */
+  public String getName();
+
+  /**
+   * Appends the content of this debug information part
+   * to the given JSON stream writer.
+   * @param jsonGenerator a JSON generator
+   */
+  public void appendJson(JsonGenerator jsonGenerator) throws IOException;
+
+  /**
+   * Appends the content of this debug information part to the given writer.
+   * @param writer a {@link Writer}
+   */
+  public void appendHtml(Writer writer) throws IOException;
+}