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

    //@include lib_Class.js
    //@include lib_sol.common.Config.js
    //@include lib_sol.common.JsonUtils.js
    //@include lib_sol.common.SordUtils.js
    //@include lib_sol.common.RepoUtils.js
    //@include lib_sol.common.TranslateTerms.js
    //@include lib_sol.common.ix.RfUtils.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.ContactList" });

    /**
     * Retrieves available contactlist 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.GetContactListTypes", {
      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 contactlist 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 contactlist types
       */
      process: function () {
        var me = this,
            contactlistTemplates;

        contactlistTemplates = me.getAllTemplates();

        return me.convert(contactlistTemplates);
      },

      /**
       * @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.contactlist.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;
      }

    });

    /**
     * Checks the preconditions for creation of a contactlist.
     *
     * This service uses the mask of the parent to determine if it is a valid location for the contactlist.
     *
     * Returns an Object:
     *
     *     {
     *       valid: true,
     *       msg: "optional message"
     *       targetId: valid target
     *     }
     *
     * # Configuration
     *
     * |Property|Description|
     * |:------|:------|
     * |fields.FILE_TYPE|The existence of this field on a mask, marks the element as a valid target|
     *
     * @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.TranslateTerms
     * @requires sol.common.ix.RfUtils
     * @requires sol.common.ix.ServiceBase
     */
    sol.define("sol.contact.ix.services.CheckContactListPreconditions", {
      extend: "sol.common.ix.ServiceBase",

      requiredConfig: ["ci", "targetId"],

      /**
       * @cfg {String} targetId (required)
       * ObjectId of the target folder
       */

      /**
       * @cfg {de.elo.ix.client.ClientInfo} ci (required)
       */

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

      /**
       * Checks the preconditions for creating a contactlist.
       * @returns {Object}
       */
      process: function () {
        var me = this,
            result = { valid: false },
            sord, typeService;

        result.targetId = me.targetId;
        try {
          sord = ixConnect.ix().checkoutSord(result.targetId, SordC.mbAllIndex, LockC.NO);
        } catch (ex) {
          me.logger.warn("invalid location for contactlist", ex);
          result.msg = sol.common.TranslateTerms.getTerm(me.ci, "sol.contact.ix.services.CreateContactList.errorNoElement");
          return result;
        }

        if (me.isValidLocation(sord)) {
          result.valid = true;

          // identify valid contact list types
          typeService = sol.create("sol.contact.ix.services.GetContactListTypes", {});
          result.types = typeService.process();

        } else {
          result.msg = sol.common.TranslateTerms.getTerm(me.ci, "sol.contact.ix.services.CreateContactList.errorInvalidLocation");
        }

        return result;
      },

      /**
       * @private
       * Checks valid location for new contact list element
       * @param {de.elo.ix.client.Sord[]} sord
       * @returns {Boolean} If valid or not
       */
      isValidLocation: function (sord) {
        return (sol.common.SordUtils.isFolder(sord) && !sol.contact.Utils.getParentContactList(sord.id)) || (sord.id === 1);
      }

    });

    /**
     * @member sol.contact.ix.services.CheckContactListPreconditions
     * @method RF_sol_contact_service_CheckContactListPreconditions
     * @static
     * @inheritdoc sol.common.ix.ServiceBase#RF_ServiceBaseName
     */
    function RF_sol_contact_service_CheckContactListPreconditions(iXSEContext, args) {
      logger.enter("RF_sol_contact_service_CheckContactListPreconditions", args);
      var rfUtils = sol.common.ix.RfUtils,
          config = rfUtils.parseAndCheckParams(iXSEContext, arguments.callee.name, args, "targetId"),
          service, result;

      config.ci = iXSEContext.ci;

      service = sol.create("sol.contact.ix.services.CheckContactListPreconditions", config);
      result = rfUtils.stringify(service.process());
      logger.exit("RF_sol_contact_service_CheckContactListPreconditions", result);
      return result;
    }