private void setPosition(
      ExtSensor positionSensor,
      final List<ExtDevice> devices,
      final int index,
      final String name,
      final int floors,
      final Polygon outline,
      final List<ExtSensor> sensors) {

    ExtDevice device = devices.get(index);
    LatLng latLng = device.<LatLng>get("latlng");

    // prepare request properties
    final Method method = RequestBuilder.POST;
    final UrlBuilder urlBuilder =
        new UrlBuilder()
            .setProtocol(CommonSenseClient.Urls.PROTOCOL)
            .setHost(CommonSenseClient.Urls.HOST);
    urlBuilder.setPath(Urls.PATH_SENSORS + "/" + positionSensor.getId() + "/data.json");
    final String url = urlBuilder.buildString();
    final String sessionId = SessionManager.getSessionId();

    String value =
        "{\\\"latitude\\\":"
            + latLng.getLatitude()
            + ",\\\"longitude\\\":"
            + latLng.getLongitude()
            + ",\\\"provider\\\":\\\"environment\\\"}";
    String body = "{\"data\":[";
    body +=
        "{\"value\":\""
            + value
            + "\",\"date\":"
            + NumberFormat.getFormat("#.#").format(System.currentTimeMillis() / 1000)
            + "}";
    body += "]}";

    // prepare request callback
    RequestCallback reqCallback =
        new RequestCallback() {

          @Override
          public void onError(Request request, Throwable exception) {
            LOG.warning("POST position onError callback: " + exception.getMessage());
            onSetPositionFailure();
          }

          @Override
          public void onResponseReceived(Request request, Response response) {
            LOG.finest("POST position response received: " + response.getStatusText());
            int statusCode = response.getStatusCode();
            if (Response.SC_CREATED == statusCode) {
              onSetPositionSuccess(
                  response.getText(), devices, index, name, floors, outline, sensors);
            } else {
              LOG.warning("POST position returned incorrect status: " + statusCode);
              onSetPositionFailure();
            }
          }
        };

    // send request
    try {
      RequestBuilder builder = new RequestBuilder(method, url);
      builder.setHeader("X-SESSION_ID", sessionId);
      builder.setHeader("Content-Type", "application/json");
      builder.sendRequest(body, reqCallback);
    } catch (Exception e) {
      LOG.warning("POST position request threw exception: " + e.getMessage());
      reqCallback.onError(null, e);
    }
  }
  private void addSensors(final ExtEnvironment environment, final List<ExtSensor> sensors) {

    if (false == sensors.isEmpty()) {

      // prepare body
      String sensorsArray = "[";
      for (ExtSensor sensor : sensors) {
        if (sensor.getAlias() == -1) {
          sensorsArray += "{\"id\":" + sensor.getId() + "},";
        }
      }
      sensorsArray = sensorsArray.substring(0, sensorsArray.length() - 1) + "]";
      String body = "{\"sensors\":" + sensorsArray + "}";

      // prepare request properties
      final Method method = RequestBuilder.POST;
      final UrlBuilder urlBuilder =
          new UrlBuilder()
              .setProtocol(CommonSenseClient.Urls.PROTOCOL)
              .setHost(CommonSenseClient.Urls.HOST);
      urlBuilder.setPath(Urls.PATH_ENVIRONMENTS + "/" + environment.getId() + "/sensors.json");
      final String url = urlBuilder.buildString();
      final String sessionId = SessionManager.getSessionId();

      // prepare request callback
      RequestCallback reqCallback =
          new RequestCallback() {

            @Override
            public void onError(Request request, Throwable exception) {
              LOG.warning("POST environment sensors onError callback: " + exception.getMessage());
              onAddSensorsFailure(environment);
            }

            @Override
            public void onResponseReceived(Request request, Response response) {
              LOG.finest("POST environment sensors response received: " + response.getStatusText());
              int statusCode = response.getStatusCode();
              if (Response.SC_CREATED == statusCode) {
                onAddSensorSuccess(environment, sensors);
              } else {
                LOG.warning("POST environment sensors returned incorrect status: " + statusCode);
                onAddSensorsFailure(environment);
              }
            }
          };

      // send request
      try {
        RequestBuilder builder = new RequestBuilder(method, url);
        builder.setHeader("X-SESSION_ID", sessionId);
        builder.setHeader("Content-Type", "application/json");
        builder.sendRequest(body, reqCallback);
      } catch (Exception e) {
        LOG.warning("POST environment sensors request threw exception: " + e.getMessage());
        reqCallback.onError(null, e);
      }

    } else {
      onCreateComplete();
    }
  }
  private void createEnvironment(
      String name, int floors, Polygon outline, final List<ExtSensor> sensors) {

    // create GPS outline String
    String gpsOutline = "";
    for (int i = 0; i < outline.getVertexCount(); i++) {
      LatLng vertex = outline.getVertex(i);
      gpsOutline += vertex.toUrlValue() + ";";
    }
    gpsOutline = gpsOutline.substring(0, gpsOutline.length() - 1);

    // create GPS position String
    String position = outline.getBounds().getCenter().toUrlValue();

    // prepare request properties
    final Method method = RequestBuilder.POST;
    final UrlBuilder urlBuilder =
        new UrlBuilder()
            .setProtocol(CommonSenseClient.Urls.PROTOCOL)
            .setHost(CommonSenseClient.Urls.HOST);
    urlBuilder.setPath(Urls.PATH_ENVIRONMENTS + ".json");
    final String url = urlBuilder.buildString();
    final String sessionId = SessionManager.getSessionId();

    String body = "{\"environment\":{";
    body += "\"" + ExtEnvironment.NAME + "\":\"" + name + "\",";
    body += "\"" + ExtEnvironment.FLOORS + "\":" + floors + ",";
    body += "\"" + ExtEnvironment.OUTLINE + "\":\"" + gpsOutline + "\",";
    body += "\"" + ExtEnvironment.POSITION + "\":\"" + position + "\"}";
    body += "}";

    // prepare request callback
    RequestCallback reqCallback =
        new RequestCallback() {

          @Override
          public void onError(Request request, Throwable exception) {
            LOG.warning("POST environments onError callback: " + exception.getMessage());
            onCreateEnvironmentFailure();
          }

          @Override
          public void onResponseReceived(Request request, Response response) {
            LOG.finest("POST environments response received: " + response.getStatusText());
            int statusCode = response.getStatusCode();
            if (Response.SC_CREATED == statusCode) {
              onCreateEnvironmentSuccess(response.getText(), sensors);
            } else {
              LOG.warning("POST environments returned incorrect status: " + statusCode);
              onCreateEnvironmentFailure();
            }
          }
        };

    // send request
    try {
      RequestBuilder builder = new RequestBuilder(method, url);
      builder.setHeader("X-SESSION_ID", sessionId);
      builder.setHeader("Content-Type", "application/json");
      builder.sendRequest(body, reqCallback);
    } catch (Exception e) {
      LOG.warning("POST environments request threw exception: " + e.getMessage());
      reqCallback.onError(null, e);
    }
  }
  private void createSensor(
      final List<ExtDevice> devices,
      final int index,
      final String name,
      final int floors,
      final Polygon outline,
      final List<ExtSensor> sensors) {

    // prepare body
    String dataStructure =
        "{\\\"latitude\\\":\\\"string\\\",\\\"longitude\\\":\\\"string\\\",\\\"altitude\\\":\\\"string\\\"}";
    String sensor = "{";
    sensor += "\"" + ExtSensor.NAME + "\":\"position\",";
    sensor += "\"" + ExtSensor.DISPLAY_NAME + "\":\"position\",";
    sensor += "\"" + ExtSensor.DESCRIPTION + "\":\"position\",";
    sensor += "\"" + ExtSensor.DATA_TYPE + "\":\"json\",";
    sensor += "\"" + ExtSensor.DATA_STRUCTURE + "\":\"" + dataStructure + "\"";
    sensor += "}";
    String body = "{\"sensor\":" + sensor + "}";

    // prepare request properties
    final Method method = RequestBuilder.POST;
    final UrlBuilder urlBuilder =
        new UrlBuilder()
            .setProtocol(CommonSenseClient.Urls.PROTOCOL)
            .setHost(CommonSenseClient.Urls.HOST);
    urlBuilder.setPath(Urls.PATH_SENSORS + ".json");
    final String url = urlBuilder.buildString();
    final String sessionId = SessionManager.getSessionId();

    // prepare request callback
    RequestCallback reqCallback =
        new RequestCallback() {

          @Override
          public void onError(Request request, Throwable exception) {
            LOG.warning("POST sensor onError callback: " + exception.getMessage());
            onCreateSensorFailure();
          }

          @Override
          public void onResponseReceived(Request request, Response response) {
            LOG.finest("POST sensor response received: " + response.getStatusText());
            int statusCode = response.getStatusCode();
            if (Response.SC_CREATED == statusCode) {
              onCreateSensorSuccess(
                  response.getText(), devices, index, name, floors, outline, sensors);
            } else {
              LOG.warning("POST sensor returned incorrect status: " + statusCode);
              onCreateSensorFailure();
            }
          }
        };

    // send request
    try {
      RequestBuilder builder = new RequestBuilder(method, url);
      builder.setHeader("X-SESSION_ID", sessionId);
      builder.setHeader("Content-Type", "application/json");
      builder.sendRequest(body, reqCallback);
    } catch (Exception e) {
      LOG.warning("POST sensor request threw exception: " + e.getMessage());
      reqCallback.onError(null, e);
    }
  }
  private void addSensorToDevice(
      final ExtSensor sensor,
      final List<ExtDevice> devices,
      final int index,
      final String name,
      final int floors,
      final Polygon outline,
      final List<ExtSensor> sensors) {

    ExtDevice device = devices.get(index);

    // prepare body
    String body = "{\"device\":{";
    body += "\"" + ExtDevice.ID + "\":\"" + device.getId() + "\",";
    body += "\"" + ExtDevice.TYPE + "\":\"" + device.getType() + "\",";
    body += "\"" + ExtDevice.UUID + "\":\"" + device.getUuid() + "\"}";
    body += "}";

    // prepare request properties
    final Method method = RequestBuilder.POST;
    final UrlBuilder urlBuilder =
        new UrlBuilder()
            .setProtocol(CommonSenseClient.Urls.PROTOCOL)
            .setHost(CommonSenseClient.Urls.HOST);
    urlBuilder.setPath(Urls.PATH_SENSORS + "/" + sensor.getId() + "/device.json");
    final String url = urlBuilder.buildString();
    final String sessionId = SessionManager.getSessionId();

    // prepare request callback
    RequestCallback reqCallback =
        new RequestCallback() {

          @Override
          public void onError(Request request, Throwable exception) {
            LOG.warning("POST sensor device onError callback: " + exception.getMessage());
            onSensorToDeviceFailure();
          }

          @Override
          public void onResponseReceived(Request request, Response response) {
            LOG.finest("POST sensor device response received: " + response.getStatusText());
            int statusCode = response.getStatusCode();
            if (Response.SC_CREATED == statusCode) {
              onSensorToDeviceSuccess(
                  response.getText(), sensor, devices, index, name, floors, outline, sensors);
            } else {
              LOG.warning("POST sensor device returned incorrect status: " + statusCode);
              onSensorToDeviceFailure();
            }
          }
        };

    // send request
    try {
      RequestBuilder builder = new RequestBuilder(method, url);
      builder.setHeader("X-SESSION_ID", sessionId);
      builder.setHeader("Content-Type", "application/json");
      builder.sendRequest(body, reqCallback);
    } catch (Exception e) {
      LOG.warning("POST sensor device request threw exception: " + e.getMessage());
      reqCallback.onError(null, e);
    }
  }