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

    //@include lib_Class.js
    //@include lib_sol.common.Config.js
    //@include lib_sol.common.RepoUtils.js
    //@include lib_sol.common.Template.js
    //@include lib_sol.common.ix.ServiceBase.js

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

    /**
     * Returns merged Timed Event Configuration Files which are stored in Business Solutions configuration Folders
     *
     *
     * @author ELO Digital Office GmbH
     * @version 1.05.000
     *
     * @eloix
     * @requires  sol.common.Config
     * @requires  sol.common.RepoUtils
     * @requires  sol.common.Template
     * @requires  sol.common.ix.ServiceBase
     */
    sol.define("sol.common.ix.services.GetNamespacedConfigs", {
      extend: "sol.common.ix.ServiceBase",

      /**
       * @since 1.05.000
       * @cfg {String[]} paths (optional) an array of relative paths inside the 'Business Solutions' (or its 'Custom') folders or even an objId. The configs will be loaded composed.
       */

      /**
       * @cfg {Boolean} [allSolutions=false] (optional) If `true` all configurations with path /Business Solutions/{{solution}}/Configuration/timedEvent.config will be added
       */

      utils: {
        removeDuplicats: function (arr) {
          return Object.keys(
            arr.reduce(function (acc, path) {
              acc[path] = true;
              return acc;
            }, {})
          );
        }
      },

      initialize: function (config) {
        var me = this;
        if (!config.paths && !config.allSolutions) {
          throw new Error("InitializationException: either 'paths' has to be defined or allSolutions has to be true");
        }
        me.$super("sol.common.ix.ServiceBase", "initialize", [config]);
      },

      getBusinessSolutionBasePath: function () {
        return sol.common.RepoUtils.resolveSpecialFolder("{{bsFolderPath}}");
      },

      getBusinessSolutionBaseFolder: function () {
        var me = this;

        return sol.common.RepoUtils.findChildren(
          sol.common.RepoUtils.getObjId(me.getBusinessSolutionBasePath()),
          {
            includeFolders: true,
            includeDocuments: false
          },
          ixConnectAdmin
        );
      },

      getBusinessSolutionBaseFolderNames: function () {
        var me = this;

        return (me.getBusinessSolutionBaseFolder() || [])
          .map(function (sord) {
            return sord.name;
          })
          .filter(function (name) {
            return !!name;
          });
      },

      getAllSolutionsPaths: function () {
        var me = this;

        return (me.getBusinessSolutionBaseFolderNames() || [])
          .map(function (name) {
            return "/" + name + "/Configuration/timedevent.config";
          });
      },

      filterInvalidPaths: function (path) {
        return path.indexOf("[") === -1;
      },

      getComposedConfig: function (path) {
        return { path: path, config: sol.create("sol.common.Config", { compose: path }).config };
      },

      isEmpty: function (configContainer) {
        return !sol.common.ObjectUtils.isEmpty(configContainer.config);
      },

      getConfigs: function (configContainer) {
        return {
          path: configContainer.path,
          namespace: (configContainer.config || {}).namespace,
          configs: (configContainer.config || {}).configs
        };
      },

      checkNamespace: function (config) {
        return !!(config || {}).namespace;
      },

      groupByIdAndNamespace: function (acc, config) {
        var configs = (config || {}).configs || {},
            key,
            element;
        for (key in configs) {
          if (configs.hasOwnProperty(key)) {
            element = configs[key];
            if (element.id) {
              element.namespace = element.namespace || config.namespace;
              element.path = element.path || config.path;
              acc[element.namespace] = acc[element.namespace] || {};
              acc[element.namespace][element.id] = acc[element.namespace][element.id]
                ? sol.common.ObjectUtils.mergeObjects(acc[config[key]], config)
                : element;
            }
          }
        }
        return acc;
      },

      /**
       * Downloads the given file content as string
       * @return {Object}
       */
      process: function () {
        var me = this,
            paths,
            addSolutions,
            preparedPaths;

        // prepare
        paths = me.paths
          ? Array.isArray(me.paths)
            ? me.paths
            : [me.paths]
          : [];
        addSolutions = me.allSolutions || false;

        preparedPaths = me.utils.removeDuplicats(
          addSolutions
            ? paths.concat(me.getAllSolutionsPaths())
            : paths
        );

        return preparedPaths
          .filter(me.filterInvalidPaths)
          .map(me.getComposedConfig)
          .filter(me.isEmpty)
          .map(me.getConfigs)
          .filter(me.checkNamespace)
          .reduce(me.groupByIdAndNamespace, {});
      }
    });

    /**
     * @member sol.common.ix.services.GetNamespacedConfigs
     * @method RF_sol_common_service_GetNamespacedConfigs
     * @since 1.05.000
     * @static
     * @inheritdoc sol.common.ix.ServiceBase#RF_ServiceBaseName
     */
    function RF_sol_common_service_GetNamespacedConfigs(ec, args) {
      var params, service, result;
      logger.enter("RF_sol_common_service_GetNamespacedConfigs", args);

      params = sol.common.ix.RfUtils.parseAndCheckParams(ec, arguments.callee.name, args);

      service = sol.create("sol.common.ix.services.GetNamespacedConfigs", params);

      result = service.process();

      logger.exit("RF_sol_common_service_GetNamespacedConfigs", result);
      return sol.common.JsonUtils.stringifyAll(result);
    }