gt:       throw new OAuthException("Malformed URL", mue);
context: package oauthP5.oauth;
  
  import java.io.IOException;
  import java.io.UnsupportedEncodingException;
  import java.net.HttpURLConnection;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.nio.charset.Charset;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.concurrent.TimeUnit;
  
  /**
   * Represents an HTTP Request object
   * 
   * @author Pablo Fernandez
   */
  class Request
  {
    private static final String CONTENT_LENGTH = "Content-Length";
    private static final String CONTENT_TYPE = "Content-Type";
    public static final String DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded";
  
    private String url;
    private Verb verb;
    private ParameterList querystringParams;
    private ParameterList bodyParams;
    private Map<String, String> headers;
    private String payload = null;
    private HttpURLConnection connection;
    private String charset;
    private byte[] bytePayload = null;
    private boolean connectionKeepAlive = false;
    private Long connectTimeout = null;
    private Long readTimeout = null;
  
    /**
     * Creates a new Http Request
     * 
     * @param verb Http Verb (GET, POST, etc)
     * @param url url with optional querystring parameters.
     */
    public Request(Verb verb, String url)
    {
      this.verb = verb;
      this.url = url;
      this.querystringParams = new ParameterList();
      this.bodyParams = new ParameterList();
      this.headers = new HashMap<String, String>();
    }
  
    /**
     * Execute the request and return a {@link Response}
     * 
     * @return Http Response
     * @throws RuntimeException
     *           if the connection cannot be created.
     */
    public Response send()
    {
      try
      {
        createConnection();
        return doSend();
      }
      catch (Exception e)
      {
        throw new OAuthConnectionException(e);
      }
    }
  
    private void createConnection() throws IOException
    {
      String completeUrl = getCompleteUrl();
      if (connection == null)
      {
        System.setProperty("http.keepAlive", connectionKeepAlive ? "true" : "false");
        connection = (HttpURLConnection) new URL(completeUrl).openConnection();
      }
    }
  
    /**
     * Returns the complete url (host + resource + encoded querystring parameters).
     *
     * @return the complete url.
     */
    public String getCompleteUrl()
    {
      return querystringParams.appendTo(url);
    }
  
    Response doSend() throws IOException
    {
      connection.setRequestMethod(this.verb.name());
      if (connectTimeout != null) 
      {
        connection.setConnectTimeout(connectTimeout.intValue());
      }
      if (readTimeout != null)
      {
        connection.setReadTimeout(readTimeout.intValue());
      }
      addHeaders(connection);
      if (verb.equals(Verb.PUT) || verb.equals(Verb.POST))
      {
        addBody(connection, getByteBodyContents());
      }
      return new Response(connection);
    }
  
    void addHeaders(HttpURLConnection conn)
    {
      for (String key : headers.keySet())
        conn.setRequestProperty(key, headers.get(key));
    }
  
    void addBody(HttpURLConnection conn, byte[] content) throws IOException
    {
      conn.setRequestProperty(CONTENT_LENGTH, String.valueOf(content.length));
  
      // Set default content type if none is set.
      if (conn.getRequestProperty(CONTENT_TYPE) == null)
      {
        conn.setRequestProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
      }
      conn.setDoOutput(true);
      conn.getOutputStream().write(content);
    }
  
    /**
     * Add an HTTP Header to the Request
     * 
     * @param key the header name
     * @param value the header value
     */
    public void addHeader(String key, String value)
    {
      this.headers.put(key, value);
    }
  
    /**
     * Add a body Parameter (for POST/ PUT Requests)
     * 
     * @param key the parameter name
     * @param value the parameter value
     */
    public void addBodyParameter(String key, String value)
    {
      this.bodyParams.add(key, value);
    }
  
    /**
     * Add a QueryString parameter
     *
     * @param key the parameter name
     * @param value the parameter value
     */
    public void addQuerystringParameter(String key, String value)
    {
      this.querystringParams.add(key, value);
    }
  
    /**
     * Add body payload.
     * 
     * This method is used when the HTTP body is not a form-url-encoded string,
     * but another thing. Like for example XML.
     * 
     * Note: The contents are not part of the OAuth signature
     * 
     * @param payload the body of the request
     */
    public void addPayload(String payload)
    {
      this.payload = payload;
    }
  
    /**
     * Overloaded version for byte arrays
     *
     * @param payload
     */
    public void addPayload(byte[] payload)
    {
      this.bytePayload = payload;
    }
  
    /**
     * Get a {@link ParameterList} with the query string parameters.
     * 
     * @return a {@link ParameterList} containing the query string parameters.
     * @throws OAuthException if the request URL is not valid.
     */
    public ParameterList getQueryStringParams()
    {
      try
      {
        ParameterList result = new ParameterList();
        String queryString = new URL(url).getQuery();
        result.addQuerystring(queryString);
        result.addAll(querystringParams);
        return result;
      }
      catch (MalformedURLException mue)
      {
  