var Portfolio = Portfolio || {
    pd: {
        util: {
            Handler: {

                singleton: true,
            
                config: {
            
                },
            
                constructor: function (o_config) {
            
                    var i_self = this;
            
                    i_self.initConfig(o_config);
            
                    return i_self;
                },
            
                processData: function(o_data, a_definition) {
            
                    var i_self = this;
            
                    var o_return = {};
            
                    Ext.Object.each(o_data, function(s_key, value) {
            
                        var o_result = {};
            
                        var o_property = Ext.Array.findBy(a_definition, function (o_definition) {
                            return o_definition.name == s_key && (o_definition.type == "collection" || o_definition.type == "group");
                        });
            
                        if (!o_property) {
            
                            o_property = Ext.Array.findBy(a_definition, function (o_definition) {
                                return o_definition.name == s_key;
                            });
                        }
            
                        if (o_property) {
            
                            if (o_property.type == "collection" || o_property.type == "group") {
                                o_result = i_self.createCollection(o_property, a_definition,  value);
                            }
                            else {
                                o_result = i_self.createProperty(o_property, a_definition, value);
                            }
                
                            o_return[s_key] = o_result;
                        }
                    });
            
                    return o_return;
            
                },
            
                createCollection: function (o_collection, a_definition, o_data) {
            
                    var i_self = this;
                    
                    var o_clone = Ext.clone(o_collection);
            
                    var a_extend = Ext.Array.from(o_collection.extend);
            
                    if (a_extend.length > 0) {
            
                        var a_recursion = i_self.getExtended(a_extend, a_definition);
            
                        a_recursion.reverse();
            
                        var o_merged = {};
            
                        Ext.Array.each(a_recursion, function(o_extended){
            
                            Ext.Object.each(o_extended, function(s_key, value) {
            
                                if (Ext.isPrimitive(value)) {
                                    o_merged[s_key] = value;
                                }
                                else {
                                    if (Ext.isArray(value)) {
            
                                        var a_temp = Ext.Array.from(o_merged[s_key]) || [];
                                        var a_value = Ext.Array.from(value);
            
                                        a_temp = a_value.concat(a_temp);
            
                                        o_merged[s_key] = a_temp;
                                    }
                                    else{
                                        if (Ext.isObject(value)) {
                                            o_merged[s_key] = Ext.apply(o_merged[s_key] || {}, value);
                                        }
                                    }
                                }
            
                            });
                        });
            
                        Ext.Object.each(o_clone, function (s_key, value) {
            
                            if (Ext.isPrimitive(value)) {
                                o_merged[s_key] = value;
                            }
                            else {
                                if (Ext.isArray(value)) {
            
                                    var a_temp = Ext.Array.from(value) || [];
                                    var a_value = Ext.Array.from(o_merged[s_key]);
            
                                    a_temp = a_value.concat(a_temp);
            
                                    o_merged[s_key] = a_temp;
                                }
                                else {
                                    if (Ext.isObject(value)) {
                                        o_merged[s_key] = Ext.apply(o_merged[s_key] || {}, value);
                                    }
                                }
                            }
            
                        });
            
                        o_clone = o_merged;
            
                        delete o_clone.extend;
            
                    }
            
                    var a_items = Ext.Array.from(o_clone.items);
            
                    var a_return = [];
            
                    Ext.Array.each(a_items, function(item) {
            
                        var o_property = item;
            
                        if (Ext.isString(item)) {
            
                            o_property = Ext.Array.findBy(a_definition, function (o_definition) {
                                return o_definition.name == item && (o_definition.type == "collection" || o_definition.type == "group");
                            });
                
                            if (!o_property) {
                
                                o_property = Ext.Array.findBy(a_definition, function (o_definition) {
                                    return o_definition.name == item;
                                });
                            }
                        }
            
                        if (o_property) {
            
                            var value = o_data[o_property.name] || "";
            
                            var o_output = i_self.createProperty(o_property, a_definition, value);
            
                            a_return.push(o_output);
                        }
            
                    });
            
                    var o_return = Ext.apply(o_clone, {
                        items: a_return
                    });
            
                    var o_rule = o_clone.rule || {};
            
                    o_rule = Ext.clone(o_rule);
            
                    Ext.apply(o_clone, o_rule);
            
                    delete o_clone.rule;
            
                    o_return.apperence = o_return.apperence || "field";
                    o_return.prioritized = o_data.hasOwnProperty("prioritized") ? o_data.prioritized : null;
            
                    return o_return;
            
                },
            
                createProperty: function (o_config, a_definition, value) {
            
                    var i_self = this;
            
                    var o_result = {};
            
                    var o_clone = Ext.clone(o_config);
            
                    if (o_clone.type == "collection" || o_clone.type == "group") {
                        o_result = i_self.createCollection(o_clone, a_definition, value);
                    }
                    else {
            
                        if (o_clone.extend) {
            
                            var a_extended = i_self.getExtended(Ext.Array.from(o_clone.extend), a_definition);
            
                            a_extended.reverse();
            
                            var o_merged = {};
            
                            Ext.Array.each(a_extended, function (o_extended) {
            
                                Ext.Object.each(o_extended, function (s_key, value) {
            
                                    if (Ext.isPrimitive(value)) {
                                        o_merged[s_key] = value;
                                    }
                                    else {
                                        if (Ext.isArray(value)) {
            
                                            var a_temp = Ext.Array.from(o_merged[s_key]) || [];
                                            var a_value = Ext.Array.from(value);
            
                                            a_temp = a_value.concat(a_temp);
            
                                            o_merged[s_key] = a_temp;
                                        }
                                        else {
                                            if (Ext.isObject(value)) {
                                                o_merged[s_key] = Ext.apply(o_merged[s_key] || {}, value);
                                            }
                                        }
                                    }
            
                                });
                            });
            
                            Ext.Object.each(o_clone, function (s_key, value) {
            
                                if (Ext.isPrimitive(value)) {
                                    o_merged[s_key] = value;
                                }
                                else {
                                    if (Ext.isArray(value)) {
            
                                        var a_temp = Ext.Array.from(o_merged[s_key]) || [];
                                        var a_value = Ext.Array.from(value);
            
                                        a_temp = a_value.concat(a_temp);
            
                                        o_merged[s_key] = a_temp;
                                    }
                                    else {
                                        if (Ext.isObject(value)) {
                                            o_merged[s_key] = Ext.apply(o_merged[s_key] || {}, value);
                                        }
                                    }
                                }
            
                            });
            
                            o_clone = o_merged;
                            delete o_clone.extend;
                        }
            
                        var o_rule = o_clone.rule || {};
            
                        o_rule = Ext.clone(o_rule);
                        
                        delete o_clone.rule;
            
                        Ext.apply(o_clone, o_rule);
            
                        Ext.apply(o_result, o_clone);
            
                        i_self.processProperties(o_result);
            
                        o_result.value = value;
                        o_result.originalValue = value;
                    }
            
                    return o_result;
                },
            
                getExtended: function (a_values, a_definition) {
            
                    var i_self = this;
            
                    var a_return = [];
            
                    Ext.Array.each(a_values, function(s_extend) {
            
                        var o_property = Ext.Array.findBy(a_definition, function (o_definition) {
                            return o_definition.id == s_extend || o_definition.name == s_extend;
                        });
            
                        if (o_property) {

                            var o_clone = Ext.clone(o_property);

                            var o_rule = o_clone.rule || {};
                    
                            Ext.apply(o_clone, o_rule);
                    
                            delete o_clone.rule;


                            if (o_clone.hasOwnProperty("extend")) {
            
                                var a_extend = Ext.Array.from(o_clone.extend);
                
                                var a_result = i_self.getExtended(a_extend, a_definition);
                
                                a_return = a_return.concat(a_result);
                            }
                            else {
                                a_return.push(o_clone);
                            }
                        }			
                    });
            
                    return a_return;
                },
            
                getExtendedFormCollection: function (a_values, a_definition) {
            
                    var i_self = this;
            
                    var a_return = [];
            
                    Ext.Array.each(a_values, function(s_extend) {
            
                        var o_property = Ext.Array.findBy(a_definition, function (o_definition) {
                            return (o_definition.id == s_extend || o_definition.name == s_extend) && o_definition.type == "formCollection";
                        });
            
                        if (o_property) {

                            var o_clone = Ext.clone(o_property);

                            var o_rule = o_clone.rule || {};
                    
                            Ext.apply(o_clone, o_rule);
                    
                            delete o_clone.rule;

                            if (o_clone.hasOwnProperty("extend") && o_clone.extend.length > 0) {
            
                                var a_extend = Ext.Array.from(o_clone.extend);
                
                                var a_result = i_self.getExtendedFormCollection(a_extend, a_definition);
                
                                a_return = a_return.concat(a_result);
                            }
                            else {
                                a_return.push(o_clone);
                            }
                        }			
                    });
            
                    return a_return;
                },
            
                processProperties: function(o_config) {
            
                    var o_apply = {};
            
                    Ext.Object.each(o_config, function(s_key, value) {
            
                        switch (s_key) {
                            case "dbtype":
            
                                var s_type = value;
            
                                var a_type = /\(\d*|[,.]*d\)/g.exec(value);
                                var a_length = /\d+/g.exec(value);
            
                                if (a_type) {
            
                                    s_type = value.substr(0, a_type.index);
                                }
            
                                Ext.apply(o_apply, {
                                    datatype: s_type,
                                });
            
                                if (a_length) {
            
                                    var n_end = value.indexOf(")");
                                    var n_length = n_end - a_length.index;
                                    var s_number = value.substr(a_length.index, n_length);
            
                                    s_number = s_number.replace(",", ".");
            
                                    s_type = s_type.toLowerCase();
            
                                    switch (s_type) {
                                        case "char":
                                        case "varchar":
                                            Ext.apply(o_apply, {
                                                maxLength: Ext.Number.parseInt(s_number),
                                            });
                                            break;
                                        case "dec":
                                        case "decimal":
                                        case "int":
                                        case "integer":
                                        case "smallint":
                                        case "bigint":
                                        case "int":
                                        case "integer":
            
                                            var n_digital;
                                            var s_first;
            
                                            if (s_number.indexOf(".") > -1) {
            
                                                var a_split = s_number.split(".");
            
                                                var s_digital = a_split[0];
                                                var s_decimal = a_split[1];
            
                                                n_digital =  Ext.Number.parseFloat(s_digital);
                                                var n_decimal = Ext.Number.parseFloat(s_decimal) || 0;
                                                var n_precision = n_decimal;
                                                
            
                                                s_first = "";
                                                var s_last = "";
            
                                                while(n_digital) {
                                                    s_first += "9";
                                                    n_digital--;
                                                }
            
                                                while(n_decimal) {
                                                    s_last += "9";
                                                    n_decimal--;
                                                }
            
                                                var n_maxValue = Ext.Number.parseFloat([s_first, s_last].join("."));
            
                                                Ext.apply(o_apply, {
                                                    maxValue: n_maxValue,
                                                    decimalPrecision: n_precision
                                                });
            
                                            }
                                            else {
            
                                                n_digital = Ext.Number.parseFloat(s_number) || 0;
                                                s_first = "";
            
                                                while(n_digital) {
                                                    s_first += "9";
                                                    n_digital--;
                                                }
            
                                                Ext.apply(o_apply, {
                                                    maxValue: Ext.Number.parseInt(s_first),
                                                    decimalPrecision: 0
                                                });
                                            }
                                            break;
                                        case "timestamp":
                                        case "isotimestamp":
                                        case "date":
                                            Ext.apply(o_apply, {
                                                maxValue: Ext.Number.parseInt(s_number),
                                            });
            
                                            break;
                                        default:
                                            break;
                                    }
            
                                }
            
                                delete o_config[s_key];
            
                                break;
            
                            default:
                                break;
                        }
                    });
            
                    Ext.apply(o_config, o_apply);
            
                    return o_config;
                },
            
                createUI: function(o_data, a_definition) {
            
                    var i_self = this;
            
                    var o_processed = i_self.processData(o_data, a_definition);
            
                    var a_items = i_self.createItems(o_processed);
            
                    return a_items;
            
                },
            
                createItems: function(o_processed) {
            
                    var i_self = this;
            
                    var a_items = [];
            
                    Ext.Object.each(o_processed, function(s_key, o_property) {
            
                        if (o_property.type == "collection" || o_property.type == "group") {
                            if (o_property.apperence == "field") {
                                a_items.push(i_self.createField(o_property));
                            }
                            else {
                                a_items.push(i_self.createGroup(o_property));
                            }
                        }
                        else if (o_property.type == "property") {
                            a_items.push(i_self.createField(o_property));
                        }
                    });
            
                    return a_items;
                },
            
                createFormCollection: function(o_data, a_definition, b_config) {
            
                    var i_self = this;
                    
                    var o_formCollection = Ext.Array.findBy(a_definition, function (o_definition) {
                        return (o_definition.id == o_data.fcid  ||
                            o_definition.name == o_data.fcid) && o_definition.type == "formCollection";
                    });
            
                    var o_clone = Ext.clone(o_formCollection);

                    var o_rule = o_clone.rule || {};
            
                    Ext.apply(o_clone, o_rule);
            
                    delete o_clone.rule;
            
                    var a_extend = Ext.Array.from(o_clone.extend);
            
                    if (a_extend.length > 0) {
            
                        var a_recursion = i_self.getExtendedFormCollection(a_extend, a_definition);
            
                        a_recursion.reverse();
            
                        var o_merged = {};
            
                        Ext.Array.each(a_recursion, function(o_extended){
            
                            Ext.Object.each(o_extended, function(s_key, value) {
            
                                if (Ext.isPrimitive(value)) {
                                    o_merged[s_key] = value;
                                }
                                else {
                                    if (Ext.isArray(value)) {
            
                                        var a_temp = Ext.Array.from(o_merged[s_key]) || [];
                                        var a_value = Ext.Array.from(value);
            
                                        a_temp = a_value.concat(a_temp);
            
                                        o_merged[s_key] = a_temp;
                                    }
                                    else{
                                        if (Ext.isObject(value)) {
                                            o_merged[s_key] = Ext.apply(o_merged[s_key] || {}, value);
                                        }
                                    }
                                }
            
                            });
                        });
            
                        Ext.Object.each(o_clone, function (s_key, value) {
            
                            if (Ext.isPrimitive(value)) {
                                o_merged[s_key] = value;
                            }
                            else {
                                if (Ext.isArray(value)) {
            
                                    var a_temp = Ext.Array.from(value) || [];
                                    var a_value = Ext.Array.from(o_merged[s_key]);
            
                                    a_temp = a_value.concat(a_temp);
            
                                    o_merged[s_key] = a_temp;
                                }
                                else {
                                    if (Ext.isObject(value)) {
                                        o_merged[s_key] = Ext.apply(o_merged[s_key] || {}, value);
                                    }
                                }
                            }
            
                        });
            
                        o_clone = o_merged;
            
                        delete o_clone.extend;
                    }
            
                    var a_fields = Ext.Array.from(o_clone.fields || o_clone.items);
            
                    var o_temp = {};
            
                    Ext.Array.each(a_fields, function(s_field) {
                        o_temp[s_field] = o_data[s_field] || "";
                    });
            
                    var o_processed = i_self.processData(o_temp, a_definition);
                    
                    return b_config ? o_processed : i_self.createItems(o_processed);
            
                },
            
                createGroup: function (o_property) {
            
                    var i_self = this;
            
                    var a_items = [];
            
                    Ext.Array.each(o_property.items, function(o_item) {
            
                        var i_field = i_self.createField(o_item);
            
                        i_field.isFormField = false;
            
                        a_items.push(i_field);
                    });
            
                    var i_define = Ext.define(null, {
            
                        extend: "Ext.form.FieldSet",
            
                        mixins: {
                            field: "Ext.form.field.Field"
                        },
            
                        initComponent: function () {
            
                            var i_field = this;
            
                            i_field.initField();
            
                            i_field.callParent(arguments);
                        },
            
                        getValue: function () {
            
                            var i_field = this;
            
                            var o_value = {};
            
                            if (!i_field.items.getRange) {
                                return i_field.mixins.field.getValue.call(i_field);
                            }
            
                            var a_items = i_field.items.getRange();
            
                            Ext.Array.each(a_items, function (i_subfield) {
                                o_value[i_subfield.name] = i_subfield.getSubmitValue ? i_subfield.getSubmitValue() : i_subfield.getValue();
                            });
            
                            return o_value;
                        },
            
                        getSubmitData: function () {
                            var i_field = this;
                            var o_data = null;
            
                            if (!i_field.disabled && i_field.submitValue) {
                                o_data = {};
                                o_data[i_field.getName()] = i_field.getSubmitValue();
                            }
                            return o_data;
                        },
            
                        getSubmitValue: function () {
            
                            var i_field = this;
            
                            return i_field.getValue();
                        },
                        setValue: function (o_value) {
            
                            var i_field = this;
            
                            var a_items = Ext.Array.from(i_field.items.getRange());
            
                            Ext.Array.each(a_items, function (i_subfield) {
                                i_subfield.setValue(o_value[i_subfield.name]);
                            });
            
                            i_field.mixins.field.setValue.call(i_field, o_value);
                        },
                        checkChange: function () {
            
                            var i_self = this;
                            var newVal;
                            var oldVal;
            
                            if (!i_self.suspendCheckChange && !i_self.destroying && !i_self.destroyed) {
                                newVal = i_self.getValue();
                                oldVal = i_self.lastValue;
                                if (i_self.didValueChange(newVal, oldVal)) {
                                    i_self.lastValue = newVal;
                                    i_self.fireEvent("change", i_self, newVal, oldVal);
                                    i_self.onChange(newVal, oldVal);
                                }
                            }
                        },
                        didValueChange: function (newVal, oldVal) {
            
                            var s_new = Ext.encode(newVal);
                            var s_old = Ext.encode(oldVal);
            
                            return s_new != s_old;
                        },
                        isDirty: function () {
            
                            var i_field = this;
            
                            var s_originalValue = Ext.encode(i_field.originalValue);
                            var s_value = Ext.encode(i_field.getSubmitValue());
            
                            return s_originalValue != s_value;
                        }
                    });
                    
            
                    var i_group = i_define.create({
                        title: o_property.title || o_property.label || o_property.name,
                        name: o_property.name,
                        items: a_items,
                        collapsible: true,
                        collapsed: false,
                        layout: "anchor",
                        defaults: {
                            minWidth: 1024,
                            labelWidth: 150
                        }
                    });
            
                    return i_group;
                },
            
                createField: function (o_property) {
            
                    var i_self = this;
                    var o_clone = Ext.clone(o_property);
            
                    var i_field;
            
                    if (o_clone.type == "collection" || o_clone.type == "group") {
            
                        var a_items = [];
            
                        var a_label = [];
            
                        if (o_clone.hasOwnProperty("prioritized")) {
                            var i_prioritized = i_self.createPrioritiezed(o_clone.prioritized);
                            a_items.push(i_prioritized);
                        }
            
                        a_label.push(o_clone.fieldLabel || o_clone.label || o_clone.name);
            
                        Ext.Array.each(o_property.items, function (o_item) {
            
                            var i_field = i_self.createField(o_item);
            
                            i_field.fieldLabel = "";
                            i_field.isFormField = false;
            
                            a_items.push(i_field);
                        });
            
                        var i_define = Ext.define(null, {
            
                            extend: "Ext.form.FieldContainer",
                            mixins: {
                                field: "Ext.form.field.Field"
                            },
            
                            initComponent: function() {
            
                                var i_field = this;
            
                                i_field.initField();
            
                                i_field.callParent(arguments);
                            },
            
                            getValue: function () {
            
                                var i_field = this;
            
                                var o_value = {};
            
                                if (!i_field.items.getRange) {
                                    return i_field.mixins.field.getValue.call(i_field);
                                }
            
                                var a_items = i_field.items.getRange();
            
                                Ext.Array.each(a_items, function (i_subfield) {
                                    o_value[i_subfield.name] = i_subfield.getSubmitValue ? i_subfield.getSubmitValue() : i_subfield.getValue();
                                });
            
                                return o_value;
                            },
            
                            getSubmitData: function () {
                                var i_field = this;
                                var o_data = null;
            
                                if (!i_field.disabled && i_field.submitValue) {
                                    o_data = {};
                                    o_data[i_field.getName()] = i_field.getSubmitValue();
                                }
                                return o_data;
                            },
            
                            getSubmitValue: function () {
            
                                var i_field = this;
            
                                return i_field.getValue();
                            },
                            setValue: function (o_value) {
            
                                var i_field = this;
            
                                var a_items = Ext.Array.from(i_field.items.getRange());
            
                                Ext.Array.each(a_items, function (i_subfield) {
                                    i_subfield.setValue(o_value[i_subfield.name]);
                                });
            
                                i_field.mixins.field.setValue.call(i_field, o_value);
                            },
                            checkChange: function () {
            
                                var i_self = this;
                                var newVal;
                                var oldVal;
            
                                if (!i_self.suspendCheckChange && !i_self.destroying && !i_self.destroyed) {
                                    newVal = i_self.getValue();
                                    oldVal = i_self.lastValue;
                                    if (i_self.didValueChange(newVal, oldVal)) {
                                        i_self.lastValue = newVal;
                                        i_self.fireEvent("change", i_self, newVal, oldVal);
                                        i_self.onChange(newVal, oldVal);
                                    }
                                }
                            },
                            didValueChange: function(newVal, oldVal) {
            
                                var s_new = Ext.encode(newVal);
                                var s_old = Ext.encode(oldVal);
            
                                return s_new != s_old;
                            },
                            isDirty: function () {
            
                                var i_field = this;
            
                                var s_originalValue = Ext.encode(i_field.originalValue);
                                var s_value = Ext.encode(i_field.getSubmitValue());
            
                                return s_originalValue != s_value;
                            }
                        });
                        
            
                        i_field = i_define.create({
                            title: o_property.name,
                            name: o_property.name,
                            fieldLabel: a_label.join(" / "),
                            items: a_items,
                            layout: {
                                type: "hbox"
                            },
                            defaults: {
                                margin: "0 10 0 0"
                            }
                        });
                    }
                    else {
            
                        var value = o_clone.value;
            
                        if (Ext.isObject(value)) {
                            if (value.hasOwnProperty("prioritized")) {
                                o_clone.prioritized = value.prioritized;
                            }
                        }
            
                        var s_datatype = o_clone.datatype;
            
                        o_clone.fieldLabel = o_clone.fieldLabel || o_clone.label || o_clone.name;
            
                        var a_type = /\(\d*|[,.]*d\)/g.exec(s_datatype);
            
                        if (a_type) {
                            s_datatype = s_datatype.substr(0, a_type.index);
                        }
            
                        s_datatype = s_datatype ? s_datatype.toLowerCase() : "varchar";
            
                        var s_xtype = "textfield";
            
                        switch (s_datatype) {
                            case "char":
                            case "varchar":
            
                                if (o_clone.values) {
            
                                    var a_values = Ext.Array.from(o_clone.values);
            
                                    var i_store = Ext.create("Ext.data.Store", {
                                        data: a_values,
                                        fields: [
                                            {
                                                name: "key",
                                                type: "auto"
                                            },
                                            {
                                                name: "value",
                                                type: "auto"
                                            }
                                        ],
                                        autoLoad: true
                                    });
            
                                    s_xtype = "combobox";
            
                                    Ext.apply(o_clone, {
                                        store: i_store,
                                        displayField: "key",
                                        valueField: "value"
                                    }, o_clone);
                                }
                                else {
                                    s_xtype = o_clone.apperence || "textfield";
                                }
                                break;
                            case "dec":
                            case "decimal":
                            case "int":
                            case "integer":
                            case "smallint":
                            case "bigint":
                            case "int":
                            case "integer":
            
                                    if (o_clone.values) {
            
                                        var a_data = Ext.Array.from(o_clone.values);
            
                                        var i_pStore = Ext.create("Ext.data.Store", {
                                            data: a_data,
                                            fields: [
                                                {
                                                    name: "key",
                                                    type: "auto"
                                                },
                                                {
                                                    name: "value",
                                                    type: "integer"
                                                }
                                            ],
                                            autoLoad: true
                                        });
            
                                        s_xtype = "combobox";
            
                                        Ext.apply(o_clone, {
                                            store: i_pStore,
                                            displayField: "key",
                                            valueField: "value"
                                        });
                                    }
                                    else {
                                        s_xtype = o_clone.apperence || "numberfield";
                                    }
            
            
                                break;
                            case "timestamp":
                            case "isotimestamp":
                                    s_xtype = "isotimestampfield";
                                break;
                            case "date":
                                    s_xtype = "datefield";
                                break;
                            default:
                                break;
                        }
            
                        if (o_clone.apperence) {
            
                            switch(o_clone.apperence) {
                                case "date":
                                    o_clone.apperence = "isotimestampfield";
                                    o_clone.datatype = "timestamp";
                                    s_xtype = "isotimestampfield";
                                    break;
                            }
                        }
            
                        if (o_clone.hasOwnProperty("uom") || o_clone.hasOwnProperty("prioritized")) {
            
                            var s_label = o_clone.fieldLabel;
                            o_clone.fieldLabel = "";
                            o_clone.originalValue = o_clone.value = value.value;
            
                            var i_uomfield = Ext.define(null, {
            
                                extend: "Ext.form.FieldContainer",
                                mixins: {
                                    field: "Ext.form.field.Field"
                                },
                
                                initComponent: function() {
                
                                    var i_field = this;
                
                                    i_field.initField();
                
                                    i_field.callParent(arguments);
                                },
                
                                getValue: function () {
                
                                    var i_field = this;
                
                                    var o_value = {};
                
                                    if (!i_field.items.getRange) {
                                        return i_field.mixins.field.getValue.call(i_field);
                                    }
                
                                    var a_items = i_field.items.getRange();
                
                                    Ext.Array.each(a_items, function (i_subfield) {
                                        if (i_subfield.uom) {
                                            o_value.value = i_subfield.getSubmitValue ? i_subfield.getSubmitValue() : i_subfield.getValue();
                                        }
                                        else {
                                            o_value[i_subfield.name] = i_subfield.getSubmitValue ? i_subfield.getSubmitValue() : i_subfield.getValue();
                                        }
                                    });
                
                                    return o_value;
                                },
                
                                getSubmitData: function () {
                                    var i_field = this;
                                    var o_data = null;
                
                                    if (!i_field.disabled && i_field.submitValue) {
                                        o_data = {};
                                        o_data[i_field.getName()] = i_field.getSubmitValue();
                                    }
                                    return o_data;
                                },
                
                                getSubmitValue: function () {
                
                                    var i_field = this;
                
                                    return i_field.getValue();
                                },
                                setValue: function (o_value) {
                
                                    var i_field = this;
                
                                    var a_items = Ext.Array.from(i_field.items.getRange());
                
                                    Ext.Array.each(a_items, function (i_subfield) {
                                        i_subfield.setValue(o_value[i_subfield.name]);
                                    });
                
                                    i_field.mixins.field.setValue.call(i_field, o_value);
                                },
                                checkChange: function () {
                
                                    var i_self = this;
                                    var newVal;
                                    var oldVal;
                
                                    if (!i_self.suspendCheckChange && !i_self.destroying && !i_self.destroyed) {
                                        newVal = i_self.getValue();
                                        oldVal = i_self.lastValue;
                                        if (i_self.didValueChange(newVal, oldVal)) {
                                            i_self.lastValue = newVal;
                                            i_self.fireEvent("change", i_self, newVal, oldVal);
                                            i_self.onChange(newVal, oldVal);
                                        }
                                    }
                                },
                                didValueChange: function(newVal, oldVal) {
                
                                    var s_new = Ext.encode(newVal);
                                    var s_old = Ext.encode(oldVal);
                
                                    return s_new != s_old;
                                },
                                isDirty: function () {
                
                                    var i_field = this;
                
                                    var s_originalValue = Ext.encode(i_field.originalValue);
                                    var s_value = Ext.encode(i_field.getSubmitValue());
                
                                    return s_originalValue != s_value;
                                }
                            });
            
                            var i_primary = Ext.widget(s_xtype, o_clone);
            
                            var a_temp = [
                                i_primary
                            ];
            
                            if (o_clone.hasOwnProperty("uom")) {
                                var i_uom = i_self.createUOM(o_clone.uom);
                                a_temp.push(i_uom);
                            }
            
                            if (o_clone.hasOwnProperty("prioritized")) {
                                var i_prioritized = i_self.createPrioritiezed(o_clone.prioritized);
                                a_temp.unshift(i_prioritized);
                            }
            
                            i_field = i_uomfield.create({
                                name: o_clone.name,
                                fieldLabel: s_label,
                                items: a_temp,
                                layout: {
                                    type: "hbox"
                                },
                                defaults: {
                                    margin: "0 10 0 0"
                                }
                            });
                        }
                        else{
                            i_field = Ext.widget(s_xtype, o_clone);
                        }
                    }
            
                    return i_field;
                },
                
                createUOM: function(value) {
            
                    var o_config = {
                        name: "uom",
                        isFormField: false,
                        margin: "0 0 0 0"
                    };
            
                    var s_xtype = "";
            
                    if (Ext.isArray(value)) {
            
                        var a_values = Ext.Array.from(value);
            
                        var i_store = Ext.create("Ext.data.Store", {
                            data: a_values,
                            fields: [
                                {
                                    name: "key",
                                    type: "auto"
                                },
                                {
                                    name: "value",
                                    type: "auto"
                                }
                            ],
                            autoLoad: true
                        });
            
                        s_xtype = "combobox";
            
                        Ext.apply(o_config, {
                            store: i_store,
                            displayField: "key",
                            valueField: "value",
                            value: value
                        });
                    }
                    else {
                        s_xtype = "i18ntextfield";
            
                        Ext.apply(o_config, {
                            readOnly: true,
                            value: value
                        });
                    }
            
                    var i_field = Ext.widget(s_xtype, o_config);
            
                    return i_field;
                },
            
                createPrioritiezed: function(value) {
            
                    var o_config = {
                        name: "prioritized",
                        isFormField: false,
                        value: value
                    };
            
                    var i_field = Ext.widget("checkbox", o_config);
            
                    return i_field;
                },
            
                getFormFields: function(o_formCollection, a_definition) {
            
                    var i_self = this;
            
                    var o_clone = Ext.clone(o_formCollection);
            
                    var a_extend = Ext.Array.from(o_clone.extend);
            
                    if (a_extend.length > 0) {
            
                        var a_recursion = i_self.getExtended(a_extend, a_definition);
            
                        a_recursion.reverse();
            
                        var o_merged = {};
            
                        Ext.Array.each(a_recursion, function(o_extended){
            
                            Ext.Object.each(o_extended, function(s_key, value) {
            
                                if (Ext.isPrimitive(value)) {
                                    o_merged[s_key] = value;
                                }
                                else {
                                    if (Ext.isArray(value)) {
            
                                        var a_temp = Ext.Array.from(o_merged[s_key]) || [];
                                        var a_value = Ext.Array.from(value);
            
                                        a_temp = a_value.concat(a_temp);
            
                                        o_merged[s_key] = a_temp;
                                    }
                                    else{
                                        if (Ext.isObject(value)) {
                                            o_merged[s_key] = Ext.apply(o_merged[s_key] || {}, value);
                                        }
                                    }
                                }
            
                            });
                        });
            
                        Ext.Object.each(o_clone, function (s_key, value) {
            
                            if (Ext.isPrimitive(value)) {
                                o_merged[s_key] = value;
                            }
                            else {
                                if (Ext.isArray(value)) {
            
                                    var a_temp = Ext.Array.from(value) || [];
                                    var a_value = Ext.Array.from(o_merged[s_key]);
            
                                    a_temp = a_value.concat(a_temp);
            
                                    o_merged[s_key] = a_temp;
                                }
                                else {
                                    if (Ext.isObject(value)) {
                                        o_merged[s_key] = Ext.apply(o_merged[s_key] || {}, value);
                                    }
                                }
                            }
            
                        });
            
                        o_clone = o_merged;
            
                        delete o_clone.extend;
                    }
            
                    var a_fields = Ext.Array.from(o_clone.fields || o_clone.items);
            
                    return a_fields;
                }
            }
        }
    }
};