    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.TimedEventUtils.js
    //@include sol.common.ix.services.GetNamespacedConfigs.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.ix.services.GetNamespacedConfigs
    * @requires sol.common_monitoring.ix.TimedEventUtils
    *
    */
    sol.define("sol.common_monitoring.ix.functions.CreateTimedEvent", {
      extend: "sol.common.ix.FunctionBase",

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

      templatePaths: {
        createSord: "create.createSord.params",
        setValues: "create.setValues.params"
      },

      messages: {
        missingReferenceId: "sol.common_monitoring.error.message.missing_reference_id",
        missingCreate: "sol.common_monitoring.error.message.missing_create",
        missingSource: "sol.common_monitoring.error.message.missing_source",
        missingConfig: "sol.common_monitoring.error.message.missing_config",
        failedCreation: "sol.common_monitoring.error.message.failed_creation",
        missingSetValueRequest: "sol.common_monitoring.error.message.missing_setvaluerequest",
        success: "sol.common_monitoring.error.message.success"
      },

      requests: {
        create: {
          provider: "RF_sol_function_CreateSord",
          optimize: "createRequest",
          output: ["output"]
        },
        setValues: {
          provider: "RF_sol_function_Set",
          optimize: "updateRequest",
          output: ["output"]
        }
      },

      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;

        me.params = config;
        me.inject = me.inject || {};
        if (config.configName) {
          me.inject.create = { config: "config", prop: config.configName + ".create", template: false };
        }
        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);
        }
      },

      getTimedEvent: function (params) {
        var me = this;

        return me.utils.getTimedEventDirectly(params) || me.utils.getTimedEventFromId(params);
      },

      getSource: function (params) {
        var me = this;

        return me.utils.getSourceDirectly(params) || me.utils.getSourceFromSourceId(params);
      },

      getTimedEventConfig: function (params) {
        var me = this;

        return me.utils.getTimedEventConfigDirectly(params)
          || me.getTimedEventConfigByParams(params);
      },

      getTimedEventConfigByParams: function (params) {
        var me = this;

        return (params.configId && params.configNamespace)
          ? me.utils.getTimedEventConfigFromConfigs(
            me.utils.getAndCacheTimedEventConfigs(params, me.timedEventConfigs),
            params
          )
          : null;
      },

      getUpdateRequest: function (template, params) {
        var me = this,
            request;

        request = sol.common.ObjectUtils.clone(me.requests.setValues);

        request.params = me.getUpdateRequestParams(template, params);

        return request;
      },

      getUpdateRequestParams: function (template, params) {
        var me = this,
            requestParams;

        requestParams = me.renderUpdateRequestEntries(sol.common.ObjectUtils.clone(template), params);
        requestParams.entries = requestParams.entries.concat(me.createUpdateEntries(template));

        return requestParams;
      },

      renderUpdateRequestEntries: function (template, params) {
        var me = this;

        template.entries = (template.entries || [])
          .map(me.mapUpdateRequestEntries.bind(me, params));

        return me.utils.renderRequestParams(template, params);
      },

      mapUpdateRequestEntries: function (params, entry) {
        var me = this;

        if (entry.key == "TIMED_EVENT_DATE" && entry.type === "GRP") {
          return me.utils.setTimedEventDate(entry, params);
        }

        return entry;
      },

      createUpdateEntries: function (template) {
        var me = this;

        return me.utils.mapUpdateEntriesToKeys(template.entries || [], "UPDATE_");
      },

      getCreateRequest: function (template, params) {
        var me = this,
            request,
            requestParams;

        requestParams = me.utils.renderRequestParams(template, params);

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

        return request;
      },

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

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

        if (!params.referenceId) {
          return { message: me.messages.missingReferenceId, params: params };
        }

        if (!params.create) {
          return { message: me.messages.missingCreate, params: params };
        }

        params.source = me.getSource(params);
        if (!params.source) {
          return { message: me.messages.missingSource, params: params };
        }

        params.config = me.getTimedEventConfig(params);

        if (!params.config) {
          return { message: me.messages.missingConfig, params: params };
        }

        createRequest = me.getCreateRequest(sol.common.ObjectUtils.getProp(me, me.templatePaths.createSord), params);
        params.created = me.utils.optimizedExecute(me, createRequest);
        params.timedEvent = me.getTimedEvent({ id: (params.created || {}).objId });

        if (!params.timedEvent) {
          return { message: me.messages.failedCreation, params: params };
        }

        updateRequest = me.getUpdateRequest(sol.common.ObjectUtils.getProp(me, me.templatePaths.setValues), params);

        if (!updateRequest) {
          // TODO delete created timed event
          return { message: me.messages.missingSetValueRequest, params: params };
        }

        me.utils.optimizedExecute(me, updateRequest);

        return { message: me.messages.success, id: params.timedEvent.id };
      }
    });

    /**
    * @member sol.common_monitoring.ix.functions.CreateTimedEvent
    * @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.CreateTimedEvent", params).process();
    }

    /**
    * @member sol.common_monitoring.ix.functions.CreateTimedEvent
    * @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.CreateTimedEvent", params).process();
    }

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

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

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

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