/**
   * Executes a query.
   *
   * @param command Name of the command to execute
   * @param parameters Parameters
   * @param manager Reference back to business layer
   * @return Parsed JSON object, empty object on error.
   */
  public JsonNode query(String command, JsonNode parameters, INotifiableManager manager) {
    URLConnection uc = null;
    try {
      final ObjectMapper mapper = Client.MAPPER;

      if (mUrlSuffix == null) {
        throw new NoSettingsException();
      }

      final URL url = new URL(mUrlSuffix + XBMC_JSONRPC_BOOTSTRAP);
      uc = url.openConnection();
      uc.setConnectTimeout(SOCKET_CONNECTION_TIMEOUT);
      uc.setReadTimeout(mSocketReadTimeout);
      if (authEncoded != null) {
        uc.setRequestProperty("Authorization", "Basic " + authEncoded);
      }
      uc.setRequestProperty("Content-Type", "application/json");
      uc.setDoOutput(true);

      final ObjectNode data = Client.obj().p("jsonrpc", "2.0").p("method", command).p("id", "1");
      if (parameters != null) {
        data.put("params", parameters);
      }

      final JsonFactory jsonFactory = new JsonFactory();
      final JsonGenerator jg =
          jsonFactory.createJsonGenerator(uc.getOutputStream(), JsonEncoding.UTF8);
      jg.setCodec(mapper);

      // POST data
      jg.writeTree(data);
      jg.flush();

      final JsonParser jp = jsonFactory.createJsonParser(uc.getInputStream());
      jp.setCodec(mapper);
      final JsonNode ret = jp.readValueAs(JsonNode.class);
      return ret;

    } catch (MalformedURLException e) {
      manager.onError(e);
    } catch (IOException e) {
      int responseCode = -1;
      try {
        responseCode = ((HttpURLConnection) uc).getResponseCode();
      } catch (IOException e1) {
      } // do nothing, getResponse code failed so treat as default i/o exception.
      if (uc != null && responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
        manager.onError(new HttpException(Integer.toString(HttpURLConnection.HTTP_UNAUTHORIZED)));
      } else {
        manager.onError(e);
      }
    } catch (NoSettingsException e) {
      manager.onError(e);
    }
    return new ObjectNode(null);
  }
 public JsonNode getJson(
     INotifiableManager manager, String method, JsonNode parameters, String resultField) {
   try {
     final JsonNode response = getJson(manager, method, parameters);
     final JsonNode result = response.get(resultField);
     if (result == null) {
       throw new Exception("Could not find field \"" + resultField + "\" as return value.");
     } else {
       return response.get(resultField);
     }
   } catch (Exception e) {
     manager.onError(e);
   }
   return Client.obj();
 }
 /**
  * Executes a JSON-RPC command and returns the result as JSON object.
  *
  * @param manager Upper layer reference for error posting
  * @param method Name of the method to run
  * @param parameters Parameters of the method
  * @return Result
  */
 public JsonNode getJson(INotifiableManager manager, String method, JsonNode parameters) {
   try {
     final JsonNode response = query(method, parameters, manager);
     final JsonNode result = response.get(RESULT_FIELD);
     if (result == null) {
       if (response.get(ERROR_FIELD) == null) {
         throw new Exception("Weird JSON response, could not parse error.");
       } else {
         throw new Exception(response.get(ERROR_FIELD).get("message").getTextValue());
       }
     } else {
       return response.get(RESULT_FIELD);
     }
   } catch (Exception e) {
     manager.onError(e);
   }
   return Client.obj();
 }