/** {@inheritDoc} */
  @Override
  public ServiceConfiguration fromJSON(JSONObject json) throws JSONException {
    ServiceConfiguration serviceConfiguration = new ServiceConfiguration();

    JsonObjectWrapper wrapper = JsonObjectWrapper.newInstance(json);

    serviceConfiguration.setEnsureRunning(wrapper.optBooleanNull(ENSURE_RUNNING));
    serviceConfiguration.setEnabled(wrapper.optBooleanNull(ENABLED));

    if (wrapper.has(FILES)) {
      JSONArray files = wrapper.getArray(FILES);
      for (int i = 0; i < files.length(); i++) {
        serviceConfiguration.getFiles().add(files.getString(i));
      }
    }

    if (wrapper.has(SOURCES)) {
      JSONArray sources = wrapper.getArray(SOURCES);
      for (int i = 0; i < sources.length(); i++) {
        serviceConfiguration.getSources().add(sources.getString(i));
      }
    }

    if (wrapper.has(COMMANDS)) {
      JSONArray commands = wrapper.getArray(COMMANDS);
      for (int i = 0; i < commands.length(); i++) {
        serviceConfiguration.getCommands().add(commands.getString(i));
      }
    }

    if (wrapper.has(PACKAGES)) {
      JsonObjectWrapper jsonPackagesWrapper = wrapper.getWrapper(PACKAGES);

      @SuppressWarnings("unchecked")
      Iterator<String> keysIterator = (Iterator<String>) jsonPackagesWrapper.toJsonObject().keys();
      while (keysIterator.hasNext()) {
        String packageManagerName = keysIterator.next();
        PackageDependenciesParser parser = new PackageDependenciesParser();
        PackageManagerName packageManagerKey = PackageManagerName.fromString(packageManagerName);

        if (packageManagerKey != null) {
          serviceConfiguration
              .getPackages()
              .put(
                  packageManagerKey,
                  parser.fromJSON(jsonPackagesWrapper.getArray(packageManagerKey)));
        } else {
          LOG.error(
              "Unknown package manager specified under config section: " + packageManagerName);
          throw new JSONException(
              "Unknown package manager specified under config section: " + packageManagerName);
        }
      }
    }

    return serviceConfiguration;
  }
  /** {@inheritDoc} */
  @Override
  public JSONObject fromPojo(ServiceConfiguration pojo) throws JSONException {
    JSONObject jsonObject = new JSONObject();

    if (pojo.getEnsureRunning() != null) {
      jsonObject.put(ENSURE_RUNNING.jsonKey(), pojo.getEnsureRunning().toString());
    }

    if (pojo.getEnabled() != null) {
      jsonObject.put(ENABLED.jsonKey(), pojo.getEnabled().toString());
    }

    if (!pojo.getFiles().isEmpty()) {
      JSONArray filesArray = new JSONArray(pojo.getFiles());
      jsonObject.put(FILES.jsonKey(), filesArray);
    }

    if (!pojo.getSources().isEmpty()) {
      JSONArray sourcesArray = new JSONArray(pojo.getSources());
      jsonObject.put(SOURCES.jsonKey(), sourcesArray);
    }

    if (!pojo.getCommands().isEmpty()) {
      JSONArray commandsArray = new JSONArray(pojo.getCommands());
      jsonObject.put(COMMANDS.jsonKey(), commandsArray);
    }

    if (!pojo.getPackages().isEmpty()) {
      JSONObject packageManagers = new JSONObject();

      for (Map.Entry<PackageManagerName, PackageDependencies> mapEntry :
          pojo.getPackages().entrySet()) {
        PackageManagerName packageManagerKey = mapEntry.getKey();
        PackageDependencies packageDependencies = mapEntry.getValue();

        PackageDependenciesParser parser = new PackageDependenciesParser();
        packageManagers.put(packageManagerKey.jsonKey(), parser.fromPojo(packageDependencies));
      }

      jsonObject.put(PACKAGES.jsonKey(), packageManagers);
    }

    return jsonObject;
  }