// Path: janos-api/src/main/java/org/apache/olingo/odata2/janos/processor/api/extension/ExtensionContext.java
// public interface ExtensionContext {
//   String PARA_URI_INFO = "~uriinfo";
//   String PARA_ACCEPT_HEADER = "~acceptheader";
//   String PARA_REQUEST_BODY = "~requestbody";
//   String PARA_REQUEST_TYPE = "~requesttype";
// 
//   ExtensionContext addParameter(String name, Object value);
// 
//   Object getParameter(String name);
// 
//   UriInfo getUriInfo();
// 
//   String getAcceptHeader();
// 
//   InputStream getRequestBody();
// 
//   Extension.Method getRequestType();
// 
//   ODataResponse proceed() throws Exception;
// }
// 
// Path: janos-core/src/main/java/org/apache/olingo/odata2/janos/processor/core/ODataProcessor.java
// public interface ODataProcessor extends MetadataProcessor, ServiceDocumentProcessor, EntityProcessor, EntitySetProcessor,
//     EntityComplexPropertyProcessor, EntityLinkProcessor, EntityLinksProcessor, EntityMediaProcessor, EntitySimplePropertyProcessor,
//     EntitySimplePropertyValueProcessor, FunctionImportProcessor, FunctionImportValueProcessor, BatchProcessor, CustomContentType {
// }


import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.processor.ODataContext;
import org.apache.olingo.odata2.api.processor.ODataResponse;
import org.apache.olingo.odata2.api.processor.feature.ODataProcessorFeature;
import org.apache.olingo.odata2.api.uri.UriInfo;
import org.apache.olingo.odata2.janos.processor.api.extension.Extension;
import org.apache.olingo.odata2.janos.processor.api.extension.ExtensionContext;
import org.apache.olingo.odata2.janos.processor.core.ODataProcessor;
import org.omg.CORBA.portable.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
      return ext.process(this);
    }
    return handler.process();
  }

  private Extension.Method mapMethod(String httpMethod) {
    switch (httpMethod) {
      case "GET": return Extension.Method.GET;
      case "POST": return Extension.Method.POST;
      case "PUT": return Extension.Method.PUT;
      case "DELETE": return Extension.Method.DELETE;
    }
    throw new RuntimeException("Not mappable/supported HTTP method: " + httpMethod);
  }

  /**
   * Proceed (process) to wrapped processor instance
   *
   * @return
   * @throws Exception
   */
  public ODataResponse proceed() throws Exception {
    Object o = this.handler.process();
    if(o instanceof ODataResponse) {
      return (ODataResponse) o;
    }
    // TODO: change with 'better/concrete' exception
    throw new RuntimeException("Could not cast to ODataResponse");
  }

// Path: janos-api/src/main/java/org/apache/olingo/odata2/janos/processor/api/extension/ExtensionContext.java
// public interface ExtensionContext {
//   String PARA_URI_INFO = "~uriinfo";
//   String PARA_ACCEPT_HEADER = "~acceptheader";
//   String PARA_REQUEST_BODY = "~requestbody";
//   String PARA_REQUEST_TYPE = "~requesttype";
// 
//   ExtensionContext addParameter(String name, Object value);
// 
//   Object getParameter(String name);
// 
//   UriInfo getUriInfo();
// 
//   String getAcceptHeader();
// 
//   InputStream getRequestBody();
// 
//   Extension.Method getRequestType();
// 
//   ODataResponse proceed() throws Exception;
// }
// 
// Path: janos-core/src/main/java/org/apache/olingo/odata2/janos/processor/core/ODataProcessor.java
// public interface ODataProcessor extends MetadataProcessor, ServiceDocumentProcessor, EntityProcessor, EntitySetProcessor,
//     EntityComplexPropertyProcessor, EntityLinkProcessor, EntityLinksProcessor, EntityMediaProcessor, EntitySimplePropertyProcessor,
//     EntitySimplePropertyValueProcessor, FunctionImportProcessor, FunctionImportValueProcessor, BatchProcessor, CustomContentType {
// }


// Path: janos-core/src/main/java/org/apache/olingo/odata2/janos/processor/core/extension/ExtensionProcessor.java
import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.processor.ODataContext;
import org.apache.olingo.odata2.api.processor.ODataResponse;
import org.apache.olingo.odata2.api.processor.feature.ODataProcessorFeature;
import org.apache.olingo.odata2.api.uri.UriInfo;
import org.apache.olingo.odata2.janos.processor.api.extension.Extension;
import org.apache.olingo.odata2.janos.processor.api.extension.ExtensionContext;
import org.apache.olingo.odata2.janos.processor.core.ODataProcessor;
import org.omg.CORBA.portable.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

      return ext.process(this);
    }
    return handler.process();
  }

  private Extension.Method mapMethod(String httpMethod) {
    switch (httpMethod) {
      case "GET": return Extension.Method.GET;
      case "POST": return Extension.Method.POST;
      case "PUT": return Extension.Method.PUT;
      case "DELETE": return Extension.Method.DELETE;
    }
    throw new RuntimeException("Not mappable/supported HTTP method: " + httpMethod);
  }

  /**
   * Proceed (process) to wrapped processor instance
   *
   * @return
   * @throws Exception
   */
  public ODataResponse proceed() throws Exception {
    Object o = this.handler.process();
    if(o instanceof ODataResponse) {
      return (ODataResponse) o;
    }
    // TODO: change with 'better/concrete' exception
    throw new RuntimeException("Could not cast to ODataResponse");
  }

  public ExtensionContext createContext() {