/**
   * This method return a SpaceResData created from input Hashtable structure of an xmlrpc
   * spaceReservation v2.1 call. SpaceResData can be used to invoke SpaceResevation Manager
   */
  public InputData convertToInputData(Map inputParam) {

    log.debug(
        "reserveSpaceConverter :Call received :Creation of SpaceResData = {}", inputParam.size());
    log.debug(
        "reserveSpaceConverter: Input Structure toString: {}",
        ParameterDisplayHelper.display(inputParam));

    String memberName = null;

    GridUserInterface guser = GridUserManager.decode(inputParam);

    memberName = new String("authorizationID");
    String authID = (String) inputParam.get(memberName);

    memberName = new String("userSpaceTokenDescription");
    String spaceAlias = (String) inputParam.get(memberName);
    if (spaceAlias == null) {
      spaceAlias = new String("");
    }

    TRetentionPolicyInfo retentionPolicyInfo =
        TRetentionPolicyInfo.decode(inputParam, TRetentionPolicyInfo.PNAME_retentionPolicyInfo);

    TSizeInBytes desiredSizeOfTotalSpace =
        TSizeInBytes.decode(inputParam, TSizeInBytes.PNAME_DESIREDSIZEOFTOTALSPACE);

    TSizeInBytes desiredSizeOfGuaranteedSpace =
        TSizeInBytes.decode(inputParam, TSizeInBytes.PNAME_DESIREDSIZEOFGUARANTEEDSPACE);

    ArrayOfTExtraInfo storageSystemInfo;
    try {
      storageSystemInfo =
          ArrayOfTExtraInfo.decode(inputParam, ArrayOfTExtraInfo.PNAME_STORAGESYSTEMINFO);
    } catch (InvalidArrayOfTExtraInfoAttributeException e) {
      storageSystemInfo = null;
    }

    ReserveSpaceInputData inputData;
    if (guser != null) {
      inputData =
          new IdentityReserveSpaceInputData(
              guser,
              spaceAlias,
              retentionPolicyInfo,
              desiredSizeOfTotalSpace,
              desiredSizeOfGuaranteedSpace,
              storageSystemInfo);
    } else {
      inputData =
          new AnonymousReserveSpaceInputData(
              spaceAlias,
              retentionPolicyInfo,
              desiredSizeOfTotalSpace,
              desiredSizeOfGuaranteedSpace,
              storageSystemInfo);
    }
    TLifeTimeInSeconds desiredLifetimeOfReservedSpace =
        TLifeTimeInSeconds.decode(
            inputParam, TLifeTimeInSeconds.PNAME_DESIREDLIFETIMEOFRESERVEDSPACE);
    if (desiredLifetimeOfReservedSpace != null && !desiredLifetimeOfReservedSpace.isEmpty()) {
      inputData.setSpaceLifetime(desiredLifetimeOfReservedSpace);
    }
    return inputData;
  }
  @Override
  public InputData convertToInputData(Map<String, Object> inputParam)
      throws IllegalArgumentException, StoRMXmlRpcException {

    TSURL surl = decodeSURL(inputParam);
    GridUserInterface user = decodeUser(inputParam);
    TURLPrefix transferProtocols = decodeTransferProtocols(inputParam);

    PrepareToPutInputData inputData;
    try {
      if (user != null) {
        inputData = new IdentityPrepareToPutInputData(user, surl, transferProtocols);
      } else {
        inputData = new AnonymousPrepareToPutInputData(surl, transferProtocols);
      }
    } catch (IllegalArgumentException e) {
      log.error(
          "Unable to build PrepareToPutInputData. IllegalArgumentException: {}", e.getMessage(), e);
      throw new StoRMXmlRpcException("Unable to build PrepareToPutInputData");
    }
    TLifeTimeInSeconds desiredFileLifetime =
        TLifeTimeInSeconds.decode(inputParam, TLifeTimeInSeconds.PNAME_FILELIFETIME);
    if (desiredFileLifetime != null && !desiredFileLifetime.isEmpty()) {
      inputData.setDesiredFileLifetime(desiredFileLifetime);
    }

    TLifeTimeInSeconds desiredPinLifetime = decodeDesiredPinLifetime(inputParam);
    if (desiredPinLifetime != null) {
      inputData.setDesiredPinLifetime(desiredPinLifetime);
    }
    TSpaceToken targetSpaceToken = decodeTargetSpaceToken(inputParam);
    if (targetSpaceToken != null) {
      inputData.setTargetSpaceToken(targetSpaceToken);
    }
    TSizeInBytes fileSize = TSizeInBytes.decode(inputParam, TSizeInBytes.PNAME_SIZE);
    if (fileSize != null) {
      inputData.setFileSize(fileSize);
    }

    String overwriteModeString = (String) inputParam.get(OVERWRITE_MODE_PARAMETER_NAME);
    if (overwriteModeString != null) {
      TOverwriteMode overwriteMode;
      try {
        overwriteMode = TOverwriteMode.getTOverwriteMode(overwriteModeString);
      } catch (IllegalArgumentException e) {
        log.error(
            "Unable to build TOverwriteMode from '{}'. IllegalArgumentException: {}",
            overwriteModeString,
            e.getMessage(),
            e);
        throw new StoRMXmlRpcException("Unable to build PrepareToPutInputData");
      }
      if (!overwriteMode.equals(TOverwriteMode.EMPTY)) {
        inputData.setOverwriteMode(overwriteMode);
      } else {
        log.warn(
            "Unable to use the received '{}', interpreted as an empty value",
            OVERWRITE_MODE_PARAMETER_NAME);
      }
    }
    log.debug("PrepareToPutInputData Created!");
    return inputData;
  }
  public Map convertFromOutputData(OutputData data) {

    log.debug("reserveSpaceConverter :Call received :Creation of XMLRPC Output Structure! ");

    // Creation of new Hashtable to return
    Map outputParam = new HashMap();

    ReserveSpaceOutputData outputData = (ReserveSpaceOutputData) data;

    /* (1) returnStatus */
    TReturnStatus returnStatus = outputData.getStatus();
    returnStatus.encode(outputParam, TReturnStatus.PNAME_RETURNSTATUS);

    /* (2) requestToken */
    /*
     * Actually we are not planning an asynchronous version of ReserveSpace (in
     * theory not needed for StoRM). Therefor this parameter is not set.
     */

    /* (3) estimatedProcessingTime */
    // TODO: in the future (actually the FE is predisposed to decode this value
    // as an int).

    /* (4) retentionPolocyInfo */
    TRetentionPolicyInfo retentionPolicyInfo = outputData.getRetentionPolicyInfo();
    if (retentionPolicyInfo != null) {
      retentionPolicyInfo.encode(outputParam, TRetentionPolicyInfo.PNAME_retentionPolicyInfo);
    }

    /* (5) sizeOfTotalReservedSpace */
    TSizeInBytes sizeOfTotalReservedSpace = outputData.getTotalSize();
    if (sizeOfTotalReservedSpace != null) {
      if (!(sizeOfTotalReservedSpace.isEmpty())) {
        sizeOfTotalReservedSpace.encode(outputParam, TSizeInBytes.PNAME_SIZEOFTOTALRESERVEDSPACE);
      }
    }

    /* (6) sizeOfGuaranteedReservedSpace */
    TSizeInBytes sizeOfGuaranteedReservedSpace = outputData.getGuaranteedSize();
    if (sizeOfGuaranteedReservedSpace != null) {
      if (!(sizeOfGuaranteedReservedSpace.isEmpty())) {
        sizeOfGuaranteedReservedSpace.encode(
            outputParam, TSizeInBytes.PNAME_SIZEOFGUARANTEEDRESERVEDSPACE);
      }
    }

    /* (7) lifetimeOfReservedSpace */
    TLifeTimeInSeconds lifetimeOfReservedSpace = outputData.getLifeTimeInSeconds();
    if (lifetimeOfReservedSpace != null) {
      if (!(lifetimeOfReservedSpace.isEmpty())) {
        lifetimeOfReservedSpace.encode(
            outputParam, TLifeTimeInSeconds.PNAME_LIFETIMEOFRESERVEDSPACE);
      }
    }

    /* (8) spaceToken */
    TSpaceToken spaceToken = outputData.getSpaceToken();
    if (spaceToken != null) {
      spaceToken.encode(outputParam, TSpaceToken.PNAME_SPACETOKEN);
    }

    log.debug(outputParam.toString());

    return outputParam;
  }