///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// Copyright (c) 2000-2019 Ericsson Telecom AB                               //
//                                                                           //
// All rights reserved. This program and the accompanying materials          //
// are made available under the terms of the Eclipse Public License v2.0     //
// which accompanies this distribution, and is available at                  //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html                                 //
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
//  Module: EPTF_CLL_DsRestAPI_DSServer_Functions
//
//  Purpose:
//    This module contains functions of EPTF_CLL_DsRestAPI_DSServer.
//
//  Module depends on:
//    <EPTF_CLL_Variable_Definitions>
//    <EPTF_CLL_DataSource_Definitions>
//    <EPTF_CLL_DataSource_Functions>
//    <EPTF_CLL_Logging_Functions>
//    <EPTF_CLL_Variable_Functions>
//    <EPTF_CLL_Base_Functions>
//    <EPTF_CLL_DsRestAPI_DSServer_Definitions>
//    <TCCConversion_Functions>
//    <EPTF_CLL_Common_Definitions>
//
//  Current Owner:
//    Tamas Kis (ekistam)
//
//  Last Review Date:
//    -
//
//  Detailed Comments:
//    This module contains the interface functions for the EPTF_CLL_DsRestAPI.
//    Public functions:
//      <f_EPTF_DsRestAPI_DSServer_init_CT>
//      <f_EPTF_DsRestAPI_DSServer_processJSONRequest>
//
///////////////////////////////////////////////////////////////
module EPTF_CLL_DsRestAPI_DSServer_Functions
{
  //=========================================================================
  // Import Part
  //=========================================================================
  import from EPTF_CLL_Variable_Definitions all;
  import from EPTF_CLL_DataSource_Definitions all;
  import from EPTF_CLL_DataSource_Functions all;
  import from EPTF_CLL_Variable_Functions all;
  import from EPTF_CLL_Base_Functions all;
  import from EPTF_CLL_DsRestAPI_DSServer_Definitions all;
  import from EPTF_CLL_DsRestAPI_Timeline_Definitions all;
  import from TCCConversion_Functions all;
  import from EPTF_CLL_Common_Definitions all;
  import from EPTF_CLL_FBQ_Functions all;
  import from EPTF_CLL_DsRestAPI_Filter_Definitions all;
  import from EPTF_CLL_DsRestAPI_Filter_Functions all;
  import from EPTF_CLL_DsRestAPI_Storage_Definitions all;
  import from EPTF_CLL_DsRestAPI_Storage_Functions all;

  friend module EPTF_CLL_DsRestAPI_Timeline_Functions;

  //=========================================================================
  // Functions
  //=========================================================================

  private external function ef_DsRestAPI_dec_Requests(in octetstring pl_par) return EPTF_DsRestAPI_RqWrapper with { extension "prototype(convert) decode(JSON)" }
  private external function ef_DsRestAPI_enc_ContentList(in EPTF_DsRestAPI_ContentAndChildrenListWrapper pl_par) return octetstring with { extension "prototype(convert) encode(JSON) errorbehavior(ALL:WARNING)" }

  /////////////////////////////////////////////////////////////////////////
  //  Function: f_EPTF_DsRestAPI_DSServer_init_CT
  //
  //  Purpose:
  //    Initialize the DataSource Server for DsRestAPI
  //
  //  Parameters:
  //    pl_selfName - *in* *charstring* - the name of the component
  //
  //  Return Value:
  //    -
  /////////////////////////////////////////////////////////////////////////
  public function f_EPTF_DsRestAPI_DSServer_init_CT(in charstring pl_selfName) runs on EPTF_DsRestAPI_DSServer_CT {
    if (not v_DsRestAPI_DSServer_initialized) {
      f_EPTF_Base_init_CT(pl_selfName);
      f_EPTF_Var_init_CT(pl_selfName);
      f_EPTF_DataSource_init_CT(pl_selfName);
      f_EPTF_DsRestAPI_Filter_init_CT(pl_selfName);
      f_EPTF_FBQ_init_CT(pl_selfName);

      f_EPTF_FBQ_initFreeBusyQueue(v_DsRestAPI_DSServer_requestQueue);
      f_EPTF_FBQ_initFreeBusyQueue(v_DsRestAPI_DSServer_responseQueue);

      var EPTF_DataSource_ValueType vl_tmp := intType; v_DsRestAPI_DSServer_intType := enum2int(vl_tmp) + 1;
      vl_tmp := floatType; v_DsRestAPI_DSServer_floatType := enum2int(vl_tmp) + 1;
      vl_tmp := boolType;  v_DsRestAPI_DSServer_boolType := enum2int(vl_tmp) + 1;
      vl_tmp := charstringType; v_DsRestAPI_DSServer_charstringType := enum2int(vl_tmp) + 1;
      vl_tmp := octetstringType; v_DsRestAPI_DSServer_octetstringType := enum2int(vl_tmp) + 1;
      vl_tmp := hexstringType; v_DsRestAPI_DSServer_hexstringType := enum2int(vl_tmp) + 1;
      vl_tmp := bitstringType; v_DsRestAPI_DSServer_bitstringType := enum2int(vl_tmp) + 1;
      vl_tmp := integerlistType; v_DsRestAPI_DSServer_integerlistType := enum2int(vl_tmp) + 1;
      vl_tmp := floatlistType; v_DsRestAPI_DSServer_floatlistType := enum2int(vl_tmp) + 1;
      vl_tmp := charstringlistType; v_DsRestAPI_DSServer_charstringlistType := enum2int(vl_tmp) + 1;
      vl_tmp := statusLEDType; v_DsRestAPI_DSServer_statusLEDType := enum2int(vl_tmp) + 1;

      f_EPTF_Base_registerCleanup(refers(f_EPTF_DsRestAPI_DSServer_cleanup_CT));
      v_DsRestAPI_DSServer_initialized := true;
    }
  }

  private function f_EPTF_DsRestAPI_DSServer_cleanup_CT() runs on EPTF_DsRestAPI_DSServer_CT {
    if (v_DsRestAPI_DSServer_initialized) {
      f_EPTF_FBQ_deleteFreeBusyQueue(v_DsRestAPI_DSServer_requestQueue);
      f_EPTF_FBQ_deleteFreeBusyQueue(v_DsRestAPI_DSServer_responseQueue);
      v_DsRestAPI_DSServer_requestHandlerDB := {};
      v_DsRestAPI_DSServer_responseHandlerDB := {};
      v_DsRestAPI_DSServer_filterItemsDB := {};
      v_DsRestAPI_DSServer_initialized := false;
    }
  }

  private function f_EPTF_DsRestAPI_DSServer_getContentTypeInteger(in EPTF_Var_DirectContent pl_Content) runs on EPTF_DsRestAPI_DSServer_CT return integer {
    var integer vl_Res := v_DsRestAPI_DSServer_charstringType;
    if (ischosen(pl_Content.intVal)) {
      vl_Res := v_DsRestAPI_DSServer_intType;
    } else if (ischosen(pl_Content.floatVal)) {
      vl_Res := v_DsRestAPI_DSServer_floatType;
    } else if (ischosen(pl_Content.boolVal)) {
      vl_Res := v_DsRestAPI_DSServer_boolType;
    } else if (ischosen(pl_Content.charstringVal)) {
      vl_Res := v_DsRestAPI_DSServer_charstringType;
    } else if (ischosen(pl_Content.octetstringVal)) {
      vl_Res := v_DsRestAPI_DSServer_octetstringType;
    } else if (ischosen(pl_Content.hexstringVal)) {
      vl_Res := v_DsRestAPI_DSServer_hexstringType;
    } else if (ischosen(pl_Content.bitstringVal)) {
      vl_Res := v_DsRestAPI_DSServer_bitstringType;
    } else if (ischosen(pl_Content.integerlistVal)) {
      vl_Res := v_DsRestAPI_DSServer_integerlistType;
    } else if (ischosen(pl_Content.floatlistVal)) {
      vl_Res := v_DsRestAPI_DSServer_floatlistType;
    } else if (ischosen(pl_Content.charstringlistVal)) {
      vl_Res := v_DsRestAPI_DSServer_charstringlistType;
    } else if (ischosen(pl_Content.statusLEDVal)) {
      vl_Res := v_DsRestAPI_DSServer_statusLEDType;
    } else if (ischosen(pl_Content.unknownVal)) {
      vl_Res := v_DsRestAPI_DSServer_noType;
    }
    return vl_Res;
  }

