/**
   * Parses restore definition
   *
   * @param source restore definition
   * @return this request
   */
  public RestoreSnapshotRequest source(Map source) {
    boolean ignoreUnavailable = IndicesOptions.lenient().ignoreUnavailable();
    boolean allowNoIndices = IndicesOptions.lenient().allowNoIndices();
    boolean expandWildcardsOpen = IndicesOptions.lenient().expandWildcardsOpen();
    boolean expandWildcardsClosed = IndicesOptions.lenient().expandWildcardsClosed();

    for (Map.Entry<String, Object> entry : ((Map<String, Object>) source).entrySet()) {
      String name = entry.getKey();
      if (name.equals("indices")) {
        if (entry.getValue() instanceof String) {
          indices(Strings.splitStringByCommaToArray((String) entry.getValue()));
        } else if (entry.getValue() instanceof ArrayList) {
          indices((ArrayList<String>) entry.getValue());
        } else {
          throw new ElasticSearchIllegalArgumentException(
              "malformed indices section, should be an array of strings");
        }
      } else if (name.equals("ignore_unavailable") || name.equals("ignoreUnavailable")) {
        assert entry.getValue() instanceof String;
        ignoreUnavailable = Boolean.valueOf(entry.getValue().toString());
      } else if (name.equals("allow_no_indices") || name.equals("allowNoIndices")) {
        assert entry.getValue() instanceof String;
        allowNoIndices = Boolean.valueOf(entry.getValue().toString());
      } else if (name.equals("expand_wildcards_open") || name.equals("expandWildcardsOpen")) {
        assert entry.getValue() instanceof String;
        expandWildcardsOpen = Boolean.valueOf(entry.getValue().toString());
      } else if (name.equals("expand_wildcards_closed") || name.equals("expandWildcardsClosed")) {
        assert entry.getValue() instanceof String;
        expandWildcardsClosed = Boolean.valueOf(entry.getValue().toString());
      } else if (name.equals("settings")) {
        if (!(entry.getValue() instanceof Map)) {
          throw new ElasticSearchIllegalArgumentException(
              "malformed settings section, should indices an inner object");
        }
        settings((Map<String, Object>) entry.getValue());
      } else if (name.equals("include_global_state")) {
        if (!(entry.getValue() instanceof Boolean)) {
          throw new ElasticSearchIllegalArgumentException(
              "malformed include_global_state, should be boolean");
        }
        includeGlobalState((Boolean) entry.getValue());
      } else if (name.equals("rename_pattern")) {
        if (entry.getValue() instanceof String) {
          renamePattern((String) entry.getValue());
        } else {
          throw new ElasticSearchIllegalArgumentException("malformed rename_pattern");
        }
      } else if (name.equals("rename_replacement")) {
        if (entry.getValue() instanceof String) {
          renameReplacement((String) entry.getValue());
        } else {
          throw new ElasticSearchIllegalArgumentException("malformed rename_replacement");
        }
      } else {
        throw new ElasticSearchIllegalArgumentException("Unknown parameter " + name);
      }
    }
    indicesOptions(
        IndicesOptions.fromOptions(
            ignoreUnavailable, allowNoIndices, expandWildcardsOpen, expandWildcardsClosed));
    return this;
  }