ProspectDirector.Web.UI.Packagers.PackagerCommandHandler =
Class.extend({

    //================================
    // FIELDS
    //================================

    _context: null,
    _command: null,
    _errors: null,
    _valueCommands: null,
    _valueHandlers: null,
    _valueProducts: null,

    //================================
    // CONSTRUCTOR
    //================================

    init: function (options) {
        this._context = options.context;
        this._command = options.command;
        this._errors = new ProspectDirector.Web.List();
        this._valueCommands = new ProspectDirector.Web.List(options.command.params.slice(0));
        this._valueHandlers = new ProspectDirector.Web.List();
        this._valueProducts = new ProspectDirector.Web.List();
    },

    //================================
    // PROPERETIES
    //================================

    get_context: function () {
        return this._context;
    },

    get_command: function () {
        return this._command;
    },

    get_valueCommands: function () {
        return this._valueCommands;
    },

    get_valueHandlers: function () {
        return this._valueHandlers;
    },

    get_errors: function () {
        return this._errors;
    },

    //================================
    // PUBLIC METHODS
    //================================

    execute: function () {

        if (this._valueHandlers.count() === 0) {
            this._buildValueHandlers(this._context);
        }

        this._valueProducts.clear();

        this._executeValueHandlers();

        return $.extend(this.get_command(), {
            params: this._transformValueProducts()
        });

    },

    onRequestHandler: function (command) {

        return new ProspectDirector.Web.UI.Packagers.PackagerValueHandler({
            context: this.get_context(),
            command: command
        });

    },

    onExecuteHandler: function (handler) {

        this._valueProducts.add({
            name: handler.get_name(),
            value: handler.execute()
        });

        this.get_errors().addRange(handler.get_errors().toArray());

    },

    //================================
    // PRIVATE METHODS
    //================================

    _transformValueProducts: function () {

        var result = {};

        this._valueProducts.each(function (index, product) {
            result[product.name] = product.value;
        });

        return result;

    },

    _buildValueHandlers: function () {

        var that = this;

        this._valueCommands.each(function (index, command) {
            var handler = that.onRequestHandler(command);
            if (handler) {
                that._valueHandlers.add(handler);
            }
        });

    },

    _executeValueHandlers: function () {

        var that = this;

        this._valueHandlers.each(function (index, handler) {
            that.onExecuteHandler(handler);
        });

    }

});