  private function f_EPTF_DsRestAPI_DSServer_processSetData(in EPTF_DsRestAPI_SetData pl_setData, out EPTF_Var_DirectContent pl_dataValue) runs on EPTF_DsRestAPI_DSServer_CT return integer {
    var integer vl_Ret := 0;
    var integer vl_dataType := pl_setData.tp;
    @try {
      if (vl_dataType == v_DsRestAPI_DSServer_intType) {
        pl_dataValue := {intVal := str2int(pl_setData.content)};
      }
      else if (vl_dataType == v_DsRestAPI_DSServer_floatType) {
        pl_dataValue := {floatVal := str2float(pl_setData.content)};
      }
      else if (vl_dataType == v_DsRestAPI_DSServer_boolType) {
        pl_dataValue := {boolVal := pl_setData.content == "true"};
      }
      else if (vl_dataType == v_DsRestAPI_DSServer_charstringType) {
        pl_dataValue := {charstringVal := pl_setData.content};
      }
      else if (vl_dataType == v_DsRestAPI_DSServer_octetstringType) {
        pl_dataValue := {octetstringVal := char2oct(pl_setData.content)};
      }
      else if (vl_dataType == v_DsRestAPI_DSServer_hexstringType) {
        pl_dataValue := {hexstringVal := str2hex(pl_setData.content)};
      }
      else if (vl_dataType == v_DsRestAPI_DSServer_bitstringType) {
        pl_dataValue := {bitstringVal := str2bit(pl_setData.content)};
      }
      else if (vl_dataType == v_DsRestAPI_DSServer_integerlistType) {
        pl_dataValue := {integerlistVal := {str2int(pl_setData.content)}};
      }
      else if (vl_dataType == v_DsRestAPI_DSServer_floatlistType) {
        pl_dataValue := {floatlistVal := {str2float(pl_setData.content)}};
      }
      else if (vl_dataType == v_DsRestAPI_DSServer_charstringlistType) {
        pl_dataValue := {charstringlistVal := {pl_setData.content}};
      }
      else if (vl_dataType == v_DsRestAPI_DSServer_statusLEDType) {
        //TODO vl_dataValue := {statusLEDVal := {pl_setData.content}};
        pl_dataValue := {statusLEDVal := {led_black,""}};
        vl_Ret := f_EPTF_Var_str2directContent(pl_setData.content, pl_dataValue);
      } else {
        pl_dataValue := {charstringVal := "Invalid tp: " & int2str(vl_dataType)};
        vl_dataType := v_DsRestAPI_DSServer_charstringType;
        vl_Ret := 1;
      }
    } @catch(dte_str) {
      var charstring vl_searchStr := "Dynamic test case error:";
      var charstring vl_dteErrorMsg := "";
      var integer vl_strPos := f_strstr(dte_str, vl_searchStr);
      var integer vl_lenSearchStr := lengthof(vl_searchStr);
      if (vl_strPos != -1) {
        vl_dteErrorMsg := substr(dte_str, vl_strPos+vl_lenSearchStr+1, lengthof(dte_str)-vl_strPos-vl_lenSearchStr-1);
      } else {
        vl_dteErrorMsg := substr(dte_str, 0, lengthof(dte_str));
      }
      pl_dataValue := {charstringVal := "Cannot convert content: " & pl_setData.content & " to tp: " & int2str(vl_dataType) & ", Reason: " & vl_dteErrorMsg};
      vl_dataType := v_DsRestAPI_DSServer_charstringType;
      vl_Ret := 2;
    }

    return vl_Ret;
  }

