    importClass(Packages.de.elo.client.scripting.constants.CONSTANTS);

    //@include lib_handlebars.js
    //@include lib_Class.js
    //@include lib_sol.common.Config.js
    //@include lib_sol.common.Template.js
    //@include lib_sol.common.JsonUtils.js
    //@include lib_sol.common.IxUtils.js
    //@include lib_sol.common.RepoUtils.js
    //@include lib_sol.common.AsUtils.js
    //@include lib_sol.common.HttpUtils.js
    //@include lib_sol.common.ObjectUtils.js
    //@include lib_sol.common.jc.ClipboardUtils.js

    /**
     * This class provides helper functions for executing complex actions.
     *
     * @author PZ, ELO Digital Office GmbH
     * @version 1.0
     *
     * @elojc
     * @requires sol.common.Config
     * @requires sol.common.IxUtils
     * @requires sol.common.jc.ActionHandler
     */
    sol.define("sol.common.jc.ActionHelper", {
      singleton: true,

      initialize: function (config) {
        var me = this;
        me.$super("sol.Base", "initialize", [config]);
      },

      executeSimpleAction: function (objId, cfg) {
        var me = this,
            actionCfg = me.initActionCfg(objId);

        me.logger.info(["executing simple action on objId: {0}", objId], cfg);

        if (!cfg || !cfg.fct) {
          throw "executing simple action is missing mandatory config properties.";
        }

        me.handleExecuteAction(cfg, actionCfg);
      },

      /**
       * Helps in executing advanced actions that include precondition checks and
       * different object types.
       *
       * Advanced action configurations are handled in the following order:
       *
       * 1.  select types (optional)
       * 2.  check preconditions (type selection possible if returned by check) (optional)
       * 3.  select target (optional)
       * 4.  execute action (IX/ AS) (required)
       *
       * Please note that step 1 and 2 can be used for selecting types. If a special function
       * is used for type selection (Step 1), the user selection is overriden if a second
       * type selection is handled by step 2.
       *
       *     {
       *       preconditions: {
       *         fct: 'RF_sol_contact_service_CheckContactPreconditions',
       *       },
       *       fct: 'RF_sol_contact_action_CreateContact',
       *       cfgTemplate: '{
       *         "parentId": "{{objId}}",
       *         "contactType": "{{type.name}},
       *         "templateId": "{{type.objId}}
       *       }',
       *       locale: {
       *           errorDlgTitle: locale['sol.contact.client.contact.create.dialog.error.title'],
       *           typesDlgTitle: locale['sol.contact.client.contact.create.dialog.title'],
       *           typesDlgHeader: locale['sol.contact.client.contact.create.dialog.header'],
       *           typesDlgText: locale['sol.contact.client.contact.create.dialog.text'],
       *           typesDlgNoTypes: locale['sol.contact.client.contact.create.msg.notype'],
       *
       *           targetDlgTitle: locale['sol.contact.client.contact.create.dialog.title'],
       *           targetDlgHeader: locale['sol.contact.client.contact.create.dialog.header'],
       *           targetDlgText: locale['sol.contact.client.contact.create.dialog.text'],
       *       }
       *     }
       *
       * @param {String} objId Object ID
       * @param {Object} cfg Configuration
       */
      executeAdvancedAction: function (objId, cfg) {
        var me = this,
            actionCfg = me.initActionCfg(objId),
            checkResult, selectedType, selectedTarget;

        me.logger.info(["executing advanced action on objId: {0}", objId], cfg);

        if (!cfg || !cfg.fct || !cfg.cfgTemplate) {
          throw "executing advanced action is missing mandatory config properties.";
        }

        // handle type selection
        if (me.requiresTypeSelection(cfg)) {
          selectedType = me.handleTypeSelection(cfg, actionCfg);
          if (!selectedType) {
            return;
          }
          actionCfg.type = selectedType;
        }

        // handle prepare & preconditions
        if (me.requiresPrepare(cfg)) {
          checkResult = sol.common.IxUtils.execute(cfg.preconditions.fct, { targetId: objId });
          if (checkResult.valid !== true) {
            workspace.showAlertBox(cfg.locale.errorDlgTitle, checkResult.msg);
            return;
          }
        }

        if (checkResult) {
          if (checkResult.targetId && (checkResult.targetId != objId)) {
            me.logger.info(["changed objId by prepare: {0} -> {1}", objId, checkResult.targetId]);
            actionCfg.objId = checkResult.targetId;
          }
          if (checkResult.types) {
            actionCfg.type = me.handleTypeSelection(cfg, actionCfg, checkResult.types);
            if (!actionCfg.type) {
              return;
            }
          }
          actionCfg.preconditions = checkResult;
        }

        // handle target selection
        if (me.requiresTargetSelection(cfg)) {
          selectedTarget = me.handleTargetSelection(cfg);
          if (!selectedTarget) {
            return;
          }
          actionCfg.tree = selectedTarget;
        }

        // handle execution
        me.handleExecuteAction(cfg, actionCfg);

      },

      initActionCfg: function (objId) {
        var actionCfg = { objId: objId };
        return actionCfg;
      },

      getConfigObject: function (cfgTemplate, data) {
        var str = Handlebars.compile(cfgTemplate)(data);
        return JSON.parse(str);
      },

      requiresPrepare: function (cfg) {
        return cfg.preconditions && cfg.preconditions.fct;
      },

      requiresTypeSelection: function (cfg) {
        if (cfg.selectType && cfg.selectType.fct) {
          return true;
        }
        return false;
      },

      requiresTargetSelection: function (cfg) {
        return !!cfg.selectTree;
      },

      handleTypeSelection: function (cfg, actionCfg, types) {
        var me = this,
            typeServiceCfg, optionNames, optionDescriptions, icons, selected;

        if (!types) {
          typeServiceCfg = (cfg.selectType.cfgTemplate) ? me.getConfigObject(cfg.selectType.cfgTemplate, actionCfg) : {};
          types = sol.common.IxUtils.execute(cfg.selectType.fct, typeServiceCfg);
        }

        if (!types || (types.length === 0)) {
          workspace.setFeedbackMessage(cfg.locale.typesDlgNoTypes);
          return null;
        }

        if (types.length > 1) {
          optionNames = types.map(function (type) {
            return type.name;
          });
          optionDescriptions = types.map(function (type) {
            return type.desc || "";
          });
          icons = [];
          selected = workspace.showCommandLinkDialog(
            cfg.locale.typesDlgTitle,
            cfg.locale.typesDlgHeader,
            cfg.locale.typesDlgText,
            CONSTANTS.DIALOG_ICON.QUESTION,
            optionNames,
            optionDescriptions,
            icons);
        } else {
          selected = 1;
        }

        return (selected < 0) ? null : types[selected - 1];
      },

      handleTargetSelection: function (cfg) {
        var me = this,
            documentsSelectable = (cfg.selectTree.hasOwnProperty("document")) ? cfg.selectTree.document : true,
            folderSelectable = (cfg.selectTree.hasOwnProperty("folder")) ? cfg.selectTree.folder : true,
            showFavorites = (cfg.selectTree.hasOwnProperty("favorite")) ? cfg.selectTree.favorite : true,
            dlgRootId, config, selectedId, selectedElement;

        if (cfg.selectTree.root) {
          dlgRootId = ixConnect.ix().checkoutSord(cfg.selectTree.root, SordC.mbOnlyId, LockC.NO).id;
        } else if (cfg.selectTree.rootFromCfgFile && cfg.selectTree.rootFromCfgProperty) {
          config = sol.create("sol.common.Config", { compose: cfg.selectTree.rootFromCfgFile });
          dlgRootId = ixConnect.ix().checkoutSord(me.getConfigObject(cfg.selectTree.rootFromCfgProperty, config), SordC.mbOnlyId, LockC.NO).id;
        }

        if (!dlgRootId) {
          return null;
        }

        me.logger.info("action requires target selection. Using root: {0}", dlgRootId);

        selectedId = workspace.showTreeSelectDialog(
          cfg.locale.treeDlgTitle,
          cfg.locale.treeDlgHeader,
          dlgRootId, documentsSelectable, folderSelectable, showFavorites);

        if (selectedId > 0) {
          selectedElement = archive.getElement(selectedId);
          return { name: selectedElement.name + "", objId: selectedElement.id + "" };
        }

        return null;
      },

      prepareCfgObj: function (cfgTemplate, actionCfg) {
        var cfgObj, regex, objIdReplacement;

        cfgTemplate = cfgTemplate.replace(/\\{{/g, "{{");
        if (cfgTemplate.indexOf("\"{{objId}}\"") > -1) {
          regex = new RegExp("\"{{objId}}\"", "g");
          objIdReplacement = (actionCfg.objId) ? "\"" + actionCfg.objId + "\"" : null;
        } else {
          regex = new RegExp("{{objId}}", "g");
          objIdReplacement = (actionCfg.objId) ? actionCfg.objId : null;
        }
        cfgTemplate = cfgTemplate.replace(regex, objIdReplacement);

        cfgObj = cfgTemplate ? JSON.parse(cfgTemplate) : {};

        cfgObj.$templating = { $type: actionCfg.type, $tree: actionCfg.tree, $preconditions: actionCfg.preconditions };

        return cfgObj;
      },

      /**
       * Handles the final execution of the action.
       * @private
       * @param {Object} cfg Configuration
       * @param {Object} actionCfg Action configuration
       */
      handleExecuteAction: function (cfg, actionCfg) {
        var me = this, cfgObj;

        cfgObj = me.prepareCfgObj(cfg.cfgTemplate, actionCfg); // render objId and setup serverside templating data

        try {
          switch (cfg.type) {
            case "AS":
              sol.common.jc.ActionHandler.executeAS(cfg.solution, cfg.fct, cfgObj);
              break;
            default:
              sol.common.jc.ActionHandler.execute(cfg.fct, cfgObj);
          }
        } catch (ex) {
          me.logger.error(["Error executing action: '{0}'", cfg.fct], ex);
          workspace.showAlertBox("Error executing action", ex);
        }
      }

    });

    /**
     * This class provides utility functions to call IX or AS functions and handle the response in a standardized way.
     *
     * Following example shows executing an Index Server action.
     *
     *     sol.common.jc.ActionHandler.execute('RF_sol_pubsec_functions_CreateFile', {
     *         objId: '123'
     *       }, function ( result ) {
     *         // handle resultObj returned by the action
     *       });
     *
     * # Supported events
     *
     * - REFRESH
     * - GOTO
     * - DIALOG
     * - ERROR
     * - ACTION
     * - FEEDBACK
     *
     * # Conditional events
     * It is possible for actions to declare the events as conditional.
     * Therefor they have to declare a `ON` attribute (see {@link sol.common.ActionBase}).
     *
     * @author PZ, ELO Digital Office GmbH
     * @version 1.03.000
     *
     * @elojc
     * @requires sol.common.ObjectUtils
     * @requires sol.common.JsonUtils
     * @requires sol.common.IxUtils
     */
    sol.define("sol.common.jc.ActionHandler", {
      singleton: true,

      /**
       * Executes a IX registered function and handles the response in a standardized way.
       *
       * Depricated feature:
       * If special handling is needed a custom callback can be spezified as parameter.
       * This callback get's the result Object of the registered function as only parameter.
       *
       * @param {String} registeredFunctionName
       * @param {Object} params (optional) The configuration object which will be send to the registered function
       * @param {Function} callback (optional) Should not be used, due to client interoperability
       */
      execute: function (registeredFunctionName, params, callback) {
        var me = this,
            resultObj;

        workspace.setWaitCursor();
        try {
          resultObj = sol.common.IxUtils.execute(registeredFunctionName, params);

          if (callback && Object.prototype.toString.call(callback) === "[object Function]") {
            me.logger.warn("Use of 'callback' parameter is depricated and therefore not recommended.");
            callback.call(me, resultObj);
            workspace.setNormalCursor();
            return;
          }

          if (resultObj) {
            me.handleEvents(resultObj.events);
          }

        } catch (ex) {
          sol.common.jc.ClipboardUtils.setText(ex);
          me.logger.error(["Error calling RF '{0}'", registeredFunctionName], ex);
          throw ex;
        } finally {
          workspace.setNormalCursor();
        }
      },

      /**
       * Executes an ELOas ruleset and handles the response in a standardized way.
       *
       * If spezial handling is needed a custom callback can be spezified as parameter.
       * This callback get's the result Object of the registered function as only parameter.
       *
       * @param {String} solutionName Name used to determine the ELOas configuration (see {@link sol.common.Config#loadEloAsConfig loadEloAsConfig})
       * @param {String} ruleName Rule name
       * @param {Object} param2Obj (optional) The configuration object which will be send to the ELOas rule as PARAM2 (JSON String)
       * @param {Function} callback (optional) Should not be used anymore, due to client interoperability
       * @param {Boolean} async (optional) Not supported anymore, due to client interoperability
       */
      executeAS: function (solutionName, ruleName, param2Obj, callback, async) {
        var me = this,
            resultObj = {},
            language, result;

        workspace.setWaitCursor();
        try {
          language = ixConnect.loginResult.clientInfo.language + "";

          result = sol.common.IxUtils.execute("RF_sol_common_service_ExecuteAsAction", {
            solution: solutionName,
            action: ruleName,
            config: param2Obj,
            connParams: {
              language: language
            }
          });

          if (async) {
            workspace.setNormalCursor();
            return;
          }

          resultObj = {};
          if (result) {
            resultObj = JSON.parse(result.content);
          }

          if (callback && Object.prototype.toString.call(callback) === "[object Function]") {
            me.logger.warn("Use of 'callback' parameter is depricated and therefore not recommended.");
            callback.call(me, resultObj);
            workspace.setNormalCursor();
            return;
          }

          if (resultObj.events && (resultObj.events.length > 0)) {
            resultObj.events.forEach(function (event) {
              event.solutionName = solutionName;
              event.async = async;
            });
          }

          if (resultObj) {
            me.handleEvents(resultObj.events);
          }
        } catch (ex) {
          sol.common.jc.ClipboardUtils.setText(ex);
          me.logger.error(["Error calling ELOas direct rule '{0}'", ruleName], ex);
          throw ex;
        } finally {
          workspace.setNormalCursor();
        }
      },

      /**
       * @private
       * @param {Array} events
       */
      handleEvents: function (events) {
        var eventTypes = sol.common.IxUtils.CONST.EVENT_TYPES,
            eventChain;

        if (events) {
          eventChain = sol.create("sol.common.jc.ActionHandler.EventChain");
          events.forEach(function (event) {
            switch (event.ID) {
              case eventTypes.REFRESH:
                event.$handler = sol.create("sol.common.jc.ActionHandler.Refresh");
                break;
              case eventTypes.GOTO:
                event.$handler = sol.create("sol.common.jc.ActionHandler.Goto");
                break;
              case eventTypes.DIALOG:
                event.$handler = sol.create("sol.common.jc.ActionHandler.Dialog");
                break;
              case eventTypes.ERROR:
                event.$handler = sol.create("sol.common.jc.ActionHandler.Error");
                break;
              case eventTypes.ACTION:
                event.$handler = sol.create("sol.common.jc.ActionHandler.Action");
                break;
              case eventTypes.FEEDBACK:
                event.$handler = sol.create("sol.common.jc.ActionHandler.Feedback");
                break;
              default:
                break;
            }
            eventChain.add(event);
          });

          eventChain.chain();
        }
      }

    });

    /**
     * This class handles the asynchrous event handling for the JavaClient `sol.common.jc.ActionHandler`
     *
     * @author PZ, ELO Digital Office GmbH
     * @version 1.01.002
     *
     * @elojc
     * @requires sol.common.ObjectUtils
     * @requires sol.common.SordUtils
     * @requires sol.common.IxUtils
     */
    sol.define("sol.common.jc.ActionHandler.EventChain", {

      /**
       * @private
       * @property {Object[]} events The remaining event chain.
       */

      /**
       * @private
       * @property {Object} context The execution context.
       */

      initialize: function (config) {
        var me = this;
        me.$super("sol.Base", "initialize", [config]);
        me.events = [];
        me.context = { dirtySord: true, dirtyWfStatus: true };
      },

      /**
       * Adds an event to the event chain.
       * @param {Object} event
       */
      add: function (event) {
        var me = this;
        if (event) {
          me.events.push(event);
        }
      },

      /**
       * Retrieves the current active event.
       * @return {Object}
       */
      getCurrent: function () {
        var me = this;
        return me.current;
      },

      /**
       * Retrieves the context.
       * @return {Object}
       */
      getContext: function () {
        var me = this;
        return me.context;
      },

      /**
       * Handles the event chaining.
       * If the next event is executable, this will call it's handler (and the handler needs to take care of the further chaining), if not the chain will be continued.
       */
      chain: function () {
        var me = this;

        me.logger.enter("chaining");
        me.current = me.events.shift();

        if (!me.current) {
          me.logger.exit("chaining");
          return; // event chain finished
        }

        if (me.checkExecution(me.current)) {
          me.current.$handler.execute(me);
        } else {
          me.chain();
        }
      },

      /**
       * @private
       * Checks, if an event defines a valid handler, and if the event has an `ON` property it will be evaluated.
       * @return {Boolean}
       */
      checkExecution: function () {
        var me = this,
            event = me.current,
            canExecute = true,
            ignore = false,
            checkValue;

        me.logger.enter("checkExecution", event);

        if (!event) {
          me.logger.warn("No event to check");
          canExecute = false;
        }

        if (canExecute && (!event.$handler || !sol.common.ObjectUtils.isFunction(event.$handler.execute))) {
          me.logger.warn(["No handler for event of type '{0}' -> skip", event.ID]);
          canExecute = false;
        }

        if (canExecute && event.ON) {
          if (me.context.dirtySord && event.ON.objId) {
            me.context.sord = ixConnect.ix().checkoutSord(event.ON.objId, SordC.mbAllIndex, LockC.NO);
            me.context.dirtySord = false;
          }

          if (me.context.dirtyWfStatus && event.ON.flowId) {
            me.context.wfStatus = sol.common.IxUtils.execute("RF_sol_common_service_GetWorkflowMetadata", { flowId: event.ON.flowId }).status;
            me.context.dirtyWfStatus = false;
          }

          switch (event.ON.type) {
            case "WF_STATUS":
              checkValue = me.context.wfStatus;
              break;
            case "GRP":
              checkValue = sol.common.SordUtils.getValue(me.context.sord, event.ON);
              break;
            case "SORD":
              checkValue = sol.common.SordUtils.getValue(me.context.sord, event.ON);
              break;
            case "MAP":
              checkValue = sol.common.SordUtils.getValue(me.context.sord, event.ON);
              break;
            default:
              me.logger.warn(["event defines non existing ON.type={0}, ON condition will be ignored", event.ON.type]);
              ignore = true;
          }

          if (!ignore) {
            canExecute = checkValue == event.ON.value;
          }
        }

        me.logger.exit("checkExecution", { canExecute: canExecute });

        return canExecute;
      }

    });

    /**
     * This class handles the refresh event.
     *
     * @author PZ, ELO Digital Office GmbH
     * @version 1.01.002
     *
     * @elojc
     * @requires sol.common.ObjectUtils
     * @requires sol.common.SordUtils
     * @requires sol.common.IxUtils
     * @requires sol.common.jc.ActionHandler.EventChain
     */
    sol.define("sol.common.jc.ActionHandler.Refresh", {

      execute: function (eventChain) {
        var event, eventConfig, element, taskViewIterator, taskView;

        event = eventChain.getCurrent();

        if (event.ID !== sol.common.IxUtils.CONST.EVENT_TYPES.REFRESH) {
          throw "'sol.common.jc.ActionHandler.REFRESH' can only handle '" + sol.common.IxUtils.CONST.EVENT_TYPES.REFRESH + "' events, but event-ID was '" + event.ID + "'";
        }

        taskViewIterator = tasksViews.tasksViews.iterator();

        while (taskViewIterator.hasNext()) {
          taskView = taskViewIterator.next();
          taskView.refresh();
        }

        if (event.obj) {
          eventConfig = event.obj;
          element = archive.getElement(eventConfig.objId);
          if (element instanceof Packages.de.elo.client.scripting.items.ArchiveElement) {
            element.refresh();
          }
        }
        eventChain.chain();
      }
    });

    /**
     * This class handles the goto event.
     *
     * @author PZ, ELO Digital Office GmbH
     * @version 1.01.002
     *
     * @elojc
     * @requires sol.common.ObjectUtils
     * @requires sol.common.SordUtils
     * @requires sol.common.IxUtils
     * @requires sol.common.jc.ActionHandler.EventChain
     */
    sol.define("sol.common.jc.ActionHandler.Goto", {

      execute: function (eventChain) {
        var event, eventConfig, firstTaskView, taskView, element, lastCheckedOut, docFile;

        event = eventChain.getCurrent();

        if (event.ID !== sol.common.IxUtils.CONST.EVENT_TYPES.GOTO) {
          throw "'sol.common.jc.ActionHandler.GOTO' can only handle '" + sol.common.IxUtils.CONST.EVENT_TYPES.GOTO + "' events, but event-ID was '" + event.ID + "'";
        }

        if (event.obj) {
          eventConfig = event.obj;

          if (eventConfig.flowId) {
            firstTaskView = tasksViews.tasksViews.get(0);
            firstTaskView.show();
            firstTaskView.refresh();
            taskView = tasksViews.getTasksViewForWorkflow(eventConfig.flowId);
            if (taskView) {
              taskView.show();
              taskView.clearSelection();
              taskView.selectWorkflow(eventConfig.flowId);
            }
          } else if (eventConfig.objId) {
            workspace.updateSordLists();

            workspace.activeView && workspace.activeView.refresh();

            workspace.gotoId(eventConfig.objId);

            element = archive.getElement(eventConfig.objId);

            if (eventConfig.checkout && (element instanceof Packages.de.elo.client.scripting.items.ArchiveDocument)) {
              element.checkOut();
              lastCheckedOut = checkout.getLastDocument();
              if (lastCheckedOut.id === element.id) {
                docFile = lastCheckedOut.getDocumentFile();
                if (docFile) {
                  docFile.setWritable(true);
                  utils.editFile(docFile);
                }
              }
            }
            workspace.updateEnabledFunctions();
          }
        }
        eventChain.chain();
      }
    });

    /**
     * This class handles the dialog event.
     *
     * @author PZ, ELO Digital Office GmbH
     * @version 1.01.002
     *
     * @elojc
     * @requires sol.common.ObjectUtils
     * @requires sol.common.SordUtils
     * @requires sol.common.IxUtils
     * @requires sol.common.RepoUtils
     * @requires sol.common.jc.ActionHandler.EventChain
     */
    sol.define("sol.common.jc.ActionHandler.Dialog", {

      execute: function (eventChain) {
        var me = this,
            event, context, eventConfig, dlg;

        event = eventChain.getCurrent();

        if (event.ID !== sol.common.IxUtils.CONST.EVENT_TYPES.DIALOG) {
          throw "'sol.common.jc.ActionHandler.DIALOG' can only handle '" + sol.common.IxUtils.CONST.EVENT_TYPES.DIALOG + "' events, but event-ID was '" + event.ID + "'";
        }

        context = eventChain.getContext();
        context.dirtySord = true;
        context.dirtyWfStatus = true;

        if (event.obj) {
          eventConfig = event.obj;

          dlg = workspace.createAppDialog(eventConfig.title || "");
          dlg.hideStatusBar = true;
          if (eventConfig.dialogId) {
            dlg.dialogId = eventConfig.dialogId;
          }

          if (eventConfig.url) {
            dlg.loadUrl(eventConfig.url);
          } else if (eventConfig.flowId && eventConfig.nodeId) {
            dlg.loadWFForm(eventConfig.flowId, eventConfig.nodeId);
          }

          if (sol.common.RepoUtils.checkVersion(workspace.clientVersion, "10.00.012")) {
            dlg.show(null, function (dialog, closeSource) {
              if (closeSource == "ABORT") {
                sol.common.IxUtils.execute("RF_sol_common_service_ActionCancelForm", { flowId: eventConfig.flowId, nodeId: eventConfig.nodeId });
              }
              eventChain.chain();
            }, me);
          } else {
            dlg.show();
            eventChain.chain();
          }
        }
      }
    });

    /**
     * This class handles the error event.
     *
     * @author PZ, ELO Digital Office GmbH
     * @version 1.01.002
     *
     * @elojc
     * @requires sol.common.ObjectUtils
     * @requires sol.common.SordUtils
     * @requires sol.common.IxUtils
     * @requires sol.common.jc.ActionHandler.EventChain
     */
    sol.define("sol.common.jc.ActionHandler.Error", {

      execute: function (eventChain) {
        var event, eventConfig;

        event = eventChain.getCurrent();

        if (event.ID !== sol.common.IxUtils.CONST.EVENT_TYPES.ERROR) {
          throw "'sol.common.jc.ActionHandler.ERROR' can only handle '" + sol.common.IxUtils.CONST.EVENT_TYPES.ERROR + "' events, but event-ID was '" + event.ID + "'";
        }

        if (event.obj) {
          eventConfig = event.obj;
          workspace.showAlertBox(utils.getText("sol.common", "sol.common.client.ActionHandler.errordlg.title"), eventConfig.msg);
        }
        eventChain.chain();
      }
    });

    /**
     * This class handles the action event.
     *
     * @author PZ, ELO Digital Office GmbH
     * @version 1.01.002
     *
     * @elojc
     * @requires sol.common.ObjectUtils
     * @requires sol.common.SordUtils
     * @requires sol.common.IxUtils
     * @requires sol.common.jc.ActionHandler
     * @requires sol.common.jc.ActionHandler.EventChain
     */
    sol.define("sol.common.jc.ActionHandler.Action", {

      execute: function (eventChain) {
        var event, context;

        event = eventChain.getCurrent();

        if (event.ID !== sol.common.IxUtils.CONST.EVENT_TYPES.ACTION) {
          throw "'sol.common.jc.ActionHandler.ACTION' can only handle '" + sol.common.IxUtils.CONST.EVENT_TYPES.ACTION + "' events, but event-ID was '" + event.ID + "'";
        }

        context = eventChain.getContext();
        context.dirtySord = true;
        context.dirtyWfStatus = true;

        if (event.COMPONENT === sol.common.IxUtils.CONST.COMPONENTS.IX) {
          sol.common.jc.ActionHandler.execute(event.obj.registeredFunction, event.obj.params);
        } else if (event.COMPONENT === sol.common.IxUtils.CONST.COMPONENTS.AS) {
          sol.common.jc.ActionHandler.executeAS(event.solutionName, event.obj.directRule, event.obj.params, null, event.async);
        }
        eventChain.chain();
      }
    });

    /**
     * This class handles the feedback event.
     *
     * @author PZ, ELO Digital Office GmbH
     * @version 1.03.000
     *
     * @elojc
     * @requires sol.common.ObjectUtils
     * @requires sol.common.SordUtils
     * @requires sol.common.IxUtils
     * @requires sol.common.jc.ActionHandler.EventChain
     */
    sol.define("sol.common.jc.ActionHandler.Feedback", {

      execute: function (eventChain) {
        var event, eventConfig;

        event = eventChain.getCurrent();

        if (event.ID !== sol.common.IxUtils.CONST.EVENT_TYPES.FEEDBACK) {
          throw "'sol.common.jc.ActionHandler.FEEDBACK' can only handle '" + sol.common.IxUtils.CONST.EVENT_TYPES.FEEDBACK + "' events, but event-ID was '" + event.ID + "'";
        }

        if (event.obj) {
          eventConfig = event.obj;
          if (eventConfig.permanent === true) {
            workspace.showInfoBox(utils.getText("sol.common", "sol.common.client.ActionHandler.infodlg.title"), eventConfig.msg);
          } else {
            workspace.setFeedbackMessage(eventConfig.msg);
          }
        }
        eventChain.chain();
      }
    });