    //@include lib_Class.js
    //@include lib_sol.common.Template.js

    /**
     * Version check and reporting.
     *
     * @author JHR, ELO Digital Office GmbH
     * @version 1.0
     *
     * @requires sol.common.JsonUtils
     * @requires sol.common.IxUtils
     * @requires sol.common.Template
     */
    sol.define("sol.dev.jc.Versions", {
      singleton: true,

      /**
       * @private
       * @property
       */
      htmlReport: undefined,

      /**
       * @private
       * @property
       */
      fileName: "",

      /**
       * Generates a Version Script List in JSON-Format into a document.
       */
      generateReport: function () {
        var me = this,
            arcPath, scriptVersionList, strScriptVersionList, element;

        arcPath = "ARCPATH[1]:\\Administration\\Business Solutions";
        element = workspace.activeView.firstSelected;
        if (!element) {
          workspace.showInfoBox(me.getText("sol.dev.Versions.titleCancel"), me.getText("sol.dev.Versions.msgNoArchiveFolderSelected"));
          return;
        }
        arcPath = "ARCPATH[1]:" + element.sord.refPaths[0].pathAsString + "\\" + element.sord.name;
        arcPath = me.replaceAll("¶", "\\", arcPath);
        scriptVersionList = sol.common.IxUtils.execute("RF_sol_common_service_ScriptVersionReportCreate", {
          arcPath: arcPath
        });
        strScriptVersionList = sol.common.JsonUtils.stringifyAll(scriptVersionList, { tabStop: 2 });
        me.saveTextToFile(strScriptVersionList, element.sord.name + ".json", me.getText("sol.dev.Versions.titleSave"));
      },

      /**
       * Validates the report Version Script List in JSON-Format.
       */
      validateReport: function () {
        var me = this,
            result, strScriptVersionList, strFileName, jsonScriptVersionList, jsonScriptModifiedVersionList;

        result = me.readTextFromFile("BusinessSolutions.json", me.getText("sol.dev.Versions.titleLoad"));
        strScriptVersionList = null;
        strFileName = null;
        if (result) {
          strScriptVersionList = result.StrText;
          strFileName = result.FileName;
          me.fileName = strFileName.substr(0, strFileName.lastIndexOf("."));
        }

        jsonScriptVersionList = null;
        if (strScriptVersionList) {
          try {
            jsonScriptVersionList = JSON.parse(strScriptVersionList);

            jsonScriptModifiedVersionList = sol.common.IxUtils.execute("RF_sol_common_service_ScriptVersionReportValidate", {
              jsonScriptVersionList: jsonScriptVersionList
            });
            me.createHtmlReport(jsonScriptModifiedVersionList);
          } catch (e) {
            jsonScriptVersionList = null;
            jsonScriptModifiedVersionList = null;
            workspace.showAlertBox("function validateReport() catch (e)", "name:" + e.name + "\nmessage:" + e.message);
          }
        }
      },

      /**
       * @private
       * Replace all
       * @param {String} find Value, that will be replaced overall.
       * @param {String} replace New Value to replace the old value.
       * @param {String} str String to operate.
       * @return {String} String after replacing.
       */
      replaceAll: function (find, replace, str) {
        return str.replace(new RegExp(find, "g"), replace);
      },

      /**
       * @private
       * Saves text to file
       * @param {String} strText Text content to save in file.
       * @param {String} strFileName Default file name.
       * @param {String} strDialogTitle Title of FileChooserDialog.
       */
      saveTextToFile: function (strText, strFileName, strDialogTitle) {
        var file;

        file = workspace.showFileChooserDialog(strDialogTitle, true, true, strFileName);
        if (file) {
          FileUtils.writeStringToFile(file[0], strText, "UTF-8");
        }
      },

      /**
       * @private
       * Read text from file
       * @param {String} strFileName Default file name.
       * @param {String} strDialogTitle Title of FileChooserDialog.
       * @return {Object} Text content read from file, file name.
       */
      readTextFromFile: function (strFileName, strDialogTitle) {
        var file, strText, fileName, result;

        strText = null;
        fileName = null;
        result = null;
        file = workspace.showFileChooserDialog(strDialogTitle, false, true, strFileName);
        if (file) {
          try {
            strText = FileUtils.readFileToString(file[0], "UTF-8");
            fileName = file[0].getName();
            result = { StrText: strText, FileName: fileName };
          } catch (e) {
            strText = null;
            fileName = null;
            result = null;
            workspace.showAlertBox("function readTextFromFile(strFileName, strDialogTitle) catch (e)", "name:" + e.name + "\nmessage:" + e.message);
          }
        }
        return result;
      },

      dateFromIso: function (isoDate) {
        var year, month, day, hours, minutes, seconds, milliseconds, timeDateJava;

        year = isoDate.substr(0, 4);
        month = isoDate.substr(4, 2);
        month--;
        day = isoDate.substr(6, 2);
        hours = isoDate.substr(8, 2);
        minutes = isoDate.substr(10, 2);
        seconds = isoDate.substr(12, 2);
        milliseconds = 0;
        timeDateJava = new Date(year, month, day, hours, minutes, seconds, milliseconds);
        return timeDateJava;
      },

      /**
       * @private
       * Format HTML-Report from Version Script List in JSON-Format for Table-Output.
       * @param {Object} scriptFiles Version Scriptfile List in JSON-Format.
       * @return {Object} Modified Scriptfile List in JSON-Format with table format info
       */
      formatHtmlTableOutput: function (scriptFiles) {
        var me = this,
            i, fileentry, timeDateJava, f;

        for (i = 0; i < scriptFiles.length; i++) {
          fileentry = scriptFiles[i];
          if (i % 2 == 0) {
            fileentry.td = "td1";
          } else {
            fileentry.td = "td2";
          }
          if (i == scriptFiles.length - 1) {
            fileentry.td += "b";
          }
          timeDateJava = me.dateFromIso(fileentry.date);
          f = Packages.java.text.DateFormat.getDateTimeInstance(Packages.java.text.DateFormat.FULL, Packages.java.text.DateFormat.FULL, Packages.java.util.Locale.ENGLISH);
          fileentry.date = f.format(timeDateJava);
        }
        return scriptFiles;
      },

      /**
       * @private
       * Creates HTML-Report from Version Script List in JSON-Format.
       * @param {Object} jsonScriptVersionList Version Script List in JSON-Format.
       */
      createHtmlReport: function (jsonScriptVersionList) {
        var me = this,
            modifiedScriptFiles, originalScriptFiles, scriptFiles, i, fileentry,
            tpl, titleReport, data, dlgBrowserReport, pnl, ctrBrowser, tempDir;

        modifiedScriptFiles = [];
        originalScriptFiles = [];
        scriptFiles = jsonScriptVersionList.files;
        for (i = 0; i < scriptFiles.length; i++) {
          fileentry = {};
          fileentry.name = scriptFiles[i].name;
          fileentry.editor = scriptFiles[i].editor;
          fileentry.date = scriptFiles[i].date;
          fileentry.guid = scriptFiles[i].guid;
          fileentry.version = scriptFiles[i].version;
          if (scriptFiles[i].modified) {
            modifiedScriptFiles.push(fileentry);
          } else {
            originalScriptFiles.push(fileentry);
          }
        }
        modifiedScriptFiles = me.formatHtmlTableOutput(modifiedScriptFiles);
        originalScriptFiles = me.formatHtmlTableOutput(originalScriptFiles);

        tpl = sol.create("sol.common.Template", {});
        tpl.load("ARCPATH[(E10E1000-E100-E100-E100-E10E10E10E00)]:/Business Solutions/development/Configuration/Script Version List Templates/Default");
        titleReport = "ScriptVersionReport " + me.fileName;
        data = {
          TitleReport: titleReport,
          ModifiedScriptFiles: modifiedScriptFiles,
          OriginalScriptFiles: originalScriptFiles
        };
        me.htmlReport = tpl.apply(data);

        dlgBrowserReport = workspace.createGridDialog(titleReport, 30, 60);
        pnl = dlgBrowserReport.gridPanel;
        ctrBrowser = components.createBrowser();
        pnl.addComponent(1, 1, 30, 58, ctrBrowser);

        tempDir = workspace.directories.tempDir.path;
        FileUtils.writeStringToFile(new File(tempDir + "\\htmlreport.html"), me.htmlReport, "UTF-8");
        ctrBrowser.navigate("file:///" + tempDir + "/htmlreport.html");
        dlgBrowserReport.show("okEventDlgBrowserReport", "closeEventDlgBrowserReport");
      },

      /**
       * @private
       * Event handler is called when "OK" is pressed in dialogue browser report.
       * @return {Integer}
       */
      okEventDlgBrowserReport: function () {
        var me = this;

        me.saveTextToFile(me.htmlReport, me.fileName + ".html", me.getText("sol.dev.Versions.titleHtmlSave"));
        return -1;
      },

      /**
       * @private
       * Event handler is called when "Cancel" is pressed in dialogue browser report.
       */
      closeEventDlgBrowserReport: function () {
        // workspace.showAlertBox("closeEventDlgBrowserReport", "Cancel pressed");
      },

      /**
       * @private
       * Helper function to get a localized text of a specific key.
       * @param {String} key Key for the text constant.
       * @return {String} Localized text constant.
       */
      getText: function (key) {
        return String(utils.getText("sol.dev.client", key));
      }
    });

    // Register Java Client event listeners. //////////////////////////////////////////////////////////////////////////

    /**
     * @override global.JavaClientEvents
     */

    /**
     * @member global.JavaClientEvents
     * @inheritdoc sol.dev.jc.Versions#okEventDlgBrowserReport
     */
    function okEventDlgBrowserReport() {
      return sol.dev.jc.Versions.okEventDlgBrowserReport();
    }

    /**
     * @member global.JavaClientEvents
     * @inheritdoc sol.common.jc.Functions#closeEventDlgBrowserReport
     */
    function closeEventDlgBrowserReport() {
      return sol.dev.jc.Versions.closeEventDlgBrowserReport();
    }