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

    //@include lib_Class.js
    //@include lib_sol.common.Config.js
    //@include lib_sol.common.IxUtils.js
    //@include lib_sol.common.RepoUtils.js
    //@include lib_sol.common.AclUtils.js
    //@include lib_sol.common.WfUtils.js
    //@include lib_sol.common.Template.js
    //@include lib_sol.common.TranslateTerms.js
    //@include lib_sol.common.ix.ServiceBase.js
    //@include lib_sol.contact.Utils.js

    var logger = sol.create("sol.Logger", { scope: "sol.contact.ix.services.Company" });

    /**
     * Retrieves available company types.
     *
     * # Configuration
     *
     * |Property|Description|
     * |:------|:------|
     * |||
     *
     * @author JHR, ELO Digital Office GmbH
     * @version 1.0
     *
     * @eloix
     * @requires sol.common.Config
     * @requires sol.common.JsonUtils
     * @requires sol.common.SordUtils
     * @requires sol.common.RepoUtils
     * @requires sol.common.TranslateTerms
     * @requires sol.common.ix.RfUtils
     * @requires sol.common.ix.ServiceBase
     * @requires sol.contact.Utils
     */
    sol.define("sol.contact.ix.services.GetCompanyTypes", {
      extend: "sol.common.ix.ServiceBase",

      /**
       * @cfg {Object} filter (optional) Additional filters which can be applied to the results
       * @cfg {Boolean} filter.ignorePermissions (optional) If set, all available company types will be returned ignoring the user permissions (will only work in ELOix and ELOas)
       */

      initialize: function (config) {
        var me = this;
        me.$super("sol.common.ix.ServiceBase", "initialize", [config]);
        me.config = sol.contact.Utils.loadConfig();
      },

      /**
       * Retrieves the data as spezified in the constructor configuration.
       * @returns {String[]} Array with company types
       */
      process: function () {
        var me = this,
            companyTemplates;

        companyTemplates = me.getAllTemplates();

        return me.convert(companyTemplates);
      },

      /**
       * @private
       * Retrieves all template Sord objects.
       * @returns {de.elo.ix.client.Sord[]}
       */
      getAllTemplates: function () {
        var me = this,
            conn = (me.filter && (me.filter.ignorePermissions === true) && ixConnectAdmin) ? ixConnectAdmin : ixConnect,
            path = me.config.company.templateFolderId,
            searchConf = {};

        searchConf.includeFolders = true;
        searchConf.includeDocuments = false;
        searchConf.includeReferences = true;
        searchConf.sordZ = SordC.mbAllIndex;

        return sol.common.RepoUtils.findChildren(path, searchConf, conn);
      },

      /**
       * @private
       * Converts from Sords to Objects
       * @param {de.elo.ix.client.Sord[]} reportTemplateSords
       * @returns {Object[]}
       */
      convert: function (reportTemplateSords) {
        var converted = [];
        if (reportTemplateSords) {
          reportTemplateSords.forEach(function (sord) {
            converted.push({
              objId: sord.guid,
              name: sord.name,
              desc: sord.desc
            });
          });
        }
        return converted;
      }

    });

    /**
     * Creates a company.
     *
     * # As IX function call
     * Example with some data to create the new contact.
     *
     *     sol.common.IxUtils.execute('RF_sol_contact_service_CreateCompany', {
     *       companyType: "Default",
     *       data: [
     *         { type: "SORD", key: "name", value: "TMP_SERVICE" },
     *         { type: "GRP", key: "CONTACTLIST_REFERENCE", value: "CCL000000319" },
     *         { type: "GRP", key: "COMPANY_NAME", value: "Black Sails" }
     *       ]
     *     });
     *
     * # Configuration
     *
     * |Property|Description|
     * |:------|:------|
     * |company.templateFolderId|Base path of the company templates|
     * |company.createWorkflowNameTemplate|Name template for the workflow (in handlebars syntax)|
     *
     * @author PZ, ELO Digital Office GmbH
     * @version 1.05.002
     *
     * @eloix
     * @requires sol.common.Config
     * @requires sol.common.ObjectUtils
     * @requires sol.common.StringUtils
     * @requires sol.common.IxUtils
     * @requires sol.common.JsonUtils
     * @requires sol.common.SordUtils
     * @requires sol.common.RepoUtils
     * @requires sol.common.Template
     * @requires sol.common.AclUtils
     * @requires sol.common.WfUtils
     * @requires sol.common.TranslateTerms
     * @requires sol.common.ix.RfUtils
     * @requires sol.common.ix.ServiceBase
     * @requires sol.contact.Utils
     */
    sol.define("sol.contact.ix.services.CreateCompany", {
      extend: "sol.common.ix.ServiceBase",

      requiredConfig: ["ci", "user", "companyType"],

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

        if (!me.data && !me.sordMetadata) {
          throw "Either 'data' or 'sordMetadata' property has to be defined";
        }

        if (!me.data && me.sordMetadata) {
          if (!me.sordMetadata.objKeys || !me.sordMetadata.objKeys.CONTACTLIST_REFERENCE) {
            throw "No contactlist reference defined";
          }

          me.data = sol.contact.Utils.mapData(me.sordMetadata);
        }

      },

      /**
       * Creates a new company and starts a workflow.
       * @return {Object} Result contains `objId` of the new element and `name` of the new element
       */
      process: function () {
        var me = this,
            result;

        try {
          result = sol.contact.Utils.createCompany(me.companyType, { owner: me.user, fromService: true });

          me.prefillMetadata(result.objId);

          sol.common.WfUtils.startMaskStandardWorkflow(result.objId, { name: result.name, field: "STANDARD_WORKFLOW" });

          result.reference = sol.contact.Utils.getCompanyReference(result.objId);

          return result;
        } catch (ex) {
          me.logger.error("error creating new company", ex);
          if (result && result.objId) {
            sol.common.IxUtils.execute("RF_sol_function_Delete", { objId: result.objId, deleteFinally: true, asAdmin: true });
          }
        }
      }

    });

    /**
     * @member sol.contact.ix.services.GetCompanyTypes
     * @method RF_sol_contact_service_GetCompanyTypes
     * @static
     * @inheritdoc sol.common.ix.ServiceBase#RF_ServiceBaseName
     */
    function RF_sol_contact_service_GetCompanyTypes(iXSEContext, args) {
      var rfUtils, config, service, result;

      logger.enter("RF_sol_contact_service_GetCompanyTypes", args);

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

      service = sol.create("sol.contact.ix.services.GetCompanyTypes", config);
      result = rfUtils.stringify(service.process());

      logger.exit("RF_sol_contact_service_GetCompanyTypes", result);

      return result;
    }

    /**
     * @member sol.contact.ix.services.CreateCompany
     * @method RF_sol_contact_service_CreateCompany
     * @static
     * @inheritdoc sol.common.ix.ServiceBase#RF_ServiceBaseName
     */
    function RF_sol_contact_service_CreateCompany(ec, args) {
      var rfUtils, config, service, result;

      logger.enter("RF_sol_contact_service_CreateCompany", args);

      rfUtils = sol.common.ix.RfUtils;
      config = rfUtils.parseAndCheckParams(ec, arguments.callee.name, args, "companyType");

      config.ci = ec.ci;
      config.user = ec.user;

      service = sol.create("sol.contact.ix.services.CreateCompany", config);
      result = JSON.stringify(service.process());

      logger.exit("RF_sol_contact_service_CreateCompany", result);

      return result;
    }