  private function f_EPTF_DsRestAPI_DSServer_completeGetDataParams(inout EPTF_DsRestAPI_Request pl_request, in charstring pl_replaceTemplate, in charstring pl_replacement) {
    if (ischosen(pl_request.getData)) {
      if (not ispresent(pl_request.getData.ptcname)) {
        pl_request.getData.ptcname := "";
      }
      ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.getData.source, pl_replaceTemplate, pl_replacement);
      ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.getData.ptcname, pl_replaceTemplate, pl_replacement);
      ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.getData.element, pl_replaceTemplate, pl_replacement);
      if (ispresent(pl_request.getData.params)) {
        var integer vl_getDataParamsSize := sizeof(pl_request.getData.params);
        for (var integer vl_i := 0; vl_i < vl_getDataParamsSize; vl_i := vl_i + 1) {
          ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.getData.params[vl_i].paramValue, pl_replaceTemplate, pl_replacement);
        }
      }
      if (ispresent(pl_request.getData.filter) and ischosen(pl_request.getData.filter.dataValue)) {
        ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.getData.filter.dataValue, pl_replaceTemplate, pl_replacement);
      }
    } else if (ischosen(pl_request.setData)) {
      if (not ispresent(pl_request.setData.ptcname)) {
        pl_request.setData.ptcname := "";
      }
      ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.setData.source, pl_replaceTemplate, pl_replacement);
      ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.setData.ptcname, pl_replaceTemplate, pl_replacement);
      ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.setData.element, pl_replaceTemplate, pl_replacement);
      ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.setData.content, pl_replaceTemplate, pl_replacement);
      if (ispresent(pl_request.setData.params)) {
        var integer vl_setDataParamsSize := sizeof(pl_request.setData.params);
        for (var integer vl_i := 0; vl_i < vl_setDataParamsSize; vl_i := vl_i + 1) {
          ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.setData.params[vl_i].paramValue, pl_replaceTemplate, pl_replacement);
        }
      }
    }
  }

  private function f_EPTF_DsRestAPI_DSServer_createIsWritableRequest(in EPTF_DsRestAPI_Request pl_request) return EPTF_DsRestAPI_Request {
    var EPTF_DsRestAPI_Request vl_request := {
      getData := {
        source := c_EPTF_DataSource_sourceId,
        ptcname := omit,
        element := c_EPTF_DataSource_dataElement_isWritable,
        params := {},
        cookie := omit,
        children := omit,
        filter := omit,
        rangeFilter := omit,
        selection := omit,
        selectionValues := omit,
        writableInfo := omit,
        timeline := omit
      }
    }

    var integer vl_paramIndex := 0;
    // source
    vl_request.getData.params[vl_paramIndex] := {
      paramName := c_EPTF_DataSource_paramNameSource,
      paramValue := pl_request.getData.source
    }
    // element
    vl_paramIndex := vl_paramIndex + 1;
    vl_request.getData.params[vl_paramIndex] := {
      paramName := c_EPTF_DataSource_paramNameElement,
      paramValue := pl_request.getData.element
    }
    // ptcname
    if (ispresent(pl_request.getData.ptcname)) {
      vl_paramIndex := vl_paramIndex + 1;
      vl_request.getData.params[vl_paramIndex] := {
        paramName := c_EPTF_DataSource_paramNamePTCName,
        paramValue := pl_request.getData.ptcname
      }
    }
    // params
    if (ispresent(pl_request.getData.params)) {
      var integer vl_paramsSize := sizeof(pl_request.getData.params);
      for (var integer i := 0; i < vl_paramsSize; i := i + 1) {
        vl_paramIndex := vl_paramIndex + 1;
        vl_request.getData.params[vl_paramIndex] := {
          paramName := c_EPTF_DataSource_paramNameParamName,
          paramValue := pl_request.getData.params[i].paramName
        }
        vl_paramIndex := vl_paramIndex + 1;
        vl_request.getData.params[vl_paramIndex] := {
          paramName := c_EPTF_DataSource_paramNameParamValue,
          paramValue := pl_request.getData.params[i].paramValue
        }
      }
    }

    return vl_request;
  }

  private function f_EPTF_DsRestAPI_DSServer_createITimelineRequest(inout EPTF_DsRestAPI_GetData pl_request) {
    var EPTF_DsRestAPI_GetData vl_request := {
      source := c_DsRestAPI_Timeline_DataSource_sourceId,
      ptcname := omit,
      element := c_DsRestAPI_Timeline_dataElementTimeline,
      params := {},
      cookie := omit,
      children := omit,
      filter := omit,
      rangeFilter := omit,
      selection := omit,
      selectionValues := omit,
      writableInfo := omit,
      timeline := omit
    }

    var integer vl_paramIndex := 0;
    if (ispresent(pl_request.timeline.period)) {
      vl_request.params[vl_paramIndex] := {
        paramName := c_DsRestAPI_Timeline_paramNamePeriod,
        paramValue := float2str(pl_request.timeline.period)
      }
      vl_paramIndex := vl_paramIndex + 1;
    }
    if (ispresent(pl_request.timeline.maxpoints)) {
      vl_request.params[vl_paramIndex] := {
        paramName := c_DsRestAPI_Timeline_paramNameMaxpoints,
        paramValue := int2str(pl_request.timeline.maxpoints)
      }
      vl_paramIndex := vl_paramIndex + 1;
    }
    if (ispresent(pl_request.timeline.since)) {
      vl_request.params[vl_paramIndex] := {
        paramName := c_DsRestAPI_Timeline_paramNameSince,
        paramValue := int2str(pl_request.timeline.since)
      }
      vl_paramIndex := vl_paramIndex + 1;
    }
    // source
    vl_request.params[vl_paramIndex] := {
      paramName := c_EPTF_DataSource_paramNameSource,
      paramValue := pl_request.source
    }
    // element
    vl_paramIndex := vl_paramIndex + 1;
    vl_request.params[vl_paramIndex] := {
      paramName := c_EPTF_DataSource_paramNameElement,
      paramValue := pl_request.element
    }
    // ptcname
    if (ispresent(pl_request.ptcname)) {
      vl_paramIndex := vl_paramIndex + 1;
      vl_request.params[vl_paramIndex] := {
        paramName := c_EPTF_DataSource_paramNamePTCName,
        paramValue := pl_request.ptcname
      }
    }
    // params
    if (ispresent(pl_request.params)) {
      var integer vl_paramsSize := sizeof(pl_request.params);
      for (var integer i := 0; i < vl_paramsSize; i := i + 1) {
        vl_paramIndex := vl_paramIndex + 1;
        vl_request.params[vl_paramIndex] := {
          paramName := c_EPTF_DataSource_paramNameParamName,
          paramValue := pl_request.params[i].paramName
        }
        vl_paramIndex := vl_paramIndex + 1;
        vl_request.params[vl_paramIndex] := {
          paramName := c_EPTF_DataSource_paramNameParamValue,
          paramValue := pl_request.params[i].paramValue
        }
      }
    }

    pl_request := vl_request;
  }

  private function f_EPTF_DsRestAPI_DSServer_completeGetDataParameters(inout EPTF_DsRestAPI_Request pl_request, in EPTF_CharstringList pl_parentList, in EPTF_IntegerList pl_parentIndexList) {
    var integer vl_parentListLength := sizeof(pl_parentList);
    for (var integer i := 0; i < vl_parentListLength; i := i + 1) {
      var charstring vl_parentN := "%Parent" & int2str(i) & "%";
      var charstring vl_parentIdxN := "%Parent" & int2str(i) & "::idx%";
      f_EPTF_DsRestAPI_DSServer_completeGetDataParams(pl_request, vl_parentIdxN, int2str(pl_parentIndexList[i]));
      f_EPTF_DsRestAPI_DSServer_completeGetDataParams(pl_request, vl_parentN, pl_parentList[i]);
    }
  }

  private function f_EPTF_DsRestAPI_DSServer_getListLength(in EPTF_Var_DirectContent pl_Content) return integer {
    var integer vl_nrGetDataInList := -1;
    if (ischosen(pl_Content.charstringlistVal)) {
      vl_nrGetDataInList := sizeof(pl_Content.charstringlistVal);
    } else if (ischosen(pl_Content.floatlistVal)) {
      vl_nrGetDataInList := sizeof(pl_Content.floatlistVal);
    } else if (ischosen(pl_Content.integerlistVal)) {
      vl_nrGetDataInList := sizeof(pl_Content.integerlistVal);
    }
    return vl_nrGetDataInList;
  }

  friend function f_EPTF_DsRestAPI_DSServer_getContentFromDataValue(in EPTF_Var_DirectContent pl_dataValue) runs on EPTF_DsRestAPI_DSServer_CT return EPTF_DsRestAPI_Content {
    var EPTF_DsRestAPI_Content vl_content;
    var integer vl_listLen := f_EPTF_DsRestAPI_DSServer_getListLength(pl_dataValue);
    if (vl_listLen != -1) {
      vl_content.list := {};
      for (var integer vl_i := 0; vl_i < vl_listLen; vl_i := vl_i + 1) {
        if (ischosen(pl_dataValue.charstringlistVal)) {
          vl_content.list[vl_i].node.val := pl_dataValue.charstringlistVal[vl_i];
          vl_content.list[vl_i].node.tp := v_DsRestAPI_DSServer_charstringlistType;
        } else if (ischosen(pl_dataValue.floatlistVal)) {
          vl_content.list[vl_i].node.val := log2str(pl_dataValue.floatlistVal[vl_i]);
          vl_content.list[vl_i].node.tp := v_DsRestAPI_DSServer_floatlistType;
        } else if (ischosen(pl_dataValue.integerlistVal)) {
          vl_content.list[vl_i].node.val := log2str(pl_dataValue.integerlistVal[vl_i]);
          vl_content.list[vl_i].node.tp := v_DsRestAPI_DSServer_integerlistType;
        }
        vl_content.list[vl_i].node.childVals := omit;
      }
    } else {
      vl_content.node.tp := f_EPTF_DsRestAPI_DSServer_getContentTypeInteger(pl_dataValue);
      if (vl_content.node.tp == 0) {
        vl_content.node.val := "";
      } else {
        vl_content.node.val := f_EPTF_Var_directContent2str(pl_dataValue);
      }
      vl_content.node.childVals := omit;
    }
    return vl_content;
  }

  /////////////////////////////////////////////////////////////////////////
  //  Function: f_EPTF_DsRestAPI_DSServer_sendChildRequests
  //
  //  Purpose:
  //    Sends the child requests.
  //
  //  Parameters:
  //    pl_id - *in* *integer* -
  //      Index into requestHandlerDB.
  //    pl_request - *in* *EPTF_DsRestAPI_Request* -
  //      The request whose writable info is needed.
  //    pl_parentList - *in* *EPTF_CharstringList* -
  //      The list of parent responses so we can fill out the %ParentX% parts of the filter.
  //    pl_parentIndexList - *in* *EPTF_IntegerList* -
  //      The list of parent indexes so we can fill out the %ParentX::idx% parts of the filter.
  //    pl_path - *in* *EPTF_IntegerList* -
  //      The request path so we can locate the request in the request tree.
  //      This is extended by the index of the sent child request.
  //    pl_indexesInList - *in* *EPTF_IntegerList* -
  //      The response list indexes which can be used together with pl_path in find the response.
  //
  //  Return Value:
  //    -
  //
  //  Detailed Comments:
  //    For every child of the request we fill in the %ParentX% and %ParentX:idx% parts and send it.
  /////////////////////////////////////////////////////////////////////////
  private function f_EPTF_DsRestAPI_DSServer_sendChildRequests(
    in integer pl_id,
    in EPTF_DsRestAPI_Request pl_request,
    in EPTF_CharstringList pl_parentList,
    in EPTF_IntegerList pl_parentIndexList,
    in EPTF_IntegerList pl_path,
    in EPTF_IntegerList pl_indexesInList
  ) runs on EPTF_DsRestAPI_DSServer_CT {
    var EPTF_DsRestAPI_Requests vl_children := pl_request.getData.children;
    var integer vl_pathIndex := sizeof(pl_path);
    var integer vl_childrenLength := sizeof(vl_children);
    for (var integer i := 0; i < vl_childrenLength; i := i + 1) {
      var EPTF_DsRestAPI_Request vl_request := vl_children[i];
      f_EPTF_DsRestAPI_DSServer_completeGetDataParameters(vl_request, pl_parentList, pl_parentIndexList);
      pl_path[vl_pathIndex] := i;

      var integer vl_transactionid := f_EPTF_FBQ_getOrCreateFreeSlot(v_DsRestAPI_DSServer_responseQueue);
      f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_DsRestAPI_DSServer_responseQueue);
      v_DsRestAPI_DSServer_responseHandlerDB[vl_transactionid] := {
        requestId := pl_id,
        path := pl_path,
        indexesInList := pl_indexesInList,
        writableInfo := false,
        checkPostFilter := true,
        parentList := pl_parentList,
        parentIndexList := pl_parentIndexList,
        storageKey := ""
      }

      f_EPTF_DsRestAPI_DSServer_handleRequest(vl_request, {vl_transactionid});
    }
  }

  /////////////////////////////////////////////////////////////////////////
  //  Function: f_EPTF_DsRestAPI_DSServer_sendIsWriteableRequest
  //
  //  Purpose:
  //    Prepares and sends child requests.
  //
  //  Parameters:
  //    pl_id - *in* *integer* -
  //      Index into requestHandlerDB.
  //    pl_request - *in* *EPTF_DsRestAPI_Request* -
  //      The request whose writable info is needed.
  //    pl_content - *in* *EPTF_DsRestAPI_Content* -
  //      The response that was inserted and whose childVals we now try to obtain.
  //    pl_parentList - *in* *EPTF_CharstringList* -
  //      The list of parent responses so we can fill out the %ParentX% parts of the filter.
  //    pl_parentIndexList - *in* *EPTF_IntegerList* -
  //      The list of parent indexes so we can fill out the %ParentX::idx% parts of the filter.
  //    pl_path - *in* *EPTF_IntegerList* -
  //      The request path so we can locate the request in the request tree.
  //    pl_indexesInList - *in* *EPTF_IntegerList* -
  //      The response list indexes which can be used together with pl_path in find the response.
  //      If pl_content is a list, a new index will be added to this.
  //
  //  Return Value:
  //    -
  //
  //  Detailed Comments:
  //    We send the child requests for the node or every element of a list taking into account the selection and selectionValues if either of them is present.
  /////////////////////////////////////////////////////////////////////////
  private function f_EPTF_DsRestAPI_DSServer_prepareAndSendChildRequests(
    in integer pl_id,
    in EPTF_DsRestAPI_Request pl_request,
    in EPTF_DsRestAPI_Content pl_content,
    in EPTF_CharstringList pl_parentList,
    in EPTF_IntegerList pl_parentIndexList,
    in EPTF_IntegerList pl_path,
    in EPTF_IntegerList pl_indexesInList
  ) runs on EPTF_DsRestAPI_DSServer_CT {
    var integer vl_parentListIndex := sizeof(pl_parentList);
    var integer vl_indexesInListIndex := sizeof(pl_indexesInList);
    if (ischosen(pl_content.node)) {
      pl_parentList[vl_parentListIndex] := pl_content.node.val;
      pl_parentIndexList[vl_parentListIndex] := 0;
      f_EPTF_DsRestAPI_DSServer_sendChildRequests(pl_id, pl_request, pl_parentList, pl_parentIndexList, pl_path, pl_indexesInList);
    } else if (ischosen(pl_content.list)) {
      var integer vl_listLength := sizeof(pl_content.list);
      if (ispresent(pl_request.getData.selection)) {
        if (ispresent(pl_request.getData.selectionValues)) {
          pl_request.getData.selection := {0};
        }
        var integer vl_selectionlength := sizeof(pl_request.getData.selection);
        for (var integer i := 0; i < vl_selectionlength; i := i + 1) {
          var integer vl_index := pl_request.getData.selection[i];
          if (vl_index < vl_listLength) {
            pl_parentList[vl_parentListIndex] := pl_content.list[vl_index].node.val;
            pl_parentIndexList[vl_parentListIndex] := vl_index;
            pl_indexesInList[vl_indexesInListIndex] := vl_index;
            f_EPTF_DsRestAPI_DSServer_sendChildRequests(pl_id, pl_request, pl_parentList, pl_parentIndexList, pl_path, pl_indexesInList);
          }
        }
      } else {
        for (var integer i := 0; i < vl_listLength; i := i + 1) {
          pl_parentList[vl_parentListIndex] := pl_content.list[i].node.val;
          pl_parentIndexList[vl_parentListIndex] := i;
          pl_indexesInList[vl_indexesInListIndex] := i;
          f_EPTF_DsRestAPI_DSServer_sendChildRequests(pl_id, pl_request, pl_parentList, pl_parentIndexList, pl_path, pl_indexesInList);
        }
      }
    }
  }

  private function f_EPTF_DsRestAPI_DSServer_sendIsWriteableRequest(
    in integer pl_id,
    in EPTF_DsRestAPI_Request pl_request,
    in EPTF_CharstringList pl_parentList,
    in EPTF_IntegerList pl_parentIndexList,
    in EPTF_IntegerList pl_path,
    in EPTF_IntegerList pl_indexesInList
  ) runs on EPTF_DsRestAPI_DSServer_CT {

    var EPTF_DsRestAPI_Request vl_request := pl_request;
    f_EPTF_DsRestAPI_DSServer_completeGetDataParameters(vl_request, pl_parentList, pl_parentIndexList);
    vl_request := f_EPTF_DsRestAPI_DSServer_createIsWritableRequest(vl_request);
    var integer vl_transactionid := f_EPTF_FBQ_getOrCreateFreeSlot(v_DsRestAPI_DSServer_responseQueue);
    f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_DsRestAPI_DSServer_responseQueue);
    v_DsRestAPI_DSServer_responseHandlerDB[vl_transactionid] := {
      requestId := pl_id,
      path := pl_path,
      indexesInList := pl_indexesInList,
      writableInfo := true,
      checkPostFilter := false,
      parentList := pl_parentList,
      parentIndexList := pl_parentIndexList,
      storageKey := ""
    }

    f_EPTF_DsRestAPI_DSServer_handleRequest(vl_request, {vl_transactionid});
  }

  /////////////////////////////////////////////////////////////////////////
  //  Function: f_EPTF_DsRestAPI_DSServer_sendPostFilter
  //
  //  Purpose:
  //    Sends the post filter to be evaluated.
  //
  //  Parameters:
  //    pl_transactionid - *in* *integer* -
  //      Index into responseHandlerDB
  //    pl_errorCode - *in* *integer* -
  //      The error code
  //    pl_parentList - *in* *EPTF_CharstringList* -
  //      The list of parent responses so we can fill out the %ParentX% parts of the filter.
  //    pl_parentIndexList - *in* *EPTF_IntegerList* -
  //      The list of parent indexes so we can fill out the %ParentX::idx% parts of the filter.
  //    pl_contentToInsert - *in* *EPTF_DsRestAPI_Content* -
  //      The response to filter and isert later.
  //    pl_filter - *in* *EPTF_DsRestAPI_Filter* -
  //      The filter to be evaluated
  //
  //  Return Value:
  //    -
  //
  //  Detailed Comments:
  //    We create an entry in filterItemsDB with pl_transactionid index that contains a counter of how many elements are in the response and the response to filter and insert.
  /////////////////////////////////////////////////////////////////////////
  private function f_EPTF_DsRestAPI_DSServer_sendPostFilter(in integer pl_transactionid, in integer pl_errorCode, in EPTF_CharstringList pl_parentList, in EPTF_IntegerList pl_parentIndexList, in EPTF_DsRestAPI_Content pl_contentToInsert, in EPTF_DsRestAPI_Filter pl_filter) runs on EPTF_DsRestAPI_DSServer_CT {
    var integer vl_counter;
    if (ischosen(pl_contentToInsert.node)) {
      vl_counter := 1
    } else /*if (ischosen(pl_contentToInsert.list))*/ {
      vl_counter := sizeof(pl_contentToInsert.list);
    }
    v_DsRestAPI_DSServer_filterItemsDB[pl_transactionid] := {postFilterItem := {
      errorCode := pl_errorCode,
      contentToInsert := pl_contentToInsert,
      counter := vl_counter
    }};

    var integer vl_nextParent := sizeof(pl_parentList);
    if (ischosen(pl_contentToInsert.node)) {
      pl_parentList[vl_nextParent] := pl_contentToInsert.node.val;
      pl_parentIndexList[vl_nextParent] := 0;
      v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_transactionid].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_transactionid].requestId].outstandingRequests + 1;
      f_EPTF_DsRestAPI_Filter_evaluateFilter({{pl_transactionid}, pl_filter, refers(f_EPTF_DsRestAPI_DSServer_postFilterEvaluated), v_DsRestAPI_DSServer_responseHandlerDB[pl_transactionid].requestId}, pl_parentList, pl_parentIndexList);
    } else /*if (ischosen(pl_contentToInsert.list))*/ {
      for (var integer i := 0; i < vl_counter; i := i + 1) {
        pl_parentList[vl_nextParent] := pl_contentToInsert.list[i].node.val;
        pl_parentIndexList[vl_nextParent] := i;
        v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_transactionid].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_transactionid].requestId].outstandingRequests + 1;
        f_EPTF_DsRestAPI_Filter_evaluateFilter({{pl_transactionid, i}, pl_filter, refers(f_EPTF_DsRestAPI_DSServer_postFilterEvaluated), v_DsRestAPI_DSServer_responseHandlerDB[pl_transactionid].requestId}, pl_parentList, pl_parentIndexList);
      }
    }
  }

  /////////////////////////////////////////////////////////////////////////
  //  Function: f_EPTF_DsRestAPI_DSServer_insertResponseIntoTreeAndSendChildRequests
  //
  //  Purpose:
  //    Inserts the response into the response tree and sends the child requests.
  //
  //  Parameters:
  //    pl_transactionid - *in* *integer* -
  //      Index into responseHandlerDB
  //    pl_errorCode - *in* *integer* -
  //      The error code
  //    pl_requests - *in* *EPTF_DsRestAPI_Requests* -
  //      The list of requests which will contain the sent request.
  //    pl_contentList - *inout* *EPTF_DsRestAPI_ContentList* -
  //      The content list of responses into which the response will be inserted.
  //    pl_contentToInsert - *in* *EPTF_DsRestAPI_Content* -
  //      The response to insert.
  //    pl_responseData - *in* *EPTF_DsRestAPI_ResponseHandlerItem* -
  //      responseHandlerDB[pl_transactionid]
  //    pl_nextPathIndex - *in* *integer* -
  //      The next index into pl_responseData.path for the recursion
  //    pl_nextIndexesInListIndex - *in* *integer* -
  //      The next index into a response list for the recursion
  //
  //  Return Value:
  //    -
  //
  //  Detailed Comments:
  //    We first recursively find the request and the response list where it should be inserted.
  //    During the recursion we fill up the parentList and parentIndexList which are later used to complate %ParentX% and %ParentX::idx% parts of child requests.
  //    Then we handle the insertion:
  //      - It might be a writable info response, in which case we modify the tp of an already existing response.
  //      - If we have to apply a postfilter we do so here without inserting the response (it will be inserted after the postfitler is evaluated)
  //      - Or we insert the response and
  //        - If we need writable request we send it.
  //        - Send the child requests
  /////////////////////////////////////////////////////////////////////////
  private function f_EPTF_DsRestAPI_DSServer_insertResponseIntoTreeAndSendChildRequests(
    in integer pl_transactionid,
    in integer pl_errorCode,
    in EPTF_DsRestAPI_Requests pl_requests,
    inout EPTF_DsRestAPI_ContentList pl_contentList,
    in EPTF_DsRestAPI_Content pl_contentToInsert,
    in EPTF_DsRestAPI_ResponseHandlerItem pl_responseData,
    in integer pl_nextPathIndex,
    in integer pl_nextIndexesInListIndex
  ) runs on EPTF_DsRestAPI_DSServer_CT {
    if (pl_nextPathIndex < sizeof(pl_responseData.path) - 1) {
      // we must still go down in the tree
      if (ischosen(pl_contentList[pl_responseData.path[pl_nextPathIndex]].node)) {
        pl_responseData.parentList[sizeof(pl_responseData.parentList)] := pl_contentList[pl_responseData.path[pl_nextPathIndex]].node.val;
        pl_responseData.parentIndexList[sizeof(pl_responseData.parentIndexList)] := 0;
        if (not ispresent(pl_contentList[pl_responseData.path[pl_nextPathIndex]].node.childVals)) {
          pl_contentList[pl_responseData.path[pl_nextPathIndex]].node.childVals := {};
        }
        f_EPTF_DsRestAPI_DSServer_insertResponseIntoTreeAndSendChildRequests(
          pl_transactionid,
          pl_errorCode,
          pl_requests[pl_responseData.path[pl_nextPathIndex]].getData.children,
          pl_contentList[pl_responseData.path[pl_nextPathIndex]].node.childVals,
          pl_contentToInsert,
          pl_responseData,
          pl_nextPathIndex + 1,
          pl_nextIndexesInListIndex
        );
      } else if (ischosen(pl_contentList[pl_responseData.path[pl_nextPathIndex]].list)) {
        pl_responseData.parentList[sizeof(pl_responseData.parentList)] := pl_contentList[pl_responseData.path[pl_nextPathIndex]].list[pl_responseData.indexesInList[pl_nextIndexesInListIndex]].node.val;
        pl_responseData.parentIndexList[sizeof(pl_responseData.parentIndexList)] := pl_responseData.indexesInList[pl_nextIndexesInListIndex];
        if (not ispresent(pl_contentList[pl_responseData.path[pl_nextPathIndex]].list[pl_responseData.indexesInList[pl_nextIndexesInListIndex]].node.childVals)) {
          pl_contentList[pl_responseData.path[pl_nextPathIndex]].list[pl_responseData.indexesInList[pl_nextIndexesInListIndex]].node.childVals := {};
        }
        f_EPTF_DsRestAPI_DSServer_insertResponseIntoTreeAndSendChildRequests(
          pl_transactionid,
          pl_errorCode,
          pl_requests[pl_responseData.path[pl_nextPathIndex]].getData.children,
          pl_contentList[pl_responseData.path[pl_nextPathIndex]].list[pl_responseData.indexesInList[pl_nextIndexesInListIndex]].node.childVals,
          pl_contentToInsert,
          pl_responseData,
          pl_nextPathIndex + 1,
          pl_nextIndexesInListIndex + 1
        );
      }
    } else {
      // we are at the bottom of the tree, we can insert the response
      if (pl_responseData.writableInfo and isbound(pl_contentList[pl_responseData.path[pl_nextPathIndex]])) {
        // if it was a writeable request we modify the tp if necessary
        if (pl_contentToInsert.node.val == "false") {
          pl_contentList[pl_responseData.path[pl_nextPathIndex]].node.tp := -1 * pl_contentList[pl_responseData.path[pl_nextPathIndex]].node.tp;
        }
        f_EPTF_FBQ_moveFromBusyToFreeTail(pl_transactionid, v_DsRestAPI_DSServer_responseQueue);
      } else {
        // else we insert the response and send its child requests if we do not filter it
        if (pl_responseData.path[pl_nextPathIndex] < sizeof(pl_requests)) {
          var EPTF_DsRestAPI_Request vl_request := pl_requests[pl_responseData.path[pl_nextPathIndex]];
          if (ischosen(vl_request.getData) and ispresent(vl_request.getData.filter) and pl_responseData.checkPostFilter and not ispresent(vl_request.getData.selectionValues) and (ischosen(pl_contentToInsert.node) or (ischosen(pl_contentToInsert.list) and sizeof(pl_contentToInsert.list) > 0))) {
            f_EPTF_DsRestAPI_DSServer_sendPostFilter(pl_transactionid, pl_errorCode, pl_responseData.parentList, pl_responseData.parentIndexList, pl_contentToInsert, vl_request.getData.filter);
          } else {
            pl_contentList[pl_responseData.path[pl_nextPathIndex]] := pl_contentToInsert;
            f_EPTF_FBQ_moveFromBusyToFreeTail(pl_transactionid, v_DsRestAPI_DSServer_responseQueue);
            // TODO cookie can be inserted here
            if (ischosen(pl_contentToInsert.list) or pl_contentToInsert.node.tp != 0) {
              if (ischosen(vl_request.getData) and ispresent(vl_request.getData.writableInfo)) {
                f_EPTF_DsRestAPI_DSServer_sendIsWriteableRequest(pl_responseData.requestId, vl_request, pl_responseData.parentList, pl_responseData.parentIndexList, pl_responseData.path, pl_responseData.indexesInList);
              }
              if (ischosen(vl_request.getData) and ispresent(vl_request.getData.children) and pl_errorCode == 0) {
                f_EPTF_DsRestAPI_DSServer_prepareAndSendChildRequests(pl_responseData.requestId, vl_request, pl_contentToInsert, pl_responseData.parentList, pl_responseData.parentIndexList, pl_responseData.path, pl_responseData.indexesInList);
              }
            }
          }
        }
      }
    }
  }

  /////////////////////////////////////////////////////////////////////////
  //  Function: f_EPTF_DsRestAPI_DSServer_responseArrived
  //
  //  Purpose:
  //    Handle the arrival of a response.
  //
  //  Parameters:
  //    pl_errorCode - *in* *integer* -
  //      The error code
  //    pl_dataValue - *in* *EPTF_Var_DirectContent* -
  //      The response obtained from DataSource.
  //    pl_userData - *in* *EPTF_IntegerList* -
  //      The userdata with the following elements:
  //        - 0: index into responseHandlerDB
  //
  //  Return Value:
  //    -
  //
  //  Detailed Comments:
  //    We store the response in the storage and try to insert the response into the response tree.
  /////////////////////////////////////////////////////////////////////////
  private function f_EPTF_DsRestAPI_DSServer_responseArrived(in integer pl_errorCode, in EPTF_Var_DirectContent pl_dataValue, in EPTF_IntegerList pl_userData) runs on EPTF_DsRestAPI_DSServer_CT {
    if (f_EPTF_DsRestAPI_DSServer_isOldResponse(pl_userData[0])) {
      return;
    }
    var EPTF_DsRestAPI_Content vl_contentToInsert := f_EPTF_DsRestAPI_DSServer_getContentFromDataValue(pl_dataValue);
    if (v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].storageKey != "") {
      f_EPTF_DsRestAPI_Storage_storeItem(v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId, v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].storageKey, pl_dataValue);
    }
    v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentList := {};
    v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentIndexList := {};
    f_EPTF_DsRestAPI_DSServer_insertResponseIntoTreeAndSendChildRequests(
      pl_userData[0],
      pl_errorCode,
      v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].requests,
      v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].responses,
      vl_contentToInsert,
      v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]],
      0,
      0);
    v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests -1;
  }

  /////////////////////////////////////////////////////////////////////////
  //  Function: f_EPTF_DsRestAPI_DSServer_handleGetDataRequest
  //
  //  Purpose:
  //    Handle a getData request whose %ParentX% parts are filled in.
  //
  //  Parameters:
  //    pl_request - *in* *EPTF_DsRestAPI_Request* -
  //      The request
  //    pl_userData - *in* *EPTF_IntegerList* -
  //      The userdata with the following elements:
  //        - 0: index into responseHandlerDB
  //
  //  Return Value:
  //    -
  //
  //  Detailed Comments:
  //    This function handles two things:
  //      - Handle prefilters:
  //        - Evaluate simple filters or send filter requests.
  //        - If filtering was handled and the request is not filterd, handle the request.
  //      - Handle the request:
  //        - If selectionValues is present, insert it into the response.
  //        - Else we handle the request by first checking if it is present in the storage or sending the request to the DataSource
  /////////////////////////////////////////////////////////////////////////
  private function f_EPTF_DsRestAPI_DSServer_handleGetDataRequest(in EPTF_DsRestAPI_GetData pl_getData, in EPTF_IntegerList pl_userData) runs on EPTF_DsRestAPI_DSServer_CT {
    if (ispresent(pl_getData.filter) and f_EPTF_DsRestAPI_Filter_isPreFilterAllowed(pl_getData.filter, sizeof(v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentList))) {
      if (ischosen(pl_getData.filter.dataValue)) {
        if (pl_getData.filter.dataValue != "true" and pl_getData.filter.dataValue != "false") {
          f_EPTF_DsRestAPI_Filter_warning("Root filter dataValue should be true or false, it is: " & pl_getData.filter.dataValue);
        }
        if (pl_getData.filter.dataValue != "true") {
          v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests + 1;
          v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].checkPostFilter := false;
          f_EPTF_DsRestAPI_DSServer_responseArrived(0, {unknownVal := {omit}}, pl_userData);
          return;
        }
      } else /*if (ischosen(pl_getData.filter.request))*/ {
        v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests + 1;
        v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]] := {preFilterItem := {requestToSend := pl_getData}};
        f_EPTF_DsRestAPI_Filter_evaluateFilter({pl_userData, pl_getData.filter, refers(f_EPTF_DsRestAPI_DSServer_preFilterEvaluated), v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId}, v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentList, v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentIndexList);
        return;
      }
      v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].checkPostFilter := false;
    }

    var integer vl_retVal := 0;

    v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests + 1;
    if (not ispresent(pl_getData.selectionValues)) {
      if (ispresent(pl_getData.timeline)) {
        f_EPTF_DsRestAPI_DSServer_createITimelineRequest(pl_getData);
      }

      if (not ispresent(pl_getData.params)) {
        pl_getData.params := {};
      }
      if (not ispresent(pl_getData.ptcname)) {
        pl_getData.ptcname := "";
      }
      var EPTF_DataSource_Filter vl_filter := {
        rangeFilter := pl_getData.rangeFilter
      };

      var charstring vl_keyOfStorage := f_EPTF_DsRestAPI_Storage_getKey(pl_getData.source, pl_getData.ptcname, pl_getData.element, pl_getData.params, vl_filter);
      var EPTF_CLL_DsRestAPI_Storage_Item vl_itemInStorage;
      if (f_EPTF_DsRestAPI_Storage_getStoredItem(v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId, vl_keyOfStorage, vl_itemInStorage)) {
        if (ischosen(vl_itemInStorage.content)) {
          f_EPTF_DsRestAPI_DSServer_responseArrived(vl_retVal, vl_itemInStorage.content, pl_userData);
        } else /*if (ischosen(vl_itemInStorage.preStoredItems))*/ {
          f_EPTF_DsRestAPI_Storage_addContentArrivedHandler(v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId, vl_keyOfStorage, {refers(f_EPTF_DsRestAPI_DSServer_responseArrived), pl_userData});
        }
      } else {
        v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].storageKey := vl_keyOfStorage;
        f_EPTF_DsRestAPI_Storage_preStoreItem(v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId, vl_keyOfStorage);
        vl_retVal := f_EPTF_DataSource_getDataValue_nonblocking(pl_getData.source, pl_getData.ptcname, pl_getData.element, pl_getData.params, vl_filter, {refers(f_EPTF_DsRestAPI_DSServer_responseArrived), pl_userData});
      }
    } else {
      var EPTF_Var_DirectContent vl_content;
      vl_content.charstringlistVal := pl_getData.selectionValues;
      pl_getData.selection := omit;
      f_EPTF_DsRestAPI_DSServer_responseArrived(vl_retVal, vl_content, pl_userData);
    }
  }

  private function f_EPTF_DsRestAPI_DSServer_handleSetDataRequest(in EPTF_DsRestAPI_SetData pl_setData, in EPTF_IntegerList pl_userData) runs on EPTF_DsRestAPI_DSServer_CT {
    var EPTF_Var_DirectContent vl_dataValue;

    if (not ispresent(pl_setData.ptcname)) {
      pl_setData.ptcname := "";
    }
    if (not ispresent(pl_setData.params)) {
      pl_setData.params := {};
    }
    if (not ispresent(pl_setData.indxsInList)) {
      pl_setData.indxsInList := {};
    }

    var integer vl_retVal := f_EPTF_DsRestAPI_DSServer_processSetData(pl_setData, vl_dataValue);
    v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests + 1;
    if (vl_retVal == 0) {
      vl_retVal := f_EPTF_DataSource_setDataValue_nonblocking(vl_dataValue, pl_setData.source, pl_setData.ptcname, pl_setData.element, pl_setData.params, pl_setData.indxsInList, {refers(f_EPTF_DsRestAPI_DSServer_responseArrived), pl_userData});
    } else {
      f_EPTF_DsRestAPI_DSServer_responseArrived(vl_retVal, vl_dataValue, pl_userData);
    }
  }

  private function f_EPTF_DsRestAPI_DSServer_handleRequest(in EPTF_DsRestAPI_Request pl_request, in EPTF_IntegerList pl_userData) runs on EPTF_DsRestAPI_DSServer_CT {
    if (v_DsRestAPI_DSServer_initialized) {
      if (ischosen(pl_request.getData)) {
        f_EPTF_DsRestAPI_DSServer_handleGetDataRequest(pl_request.getData, pl_userData);
      } else if (ischosen(pl_request.setData)) {
        f_EPTF_DsRestAPI_DSServer_handleSetDataRequest(pl_request.setData, pl_userData);
      }
    }
  }

  /////////////////////////////////////////////////////////////////////////
  //  Function: f_EPTF_DsRestAPI_DSServer_preFilterEvaluated
  //
  //  Purpose:
  //    Evaluate request after prefilter was evaluated.
  //
  //  Parameters:
  //    pl_isFilterTrue - *in* *boolean* -
  //      The result of the filter
  //    pl_userData - *in* *EPTF_IntegerList* -
  //      The userdata with the following elements:
  //        - 0: index into responseHandlerDB
  //
  //  Return Value:
  //    -
  //
  //  Detailed Comments:
  //    This function is called when a filter is evaluated without getting the response to the request which contains the filter (there is no reference to it in the filter; this is called a pre filter).
  //    The requestToSend is stored in v_DsRestAPI_DSServer_filterItemsDB.
  //    We reduce the filter of the request to a simple dataValue which will be evaluated by f_EPTF_DsRestAPI_DSServer_handleGetDataRequest.
  /////////////////////////////////////////////////////////////////////////
  private function f_EPTF_DsRestAPI_DSServer_preFilterEvaluated(in boolean pl_isFilterTrue, in EPTF_IntegerList pl_userData) runs on EPTF_DsRestAPI_DSServer_CT {
    if (f_EPTF_DsRestAPI_DSServer_isOldResponse(pl_userData[0])) {
      return;
    }
    v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests - 1;
    v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].checkPostFilter := false;
    v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].preFilterItem.requestToSend.filter.dataValue := ttcn2string(pl_isFilterTrue);
    f_EPTF_DsRestAPI_DSServer_handleGetDataRequest(v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].preFilterItem.requestToSend, pl_userData);
  }

  /////////////////////////////////////////////////////////////////////////
  //  Function: f_EPTF_DsRestAPI_DSServer_postFilterEvaluated
  //
  //  Purpose:
  //    Insert the response once the postfilter was evaluated for the node or every element in a response list.
  //
  //  Parameters:
  //    pl_isFilterTrue - *in* *boolean* -
  //      The result of the filter
  //    pl_userData - *in* *EPTF_IntegerList* -
  //      The userdata with the following elements:
  //        - 0: index into responseHandlerDB
  //        - 1: index into the response list if it is a list
  //
  //  Return Value:
  //    -
  //
  //  Detailed Comments:
  //    We keep a count of how many elements in the list was the filter evaluated for, and mark those which were filtered out.
  //    Once the counter reaches 0, we create a new list from the unfiltered items and insert it into the response tree.
  //    We use filterItemsDB to store the counter and the contentToInsert which is filtered.
  //    The same index is used in filterItemsDB and responseHandlerDB
  /////////////////////////////////////////////////////////////////////////
  private function f_EPTF_DsRestAPI_DSServer_postFilterEvaluated(in boolean pl_isFilterTrue, in EPTF_IntegerList pl_userData) runs on EPTF_DsRestAPI_DSServer_CT {
    if (f_EPTF_DsRestAPI_DSServer_isOldResponse(pl_userData[0])) {
      return;
    }
    v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests - 1;
    v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.counter := v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.counter - 1;
    if (not pl_isFilterTrue) {
      if (ischosen(v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.list)) {
        v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.list[pl_userData[1]].node.tp := cg_EPTF_DsRestAPI_DSServer_ConetentToBeDiscardedWhenFiltered;
      } else if (ischosen(v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.node)) {
        v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.node := {val := "", tp := 0};
      }
    }
    if (v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.counter <= 0) {
      var EPTF_DsRestAPI_Content vl_content;
      if (ischosen(v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.list)) {
        vl_content.list := {};
        var integer contentListSize := sizeof(v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.list);
        for (var integer i := 0; i < contentListSize; i := i + 1) {
          if (v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.list[i].node.tp != cg_EPTF_DsRestAPI_DSServer_ConetentToBeDiscardedWhenFiltered) {
            vl_content.list[sizeof(vl_content.list)] := v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.list[i];
          }
        }
      } else {
        vl_content := v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert;
      }

      v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].checkPostFilter := false;
      v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentList := {};
      v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentIndexList := {};
      f_EPTF_DsRestAPI_DSServer_insertResponseIntoTreeAndSendChildRequests(
        pl_userData[0],
        v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.errorCode,
        v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].requests,
        v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].responses,
        vl_content,
        v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]],
        0,
        0);
    }
  }

  /////////////////////////////////////////////////////////////////////////
  //  Function: f_EPTF_DsRestAPI_DSServer_isOldResponse
  //
  //  Purpose:
  //    Check if an id is outdated because of a timeout.
  //
  //  Parameters:
  //    pl_id - *in* *integer* -
  //      The request id used with requestHandlerDB
  //
  //  Return Value:
  //    boolean -
  //      Whether the id is outdated and no more processing should be done in connection with it.
  //
  //  Detailed Comments:
  //    When timeout occurs, the number of outstanding requests is multiplied by -1. If it is negative, we know it is outdated.
  //    When a request is outdated we free up its entry in v_DsRestAPI_DSServer_responseHandlerDB.
  //    In addition, the number of outstanding requests counter is incremented here if it is negative, so when all outstanding requests arrive, we can free up the entry in requestHandlerDB and the storage.
  /////////////////////////////////////////////////////////////////////////
  private function f_EPTF_DsRestAPI_DSServer_isOldResponse(in integer pl_id) runs on EPTF_DsRestAPI_DSServer_CT return boolean {
    var integer vl_requestId := v_DsRestAPI_DSServer_responseHandlerDB[pl_id].requestId;
    if (v_DsRestAPI_DSServer_requestHandlerDB[vl_requestId].outstandingRequests < 0) {
      f_EPTF_DsRestAPI_Filter_warning("Dropped response because of timeout for the request: " & v_DsRestAPI_DSServer_responseHandlerDB[pl_id].storageKey);
      f_EPTF_FBQ_moveFromBusyToFreeTail(pl_id, v_DsRestAPI_DSServer_responseQueue);
      v_DsRestAPI_DSServer_requestHandlerDB[vl_requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[vl_requestId].outstandingRequests + 1;
      if (v_DsRestAPI_DSServer_requestHandlerDB[vl_requestId].outstandingRequests == 0) {
        f_EPTF_FBQ_moveFromBusyToFreeTail(vl_requestId, v_DsRestAPI_DSServer_requestQueue);
        f_EPTF_DsRestAPI_Storage_deleteStorage(vl_requestId);
      }
      return true;
    } else {
      return false;
    }
  }

  /////////////////////////////////////////////////////////////////////////
  //  Function: f_EPTF_DsRestAPI_DSServer_processRequest
  //
  //  Purpose:
  //    TTCN API function of DsRestAPI, it can be used to process a request. The function is synchronous.
  //
  //  Parameters:
  //    pl_request - *in* *EPTF_DsRestAPI_Requests* -
  //      Accepts a request set organized in a tree.
  //      This request tree is built out of atomic getData or setData request elements, and their children,
  //      which are also getData or setData request elements.
  //      The child request's parameters could depend on the result of its parent requests.
  //
  //  Return Value:
  //    EPTF_DsRestAPI_ContentList -
  //      The result is an object, representing the response values, organized also in a tree.
  //      The structure of the result tree matches the structure of the request tree.
  //      The elements in the response tree are the resulted values of the getData and setData request elements
  //      located on the corresponding places of the request tree.
  //
  //  Detailed Comments:
  //    TTCN requests arrive here.
  //    We create an entry in requestHandlerDB which will store the request, the response and the number of outstanding requets towards the DataSource.
  //    For every request in the first level of the request tree, we create an entry in responseHandlerDB, which includes some important members:
  //      - requestId: the id of the large request used to insert responses and count outstanding requests
  //      - path: the index of the small request in the large request
  //      - indexesInList: this together with path helps to create an index into the response tree
  //      - writableInfo: whether we also check if the element is writable
  //      - checkPostFilter: this is set to false if the filter gets evaluated
  //      - parentList: the responses to the parent requests of this request used to fill in %ParentX%
  //      - parentIndexList: used to fill in %ParentX::idx%
  //      - storageKey: the hashmap key used for the storage
  //    Further entries are created when sending child requests or writable info requests.
  /////////////////////////////////////////////////////////////////////////
  public function f_EPTF_DsRestAPI_DSServer_processRequest(in EPTF_DsRestAPI_Requests pl_requests, in float pl_timeOut := 0.0) runs on EPTF_DsRestAPI_DSServer_CT return EPTF_DsRestAPI_ContentList {
    if (v_DsRestAPI_DSServer_initialized) {
      var integer vl_id := f_EPTF_FBQ_getOrCreateFreeSlot(v_DsRestAPI_DSServer_requestQueue);
      f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_DsRestAPI_DSServer_requestQueue);
      f_EPTF_DsRestAPI_Storage_newStorage(vl_id);

      v_DsRestAPI_DSServer_requestHandlerDB[vl_id] := {
        requests := pl_requests,
        responses := {},
        outstandingRequests := 0
      }

      var integer vl_requestsLength := sizeof(pl_requests);
      for (var integer i := 0; i < vl_requestsLength; i := i + 1) {
        var integer vl_transactionid := f_EPTF_FBQ_getOrCreateFreeSlot(v_DsRestAPI_DSServer_responseQueue);
        f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_DsRestAPI_DSServer_responseQueue);
        v_DsRestAPI_DSServer_responseHandlerDB[vl_transactionid] := {
          requestId := vl_id,
          path := {i},
          indexesInList := {},
          writableInfo := false,
          checkPostFilter := true,
          parentList := {},
          parentIndexList := {},
          storageKey := ""
        }

        f_EPTF_DsRestAPI_DSServer_handleRequest(pl_requests[i], {vl_transactionid});
      }

      timer T_dummy;
      timer T_max;
      T_dummy.start(0.0);
      
      if (pl_timeOut != 0.0) {
          T_max.start(pl_timeOut);
      }
      alt{
        [v_DsRestAPI_DSServer_requestHandlerDB[vl_id].outstandingRequests == 0] T_dummy.timeout {
          f_EPTF_FBQ_moveFromBusyToFreeTail(vl_id, v_DsRestAPI_DSServer_requestQueue);
          f_EPTF_DsRestAPI_Storage_deleteStorage(vl_id);
        }
        [] T_max.timeout {
          v_DsRestAPI_DSServer_requestHandlerDB[vl_id].responses := {
            {
              node := {
                val := "timeout",
                tp := 4
              }
            }
          };
          v_DsRestAPI_DSServer_requestHandlerDB[vl_id].requests := {};
          v_DsRestAPI_DSServer_requestHandlerDB[vl_id].outstandingRequests := -v_DsRestAPI_DSServer_requestHandlerDB[vl_id].outstandingRequests;
        }
      };

      return v_DsRestAPI_DSServer_requestHandlerDB[vl_id].responses;
    } else {
      return {};
    }
  }

  /////////////////////////////////////////////////////////////////////////
  //  Function: f_EPTF_DsRestAPI_DSServer_processJSONRequest
  //
  //  Purpose:
  //    TTCN API function of DsRestAPI, it can be used to process a JSON request. The function is synchronous.
  //    See *f_EPTF_DsRestAPI_DSServer_processRequest*
  //
  //  Parameters:
  //    pl_request - *in* *octetstring* - JSON encoded request. Octetstrings can be converted from chastrings via char2oct.
  //
  //  Return Value:
  //    octetstring - the result is also a JSON encoded object, representing the response values. Resulted octetstring can be converted to charstring via oct2char.
  //
  //  Detailed Comments:
  //    Encoded json requests arrive here from http server.
  //    We simply decode it and call f_EPTF_DsRestAPI_DSServer_processRequest.
  /////////////////////////////////////////////////////////////////////////
  public function f_EPTF_DsRestAPI_DSServer_processJSONRequest(in octetstring pl_request) runs on EPTF_DsRestAPI_DSServer_CT return octetstring {
    if (v_DsRestAPI_DSServer_initialized) {
      var octetstring vl_result := ''O;
      if (lengthof(pl_request) > 0) {
        @try {
          var EPTF_DsRestAPI_RqWrapper vl_requesWrapper := ef_DsRestAPI_dec_Requests(pl_request);
          var float vl_timeOut := 0.0;
          if (ispresent(vl_requesWrapper.timeOut)) {
              vl_timeOut := vl_requesWrapper.timeOut;
          }
          var EPTF_DsRestAPI_ContentList vl_response := f_EPTF_DsRestAPI_DSServer_processRequest(vl_requesWrapper.requests, vl_timeOut);
          vl_result := ef_DsRestAPI_enc_ContentList({vl_response});
        } @catch(dte_str) {
          var charstring vl_searchStr := "Dynamic test case error:";
          var charstring vl_dteErrorMsg := "";
          var integer vl_strPos := f_strstr(dte_str, vl_searchStr);
          var integer vl_lenSearchStr := lengthof(vl_searchStr);
          if (vl_strPos != -1) {
            vl_dteErrorMsg := substr(dte_str, vl_strPos+vl_lenSearchStr+1, lengthof(dte_str)-vl_strPos-vl_lenSearchStr-1);
          } else {
            vl_dteErrorMsg := substr(dte_str, 0, lengthof(dte_str)-1);
          }
          var EPTF_DsRestAPI_ContentAndChildrenListWrapper vl_InvalidRequest := cg_EPTF_DsRestAPI_DSServer_Error_InvalidRequest;
          vl_InvalidRequest.contentList[0].node.val := vl_InvalidRequest.contentList[0].node.val & ", Reason: " & vl_dteErrorMsg;
          vl_result := ef_DsRestAPI_enc_ContentList(vl_InvalidRequest);
          action("DTE", vl_dteErrorMsg);
        }
      }
      return vl_result;
    } else {
      return ef_DsRestAPI_enc_ContentList(cg_EPTF_DsRestAPI_DSServer_Error_Uninitialized);
    }
  }

} // ~ module EPTF_CLL_DsRestAPI_DSServer_Functions
