(function($) {

    /**
     * Framework providing client functions for plentymarkets Webshops.
     * @constructor
     */
    PlentyFramework = function() {};

    /**
     * @type {Array} Collection of registered directives
     */
    PlentyFramework.directives = [];

    /**
     * Register directive. Directives can be bound to dynamically added nodes by calling pm.bindPlentyFunctions();
     * @param   {string}    selector        jQuery selector of the DOM-elements to bind the directive to
     * @param   {function}  callback        Function to add directives behaviour
     * @param   {boolean}   allowDuplicates Defines if a directive can be bound to the same element multiple times
     * @returns {object}                    The created directive
     */
    PlentyFramework.directive = function(selector, callback, allowDuplicates) {
        var directive = {
            id:			PlentyFramework.directives.length,
            selector:	selector,
            callback:	callback,
            allowDuplicates: !!allowDuplicates,
            elements:	[]
        };
        PlentyFramework.directives.push(directive);

        return directive;
    };

    /**
     * Bind registered directives.
     * @param {string} [directiveSelector] restrict binding to elements matching this selector
     */
    PlentyFramework.prototype.bindDirectives = function( directiveSelector ) {
        $.each( PlentyFramework.directives, function(i, directive)  {

            var elements = [];
            // filter elements already bound
            $(directive.selector).each(function(j, obj) {
                if( $.inArray( $(obj)[0], directive.elements ) < 0 ) {
                    elements.push( $(obj) );
                }
            });
            if( !directiveSelector || directiveSelector === directive.selector || $.inArray(directive.selector, directiveSelector ) >= 0 ) {
                $.each( elements, directive.callback );
            }

            $(elements).each(function(j, obj) {
                // store function ID to avoid duplicate bindings
                if( !directive.allowDuplicates ) {
                    directive.elements.push( $(obj)[0] );
                }
            });
        });
    };

    PlentyFramework.service = function( serviceName, serviceFunctions ) {

        PlentyFramework.prototype[serviceName] = serviceFunctions();

    };

}(jQuery));

// Create global instance of PlentyFramework for usage in Webshop-Layouts
var pm = new PlentyFramework();

// initially bind all registered directives
jQuery(document).ready(function() {
    pm.bindDirectives();
});




@@ -151,24 +151,183 @@
 tion() %7B%7D;%0A%0A
+    var instance = null;%0A    PlentyFramework.getInstance = function() %7B%0A        instance = instance %7C%7C new PlentyFramework();%0A        return instance;%0A    %7D;%0A%0A
     /**%0A    
@@ -734,16 +734,132 @@
 haviour%0A
+     * @param   %7BArray%7D     dependencies    List of required services. Services will be passed to callback function%0A
      * @
@@ -1099,16 +1099,30 @@
 allback,
+ dependencies,
  allowDu
@@ -1276,16 +1276,56 @@
 llback,%0A
+            dependencies: dependencies,%0A
         
@@ -2246,395 +2246,2130 @@
 ts, 
-directive.callback );%0A            %7D%0A%0A            $(elements).each(function(j, obj) %7B%0A                // store function ID to avoid duplicate bindings%0A                if( !directive.allowDuplicates ) %7B%0A                    directive.elements.push( $(obj)%5B0%5D );%0A                %7D%0A            %7D);%0A        %7D);%0A    %7D;%0A%0A    PlentyFramework.service = function( serviceName, serviceFunctions ) %7B%0A
+function(i, elem) %7B%0A                    var params = %5Bi, elem%5D;%0A%0A                    // append dependencies if exists%0A                    if( !!directive.dependencies && directive.dependencies.length %3E 0 ) %7B%0A                        $.each( directive.dependencies, function(j, dependency) %7B%0A                            var service = PlentyFramework.service(dependency);%0A                            if( !service ) %7B%0A                                console.error('Cannot inject service %22' + dependency + %22': Service not found.%22);%0A                            %7D%0A                            params.push( service );%0A                        %7D);%0A                    %7D%0A%0A                    // apply loop variables and dependend services to callback%0A%0A                    directive.callback.apply(null, params);%0A                %7D);%0A            %7D%0A%0A            $(elements).each(function(j, obj) %7B%0A                // store function ID to avoid duplicate bindings%0A                if( !directive.allowDuplicates ) %7B%0A                    directive.elements.push( $(obj)%5B0%5D );%0A                %7D%0A            %7D);%0A        %7D);%0A    %7D;%0A%0A    PlentyFramework.service = function( serviceName, serviceFunctions ) %7B%0A%0A%0A        // Catch type mismatching for 'serviceName'%0A        if( typeof serviceName !== 'string' ) %7B%0A            console.error(%22Type mismatch: Expect first parameter to be a 'string', '%22 + typeof serviceFunctions + %22' given.%22);%0A            return;%0A        %7D%0A%0A        // getting services%0A        if( typeof serviceFunctions === 'undefined' ) %7B%0A            return PlentyFramework.prototype%5BserviceName%5D;%0A        %7D%0A%0A        // Catch type mismatching for 'serviceFunctions'%0A        if( typeof serviceFunctions !== 'function' ) %7B%0A            console.error(%22Type mismatch: Expect second parameter to be a 'function', '%22 + typeof serviceFunctions + %22' given.%22);%0A            return;%0A        %7D%0A%0A        // Avoid overriding existing services%0A        if( PlentyFramework.prototype.hasOwnProperty( serviceName ) ) %7B%0A            console.error(%22Service '%22 + serviceName + %22' already exists.%22);%0A            return;%0A        %7D%0A%0A        // inject service
 %0A   
@@ -4538,20 +4538,16 @@
 var pm =
- new
  PlentyF
@@ -4550,24 +4550,36 @@
 ntyFramework
+.getInstance
 ();%0A%0A// init

extend PlentyFramework giving directives additional dependencies to inject services in directives