    importPackage(Packages.de.elo.ix.client);

    //@include lib_Class.js
    //@include lib_sol.common.DateUtils.js
    //@include lib_sol.common.ObjectUtils.js
    //@include lib_sol.common.ObjectFormatter.js
    //@include lib_sol.common.Injection.js
    //@include lib_sol.common.IxUtils.js
    //@include lib_sol.common.ix.FunctionBase.js
    //@include lib_sol.common.ix.RfUtils.js
    //@include lib_sol.common.RepoUtils.js
    //@include lib_sol.common.SordUtils.js
    //@include lib_sol.common.Template.js
    //@include lib_sol.common_monitoring.ix.MonitorUtils.js
    //@include sol.common.ix.services.GetNamespacedConfigs.js
    //@include lib_sol.common_monitoring.ix.TimedEventUtils.js
    //@include sol.common_monitoring.ix.services.SearchTimedEvents.js

    /**
    *
    * @author ELO Digital Office GmbH
    * @version 1.0
    *
    * @eloix
    *
    * @requires sol.common.DateUtils
    * @requires sol.common.ObjectUtils
    * @requires sol.common.ObjectFormatter
    * @requires sol.common.Injection
    * @requires sol.common.IxUtils
    * @requires sol.common.ix.FunctionBase
    * @requires sol.common.ix.RfUtils
    * @requires sol.common.RepoUtils
    * @requires sol.common.SordUtils
    * @requires sol.common.Template
    * @requires sol.common_monitoring.ix.MonitorUtils
    * @requires sol.common.ix.services.GetNamespacedConfigs
    * @requires sol.common_monitoring.ix.TimedEventUtils
    * @requires sol.common_monitoring.ix.services.SearchTimedEvents
    *
    */
    sol.define("sol.common_monitoring.ix.functions.UpsertTimedEvents", {
      extend: "sol.common.ix.FunctionBase",

      logger: sol.create("sol.Logger", { scope: "sol.common_monitoring.ix.functions.UpsertTimedEvents" }),
      utils: sol.create("sol.common_monitoring.ix.TimedEventUtils"),

      messages: {
        creationExecuted: "sol.common_monitoring.error.message.creation_executed", // "Timed event creation executed",
        updateExecuted: "sol.common_monitoring.error.message.update_executed" // "Timed event update(s) executed"
      },

      requests: {
        search: {
          provider: "RF_sol_common_monitoring_ix_service_SearchTimedEvents",
          optimize: "searchTimedEvents",
          output: ["output"]
        },
        create: {
          provider: "RF_sol_common_monitoring_ix_function_CreateTimedEvent",
          optimize: "createTimedEvent",
          output: ["output"]

        },
        update: {
          provider: "RF_sol_common_monitoring_ix_function_UpdateTimedEvent",
          optimize: "updateTimedEvent",
          output: ["output"]
        },
        callees: []
      },

      optimize: {},

      initialize: function (config) {
        var me = this;

        if (config) {
          me.setupConfig(config);
          me.setupInjection(config);
        }

        me.$super(me.extend, "initialize", [config]);

        me.messages = me.utils.translateMap(me.messages);
      },

      setupConfig: function (config) {
        var me = this;

        if (!config.sourceId && !config.source && config.objId) {
          config.sourceId = config.objId;
        }

        me.params = config;
        me.inject = me.inject || {};
        me.inject.params = { prop: "params" };
      },

      setupInjection: function (config) {
        var me = this,
            injections;

        injections = me.utils.getInjections(config);

        if (injections && injections.$configRelation && injections.inject) {
          me.$configRelation = sol.common.ObjectUtils.mergeObjects({}, [me.$configRelation || {}, injections.$configRelation], true);
          me.inject = sol.common.ObjectUtils.mergeObjects({}, [me.inject || {}, injections.inject], true);

          sol.create("sol.common.Injection").inject(me);
        }
      },

      process: function (_params) {
        var me = this,
            params,
            timedEventIds;

        params = sol.common.ObjectUtils.mergeObjects(params, [me.config || {}, me.params || {}, _params || {}]) || {};

        timedEventIds = me.searchTimedEvents(params);

        return me.isCreationRequest(params, timedEventIds)
          ? me.createTimedEventAndReturnMessage(params)
          : me.upsertTimedEventsAndReturnMessage(timedEventIds, params.additionalParams);
      },

      searchTimedEvents: function (params) {
        var me = this,
            searchParams,
            request;

        searchParams = sol.common.ObjectUtils.clone(params);
        searchParams.configPath = params.searchConfigPath || params.configPath;
        searchParams.configName = params.searchConfigName || params.configName;

        request = sol.common.ObjectUtils.clone(me.requests.search);
        request.params = searchParams;

        return me.utils.optimizedExecute(me, request) || [];
      },

      isCreationRequest: function (params, timedEventIds) {
        return params.referenceId && timedEventIds.length == 0;
      },

      createTimedEvent: function (params) {
        var me = this,
            createParams,
            request;

        createParams = sol.common.ObjectUtils.clone(params);
        createParams.configPath = params.createConfigPath || params.configPath;
        createParams.configName = params.createConfigName || params.configName;

        request = sol.common.ObjectUtils.clone(me.requests.create);
        request.params = createParams;

        return me.utils.optimizedExecute(me, request);
      },

      updateTimedEvent: function (timedEventId, additionalParams) {
        var me = this,
            request;

        request = sol.common.ObjectUtils.clone(me.requests.update);
        request.params = {
          id: timedEventId,
          additionalParams: additionalParams
        };

        return me.utils.optimizedExecute(me, request);
      },

      createTimedEventAndReturnMessage: function (params) {
        var me = this;
        return {
          message: me.messages.creationExecuted,
          creationResponse: me.createTimedEvent(params)
        };
      },

      upsertTimedEventsAndReturnMessage: function (timedEventIds, additionalParams) {
        var me = this;

        sol.common.ObjectUtils.forEach(
          (timedEventIds || []),
          function (timedEventId) {
            me.updateTimedEvent(timedEventId, additionalParams);
          }
        );

        return { message: me.messages.updateExecuted };
      }
    });

    /**
    * @member sol.common_monitoring.ix.functions.UpsertTimedEvents
    * @static
    * @inheritdoc sol.common.ix.FunctionBase#onEnterNode
    */
    function onEnterNode(clInfo, userId, wfDiagram, nodeId) {
      var params;

      params = sol.common.WfUtils.parseAndCheckParams(wfDiagram, nodeId);
      params.objId = wfDiagram.objId;
      params.flowId = wfDiagram.id;

      sol.create("sol.common_monitoring.ix.functions.UpsertTimedEvents", params).process();
    }

    /**
    * @member sol.common_monitoring.ix.functions.UpsertTimedEvents
    * @static
    * @inheritdoc sol.common.ix.FunctionBase#onExitNode
    */
    function onExitNode(clInfo, userId, wfDiagram, nodeId) {
      var params;

      params = sol.common.WfUtils.parseAndCheckParams(wfDiagram, nodeId);
      params.objId = wfDiagram.objId;
      params.flowId = wfDiagram.id;

      sol.create("sol.common_monitoring.ix.functions.UpsertTimedEvents", params).process();
    }

    /**
    * @member sol.common_monitoring.ix.functions.UpsertTimedEvents
    * @method RF_sol_common_monitoring_ix_function_UpsertTimedEvents
    * @static
    * @inheritdoc sol.common.ix.FunctionBase#RF_FunctionName
    */
    function RF_sol_common_monitoring_ix_function_UpsertTimedEvents(iXSEContext, args) {
      var rfArgs, fun;

      rfArgs = sol.common.ix.RfUtils.parseAndCheckParams(iXSEContext, arguments.callee.name, args);

      fun = sol.create("sol.common_monitoring.ix.functions.UpsertTimedEvents", rfArgs);

      return JSON.stringify(fun.process());
    }