/*! JSON Editor v0.7.23 - JSON Schema -> HTML Editor
 * By Jeremy Dorn - https://github.com/jdorn/json-editor/
 * Released under the MIT license
 *
 * Date: 2015-09-27
 */

/**
 * See README.md for requirements and usage info
 */

(function() {

    /*jshint loopfunc: true */
    /* Simple JavaScript Inheritance
     * By John Resig http://ejohn.org/
     * MIT Licensed.
     */
    // Inspired by base2 and Prototype
    var Class;
    (function() {
        var initializing = false,
            fnTest = /xyz/.test(function() {
                window.postMessage("xyz");
            }) ? /\b_super\b/ : /.*/;

        // The base Class implementation (does nothing)
        Class = function() {};

        // Create a new Class that inherits from this class
        Class.extend = function(prop) {
            var _super = this.prototype;

            // Instantiate a base class (but only create the instance,
            // don't run the init constructor)
            initializing = true;
            var prototype = new this();
            initializing = false;

            // Copy the properties over onto the new prototype
            for (var name in prop) {
                // Check if we're overwriting an existing function
                prototype[name] = typeof prop[name] == "function" &&
                    typeof _super[name] == "function" && fnTest.test(prop[name]) ?
                    (function(name, fn) {
                    return function() {
                        var tmp = this._super;

                        // Add a new ._super() method that is the same method
                        // but on the super-class
                        this._super = _super[name];

                        // The method only need to be bound temporarily, so we
                        // remove it when we're done executing
                        var ret = fn.apply(this, arguments);
                        this._super = tmp;

                        return ret;
                    };
                })(name, prop[name]) :
                    prop[name];
            }

            // The dummy class constructor

            function Class() {
                // All construction is actually done in the init method
                if (!initializing && this.init)
                    this.init.apply(this, arguments);
            }

            // Populate our constructed prototype object
            Class.prototype = prototype;

            // Enforce the constructor to be what we expect
            Class.prototype.constructor = Class;

            // And make this class extendable
            Class.extend = arguments.callee;

            return Class;
        };

        return Class;
    })();

    // CustomEvent constructor polyfill
    // From MDN
    (function() {
        function CustomEvent(event, params) {
            params = params || {
                bubbles: false,
                cancelable: false,
                detail: undefined
            };
            var evt = document.createEvent('CustomEvent');
            evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
            return evt;
        }

        CustomEvent.prototype = window.Event.prototype;

        window.CustomEvent = CustomEvent;
    })();

    // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
    // MIT license
    (function() {
        var lastTime = 0;
        var vendors = ['ms', 'moz', 'webkit', 'o'];
        for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
            window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
            window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||
                window[vendors[x] + 'CancelRequestAnimationFrame'];
        }

        if (!window.requestAnimationFrame)
            window.requestAnimationFrame = function(callback, element) {
                var currTime = new Date().getTime();
                var timeToCall = Math.max(0, 16 - (currTime - lastTime));
                var id = window.setTimeout(function() {
                        callback(currTime + timeToCall);
                    },
                    timeToCall);
                lastTime = currTime + timeToCall;
                return id;
            };

        if (!window.cancelAnimationFrame)
            window.cancelAnimationFrame = function(id) {
                clearTimeout(id);
            };
    }());

    // Array.isArray polyfill
    // From MDN
    (function() {
        if (!Array.isArray) {
            Array.isArray = function(arg) {
                return Object.prototype.toString.call(arg) === '[object Array]';
            };
        }
    }());
    /**
     * Taken from jQuery 2.1.3
     *
     * @param obj
     * @returns {boolean}
     */
    var $isplainobject = function(obj) {
        // Not plain objects:
        // - Any object or value whose internal [[Class]] property is not "[object Object]"
        // - DOM nodes
        // - window
        if (typeof obj !== "object" || obj.nodeType || (obj !== null && obj === obj.window)) {
            return false;
        }

        if (obj.constructor && !Object.prototype.hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf")) {
            return false;
        }

        // If the function hasn't returned already, we're confident that
        // |obj| is a plain object, created by {} or constructed with new Object
        return true;
    };

    var $extend = function(destination) {
        var source, i, property;
        for (i = 1; i < arguments.length; i++) {
            source = arguments[i];
            for (property in source) {
                if (!source.hasOwnProperty(property)) continue;
                if (source[property] && $isplainobject(source[property])) {
                    if (!destination.hasOwnProperty(property)) destination[property] = {};
                    $extend(destination[property], source[property]);
                } else {
                    destination[property] = source[property];
                }
            }
        }
        return destination;
    };

    var $each = function(obj, callback) {
        if (!obj || typeof obj !== "object") return;
        var i;
        if (Array.isArray(obj) || (typeof obj.length === 'number' && obj.length > 0 && (obj.length - 1) in obj)) {
            for (i = 0; i < obj.length; i++) {
                if (callback(i, obj[i]) === false) return;
            }
        } else {
            if (Object.keys) {
                var keys = Object.keys(obj);
                for (i = 0; i < keys.length; i++) {
                    if (callback(keys[i], obj[keys[i]]) === false) return;
                }
            } else {
                for (i in obj) {
                    if (!obj.hasOwnProperty(i)) continue;
                    if (callback(i, obj[i]) === false) return;
                }
            }
        }
    };

    var $trigger = function(el, event) {
        var e = document.createEvent('HTMLEvents');
        e.initEvent(event, true, true);
        el.dispatchEvent(e);
    };
    var $triggerc = function(el, event) {
        var e = new CustomEvent(event, {
            bubbles: true,
            cancelable: true
        });

        el.dispatchEvent(e);
    };

    var JSONEditor = function(element, options) {
        if (!(element instanceof Element)) {
            throw new Error('element should be an instance of Element');
        }
        options = $extend({}, JSONEditor.defaults.options, options || {});
        this.element = element;
        this.options = options;
        this.init();
    };
    JSONEditor.prototype = {
        // necessary since we remove the ctor property by doing a literal assignment. Without this
        // the $isplainobject function will think that this is a plain object.
        constructor: JSONEditor,
        init: function() {
            var self = this;

            this.ready = false;

            var theme_class = JSONEditor.defaults.themes[this.options.theme || JSONEditor.defaults.theme];
            if (!theme_class) throw "Unknown theme " + (this.options.theme || JSONEditor.defaults.theme);

            this.schema = this.options.schema;
            this.theme = new theme_class();
            this.template = this.options.template;
            this.refs = this.options.refs || {};
            this.uuid = 0;
            this.__data = {};

            var icon_class = JSONEditor.defaults.iconlibs[this.options.iconlib || JSONEditor.defaults.iconlib];
            if (icon_class) this.iconlib = new icon_class();

            this.root_container = this.theme.getContainer();
            this.element.appendChild(this.root_container);

            this.translate = this.options.translate || JSONEditor.defaults.translate;

            // Fetch all external refs via ajax
            this._loadExternalRefs(this.schema, function() {
                self._getDefinitions(self.schema);

                // Validator options
                var validator_options = {};
                if (self.options.custom_validators) {
                    validator_options.custom_validators = self.options.custom_validators;
                }
                self.validator = new JSONEditor.Validator(self, null, validator_options);

                // Create the root editor
                var editor_class = self.getEditorClass(self.schema);
                self.root = self.createEditor(editor_class, {
                    jsoneditor: self,
                    schema: self.schema,
                    required: true,
                    container: self.root_container
                });

                self.root.preBuild();
                self.root.build();
                self.root.postBuild();

                // Starting data
                if (self.options.startval) self.root.setValue(self.options.startval);

                self.validation_results = self.validator.validate(self.root.getValue());
                self.root.showValidationErrors(self.validation_results);
                self.ready = true;

                // Fire ready event asynchronously
                window.requestAnimationFrame(function() {
                    if (!self.ready) return;
                    self.validation_results = self.validator.validate(self.root.getValue());
                    self.root.showValidationErrors(self.validation_results);
                    self.trigger('ready');
                    self.trigger('change');
                });
            });
        },
        getValue: function() {
            if (!this.ready) throw "JSON Editor not ready yet.  Listen for 'ready' event before getting the value";

            return this.root.getValue();
        },
        setValue: function(value) {
            if (!this.ready) throw "JSON Editor not ready yet.  Listen for 'ready' event before setting the value";

            this.root.setValue(value);
            return this;
        },
        validate: function(value) {
            if (!this.ready) throw "JSON Editor not ready yet.  Listen for 'ready' event before validating";

            // Custom value
            if (arguments.length === 1) {
                return this.validator.validate(value);
            }
            // Current value (use cached result)
            else {
                return this.validation_results;
            }
        },
        destroy: function() {
            if (this.destroyed) return;
            if (!this.ready) return;

            this.schema = null;
            this.options = null;
            this.root.destroy();
            this.root = null;
            this.root_container = null;
            this.validator = null;
            this.validation_results = null;
            this.theme = null;
            this.iconlib = null;
            this.template = null;
            this.__data = null;
            this.ready = false;
            this.element.innerHTML = '';

            this.destroyed = true;
        },
        on: function(event, callback) {
            this.callbacks = this.callbacks || {};
            this.callbacks[event] = this.callbacks[event] || [];
            this.callbacks[event].push(callback);

            return this;
        },
        off: function(event, callback) {
            // Specific callback
            if (event && callback) {
                this.callbacks = this.callbacks || {};
                this.callbacks[event] = this.callbacks[event] || [];
                var newcallbacks = [];
                for (var i = 0; i < this.callbacks[event].length; i++) {
                    if (this.callbacks[event][i] === callback) continue;
                    newcallbacks.push(this.callbacks[event][i]);
                }
                this.callbacks[event] = newcallbacks;
            }
            // All callbacks for a specific event
            else if (event) {
                this.callbacks = this.callbacks || {};
                this.callbacks[event] = [];
            }
            // All callbacks for all events
            else {
                this.callbacks = {};
            }

            return this;
        },
        trigger: function(event) {
            if (this.callbacks && this.callbacks[event] && this.callbacks[event].length) {
                for (var i = 0; i < this.callbacks[event].length; i++) {
                    this.callbacks[event][i]();
                }
            }

            return this;
        },
        setOption: function(option, value) {
            if (option === "show_errors") {
                this.options.show_errors = value;
                this.onChange();
            }
            // Only the `show_errors` option is supported for now
            else {
                throw "Option " + option + " must be set during instantiation and cannot be changed later";
            }

            return this;
        },
        getEditorClass: function(schema) {
            var classname;

            schema = this.expandSchema(schema);

            $each(JSONEditor.defaults.resolvers, function(i, resolver) {
                var tmp = resolver(schema);
                if (tmp) {
                    if (JSONEditor.defaults.editors[tmp]) {
                        classname = tmp;
                        return false;
                    }
                }
            });

            if (!classname) throw "Unknown editor for schema " + JSON.stringify(schema);
            if (!JSONEditor.defaults.editors[classname]) throw "Unknown editor " + classname;

            return JSONEditor.defaults.editors[classname];
        },
        createEditor: function(editor_class, options) {
            options = $extend({}, editor_class.options || {}, options);
            return new editor_class(options);
        },
        onChange: function() {
            if (!this.ready) return;

            if (this.firing_change) return;
            this.firing_change = true;

            var self = this;

            window.requestAnimationFrame(function() {
                self.firing_change = false;
                if (!self.ready) return;

                // Validate and cache results
                self.validation_results = self.validator.validate(self.root.getValue());

                if (self.options.show_errors !== "never") {
                    self.root.showValidationErrors(self.validation_results);
                } else {
                    self.root.showValidationErrors([]);
                }

                // Fire change event
                self.trigger('change');
            });

            return this;
        },
        compileTemplate: function(template, name) {
            name = name || JSONEditor.defaults.template;

            var engine;

            // Specifying a preset engine
            if (typeof name === 'string') {
                if (!JSONEditor.defaults.templates[name]) throw "Unknown template engine " + name;
                engine = JSONEditor.defaults.templates[name]();

                if (!engine) throw "Template engine " + name + " missing required library.";
            }
            // Specifying a custom engine
            else {
                engine = name;
            }

            if (!engine) throw "No template engine set";
            if (!engine.compile) throw "Invalid template engine set";

            return engine.compile(template);
        },
        _data: function(el, key, value) {
            // Setting data
            if (arguments.length === 3) {
                var uuid;
                if (el.hasAttribute('data-jsoneditor-' + key)) {
                    uuid = el.getAttribute('data-jsoneditor-' + key);
                } else {
                    uuid = this.uuid++;
                    el.setAttribute('data-jsoneditor-' + key, uuid);
                }

                this.__data[uuid] = value;
            }
            // Getting data
            else {
                // No data stored
                if (!el.hasAttribute('data-jsoneditor-' + key)) return null;

                return this.__data[el.getAttribute('data-jsoneditor-' + key)];
            }
        },
        registerEditor: function(editor) {
            this.editors = this.editors || {};
            this.editors[editor.path] = editor;
            return this;
        },
        unregisterEditor: function(editor) {
            this.editors = this.editors || {};
            this.editors[editor.path] = null;
            return this;
        },
        getEditor: function(path) {
            if (!this.editors) return;
            return this.editors[path];
        },
        watch: function(path, callback) {
            this.watchlist = this.watchlist || {};
            this.watchlist[path] = this.watchlist[path] || [];
            this.watchlist[path].push(callback);

            return this;
        },
        unwatch: function(path, callback) {
            if (!this.watchlist || !this.watchlist[path]) return this;
            // If removing all callbacks for a path
            if (!callback) {
                this.watchlist[path] = null;
                return this;
            }

            var newlist = [];
            for (var i = 0; i < this.watchlist[path].length; i++) {
                if (this.watchlist[path][i] === callback) continue;
                else newlist.push(this.watchlist[path][i]);
            }
            this.watchlist[path] = newlist.length ? newlist : null;
            return this;
        },
        notifyWatchers: function(path) {
            if (!this.watchlist || !this.watchlist[path]) return this;
            for (var i = 0; i < this.watchlist[path].length; i++) {
                this.watchlist[path][i]();
            }
        },
        isEnabled: function() {
            return !this.root || this.root.isEnabled();
        },
        enable: function() {
            this.root.enable();
        },
        disable: function() {
            this.root.disable();
        },
        _getDefinitions: function(schema, path) {
            path = path || '#/definitions/';
            if (schema.definitions) {
                for (var i in schema.definitions) {
                    if (!schema.definitions.hasOwnProperty(i)) continue;
                    this.refs[path + i] = schema.definitions[i];
                    if (schema.definitions[i].definitions) {
                        this._getDefinitions(schema.definitions[i], path + i + '/definitions/');
                    }
                }
            }
        },
        _getExternalRefs: function(schema) {
            var refs = {};
            var merge_refs = function(newrefs) {
                for (var i in newrefs) {
                    if (newrefs.hasOwnProperty(i)) {
                        refs[i] = true;
                    }
                }
            };

            if (schema.$ref && typeof schema.$ref !== "object" && schema.$ref.substr(0, 1) !== "#" && !this.refs[schema.$ref]) {
                refs[schema.$ref] = true;
            }

            for (var i in schema) {
                if (!schema.hasOwnProperty(i)) continue;
                if (schema[i] && typeof schema[i] === "object" && Array.isArray(schema[i])) {
                    for (var j = 0; j < schema[i].length; j++) {
                        if (typeof schema[i][j] === "object") {
                            merge_refs(this._getExternalRefs(schema[i][j]));
                        }
                    }
                } else if (schema[i] && typeof schema[i] === "object") {
                    merge_refs(this._getExternalRefs(schema[i]));
                }
            }

            return refs;
        },
        _loadExternalRefs: function(schema, callback) {
            var self = this;
            var refs = this._getExternalRefs(schema);

            var done = 0,
                waiting = 0,
                callback_fired = false;

            $each(refs, function(url) {
                if (self.refs[url]) return;
                if (!self.options.ajax) throw "Must set ajax option to true to load external ref " + url;
                self.refs[url] = 'loading';
                waiting++;

                var r = new XMLHttpRequest();
                r.open("GET", url, true);
                r.onreadystatechange = function() {
                    if (r.readyState != 4) return;
                    // Request succeeded
                    if (r.status === 200) {
                        var response;
                        try {
                            response = JSON.parse(r.responseText);
                        } catch (e) {
                            window.console.log(e);
                            throw "Failed to parse external ref " + url;
                        }
                        if (!response || typeof response !== "object") throw "External ref does not contain a valid schema - " + url;

                        self.refs[url] = response;
                        self._loadExternalRefs(response, function() {
                            done++;
                            if (done >= waiting && !callback_fired) {
                                callback_fired = true;
                                callback();
                            }
                        });
                    }
                    // Request failed
                    else {
                        window.console.log(r);
                        throw "Failed to fetch ref via ajax- " + url;
                    }
                };
                r.send();
            });

            if (!waiting) {
                callback();
            }
        },
        expandRefs: function(schema) {
            schema = $extend({}, schema);

            while (schema.$ref) {
                var ref = schema.$ref;
                delete schema.$ref;

                if (!this.refs[ref]) ref = decodeURIComponent(ref);

                schema = this.extendSchemas(schema, this.refs[ref]);
            }
            return schema;
        },
        expandSchema: function(schema) {
            var self = this;
            var extended = $extend({}, schema);
            var i;

            // Version 3 `type`
            if (typeof schema.type === 'object') {
                // Array of types
                if (Array.isArray(schema.type)) {
                    $each(schema.type, function(key, value) {
                        // Schema
                        if (typeof value === 'object') {
                            schema.type[key] = self.expandSchema(value);
                        }
                    });
                }
                // Schema
                else {
                    schema.type = self.expandSchema(schema.type);
                }
            }
            // Version 3 `disallow`
            if (typeof schema.disallow === 'object') {
                // Array of types
                if (Array.isArray(schema.disallow)) {
                    $each(schema.disallow, function(key, value) {
                        // Schema
                        if (typeof value === 'object') {
                            schema.disallow[key] = self.expandSchema(value);
                        }
                    });
                }
                // Schema
                else {
                    schema.disallow = self.expandSchema(schema.disallow);
                }
            }
            // Version 4 `anyOf`
            if (schema.anyOf) {
                $each(schema.anyOf, function(key, value) {
                    schema.anyOf[key] = self.expandSchema(value);
                });
            }
            // Version 4 `dependencies` (schema dependencies)
            if (schema.dependencies) {
                $each(schema.dependencies, function(key, value) {
                    if (typeof value === "object" && !(Array.isArray(value))) {
                        schema.dependencies[key] = self.expandSchema(value);
                    }
                });
            }
            // Version 4 `not`
            if (schema.not) {
                schema.not = this.expandSchema(schema.not);
            }

            // allOf schemas should be merged into the parent
            if (schema.allOf) {
                for (i = 0; i < schema.allOf.length; i++) {
                    extended = this.extendSchemas(extended, this.expandSchema(schema.allOf[i]));
                }
                delete extended.allOf;
            }
            // extends schemas should be merged into parent
            if (schema["extends"]) {
                // If extends is a schema
                if (!(Array.isArray(schema["extends"]))) {
                    extended = this.extendSchemas(extended, this.expandSchema(schema["extends"]));
                }
                // If extends is an array of schemas
                else {
                    for (i = 0; i < schema["extends"].length; i++) {
                        extended = this.extendSchemas(extended, this.expandSchema(schema["extends"][i]));
                    }
                }
                delete extended["extends"];
            }
            // parent should be merged into oneOf schemas
            if (schema.oneOf) {
                var tmp = $extend({}, extended);
                delete tmp.oneOf;
                for (i = 0; i < schema.oneOf.length; i++) {
                    extended.oneOf[i] = this.extendSchemas(this.expandSchema(schema.oneOf[i]), tmp);
                }
            }

            return this.expandRefs(extended);
        },
        extendSchemas: function(obj1, obj2) {
            obj1 = $extend({}, obj1);
            obj2 = $extend({}, obj2);

            var self = this;
            var extended = {};
            $each(obj1, function(prop, val) {
                // If this key is also defined in obj2, merge them
                if (typeof obj2[prop] !== "undefined") {
                    // Required arrays should be unioned together
                    if (prop === 'required' && typeof val === "object" && Array.isArray(val)) {
                        // Union arrays and unique
                        extended.required = val.concat(obj2[prop]).reduce(function(p, c) {
                            if (p.indexOf(c) < 0) p.push(c);
                            return p;
                        }, []);
                    }
                    // Type should be intersected and is either an array or string
                    else if (prop === 'type' && (typeof val === "string" || Array.isArray(val))) {
                        // Make sure we're dealing with arrays
                        if (typeof val === "string") val = [val];
                        if (typeof obj2.type === "string") obj2.type = [obj2.type];


                        extended.type = val.filter(function(n) {
                            return obj2.type.indexOf(n) !== -1;
                        });

                        // If there's only 1 type and it's a primitive, use a string instead of array
                        if (extended.type.length === 1 && typeof extended.type[0] === "string") {
                            extended.type = extended.type[0];
                        }
                    }
                    // All other arrays should be intersected (enum, etc.)
                    else if (typeof val === "object" && Array.isArray(val)) {
                        extended[prop] = val.filter(function(n) {
                            return obj2[prop].indexOf(n) !== -1;
                        });
                    }
                    // Objects should be recursively merged
                    else if (typeof val === "object" && val !== null) {
                        extended[prop] = self.extendSchemas(val, obj2[prop]);
                    }
                    // Otherwise, use the first value
                    else {
                        extended[prop] = val;
                    }
                }
                // Otherwise, just use the one in obj1
                else {
                    extended[prop] = val;
                }
            });
            // Properties in obj2 that aren't in obj1
            $each(obj2, function(prop, val) {
                if (typeof obj1[prop] === "undefined") {
                    extended[prop] = val;
                }
            });

            return extended;
        }
    };

    JSONEditor.defaults = {
        themes: {},
        templates: {},
        iconlibs: {},
        editors: {},
        languages: {},
        resolvers: [],
        custom_validators: []
    };

    JSONEditor.Validator = Class.extend({
        init: function(jsoneditor, schema, options) {
            this.jsoneditor = jsoneditor;
            this.schema = schema || this.jsoneditor.schema;
            this.options = options || {};
            this.translate = this.jsoneditor.translate || JSONEditor.defaults.translate;
        },
        validate: function(value) {
            return this._validateSchema(this.schema, value);
        },
        _validateSchema: function(schema, value, path) {
            var self = this;
            var errors = [];
            var valid, i, j;
            var stringified = JSON.stringify(value);

            path = path || 'root';

            // Work on a copy of the schema
            schema = $extend({}, this.jsoneditor.expandRefs(schema));

            /*
             * Type Agnostic Validation
             */

            // Version 3 `required`
            if (schema.required && schema.required === true) {
                if (typeof value === "undefined") {
                    errors.push({
                        path: path,
                        property: 'required',
                        message: this.translate("error_notset")
                    });

                    // Can't do any more validation at this point
                    return errors;
                }
            }
            // Value not defined
            else if (typeof value === "undefined") {
                // If required_by_default is set, all fields are required
                if (this.jsoneditor.options.required_by_default) {
                    errors.push({
                        path: path,
                        property: 'required',
                        message: this.translate("error_notset")
                    });
                }
                // Not required, no further validation needed
                else {
                    return errors;
                }
            }

            // `enum`
            if (schema["enum"]) {
                valid = false;
                for (i = 0; i < schema["enum"].length; i++) {
                    if (stringified === JSON.stringify(schema["enum"][i])) valid = true;
                }
                if (!valid) {
                    errors.push({
                        path: path,
                        property: 'enum',
                        message: this.translate("error_enum")
                    });
                }
            }

            // `extends` (version 3)
            if (schema["extends"]) {
                for (i = 0; i < schema["extends"].length; i++) {
                    errors = errors.concat(this._validateSchema(schema["extends"][i], value, path));
                }
            }

            // `allOf`
            if (schema.allOf) {
                for (i = 0; i < schema.allOf.length; i++) {
                    errors = errors.concat(this._validateSchema(schema.allOf[i], value, path));
                }
            }

            // `anyOf`
            if (schema.anyOf) {
                valid = false;
                for (i = 0; i < schema.anyOf.length; i++) {
                    if (!this._validateSchema(schema.anyOf[i], value, path).length) {
                        valid = true;
                        break;
                    }
                }
                if (!valid) {
                    errors.push({
                        path: path,
                        property: 'anyOf',
                        message: this.translate('error_anyOf')
                    });
                }
            }

            // `oneOf`
            if (schema.oneOf) {
                valid = 0;
                var oneof_errors = [];
                for (i = 0; i < schema.oneOf.length; i++) {
                    // Set the error paths to be path.oneOf[i].rest.of.path
                    var tmp = this._validateSchema(schema.oneOf[i], value, path);
                    if (!tmp.length) {
                        valid++;
                    }

                    for (j = 0; j < tmp.length; j++) {
                        tmp[j].path = path + '.oneOf[' + i + ']' + tmp[j].path.substr(path.length);
                    }
                    oneof_errors = oneof_errors.concat(tmp);

                }
                if (valid !== 1) {
                    errors.push({
                        path: path,
                        property: 'oneOf',
                        message: this.translate('error_oneOf', [valid])
                    });
                    errors = errors.concat(oneof_errors);
                }
            }

            // `not`
            if (schema.not) {
                if (!this._validateSchema(schema.not, value, path).length) {
                    errors.push({
                        path: path,
                        property: 'not',
                        message: this.translate('error_not')
                    });
                }
            }

            // `type` (both Version 3 and Version 4 support)
            if (schema.type) {
                // Union type
                if (Array.isArray(schema.type)) {
                    valid = false;
                    for (i = 0; i < schema.type.length; i++) {
                        if (this._checkType(schema.type[i], value)) {
                            valid = true;
                            break;
                        }
                    }
                    if (!valid) {
                        errors.push({
                            path: path,
                            property: 'type',
                            message: this.translate('error_type_union')
                        });
                    }
                }
                // Simple type
                else {
                    if (!this._checkType(schema.type, value)) {
                        errors.push({
                            path: path,
                            property: 'type',
                            message: this.translate('error_type', [schema.type])
                        });
                    }
                }
            }


            // `disallow` (version 3)
            if (schema.disallow) {
                // Union type
                if (Array.isArray(schema.disallow)) {
                    valid = true;
                    for (i = 0; i < schema.disallow.length; i++) {
                        if (this._checkType(schema.disallow[i], value)) {
                            valid = false;
                            break;
                        }
                    }
                    if (!valid) {
                        errors.push({
                            path: path,
                            property: 'disallow',
                            message: this.translate('error_disallow_union')
                        });
                    }
                }
                // Simple type
                else {
                    if (this._checkType(schema.disallow, value)) {
                        errors.push({
                            path: path,
                            property: 'disallow',
                            message: this.translate('error_disallow', [schema.disallow])
                        });
                    }
                }
            }

            /*
             * Type Specific Validation
             */

            // Number Specific Validation
            if (typeof value === "number") {
                // `multipleOf` and `divisibleBy`
                if (schema.multipleOf || schema.divisibleBy) {
                    valid = value / (schema.multipleOf || schema.divisibleBy);
                    if (valid !== Math.floor(valid)) {
                        errors.push({
                            path: path,
                            property: schema.multipleOf ? 'multipleOf' : 'divisibleBy',
                            message: this.translate('error_multipleOf', [schema.multipleOf || schema.divisibleBy])
                        });
                    }
                }

                // `maximum`
                if (schema.hasOwnProperty('maximum')) {
                    if (schema.exclusiveMaximum && value >= schema.maximum) {
                        errors.push({
                            path: path,
                            property: 'maximum',
                            message: this.translate('error_maximum_excl', [schema.maximum])
                        });
                    } else if (!schema.exclusiveMaximum && value > schema.maximum) {
                        errors.push({
                            path: path,
                            property: 'maximum',
                            message: this.translate('error_maximum_incl', [schema.maximum])
                        });
                    }
                }

                // `minimum`
                if (schema.hasOwnProperty('minimum')) {
                    if (schema.exclusiveMinimum && value <= schema.minimum) {
                        errors.push({
                            path: path,
                            property: 'minimum',
                            message: this.translate('error_minimum_excl', [schema.minimum])
                        });
                    } else if (!schema.exclusiveMinimum && value < schema.minimum) {
                        errors.push({
                            path: path,
                            property: 'minimum',
                            message: this.translate('error_minimum_incl', [schema.minimum])
                        });
                    }
                }
            }
            // String specific validation
            else if (typeof value === "string") {
                // `maxLength`
                if (schema.maxLength) {
                    if ((value + "").length > schema.maxLength) {
                        errors.push({
                            path: path,
                            property: 'maxLength',
                            message: this.translate('error_maxLength', [schema.maxLength])
                        });
                    }
                }

                // `minLength`
                if (schema.minLength) {
                    if ((value + "").length < schema.minLength) {
                        errors.push({
                            path: path,
                            property: 'minLength',
                            message: this.translate((schema.minLength === 1 ? 'error_notempty' : 'error_minLength'), [schema.minLength])
                        });
                    }
                }

                // `pattern`
                if (schema.pattern) {
                    if (!(new RegExp(schema.pattern)).test(value)) {
                        errors.push({
                            path: path,
                            property: 'pattern',
                            message: this.translate('error_pattern')
                        });
                    }
                }
            }
            // Array specific validation
            else if (typeof value === "object" && value !== null && Array.isArray(value)) {
                // `items` and `additionalItems`
                if (schema.items) {
                    // `items` is an array
                    if (Array.isArray(schema.items)) {
                        for (i = 0; i < value.length; i++) {
                            // If this item has a specific schema tied to it
                            // Validate against it
                            if (schema.items[i]) {
                                errors = errors.concat(this._validateSchema(schema.items[i], value[i], path + '.' + i));
                            }
                            // If all additional items are allowed
                            else if (schema.additionalItems === true) {
                                break;
                            }
                            // If additional items is a schema
                            // TODO: Incompatibility between version 3 and 4 of the spec
                            else if (schema.additionalItems) {
                                errors = errors.concat(this._validateSchema(schema.additionalItems, value[i], path + '.' + i));
                            }
                            // If no additional items are allowed
                            else if (schema.additionalItems === false) {
                                errors.push({
                                    path: path,
                                    property: 'additionalItems',
                                    message: this.translate('error_additionalItems')
                                });
                                break;
                            }
                            // Default for `additionalItems` is an empty schema
                            else {
                                break;
                            }
                        }
                    }
                    // `items` is a schema
                    else {
                        // Each item in the array must validate against the schema
                        for (i = 0; i < value.length; i++) {
                            errors = errors.concat(this._validateSchema(schema.items, value[i], path + '.' + i));
                        }
                    }
                }

                // `maxItems`
                if (schema.maxItems) {
                    if (value.length > schema.maxItems) {
                        errors.push({
                            path: path,
                            property: 'maxItems',
                            message: this.translate('error_maxItems', [schema.maxItems])
                        });
                    }
                }

                // `minItems`
                if (schema.minItems) {
                    if (value.length < schema.minItems) {
                        errors.push({
                            path: path,
                            property: 'minItems',
                            message: this.translate('error_minItems', [schema.minItems])
                        });
                    }
                }

                // `uniqueItems`
                if (schema.uniqueItems) {
                    var seen = {};
                    for (i = 0; i < value.length; i++) {
                        valid = JSON.stringify(value[i]);
                        if (seen[valid]) {
                            errors.push({
                                path: path,
                                property: 'uniqueItems',
                                message: this.translate('error_uniqueItems')
                            });
                            break;
                        }
                        seen[valid] = true;
                    }
                }
            }
            // Object specific validation
            else if (typeof value === "object" && value !== null) {
                // `maxProperties`
                if (schema.maxProperties) {
                    valid = 0;
                    for (i in value) {
                        if (!value.hasOwnProperty(i)) continue;
                        valid++;
                    }
                    if (valid > schema.maxProperties) {
                        errors.push({
                            path: path,
                            property: 'maxProperties',
                            message: this.translate('error_maxProperties', [schema.maxProperties])
                        });
                    }
                }

                // `minProperties`
                if (schema.minProperties) {
                    valid = 0;
                    for (i in value) {
                        if (!value.hasOwnProperty(i)) continue;
                        valid++;
                    }
                    if (valid < schema.minProperties) {
                        errors.push({
                            path: path,
                            property: 'minProperties',
                            message: this.translate('error_minProperties', [schema.minProperties])
                        });
                    }
                }

                // Version 4 `required`
                if (schema.required && Array.isArray(schema.required)) {
                    for (i = 0; i < schema.required.length; i++) {
                        if (typeof value[schema.required[i]] === "undefined") {
                            errors.push({
                                path: path,
                                property: 'required',
                                message: this.translate('error_required', [schema.required[i]])
                            });
                        }
                    }
                }

                // `properties`
                var validated_properties = {};
                if (schema.properties) {
                    for (i in schema.properties) {
                        if (!schema.properties.hasOwnProperty(i)) continue;
                        validated_properties[i] = true;
                        errors = errors.concat(this._validateSchema(schema.properties[i], value[i], path + '.' + i));
                    }
                }

                // `patternProperties`
                if (schema.patternProperties) {
                    for (i in schema.patternProperties) {
                        if (!schema.patternProperties.hasOwnProperty(i)) continue;

                        var regex = new RegExp(i);

                        // Check which properties match
                        for (j in value) {
                            if (!value.hasOwnProperty(j)) continue;
                            if (regex.test(j)) {
                                validated_properties[j] = true;
                                errors = errors.concat(this._validateSchema(schema.patternProperties[i], value[j], path + '.' + j));
                            }
                        }
                    }
                }

                // The no_additional_properties option currently doesn't work with extended schemas that use oneOf or anyOf
                if (typeof schema.additionalProperties === "undefined" && this.jsoneditor.options.no_additional_properties && !schema.oneOf && !schema.anyOf) {
                    schema.additionalProperties = false;
                }

                // `additionalProperties`
                if (typeof schema.additionalProperties !== "undefined") {
                    for (i in value) {
                        if (!value.hasOwnProperty(i)) continue;
                        if (!validated_properties[i]) {
                            // No extra properties allowed
                            if (!schema.additionalProperties) {
                                errors.push({
                                    path: path,
                                    property: 'additionalProperties',
                                    message: this.translate('error_additional_properties', [i])
                                });
                                break;
                            }
                            // Allowed
                            else if (schema.additionalProperties === true) {
                                break;
                            }
                            // Must match schema
                            // TODO: incompatibility between version 3 and 4 of the spec
                            else {
                                errors = errors.concat(this._validateSchema(schema.additionalProperties, value[i], path + '.' + i));
                            }
                        }
                    }
                }

                // `dependencies`
                if (schema.dependencies) {
                    for (i in schema.dependencies) {
                        if (!schema.dependencies.hasOwnProperty(i)) continue;

                        // Doesn't need to meet the dependency
                        if (typeof value[i] === "undefined") continue;

                        // Property dependency
                        if (Array.isArray(schema.dependencies[i])) {
                            for (j = 0; j < schema.dependencies[i].length; j++) {
                                if (typeof value[schema.dependencies[i][j]] === "undefined") {
                                    errors.push({
                                        path: path,
                                        property: 'dependencies',
                                        message: this.translate('error_dependency', [schema.dependencies[i][j]])
                                    });
                                }
                            }
                        }
                        // Schema dependency
                        else {
                            errors = errors.concat(this._validateSchema(schema.dependencies[i], value, path));
                        }
                    }
                }
            }

            // Custom type validation (global)
            $each(JSONEditor.defaults.custom_validators, function(i, validator) {
                errors = errors.concat(validator.call(self, schema, value, path));
            });
            // Custom type validation (instance specific)
            if (this.options.custom_validators) {
                $each(this.options.custom_validators, function(i, validator) {
                    errors = errors.concat(validator.call(self, schema, value, path));
                });
            }

            return errors;
        },
        _checkType: function(type, value) {
            // Simple types
            if (typeof type === "string") {
                if (type === "string") return typeof value === "string";
                else if (type === "number") return typeof value === "number";
                else if (type === "integer") return typeof value === "number" && value === Math.floor(value);
                else if (type === "boolean") return typeof value === "boolean";
                else if (type === "array") return Array.isArray(value);
                else if (type === "object") return value !== null && !(Array.isArray(value)) && typeof value === "object";
                else if (type === "null") return value === null;
                else return true;
            }
            // Schema
            else {
                return !this._validateSchema(type, value).length;
            }
        }
    });

    /**
     * All editors should extend from this class
     */
    JSONEditor.AbstractEditor = Class.extend({
        onChildEditorChange: function(editor) {
            this.onChange(true);
        },
        notify: function() {
            this.jsoneditor.notifyWatchers(this.path);
        },
        change: function() {
            if (this.parent) this.parent.onChildEditorChange(this);
            else this.jsoneditor.onChange();
        },
        onChange: function(bubble) {
            this.notify();
            if (this.watch_listener) this.watch_listener();
            if (bubble) this.change();
        },
        register: function() {
            this.jsoneditor.registerEditor(this);
            this.onChange();
        },
        unregister: function() {
            if (!this.jsoneditor) return;
            this.jsoneditor.unregisterEditor(this);
        },
        getNumColumns: function() {
            return 12;
        },
        init: function(options) {
            this.jsoneditor = options.jsoneditor;

            this.theme = this.jsoneditor.theme;
            this.template_engine = this.jsoneditor.template;
            this.iconlib = this.jsoneditor.iconlib;

            this.original_schema = options.schema;
            this.schema = this.jsoneditor.expandSchema(this.original_schema);

            this.options = $extend({}, (this.options || {}), (options.schema.options || {}), options);

            if (!options.path && !this.schema.id) this.schema.id = 'root';
            this.path = options.path || 'root';
            this.formname = options.formname || this.path.replace(/\.([^.]+)/g, '[$1]');
            if (this.jsoneditor.options.form_name_root) this.formname = this.formname.replace(/^root\[/, this.jsoneditor.options.form_name_root + '[');
            this.key = this.path.split('.').pop();
            this.parent = options.parent;

            this.link_watchers = [];

            if (options.container) this.setContainer(options.container);
        },
        setContainer: function(container) {
            this.container = container;
            if (this.schema.id) this.container.setAttribute('data-schemaid', this.schema.id);
            if (this.schema.type && typeof this.schema.type === "string") this.container.setAttribute('data-schematype', this.schema.type);
            this.container.setAttribute('data-schemapath', this.path);
        },

        preBuild: function() {

        },
        build: function() {

        },
        postBuild: function() {
            this.setupWatchListeners();
            this.addLinks();
            this.setValue(this.getDefault(), true);
            this.updateHeaderText();
            this.register();
            this.onWatchedFieldChange();
        },

        setupWatchListeners: function() {
            var self = this;

            // Watched fields
            this.watched = {};
            if (this.schema.vars) this.schema.watch = this.schema.vars;
            this.watched_values = {};
            this.watch_listener = function() {
                if (self.refreshWatchedFieldValues()) {
                    self.onWatchedFieldChange();
                }
            };

            this.register();
            if (this.schema.hasOwnProperty('watch')) {
                var path, path_parts, first, root, adjusted_path;

                for (var name in this.schema.watch) {
                    if (!this.schema.watch.hasOwnProperty(name)) continue;
                    path = this.schema.watch[name];

                    if (Array.isArray(path)) {
                        path_parts = [path[0]].concat(path[1].split('.'));
                    } else {
                        path_parts = path.split('.');
                        if (!self.theme.closest(self.container, '[data-schemaid="' + path_parts[0] + '"]')) path_parts.unshift('#');
                    }
                    first = path_parts.shift();

                    if (first === '#') first = self.jsoneditor.schema.id || 'root';

                    // Find the root node for this template variable
                    root = self.theme.closest(self.container, '[data-schemaid="' + first + '"]');
                    if (!root) throw "Could not find ancestor node with id " + first;

                    // Keep track of the root node and path for use when rendering the template
                    adjusted_path = root.getAttribute('data-schemapath') + '.' + path_parts.join('.');

                    self.jsoneditor.watch(adjusted_path, self.watch_listener);

                    self.watched[name] = adjusted_path;
                }
            }

            // Dynamic header
            if (this.schema.headerTemplate) {
                this.header_template = this.jsoneditor.compileTemplate(this.schema.headerTemplate, this.template_engine);
            }
        },

        addLinks: function() {
            // Add links
            if (!this.no_link_holder) {
                this.link_holder = this.theme.getLinksHolder();
                this.container.appendChild(this.link_holder);
                if (this.schema.links) {
                    for (var i = 0; i < this.schema.links.length; i++) {
                        this.addLink(this.getLink(this.schema.links[i]));
                    }
                }
            }
        },


        getButton: function(text, icon, title) {
            var btnClass = 'json-editor-btn-' + icon;
            if (!this.iconlib) icon = null;
            else icon = this.iconlib.getIcon(icon);

            if (!icon && title) {
                text = title;
                title = null;
            }

            var btn = this.theme.getButton(text, icon, title);
            btn.className += ' ' + btnClass + ' ';
            return btn;
        },
        setButtonText: function(button, text, icon, title) {
            if (!this.iconlib) icon = null;
            else icon = this.iconlib.getIcon(icon);

            if (!icon && title) {
                text = title;
                title = null;
            }

            return this.theme.setButtonText(button, text, icon, title);
        },
        addLink: function(link) {
            if (this.link_holder) this.link_holder.appendChild(link);
        },
        getLink: function(data) {
            var holder, link;

            // Get mime type of the link
            var mime = data.mediaType || 'application/javascript';
            var type = mime.split('/')[0];

            // Template to generate the link href
            var href = this.jsoneditor.compileTemplate(data.href, this.template_engine);

            // Image links
            if (type === 'image') {
                holder = this.theme.getBlockLinkHolder();
                link = document.createElement('a');
                link.setAttribute('target', '_blank');
                var image = document.createElement('img');

                this.theme.createImageLink(holder, link, image);

                // When a watched field changes, update the url  
                this.link_watchers.push(function(vars) {
                    var url = href(vars);
                    link.setAttribute('href', url);
                    link.setAttribute('title', data.rel || url);
                    image.setAttribute('src', url);
                });
            }
            // Audio/Video links
            else if (['audio', 'video'].indexOf(type) >= 0) {
                holder = this.theme.getBlockLinkHolder();

                link = this.theme.getBlockLink();
                link.setAttribute('target', '_blank');

                var media = document.createElement(type);
                media.setAttribute('controls', 'controls');

                this.theme.createMediaLink(holder, link, media);

                // When a watched field changes, update the url  
                this.link_watchers.push(function(vars) {
                    var url = href(vars);
                    link.setAttribute('href', url);
                    link.textContent = data.rel || url;
                    media.setAttribute('src', url);
                });
            }
            // Text links
            else {
                holder = this.theme.getBlockLink();
                holder.setAttribute('target', '_blank');
                holder.textContent = data.rel;

                // When a watched field changes, update the url  
                this.link_watchers.push(function(vars) {
                    var url = href(vars);
                    holder.setAttribute('href', url);
                    holder.textContent = data.rel || url;
                });
            }

            return holder;
        },
        refreshWatchedFieldValues: function() {
            if (!this.watched_values) return;
            var watched = {};
            var changed = false;
            var self = this;

            if (this.watched) {
                var val, editor;
                for (var name in this.watched) {
                    if (!this.watched.hasOwnProperty(name)) continue;
                    editor = self.jsoneditor.getEditor(this.watched[name]);
                    val = editor ? editor.getValue() : null;
                    if (self.watched_values[name] !== val) changed = true;
                    watched[name] = val;
                }
            }

            watched.self = this.getValue();
            if (this.watched_values.self !== watched.self) changed = true;

            this.watched_values = watched;

            return changed;
        },
        getWatchedFieldValues: function() {
            return this.watched_values;
        },
        updateHeaderText: function() {
            if (this.header) {
                // If the header has children, only update the text node's value
                if (this.header.children.length) {
                    for (var i = 0; i < this.header.childNodes.length; i++) {
                        if (this.header.childNodes[i].nodeType === 3) {
                            this.header.childNodes[i].nodeValue = this.getHeaderText();
                            break;
                        }
                    }
                }
                // Otherwise, just update the entire node
                else {
                    this.header.textContent = this.getHeaderText();
                }
            }
        },
        getHeaderText: function(title_only) {
            if (this.header_text) return this.header_text;
            else if (title_only) return this.schema.title;
            else return this.getTitle();
        },
        onWatchedFieldChange: function() {
            var vars;
            if (this.header_template) {
                vars = $extend(this.getWatchedFieldValues(), {
                    key: this.key,
                    i: this.key,
                    i0: (this.key * 1),
                    i1: (this.key * 1 + 1),
                    title: this.getTitle()
                });
                var header_text = this.header_template(vars);

                if (header_text !== this.header_text) {
                    this.header_text = header_text;
                    this.updateHeaderText();
                    this.notify();
                    //this.fireChangeHeaderEvent();
                }
            }
            if (this.link_watchers.length) {
                vars = this.getWatchedFieldValues();
                for (var i = 0; i < this.link_watchers.length; i++) {
                    this.link_watchers[i](vars);
                }
            }
        },
        setValue: function(value) {
            this.value = value;
        },
        getValue: function() {
            return this.value;
        },
        refreshValue: function() {

        },
        getChildEditors: function() {
            return false;
        },
        destroy: function() {
            var self = this;
            this.unregister(this);
            $each(this.watched, function(name, adjusted_path) {
                self.jsoneditor.unwatch(adjusted_path, self.watch_listener);
            });
            this.watched = null;
            this.watched_values = null;
            this.watch_listener = null;
            this.header_text = null;
            this.header_template = null;
            this.value = null;
            if (this.container && this.container.parentNode) this.container.parentNode.removeChild(this.container);
            this.container = null;
            this.jsoneditor = null;
            this.schema = null;
            this.path = null;
            this.key = null;
            this.parent = null;
        },
        getDefault: function() {
            if (this.schema["default"]) return this.schema["default"];
            if (this.schema["enum"]) return this.schema["enum"][0];

            var type = this.schema.type || this.schema.oneOf;
            if (type && Array.isArray(type)) type = type[0];
            if (type && typeof type === "object") type = type.type;
            if (type && Array.isArray(type)) type = type[0];

            if (typeof type === "string") {
                if (type === "number") return 0.0;
                if (type === "boolean") return false;
                if (type === "integer") return 0;
                if (type === "string") return "";
                if (type === "object") return {};
                if (type === "array") return [];
            }

            return null;
        },
        getTitle: function() {
            return this.schema.title || this.key;
        },
        enable: function() {
            this.disabled = false;
        },
        disable: function() {
            this.disabled = true;
        },
        isEnabled: function() {
            return !this.disabled;
        },
        isRequired: function() {
            if (typeof this.schema.required === "boolean") return this.schema.required;
            else if (this.parent && this.parent.schema && Array.isArray(this.parent.schema.required)) return this.parent.schema.required.indexOf(this.key) > -1;
            else if (this.jsoneditor.options.required_by_default) return true;
            else return false;
        },
        getDisplayText: function(arr) {
            var disp = [];
            var used = {};

            // Determine how many times each attribute name is used.
            // This helps us pick the most distinct display text for the schemas.
            $each(arr, function(i, el) {
                if (el.title) {
                    used[el.title] = used[el.title] || 0;
                    used[el.title]++;
                }
                if (el.description) {
                    used[el.description] = used[el.description] || 0;
                    used[el.description]++;
                }
                if (el.format) {
                    used[el.format] = used[el.format] || 0;
                    used[el.format]++;
                }
                if (el.type) {
                    used[el.type] = used[el.type] || 0;
                    used[el.type]++;
                }
            });

            // Determine display text for each element of the array
            $each(arr, function(i, el) {
                var name;

                // If it's a simple string
                if (typeof el === "string") name = el;
                // Object
                else if (el.title && used[el.title] <= 1) name = el.title;
                else if (el.format && used[el.format] <= 1) name = el.format;
                else if (el.type && used[el.type] <= 1) name = el.type;
                else if (el.description && used[el.description] <= 1) name = el.descripton;
                else if (el.title) name = el.title;
                else if (el.format) name = el.format;
                else if (el.type) name = el.type;
                else if (el.description) name = el.description;
                else if (JSON.stringify(el).length < 50) name = JSON.stringify(el);
                else name = "type";

                disp.push(name);
            });

            // Replace identical display text with "text 1", "text 2", etc.
            var inc = {};
            $each(disp, function(i, name) {
                inc[name] = inc[name] || 0;
                inc[name]++;

                if (used[name] > 1) disp[i] = name + " " + inc[name];
            });

            return disp;
        },
        getOption: function(key) {
            try {
                throw "getOption is deprecated";
            } catch (e) {
                window.console.error(e);
            }

            return this.options[key];
        },
        showValidationErrors: function(errors) {

        }
    });

    JSONEditor.defaults.editors["null"] = JSONEditor.AbstractEditor.extend({
        getValue: function() {
            return null;
        },
        setValue: function() {
            this.onChange();
        },
        getNumColumns: function() {
            return 2;
        }
    });

    JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
        register: function() {
            this._super();
            if (!this.input) return;
            this.input.setAttribute('name', this.formname);
        },
        unregister: function() {
            this._super();
            if (!this.input) return;
            this.input.removeAttribute('name');
        },
        setValue: function(value, initial, from_template) {
            var self = this;

            if (this.template && !from_template) {
                return;
            }

            if (value === null || typeof value === 'undefined') value = "";
            else if (typeof value === "object") value = JSON.stringify(value);
            else if (typeof value !== "string") value = "" + value;

            if (value === this.serialized) return;

            // Sanitize value before setting it
            var sanitized = this.sanitize(value);

            if (this.input.value === sanitized) {
                return;
            }

            this.input.value = sanitized;

            // If using SCEditor, update the WYSIWYG
            if (this.sceditor_instance) {
                this.sceditor_instance.val(sanitized);
            } else if (this.epiceditor) {
                this.epiceditor.importFile(null, sanitized);
            } else if (this.ace_editor) {
                this.ace_editor.setValue(sanitized);
            }

            var changed = from_template || this.getValue() !== value;

            this.refreshValue();

            if (initial) this.is_dirty = false;
            else if (this.jsoneditor.options.show_errors === "change") this.is_dirty = true;

            if (this.adjust_height) this.adjust_height(this.input);

            // Bubble this setValue to parents if the value changed
            this.onChange(changed);
        },
        getNumColumns: function() {
            var min = Math.ceil(Math.max(this.getTitle().length, this.schema.maxLength || 0, this.schema.minLength || 0) / 5);
            var num;

            if (this.input_type === 'textarea') num = 6;
            else if (['text', 'email'].indexOf(this.input_type) >= 0) num = 4;
            else num = 2;

            return Math.min(12, Math.max(min, num));
        },
        build: function() {
            var self = this,
                i;
            if (!this.options.compact) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
            if (this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);

            this.format = this.schema.format;
            if (!this.format && this.schema.media && this.schema.media.type) {
                this.format = this.schema.media.type.replace(/(^(application|text)\/(x-)?(script\.)?)|(-source$)/g, '');
            }
            if (!this.format && this.options.default_format) {
                this.format = this.options.default_format;
            }
            if (this.options.format) {
                this.format = this.options.format;
            }

            // Specific format
            if (this.format) {
                // Text Area
                if (this.format === 'textarea') {
                    this.input_type = 'textarea';
                    this.input = this.theme.getTextareaInput();
                }
                // Range Input
                else if (this.format === 'range') {
                    this.input_type = 'range';
                    var min = this.schema.minimum || 0;
                    var max = this.schema.maximum || Math.max(100, min + 1);
                    var step = 1;
                    if (this.schema.multipleOf) {
                        if (min % this.schema.multipleOf) min = Math.ceil(min / this.schema.multipleOf) * this.schema.multipleOf;
                        if (max % this.schema.multipleOf) max = Math.floor(max / this.schema.multipleOf) * this.schema.multipleOf;
                        step = this.schema.multipleOf;
                    }

                    this.input = this.theme.getRangeInput(min, max, step);
                }
                // Source Code
                else if ([
                    'actionscript',
                    'batchfile',
                    'bbcode',
                    'c',
                    'c++',
                    'cpp',
                    'coffee',
                    'csharp',
                    'css',
                    'dart',
                    'django',
                    'ejs',
                    'erlang',
                    'golang',
                    'handlebars',
                    'haskell',
                    'haxe',
                    'html',
                    'ini',
                    'jade',
                    'java',
                    'javascript',
                    'json',
                    'less',
                    'lisp',
                    'lua',
                    'makefile',
                    'markdown',
                    'matlab',
                    'mysql',
                    'objectivec',
                    'pascal',
                    'perl',
                    'pgsql',
                    'php',
                    'python',
                    'r',
                    'ruby',
                    'sass',
                    'scala',
                    'scss',
                    'smarty',
                    'sql',
                    'stylus',
                    'svg',
                    'twig',
                    'vbscript',
                    'xml',
                    'yaml'
                ].indexOf(this.format) >= 0) {
                    this.input_type = this.format;
                    this.source_code = true;

                    this.input = this.theme.getTextareaInput();
                }
                // HTML5 Input type
                else {
                    this.input_type = this.format;
                    this.input = this.theme.getFormInputField(this.input_type);
                }
            }
            // Normal text input
            else {
                this.input_type = 'text';
                this.input = this.theme.getFormInputField(this.input_type);
            }

            // minLength, maxLength, and pattern
            if (typeof this.schema.maxLength !== "undefined") this.input.setAttribute('maxlength', this.schema.maxLength);
            if (typeof this.schema.pattern !== "undefined") this.input.setAttribute('pattern', this.schema.pattern);
            else if (typeof this.schema.minLength !== "undefined") this.input.setAttribute('pattern', '.{' + this.schema.minLength + ',}');

            if (this.options.compact) {
                this.container.className += ' compact';
            } else {
                if (this.options.input_width) this.input.style.width = this.options.input_width;
            }

            if (this.schema.readOnly || this.schema.readonly || this.schema.template) {
                this.always_disabled = true;
                this.input.disabled = true;
            }

            this.input
                .addEventListener('change', function(e) {
                    e.preventDefault();
                    e.stopPropagation();

                    // Don't allow changing if this field is a template
                    if (self.schema.template) {
                        this.value = self.value;
                        return;
                    }

                    var val = this.value;

                    // sanitize value
                    var sanitized = self.sanitize(val);
                    if (val !== sanitized) {
                        this.value = sanitized;
                    }

                    self.is_dirty = true;

                    self.refreshValue();
                    self.onChange(true);
                }, false);

            if (this.options.input_height) this.input.style.height = this.options.input_height;
            if (this.options.expand_height) {
                this.adjust_height = function(el) {
                    if (!el) return;
                    var i, ch = el.offsetHeight;
                    // Input too short
                    if (el.offsetHeight < el.scrollHeight) {
                        i = 0;
                        while (el.offsetHeight < el.scrollHeight + 3) {
                            if (i > 100) break;
                            i++;
                            ch++;
                            el.style.height = ch + 'px';
                        }
                    } else {
                        i = 0;
                        while (el.offsetHeight >= el.scrollHeight + 3) {
                            if (i > 100) break;
                            i++;
                            ch--;
                            el.style.height = ch + 'px';
                        }
                        el.style.height = (ch + 1) + 'px';
                    }
                };

                this.input.addEventListener('keyup', function(e) {
                    self.adjust_height(this);
                }, false);
                this.input.addEventListener('change', function(e) {
                    self.adjust_height(this);
                }, false);
                this.adjust_height();
            }

            if (this.format) this.input.setAttribute('data-schemaformat', this.format);

            this.control = this.theme.getFormControl(this.label, this.input, this.description);
            this.container.appendChild(this.control);

            // Any special formatting that needs to happen after the input is added to the dom
            window.requestAnimationFrame(function() {
                // Skip in case the input is only a temporary editor,
                // otherwise, in the case of an ace_editor creation,
                // it will generate an error trying to append it to the missing parentNode
                if (self.input.parentNode) self.afterInputReady();
                if (self.adjust_height) self.adjust_height(self.input);
            });

            // Compile and store the template
            if (this.schema.template) {
                this.template = this.jsoneditor.compileTemplate(this.schema.template, this.template_engine);
                this.refreshValue();
            } else {
                this.refreshValue();
            }
        },
        enable: function() {
            if (!this.always_disabled) {
                this.input.disabled = false;
                // TODO: WYSIWYG and Markdown editors
            }
            this._super();
        },
        disable: function() {
            this.input.disabled = true;
            // TODO: WYSIWYG and Markdown editors
            this._super();
        },
        afterInputReady: function() {
            var self = this,
                options;

            // Code editor
            if (this.source_code) {
                // WYSIWYG html and bbcode editor
                if (this.options.wysiwyg && ['html', 'bbcode'].indexOf(this.input_type) >= 0 &&
                    window.jQuery && window.jQuery.fn && window.jQuery.fn.sceditor
                ) {
                    options = $extend({}, {
                        plugins: self.input_type === 'html' ? 'xhtml' : 'bbcode',
                        emoticonsEnabled: false,
                        width: '100%',
                        height: 300
                    }, JSONEditor.plugins.sceditor, self.options.sceditor_options || {});

                    window.jQuery(self.input).sceditor(options);

                    self.sceditor_instance = window.jQuery(self.input).sceditor('instance');

                    self.sceditor_instance.blur(function() {
                        // Get editor's value
                        var val = window.jQuery("<div>" + self.sceditor_instance.val() + "</div>");
                        // Remove sceditor spans/divs
                        window.jQuery('#sceditor-start-marker,#sceditor-end-marker,.sceditor-nlf', val).remove();
                        // Set the value and update
                        self.input.value = val.html();
                        self.value = self.input.value;
                        self.is_dirty = true;
                        self.onChange(true);
                    });
                }
                // EpicEditor for markdown (if it's loaded)
                else if (this.input_type === 'markdown' && window.EpicEditor) {
                    this.epiceditor_container = document.createElement('div');
                    this.input.parentNode.insertBefore(this.epiceditor_container, this.input);
                    this.input.style.display = 'none';

                    options = $extend({}, JSONEditor.plugins.epiceditor, {
                        container: this.epiceditor_container,
                        clientSideStorage: false
                    });

                    this.epiceditor = new window.EpicEditor(options).load();

                    this.epiceditor.importFile(null, this.getValue());

                    this.epiceditor.on('update', function() {
                        var val = self.epiceditor.exportFile();
                        self.input.value = val;
                        self.value = val;
                        self.is_dirty = true;
                        self.onChange(true);
                    });
                }
                // ACE editor for everything else
                else if (window.ace) {
                    var mode = this.input_type;
                    // aliases for c/cpp
                    if (mode === 'cpp' || mode === 'c++' || mode === 'c') {
                        mode = 'c_cpp';
                    }

                    this.ace_container = document.createElement('div');
                    this.ace_container.style.width = '100%';
                    this.ace_container.style.position = 'relative';
                    this.ace_container.style.height = '400px';
                    this.input.parentNode.insertBefore(this.ace_container, this.input);
                    this.input.style.display = 'none';
                    this.ace_editor = window.ace.edit(this.ace_container);

                    this.ace_editor.setValue(this.getValue());

                    // The theme
                    if (JSONEditor.plugins.ace.theme) this.ace_editor.setTheme('ace/theme/' + JSONEditor.plugins.ace.theme);
                    // The mode
                    mode = window.ace.require("ace/mode/" + mode);
                    if (mode) this.ace_editor.getSession().setMode(new mode.Mode());

                    // Listen for changes
                    this.ace_editor.on('change', function() {
                        var val = self.ace_editor.getValue();
                        self.input.value = val;
                        self.refreshValue();
                        self.is_dirty = true;
                        self.onChange(true);
                    });
                }
            }

            self.theme.afterInputReady(self.input);
        },
        refreshValue: function() {
            this.value = this.input.value;
            if (typeof this.value !== "string") this.value = '';
            this.serialized = this.value;
        },
        destroy: function() {
            // If using SCEditor, destroy the editor instance
            if (this.sceditor_instance) {
                this.sceditor_instance.destroy();
            } else if (this.epiceditor) {
                this.epiceditor.unload();
            } else if (this.ace_editor) {
                this.ace_editor.destroy();
            }


            this.template = null;
            if (this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);
            if (this.label && this.label.parentNode) this.label.parentNode.removeChild(this.label);
            if (this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);

            this._super();
        },
        /**
         * This is overridden in derivative editors
         */
        sanitize: function(value) {
            return value;
        },
        /**
         * Re-calculates the value if needed
         */
        onWatchedFieldChange: function() {
            var self = this,
                vars, j;

            // If this editor needs to be rendered by a macro template
            if (this.template) {
                vars = this.getWatchedFieldValues();
                this.setValue(this.template(vars), false, true);
            }

            this._super();
        },
        showValidationErrors: function(errors) {
            var self = this;

            if (this.jsoneditor.options.show_errors === "always") {} else if (!this.is_dirty && this.previous_error_setting === this.jsoneditor.options.show_errors) return;

            this.previous_error_setting = this.jsoneditor.options.show_errors;

            var messages = [];
            $each(errors, function(i, error) {
                if (error.path === self.path) {
                    messages.push(error.message);
                }
            });

            if (messages.length) {
                this.theme.addInputError(this.input, messages.join('. ') + '.');
            } else {
                this.theme.removeInputError(this.input);
            }
        }
    });

    JSONEditor.defaults.editors.number = JSONEditor.defaults.editors.string.extend({
        sanitize: function(value) {
            return (value + "").replace(/[^0-9\.\-eE]/g, '');
        },
        getNumColumns: function() {
            return 2;
        },
        getValue: function() {
            return this.value * 1;
        }
    });

    JSONEditor.defaults.editors.integer = JSONEditor.defaults.editors.number.extend({
        sanitize: function(value) {
            value = value + "";
            return value.replace(/[^0-9\-]/g, '');
        },
        getNumColumns: function() {
            return 2;
        }
    });

    JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
        getDefault: function() {
            return $extend({}, this.schema["default"] || {});
        },
        getChildEditors: function() {
            return this.editors;
        },
        register: function() {
            this._super();
            if (this.editors) {
                for (var i in this.editors) {
                    if (!this.editors.hasOwnProperty(i)) continue;
                    this.editors[i].register();
                }
            }
        },
        unregister: function() {
            this._super();
            if (this.editors) {
                for (var i in this.editors) {
                    if (!this.editors.hasOwnProperty(i)) continue;
                    this.editors[i].unregister();
                }
            }
        },
        getNumColumns: function() {
            return Math.max(Math.min(12, this.maxwidth), 3);
        },
        enable: function() {
            if (this.editjson_button) this.editjson_button.disabled = false;
            if (this.addproperty_button) this.addproperty_button.disabled = false;

            this._super();
            if (this.editors) {
                for (var i in this.editors) {
                    if (!this.editors.hasOwnProperty(i)) continue;
                    this.editors[i].enable();
                }
            }
        },
        disable: function() {
            if (this.editjson_button) this.editjson_button.disabled = true;
            if (this.addproperty_button) this.addproperty_button.disabled = true;
            this.hideEditJSON();

            this._super();
            if (this.editors) {
                for (var i in this.editors) {
                    if (!this.editors.hasOwnProperty(i)) continue;
                    this.editors[i].disable();
                }
            }
        },
        layoutEditors: function() {
            var self = this,
                i, j;

            if (!this.row_container) return;

            // Sort editors by propertyOrder
            this.property_order = Object.keys(this.editors);
            this.property_order = this.property_order.sort(function(a, b) {
                var ordera = self.editors[a].schema.propertyOrder;
                var orderb = self.editors[b].schema.propertyOrder;
                if (typeof ordera !== "number") ordera = 1000;
                if (typeof orderb !== "number") orderb = 1000;

                return ordera - orderb;
            });

            var container;

            if (this.format === 'grid') {
                var rows = [];
                $each(this.property_order, function(j, key) {
                    var editor = self.editors[key];
                    if (editor.property_removed) return;
                    var found = false;
                    var width = editor.options.hidden ? 0 : (editor.options.grid_columns || editor.getNumColumns());
                    var height = editor.options.hidden ? 0 : editor.container.offsetHeight;
                    // See if the editor will fit in any of the existing rows first
                    for (var i = 0; i < rows.length; i++) {
                        // If the editor will fit in the row horizontally
                        if (rows[i].width + width <= 12) {
                            // If the editor is close to the other elements in height
                            // i.e. Don't put a really tall editor in an otherwise short row or vice versa
                            if (!height || (rows[i].minh * 0.5 < height && rows[i].maxh * 2 > height)) {
                                found = i;
                            }
                        }
                    }

                    // If there isn't a spot in any of the existing rows, start a new row
                    if (found === false) {
                        rows.push({
                            width: 0,
                            minh: 999999,
                            maxh: 0,
                            editors: []
                        });
                        found = rows.length - 1;
                    }

                    rows[found].editors.push({
                        key: key,
                        //editor: editor,
                        width: width,
                        height: height
                    });
                    rows[found].width += width;
                    rows[found].minh = Math.min(rows[found].minh, height);
                    rows[found].maxh = Math.max(rows[found].maxh, height);
                });

                // Make almost full rows width 12
                // Do this by increasing all editors' sizes proprotionately
                // Any left over space goes to the biggest editor
                // Don't touch rows with a width of 6 or less
                for (i = 0; i < rows.length; i++) {
                    if (rows[i].width < 12) {
                        var biggest = false;
                        var new_width = 0;
                        for (j = 0; j < rows[i].editors.length; j++) {
                            if (biggest === false) biggest = j;
                            else if (rows[i].editors[j].width > rows[i].editors[biggest].width) biggest = j;
                            rows[i].editors[j].width *= 12 / rows[i].width;
                            rows[i].editors[j].width = Math.floor(rows[i].editors[j].width);
                            new_width += rows[i].editors[j].width;
                        }
                        if (new_width < 12) rows[i].editors[biggest].width += 12 - new_width;
                        rows[i].width = 12;
                    }
                }

                // layout hasn't changed
                if (this.layout === JSON.stringify(rows)) return false;
                this.layout = JSON.stringify(rows);

                // Layout the form
                container = document.createElement('div');
                for (i = 0; i < rows.length; i++) {
                    var row = this.theme.getGridRow();
                    container.appendChild(row);
                    for (j = 0; j < rows[i].editors.length; j++) {
                        var key = rows[i].editors[j].key;
                        var editor = this.editors[key];

                        if (editor.options.hidden) editor.container.style.display = 'none';
                        else this.theme.setGridColumnSize(editor.container, rows[i].editors[j].width);
                        row.appendChild(editor.container);
                    }
                }
            }
            // Normal layout
            else {
                container = document.createElement('div');
                $each(this.property_order, function(i, key) {
                    var editor = self.editors[key];
                    if (editor.property_removed) return;
                    var row = self.theme.getGridRow();
                    container.appendChild(row);

                    if (editor.options.hidden) editor.container.style.display = 'none';
                    else self.theme.setGridColumnSize(editor.container, 12);
                    row.appendChild(editor.container);
                });
            }
            this.row_container.innerHTML = '';
            this.row_container.appendChild(container);
        },
        getPropertySchema: function(key) {
            // Schema declared directly in properties
            var schema = this.schema.properties[key] || {};
            schema = $extend({}, schema);
            var matched = this.schema.properties[key] ? true : false;

            // Any matching patternProperties should be merged in
            if (this.schema.patternProperties) {
                for (var i in this.schema.patternProperties) {
                    if (!this.schema.patternProperties.hasOwnProperty(i)) continue;
                    var regex = new RegExp(i);
                    if (regex.test(key)) {
                        schema.allOf = schema.allOf || [];
                        schema.allOf.push(this.schema.patternProperties[i]);
                        matched = true;
                    }
                }
            }

            // Hasn't matched other rules, use additionalProperties schema
            if (!matched && this.schema.additionalProperties && typeof this.schema.additionalProperties === "object") {
                schema = $extend({}, this.schema.additionalProperties);
            }

            return schema;
        },
        preBuild: function() {
            this._super();

            this.editors = {};
            this.cached_editors = {};
            var self = this;

            this.format = this.options.layout || this.options.object_layout || this.schema.format || this.jsoneditor.options.object_layout || 'normal';

            this.schema.properties = this.schema.properties || {};

            this.minwidth = 0;
            this.maxwidth = 0;

            // If the object should be rendered as a table row
            if (this.options.table_row) {
                $each(this.schema.properties, function(key, schema) {
                    var editor = self.jsoneditor.getEditorClass(schema);
                    self.editors[key] = self.jsoneditor.createEditor(editor, {
                        jsoneditor: self.jsoneditor,
                        schema: schema,
                        path: self.path + '.' + key,
                        parent: self,
                        compact: true,
                        required: true
                    });
                    self.editors[key].preBuild();

                    var width = self.editors[key].options.hidden ? 0 : (self.editors[key].options.grid_columns || self.editors[key].getNumColumns());

                    self.minwidth += width;
                    self.maxwidth += width;
                });
                this.no_link_holder = true;
            }
            // If the object should be rendered as a table
            else if (this.options.table) {
                // TODO: table display format
                throw "Not supported yet";
            }
            // If the object should be rendered as a div
            else {
                this.defaultProperties = this.schema.defaultProperties || Object.keys(this.schema.properties);

                // Increase the grid width to account for padding
                self.maxwidth += 1;

                $each(this.defaultProperties, function(i, key) {
                    self.addObjectProperty(key, true);

                    if (self.editors[key]) {
                        self.minwidth = Math.max(self.minwidth, (self.editors[key].options.grid_columns || self.editors[key].getNumColumns()));
                        self.maxwidth += (self.editors[key].options.grid_columns || self.editors[key].getNumColumns());
                    }
                });
            }

            // Sort editors by propertyOrder
            this.property_order = Object.keys(this.editors);
            this.property_order = this.property_order.sort(function(a, b) {
                var ordera = self.editors[a].schema.propertyOrder;
                var orderb = self.editors[b].schema.propertyOrder;
                if (typeof ordera !== "number") ordera = 1000;
                if (typeof orderb !== "number") orderb = 1000;

                return ordera - orderb;
            });
        },
        build: function() {
            var self = this;

            // If the object should be rendered as a table row
            if (this.options.table_row) {
                this.editor_holder = this.container;
                $each(this.editors, function(key, editor) {
                    var holder = self.theme.getTableCell();
                    self.editor_holder.appendChild(holder);

                    editor.setContainer(holder);
                    editor.build();
                    editor.postBuild();

                    if (self.editors[key].options.hidden) {
                        holder.style.display = 'none';
                    }
                    if (self.editors[key].options.input_width) {
                        holder.style.width = self.editors[key].options.input_width;
                    }
                });
            }
            // If the object should be rendered as a table
            else if (this.options.table) {
                // TODO: table display format
                throw "Not supported yet";
            }
            // If the object should be rendered as a div
            else {
                this.header = document.createElement('span');
                this.header.textContent = this.getTitle();
                this.title = this.theme.getHeader(this.header);
                this.container.appendChild(this.title);
                this.container.style.position = 'relative';

                // Edit JSON modal
                this.editjson_holder = this.theme.getModal();
                this.editjson_textarea = this.theme.getTextareaInput();
                this.editjson_textarea.style.height = '170px';
                this.editjson_textarea.style.width = '300px';
                this.editjson_textarea.style.display = 'block';
                this.editjson_save = this.getButton('Save', 'save', 'Save');
                this.editjson_save.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    self.saveJSON();
                }, false);
                this.editjson_cancel = this.getButton('Cancel', 'cancel', 'Cancel');
                this.editjson_cancel.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    self.hideEditJSON();
                }, false);
                this.editjson_holder.appendChild(this.editjson_textarea);
                this.editjson_holder.appendChild(this.editjson_save);
                this.editjson_holder.appendChild(this.editjson_cancel);

                // Manage Properties modal
                this.addproperty_holder = this.theme.getModal();
                this.addproperty_list = document.createElement('div');
                this.addproperty_list.style.width = '295px';
                this.addproperty_list.style.maxHeight = '160px';
                this.addproperty_list.style.padding = '5px 0';
                this.addproperty_list.style.overflowY = 'auto';
                this.addproperty_list.style.overflowX = 'hidden';
                this.addproperty_list.style.paddingLeft = '5px';
                this.addproperty_list.setAttribute('class', 'property-selector');
                this.addproperty_add = this.getButton('add', 'add', 'add');
                this.addproperty_input = this.theme.getFormInputField('text');
                this.addproperty_input.setAttribute('placeholder', 'Property name...');
                this.addproperty_input.style.width = '220px';
                this.addproperty_input.style.marginBottom = '0';
                this.addproperty_input.style.display = 'inline-block';
                this.addproperty_add.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    if (self.addproperty_input.value) {
                        if (self.editors[self.addproperty_input.value]) {
                            window.alert('there is already a property with that name');
                            return;
                        }

                        self.addObjectProperty(self.addproperty_input.value);
                        if (self.editors[self.addproperty_input.value]) {
                            self.editors[self.addproperty_input.value].disable();
                        }
                        self.onChange(true);
                    }
                }, false);
                this.addproperty_holder.appendChild(this.addproperty_list);
                this.addproperty_holder.appendChild(this.addproperty_input);
                this.addproperty_holder.appendChild(this.addproperty_add);
                var spacer = document.createElement('div');
                spacer.style.clear = 'both';
                this.addproperty_holder.appendChild(spacer);


                // Description
                if (this.schema.description) {
                    this.description = this.theme.getDescription(this.schema.description);
                    this.container.appendChild(this.description);
                }

                // Validation error placeholder area
                this.error_holder = document.createElement('div');
                this.container.appendChild(this.error_holder);

                // Container for child editor area
                this.editor_holder = this.theme.getIndentedPanel();
                this.container.appendChild(this.editor_holder);

                // Container for rows of child editors
                this.row_container = this.theme.getGridContainer();
                this.editor_holder.appendChild(this.row_container);

                $each(this.editors, function(key, editor) {
                    var holder = self.theme.getGridColumn();
                    self.row_container.appendChild(holder);

                    editor.setContainer(holder);
                    editor.build();
                    editor.postBuild();
                });

                // Control buttons
                this.title_controls = this.theme.getHeaderButtonHolder();
                this.editjson_controls = this.theme.getHeaderButtonHolder();
                this.addproperty_controls = this.theme.getHeaderButtonHolder();
                this.title.appendChild(this.title_controls);
                this.title.appendChild(this.editjson_controls);
                this.title.appendChild(this.addproperty_controls);

                // Show/Hide button
                this.collapsed = false;
                this.toggle_button = this.getButton('', 'collapse', 'Collapse');
                this.title_controls.appendChild(this.toggle_button);
                this.toggle_button.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    if (self.collapsed) {
                        self.editor_holder.style.display = '';
                        self.collapsed = false;
                        self.setButtonText(self.toggle_button, '', 'collapse', 'Collapse');
                    } else {
                        self.editor_holder.style.display = 'none';
                        self.collapsed = true;
                        self.setButtonText(self.toggle_button, '', 'expand', 'Expand');
                    }
                }, false);

                // If it should start collapsed
                if (this.options.collapsed) {
                    $trigger(this.toggle_button, 'click');
                }

                // Collapse button disabled
                if (this.schema.options && typeof this.schema.options.disable_collapse !== "undefined") {
                    if (this.schema.options.disable_collapse) this.toggle_button.style.display = 'none';
                } else if (this.jsoneditor.options.disable_collapse) {
                    this.toggle_button.style.display = 'none';
                }

                // Edit JSON Button
                this.editjson_button = this.getButton('JSON', 'edit', 'Edit JSON');
                this.editjson_button.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    self.toggleEditJSON();
                }, false);
                this.editjson_controls.appendChild(this.editjson_button);
                this.editjson_controls.appendChild(this.editjson_holder);

                // Edit JSON Buttton disabled
                if (this.schema.options && typeof this.schema.options.disable_edit_json !== "undefined") {
                    if (this.schema.options.disable_edit_json) this.editjson_button.style.display = 'none';
                } else if (this.jsoneditor.options.disable_edit_json) {
                    this.editjson_button.style.display = 'none';
                }

                // Object Properties Button
                this.addproperty_button = this.getButton('Properties', 'edit', 'Object Properties');
                this.addproperty_button.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    self.toggleAddProperty();
                }, false);
                this.addproperty_controls.appendChild(this.addproperty_button);
                this.addproperty_controls.appendChild(this.addproperty_holder);
                this.refreshAddProperties();
            }

            // Fix table cell ordering
            if (this.options.table_row) {
                this.editor_holder = this.container;
                $each(this.property_order, function(i, key) {
                    self.editor_holder.appendChild(self.editors[key].container);
                });
            }
            // Layout object editors in grid if needed
            else {
                // Initial layout
                this.layoutEditors();
                // Do it again now that we know the approximate heights of elements
                this.layoutEditors();
            }
        },
        showEditJSON: function() {
            if (!this.editjson_holder) return;
            this.hideAddProperty();

            // Position the form directly beneath the button
            // TODO: edge detection
            this.editjson_holder.style.left = this.editjson_button.offsetLeft + "px";
            this.editjson_holder.style.top = this.editjson_button.offsetTop + this.editjson_button.offsetHeight + "px";

            // Start the textarea with the current value
            this.editjson_textarea.value = JSON.stringify(this.getValue(), null, 2);

            // Disable the rest of the form while editing JSON
            this.disable();

            this.editjson_holder.style.display = '';
            this.editjson_button.disabled = false;
            this.editing_json = true;
        },
        hideEditJSON: function() {
            if (!this.editjson_holder) return;
            if (!this.editing_json) return;

            this.editjson_holder.style.display = 'none';
            this.enable();
            this.editing_json = false;
        },
        saveJSON: function() {
            if (!this.editjson_holder) return;

            try {
                var json = JSON.parse(this.editjson_textarea.value);
                this.setValue(json);
                this.hideEditJSON();
            } catch (e) {
                window.alert('invalid JSON');
                throw e;
            }
        },
        toggleEditJSON: function() {
            if (this.editing_json) this.hideEditJSON();
            else this.showEditJSON();
        },
        insertPropertyControlUsingPropertyOrder: function(property, control, container) {
            var propertyOrder;
            if (this.schema.properties[property])
                propertyOrder = this.schema.properties[property].propertyOrder;
            if (typeof propertyOrder !== "number") propertyOrder = 1000;
            control.propertyOrder = propertyOrder;

            for (var i = 0; i < container.childNodes.length; i++) {
                var child = container.childNodes[i];
                if (control.propertyOrder < child.propertyOrder) {
                    this.addproperty_list.insertBefore(control, child);
                    control = null;
                    break;
                }
            }
            if (control) {
                this.addproperty_list.appendChild(control);
            }
        },
        addPropertyCheckbox: function(key) {
            var self = this;
            var checkbox, label, labelText, control;

            checkbox = self.theme.getCheckbox();
            checkbox.style.width = 'auto';

            if (this.schema.properties[key] && this.schema.properties[key].title)
                labelText = this.schema.properties[key].title;
            else
                labelText = key;

            label = self.theme.getCheckboxLabel(labelText);

            control = self.theme.getFormControl(label, checkbox);
            control.style.paddingBottom = control.style.marginBottom = control.style.paddingTop = control.style.marginTop = 0;
            control.style.height = 'auto';
            //control.style.overflowY = 'hidden';

            this.insertPropertyControlUsingPropertyOrder(key, control, this.addproperty_list);

            checkbox.checked = key in this.editors;
            checkbox.addEventListener('change', function() {
                if (checkbox.checked) {
                    self.addObjectProperty(key);
                } else {
                    self.removeObjectProperty(key);
                }
                self.onChange(true);
            }, false);
            self.addproperty_checkboxes[key] = checkbox;

            return checkbox;
        },
        showAddProperty: function() {
            if (!this.addproperty_holder) return;
            this.hideEditJSON();

            // Position the form directly beneath the button
            // TODO: edge detection
            this.addproperty_holder.style.left = this.addproperty_button.offsetLeft + "px";
            this.addproperty_holder.style.top = this.addproperty_button.offsetTop + this.addproperty_button.offsetHeight + "px";

            // Disable the rest of the form while editing JSON
            this.disable();

            this.adding_property = true;
            this.addproperty_button.disabled = false;
            this.addproperty_holder.style.display = '';
            this.refreshAddProperties();
        },
        hideAddProperty: function() {
            if (!this.addproperty_holder) return;
            if (!this.adding_property) return;

            this.addproperty_holder.style.display = 'none';
            this.enable();

            this.adding_property = false;
        },
        toggleAddProperty: function() {
            if (this.adding_property) this.hideAddProperty();
            else this.showAddProperty();
        },
        removeObjectProperty: function(property) {
            if (this.editors[property]) {
                this.editors[property].unregister();
                delete this.editors[property];

                this.refreshValue();
                this.layoutEditors();
            }
        },
        addObjectProperty: function(name, prebuild_only) {
            var self = this;

            // Property is already added
            if (this.editors[name]) return;

            // Property was added before and is cached
            if (this.cached_editors[name]) {
                this.editors[name] = this.cached_editors[name];
                if (prebuild_only) return;
                this.editors[name].register();
            }
            // New property
            else {
                if (!this.canHaveAdditionalProperties() && (!this.schema.properties || !this.schema.properties[name])) {
                    return;
                }

                var schema = self.getPropertySchema(name);


                // Add the property
                var editor = self.jsoneditor.getEditorClass(schema);

                self.editors[name] = self.jsoneditor.createEditor(editor, {
                    jsoneditor: self.jsoneditor,
                    schema: schema,
                    path: self.path + '.' + name,
                    parent: self
                });
                self.editors[name].preBuild();

                if (!prebuild_only) {
                    var holder = self.theme.getChildEditorHolder();
                    self.editor_holder.appendChild(holder);
                    self.editors[name].setContainer(holder);
                    self.editors[name].build();
                    self.editors[name].postBuild();
                }

                self.cached_editors[name] = self.editors[name];
            }

            // If we're only prebuilding the editors, don't refresh values
            if (!prebuild_only) {
                self.refreshValue();
                self.layoutEditors();
            }
        },
        onChildEditorChange: function(editor) {
            this.refreshValue();
            this._super(editor);
        },
        canHaveAdditionalProperties: function() {
            if (typeof this.schema.additionalProperties === "boolean") {
                return this.schema.additionalProperties;
            }
            return !this.jsoneditor.options.no_additional_properties;
        },
        destroy: function() {
            $each(this.cached_editors, function(i, el) {
                el.destroy();
            });
            if (this.editor_holder) this.editor_holder.innerHTML = '';
            if (this.title && this.title.parentNode) this.title.parentNode.removeChild(this.title);
            if (this.error_holder && this.error_holder.parentNode) this.error_holder.parentNode.removeChild(this.error_holder);

            this.editors = null;
            this.cached_editors = null;
            if (this.editor_holder && this.editor_holder.parentNode) this.editor_holder.parentNode.removeChild(this.editor_holder);
            this.editor_holder = null;

            this._super();
        },
        getValue: function() {
            var result = this._super();
            if (this.jsoneditor.options.remove_empty_properties || this.options.remove_empty_properties) {
                for (var i in result) {
                    if (result.hasOwnProperty(i)) {
                        if (!result[i]) delete result[i];
                    }
                }
            }
            return result;
        },
        refreshValue: function() {
            this.value = {};
            var self = this;

            for (var i in this.editors) {
                if (!this.editors.hasOwnProperty(i)) continue;
                this.value[i] = this.editors[i].getValue();
            }

            if (this.adding_property) this.refreshAddProperties();
        },
        refreshAddProperties: function() {
            if (this.options.disable_properties || (this.options.disable_properties !== false && this.jsoneditor.options.disable_properties)) {
                this.addproperty_controls.style.display = 'none';
                return;
            }

            var can_add = false,
                can_remove = false,
                num_props = 0,
                i, show_modal = false;

            // Get number of editors
            for (i in this.editors) {
                if (!this.editors.hasOwnProperty(i)) continue;
                num_props++;
            }

            // Determine if we can add back removed properties
            can_add = this.canHaveAdditionalProperties() && !(typeof this.schema.maxProperties !== "undefined" && num_props >= this.schema.maxProperties);

            if (this.addproperty_checkboxes) {
                this.addproperty_list.innerHTML = '';
            }
            this.addproperty_checkboxes = {};

            // Check for which editors can't be removed or added back
            for (i in this.cached_editors) {
                if (!this.cached_editors.hasOwnProperty(i)) continue;

                this.addPropertyCheckbox(i);

                if (this.isRequired(this.cached_editors[i]) && i in this.editors) {
                    this.addproperty_checkboxes[i].disabled = true;
                }

                if (typeof this.schema.minProperties !== "undefined" && num_props <= this.schema.minProperties) {
                    this.addproperty_checkboxes[i].disabled = this.addproperty_checkboxes[i].checked;
                    if (!this.addproperty_checkboxes[i].checked) show_modal = true;
                } else if (!(i in this.editors)) {
                    if (!can_add && !this.schema.properties.hasOwnProperty(i)) {
                        this.addproperty_checkboxes[i].disabled = true;
                    } else {
                        this.addproperty_checkboxes[i].disabled = false;
                        show_modal = true;
                    }
                } else {
                    show_modal = true;
                    can_remove = true;
                }
            }

            if (this.canHaveAdditionalProperties()) {
                show_modal = true;
            }

            // Additional addproperty checkboxes not tied to a current editor
            for (i in this.schema.properties) {
                if (!this.schema.properties.hasOwnProperty(i)) continue;
                if (this.cached_editors[i]) continue;
                show_modal = true;
                this.addPropertyCheckbox(i);
            }

            // If no editors can be added or removed, hide the modal button
            if (!show_modal) {
                this.hideAddProperty();
                this.addproperty_controls.style.display = 'none';
            }
            // If additional properties are disabled
            else if (!this.canHaveAdditionalProperties()) {
                this.addproperty_add.style.display = 'none';
                this.addproperty_input.style.display = 'none';
            }
            // If no new properties can be added
            else if (!can_add) {
                this.addproperty_add.disabled = true;
            }
            // If new properties can be added
            else {
                this.addproperty_add.disabled = false;
            }
        },
        isRequired: function(editor) {
            if (typeof editor.schema.required === "boolean") return editor.schema.required;
            else if (Array.isArray(this.schema.required)) return this.schema.required.indexOf(editor.key) > -1;
            else if (this.jsoneditor.options.required_by_default) return true;
            else return false;
        },
        setValue: function(value, initial) {
            var self = this;
            value = value || {};

            if (typeof value !== "object" || Array.isArray(value)) value = {};

            // First, set the values for all of the defined properties
            $each(this.cached_editors, function(i, editor) {
                // Value explicitly set
                if (typeof value[i] !== "undefined") {
                    self.addObjectProperty(i);
                    editor.setValue(value[i], initial);
                }
                // Otherwise, remove value unless this is the initial set or it's required
                else if (!initial && !self.isRequired(editor)) {
                    self.removeObjectProperty(i);
                }
                // Otherwise, set the value to the default
                else {
                    editor.setValue(editor.getDefault(), initial);
                }
            });

            $each(value, function(i, val) {
                if (!self.cached_editors[i]) {
                    self.addObjectProperty(i);
                    if (self.editors[i]) self.editors[i].setValue(val, initial);
                }
            });

            this.refreshValue();
            this.layoutEditors();
            this.onChange();
        },
        showValidationErrors: function(errors) {
            var self = this;

            // Get all the errors that pertain to this editor
            var my_errors = [];
            var other_errors = [];
            $each(errors, function(i, error) {
                if (error.path === self.path) {
                    my_errors.push(error);
                } else {
                    other_errors.push(error);
                }
            });

            // Show errors for this editor
            if (this.error_holder) {
                if (my_errors.length) {
                    var message = [];
                    this.error_holder.innerHTML = '';
                    this.error_holder.style.display = '';
                    $each(my_errors, function(i, error) {
                        self.error_holder.appendChild(self.theme.getErrorMessage(error.message));
                    });
                }
                // Hide error area
                else {
                    this.error_holder.style.display = 'none';
                }
            }

            // Show error for the table row if this is inside a table
            if (this.options.table_row) {
                if (my_errors.length) {
                    this.theme.addTableRowError(this.container);
                } else {
                    this.theme.removeTableRowError(this.container);
                }
            }

            // Show errors for child editors
            $each(this.editors, function(i, editor) {
                editor.showValidationErrors(other_errors);
            });
        }
    });

    JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
        getDefault: function() {
            return this.schema["default"] || [];
        },
        register: function() {
            this._super();
            if (this.rows) {
                for (var i = 0; i < this.rows.length; i++) {
                    this.rows[i].register();
                }
            }
        },
        unregister: function() {
            this._super();
            if (this.rows) {
                for (var i = 0; i < this.rows.length; i++) {
                    this.rows[i].unregister();
                }
            }
        },
        getNumColumns: function() {
            var info = this.getItemInfo(0);
            // Tabs require extra horizontal space
            if (this.tabs_holder) {
                return Math.max(Math.min(12, info.width + 2), 4);
            } else {
                return info.width;
            }
        },
        enable: function() {
            if (this.add_row_button) this.add_row_button.disabled = false;
            if (this.remove_all_rows_button) this.remove_all_rows_button.disabled = false;
            if (this.delete_last_row_button) this.delete_last_row_button.disabled = false;

            if (this.rows) {
                for (var i = 0; i < this.rows.length; i++) {
                    this.rows[i].enable();

                    if (this.rows[i].moveup_button) this.rows[i].moveup_button.disabled = false;
                    if (this.rows[i].movedown_button) this.rows[i].movedown_button.disabled = false;
                    if (this.rows[i].delete_button) this.rows[i].delete_button.disabled = false;
                }
            }
            this._super();
        },
        disable: function() {
            if (this.add_row_button) this.add_row_button.disabled = true;
            if (this.remove_all_rows_button) this.remove_all_rows_button.disabled = true;
            if (this.delete_last_row_button) this.delete_last_row_button.disabled = true;

            if (this.rows) {
                for (var i = 0; i < this.rows.length; i++) {
                    this.rows[i].disable();

                    if (this.rows[i].moveup_button) this.rows[i].moveup_button.disabled = true;
                    if (this.rows[i].movedown_button) this.rows[i].movedown_button.disabled = true;
                    if (this.rows[i].delete_button) this.rows[i].delete_button.disabled = true;
                }
            }
            this._super();
        },
        preBuild: function() {
            this._super();

            this.rows = [];
            this.row_cache = [];

            this.hide_delete_buttons = this.options.disable_array_delete || this.jsoneditor.options.disable_array_delete;
            this.hide_move_buttons = this.options.disable_array_reorder || this.jsoneditor.options.disable_array_reorder;
            this.hide_add_button = this.options.disable_array_add || this.jsoneditor.options.disable_array_add;
        },
        build: function() {
            var self = this;

            if (!this.options.compact) {
                this.header = document.createElement('span');
                this.header.textContent = this.getTitle();
                this.title = this.theme.getHeader(this.header);
                this.container.appendChild(this.title);
                this.title_controls = this.theme.getHeaderButtonHolder();
                this.title.appendChild(this.title_controls);
                if (this.schema.description) {
                    this.description = this.theme.getDescription(this.schema.description);
                    this.container.appendChild(this.description);
                }
                this.error_holder = document.createElement('div');
                this.container.appendChild(this.error_holder);

                if (this.schema.format === 'tabs') {
                    this.controls = this.theme.getHeaderButtonHolder();
                    this.title.appendChild(this.controls);
                    this.tabs_holder = this.theme.getTabHolder();
                    this.container.appendChild(this.tabs_holder);
                    this.row_holder = this.theme.getTabContentHolder(this.tabs_holder);

                    this.active_tab = null;
                } else {
                    this.panel = this.theme.getIndentedPanel();
                    this.container.appendChild(this.panel);
                    this.row_holder = document.createElement('div');
                    this.panel.appendChild(this.row_holder);
                    this.controls = this.theme.getButtonHolder();
                    this.panel.appendChild(this.controls);
                }
            } else {
                this.panel = this.theme.getIndentedPanel();
                this.container.appendChild(this.panel);
                this.controls = this.theme.getButtonHolder();
                this.panel.appendChild(this.controls);
                this.row_holder = document.createElement('div');
                this.panel.appendChild(this.row_holder);
            }

            // Add controls
            this.addControls();
        },
        onChildEditorChange: function(editor) {
            this.refreshValue();
            this.refreshTabs(true);
            this._super(editor);
        },
        getItemTitle: function() {
            if (!this.item_title) {
                if (this.schema.items && !Array.isArray(this.schema.items)) {
                    var tmp = this.jsoneditor.expandRefs(this.schema.items);
                    this.item_title = tmp.title || 'item';
                } else {
                    this.item_title = 'item';
                }
            }
            return this.item_title;
        },
        getItemSchema: function(i) {
            if (Array.isArray(this.schema.items)) {
                if (i >= this.schema.items.length) {
                    if (this.schema.additionalItems === true) {
                        return {};
                    } else if (this.schema.additionalItems) {
                        return $extend({}, this.schema.additionalItems);
                    }
                } else {
                    return $extend({}, this.schema.items[i]);
                }
            } else if (this.schema.items) {
                return $extend({}, this.schema.items);
            } else {
                return {};
            }
        },
        getItemInfo: function(i) {
            var schema = this.getItemSchema(i);

            // Check if it's cached
            this.item_info = this.item_info || {};
            var stringified = JSON.stringify(schema);
            if (typeof this.item_info[stringified] !== "undefined") return this.item_info[stringified];

            // Get the schema for this item
            schema = this.jsoneditor.expandRefs(schema);

            this.item_info[stringified] = {
                title: schema.title || "item",
                'default': schema["default"],
                width: 12,
                child_editors: schema.properties || schema.items
            };

            return this.item_info[stringified];
        },
        getElementEditor: function(i) {
            var item_info = this.getItemInfo(i);
            var schema = this.getItemSchema(i);
            schema = this.jsoneditor.expandRefs(schema);
            schema.title = item_info.title + ' ' + (i + 1);

            var editor = this.jsoneditor.getEditorClass(schema);

            var holder;
            if (this.tabs_holder) {
                holder = this.theme.getTabContent();
            } else if (item_info.child_editors) {
                holder = this.theme.getChildEditorHolder();
            } else {
                holder = this.theme.getIndentedPanel();
            }

            this.row_holder.appendChild(holder);

            var ret = this.jsoneditor.createEditor(editor, {
                jsoneditor: this.jsoneditor,
                schema: schema,
                container: holder,
                path: this.path + '.' + i,
                parent: this,
                required: true
            });
            ret.preBuild();
            ret.build();
            ret.postBuild();

            if (!ret.title_controls) {
                ret.array_controls = this.theme.getButtonHolder();
                holder.appendChild(ret.array_controls);
            }

            return ret;
        },
        destroy: function() {
            this.empty(true);
            if (this.title && this.title.parentNode) this.title.parentNode.removeChild(this.title);
            if (this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);
            if (this.row_holder && this.row_holder.parentNode) this.row_holder.parentNode.removeChild(this.row_holder);
            if (this.controls && this.controls.parentNode) this.controls.parentNode.removeChild(this.controls);
            if (this.panel && this.panel.parentNode) this.panel.parentNode.removeChild(this.panel);

            this.rows = this.row_cache = this.title = this.description = this.row_holder = this.panel = this.controls = null;

            this._super();
        },
        empty: function(hard) {
            if (!this.rows) return;
            var self = this;
            $each(this.rows, function(i, row) {
                if (hard) {
                    if (row.tab && row.tab.parentNode) row.tab.parentNode.removeChild(row.tab);
                    self.destroyRow(row, true);
                    self.row_cache[i] = null;
                }
                self.rows[i] = null;
            });
            self.rows = [];
            if (hard) self.row_cache = [];
        },
        destroyRow: function(row, hard) {
            var holder = row.container;
            if (hard) {
                row.destroy();
                if (holder.parentNode) holder.parentNode.removeChild(holder);
                if (row.tab && row.tab.parentNode) row.tab.parentNode.removeChild(row.tab);
            } else {
                if (row.tab) row.tab.style.display = 'none';
                holder.style.display = 'none';
                row.unregister();
            }
        },
        getMax: function() {
            if ((Array.isArray(this.schema.items)) && this.schema.additionalItems === false) {
                return Math.min(this.schema.items.length, this.schema.maxItems || Infinity);
            } else {
                return this.schema.maxItems || Infinity;
            }
        },
        refreshTabs: function(refresh_headers) {
            var self = this;
            $each(this.rows, function(i, row) {
                if (!row.tab) return;

                if (refresh_headers) {
                    row.tab_text.textContent = row.getHeaderText();
                } else {
                    if (row.tab === self.active_tab) {
                        self.theme.markTabActive(row.tab);
                        row.container.style.display = '';
                    } else {
                        self.theme.markTabInactive(row.tab);
                        row.container.style.display = 'none';
                    }
                }
            });
        },
        setValue: function(value, initial) {
            // Update the array's value, adding/removing rows when necessary
            value = value || [];

            if (!(Array.isArray(value))) value = [value];

            var serialized = JSON.stringify(value);
            if (serialized === this.serialized) return;

            // Make sure value has between minItems and maxItems items in it
            if (this.schema.minItems) {
                while (value.length < this.schema.minItems) {
                    value.push(this.getItemInfo(value.length)["default"]);
                }
            }
            if (this.getMax() && value.length > this.getMax()) {
                value = value.slice(0, this.getMax());
            }

            var self = this;
            $each(value, function(i, val) {
                if (self.rows[i]) {
                    // TODO: don't set the row's value if it hasn't changed
                    self.rows[i].setValue(val, initial);
                } else if (self.row_cache[i]) {
                    self.rows[i] = self.row_cache[i];
                    self.rows[i].setValue(val, initial);
                    self.rows[i].container.style.display = '';
                    if (self.rows[i].tab) self.rows[i].tab.style.display = '';
                    self.rows[i].register();
                } else {
                    self.addRow(val, initial);
                }
            });

            for (var j = value.length; j < self.rows.length; j++) {
                self.destroyRow(self.rows[j]);
                self.rows[j] = null;
            }
            self.rows = self.rows.slice(0, value.length);

            // Set the active tab
            var new_active_tab = null;
            $each(self.rows, function(i, row) {
                if (row.tab === self.active_tab) {
                    new_active_tab = row.tab;
                    return false;
                }
            });
            if (!new_active_tab && self.rows.length) new_active_tab = self.rows[0].tab;

            self.active_tab = new_active_tab;

            self.refreshValue(initial);
            self.refreshTabs(true);
            self.refreshTabs();

            self.onChange();

            // TODO: sortable
        },
        refreshValue: function(force) {
            var self = this;
            var oldi = this.value ? this.value.length : 0;
            this.value = [];

            $each(this.rows, function(i, editor) {
                // Get the value for this editor
                self.value[i] = editor.getValue();
            });

            if (oldi !== this.value.length || force) {
                // If we currently have minItems items in the array
                var minItems = this.schema.minItems && this.schema.minItems >= this.rows.length;

                $each(this.rows, function(i, editor) {
                    // Hide the move down button for the last row
                    if (editor.movedown_button) {
                        if (i === self.rows.length - 1) {
                            editor.movedown_button.style.display = 'none';
                        } else {
                            editor.movedown_button.style.display = '';
                        }
                    }

                    // Hide the delete button if we have minItems items
                    if (editor.delete_button) {
                        if (minItems) {
                            editor.delete_button.style.display = 'none';
                        } else {
                            editor.delete_button.style.display = '';
                        }
                    }

                    // Get the value for this editor
                    self.value[i] = editor.getValue();
                });

                var controls_needed = false;

                if (!this.value.length) {
                    this.delete_last_row_button.style.display = 'none';
                    this.remove_all_rows_button.style.display = 'none';
                } else if (this.value.length === 1) {
                    this.remove_all_rows_button.style.display = 'none';

                    // If there are minItems items in the array, hide the delete button beneath the rows
                    if (minItems || this.hide_delete_buttons) {
                        this.delete_last_row_button.style.display = 'none';
                    } else {
                        this.delete_last_row_button.style.display = '';
                        controls_needed = true;
                    }
                } else {
                    // If there are minItems items in the array, hide the delete button beneath the rows
                    if (minItems || this.hide_delete_buttons) {
                        this.delete_last_row_button.style.display = 'none';
                        this.remove_all_rows_button.style.display = 'none';
                    } else {
                        this.delete_last_row_button.style.display = '';
                        this.remove_all_rows_button.style.display = '';
                        controls_needed = true;
                    }
                }

                // If there are maxItems in the array, hide the add button beneath the rows
                if ((this.getMax() && this.getMax() <= this.rows.length) || this.hide_add_button) {
                    this.add_row_button.style.display = 'none';
                } else {
                    this.add_row_button.style.display = '';
                    controls_needed = true;
                }

                if (!this.collapsed && controls_needed) {
                    this.controls.style.display = 'inline-block';
                } else {
                    this.controls.style.display = 'none';
                }
            }
        },
        addRow: function(value, initial) {
            var self = this;
            var i = this.rows.length;

            self.rows[i] = this.getElementEditor(i);
            self.row_cache[i] = self.rows[i];

            if (self.tabs_holder) {
                self.rows[i].tab_text = document.createElement('span');
                self.rows[i].tab_text.textContent = self.rows[i].getHeaderText();
                self.rows[i].tab = self.theme.getTab(self.rows[i].tab_text);
                self.rows[i].tab.addEventListener('click', function(e) {
                    self.active_tab = self.rows[i].tab;
                    self.refreshTabs();
                    e.preventDefault();
                    e.stopPropagation();
                }, false);

                self.theme.addTab(self.tabs_holder, self.rows[i].tab);
            }

            var controls_holder = self.rows[i].title_controls || self.rows[i].array_controls;

            // Buttons to delete row, move row up, and move row down
            if (!self.hide_delete_buttons) {
                self.rows[i].delete_button = this.getButton(self.getItemTitle(), 'delete', 'Delete ' + self.getItemTitle());
                self.rows[i].delete_button.className += ' delete';
                self.rows[i].delete_button.setAttribute('data-i', i);
                self.rows[i].delete_button.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    var i = this.getAttribute('data-i') * 1;

                    var value = self.getValue();

                    var newval = [];
                    var new_active_tab = null;
                    $each(value, function(j, row) {
                        if (j === i) {
                            // If the one we're deleting is the active tab
                            if (self.rows[j].tab === self.active_tab) {
                                // Make the next tab active if there is one
                                // Note: the next tab is going to be the current tab after deletion
                                if (self.rows[j + 1]) new_active_tab = self.rows[j].tab;
                                // Otherwise, make the previous tab active if there is one
                                else if (j) new_active_tab = self.rows[j - 1].tab;
                            }

                            return; // If this is the one we're deleting
                        }
                        newval.push(row);
                    });
                    self.setValue(newval);
                    if (new_active_tab) {
                        self.active_tab = new_active_tab;
                        self.refreshTabs();
                    }

                    self.onChange(true);
                }, false);

                if (controls_holder) {
                    controls_holder.appendChild(self.rows[i].delete_button);
                }
            }

            if (i && !self.hide_move_buttons) {
                self.rows[i].moveup_button = this.getButton('', 'moveup', 'Move up');
                self.rows[i].moveup_button.className += ' moveup';
                self.rows[i].moveup_button.setAttribute('data-i', i);
                self.rows[i].moveup_button.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    var i = this.getAttribute('data-i') * 1;

                    if (i <= 0) return;
                    var rows = self.getValue();
                    var tmp = rows[i - 1];
                    rows[i - 1] = rows[i];
                    rows[i] = tmp;

                    self.setValue(rows);
                    self.active_tab = self.rows[i - 1].tab;
                    self.refreshTabs();

                    self.onChange(true);
                }, false);

                if (controls_holder) {
                    controls_holder.appendChild(self.rows[i].moveup_button);
                }
            }

            if (!self.hide_move_buttons) {
                self.rows[i].movedown_button = this.getButton('', 'movedown', 'Move down');
                self.rows[i].movedown_button.className += ' movedown';
                self.rows[i].movedown_button.setAttribute('data-i', i);
                self.rows[i].movedown_button.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    var i = this.getAttribute('data-i') * 1;

                    var rows = self.getValue();
                    if (i >= rows.length - 1) return;
                    var tmp = rows[i + 1];
                    rows[i + 1] = rows[i];
                    rows[i] = tmp;

                    self.setValue(rows);
                    self.active_tab = self.rows[i + 1].tab;
                    self.refreshTabs();
                    self.onChange(true);
                }, false);

                if (controls_holder) {
                    controls_holder.appendChild(self.rows[i].movedown_button);
                }
            }

            if (value) self.rows[i].setValue(value, initial);
            self.refreshTabs();
        },
        addControls: function() {
            var self = this;

            this.collapsed = false;
            this.toggle_button = this.getButton('', 'collapse', 'Collapse');
            this.title_controls.appendChild(this.toggle_button);
            var row_holder_display = self.row_holder.style.display;
            var controls_display = self.controls.style.display;
            this.toggle_button.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                if (self.collapsed) {
                    self.collapsed = false;
                    if (self.panel) self.panel.style.display = '';
                    self.row_holder.style.display = row_holder_display;
                    if (self.tabs_holder) self.tabs_holder.style.display = '';
                    self.controls.style.display = controls_display;
                    self.setButtonText(this, '', 'collapse', 'Collapse');
                } else {
                    self.collapsed = true;
                    self.row_holder.style.display = 'none';
                    if (self.tabs_holder) self.tabs_holder.style.display = 'none';
                    self.controls.style.display = 'none';
                    if (self.panel) self.panel.style.display = 'none';
                    self.setButtonText(this, '', 'expand', 'Expand');
                }
            }, false);

            // If it should start collapsed
            if (this.options.collapsed) {
                $trigger(this.toggle_button, 'click');
            }

            // Collapse button disabled
            if (this.schema.options && typeof this.schema.options.disable_collapse !== "undefined") {
                if (this.schema.options.disable_collapse) this.toggle_button.style.display = 'none';
            } else if (this.jsoneditor.options.disable_collapse) {
                this.toggle_button.style.display = 'none';
            }

            // Add "new row" and "delete last" buttons below editor
            this.add_row_button = this.getButton(this.getItemTitle(), 'add', 'Add ' + this.getItemTitle());

            this.add_row_button.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                var i = self.rows.length;
                if (self.row_cache[i]) {
                    self.rows[i] = self.row_cache[i];
                    self.rows[i].setValue(self.rows[i].getDefault());
                    self.rows[i].container.style.display = '';
                    if (self.rows[i].tab) self.rows[i].tab.style.display = '';
                    self.rows[i].register();
                } else {
                    self.addRow();
                }
                self.active_tab = self.rows[i].tab;
                self.refreshTabs();
                self.refreshValue();
                self.onChange(true);
            }, false);
            self.controls.appendChild(this.add_row_button);

            this.delete_last_row_button = this.getButton('Last ' + this.getItemTitle(), 'delete', 'Delete Last ' + this.getItemTitle());
            this.delete_last_row_button.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                var rows = self.getValue();

                var new_active_tab = null;
                if (self.rows.length > 1 && self.rows[self.rows.length - 1].tab === self.active_tab) new_active_tab = self.rows[self.rows.length - 2].tab;

                rows.pop();
                self.setValue(rows);
                if (new_active_tab) {
                    self.active_tab = new_active_tab;
                    self.refreshTabs();
                }
                self.onChange(true);
            }, false);
            self.controls.appendChild(this.delete_last_row_button);

            this.remove_all_rows_button = this.getButton('All', 'delete', 'Delete All');
            this.remove_all_rows_button.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                self.setValue([]);
                self.onChange(true);
            }, false);
            self.controls.appendChild(this.remove_all_rows_button);

            if (self.tabs) {
                this.add_row_button.style.width = '100%';
                this.add_row_button.style.textAlign = 'left';
                this.add_row_button.style.marginBottom = '3px';

                this.delete_last_row_button.style.width = '100%';
                this.delete_last_row_button.style.textAlign = 'left';
                this.delete_last_row_button.style.marginBottom = '3px';

                this.remove_all_rows_button.style.width = '100%';
                this.remove_all_rows_button.style.textAlign = 'left';
                this.remove_all_rows_button.style.marginBottom = '3px';
            }
        },
        showValidationErrors: function(errors) {
            var self = this;

            // Get all the errors that pertain to this editor
            var my_errors = [];
            var other_errors = [];
            $each(errors, function(i, error) {
                if (error.path === self.path) {
                    my_errors.push(error);
                } else {
                    other_errors.push(error);
                }
            });

            // Show errors for this editor
            if (this.error_holder) {
                if (my_errors.length) {
                    var message = [];
                    this.error_holder.innerHTML = '';
                    this.error_holder.style.display = '';
                    $each(my_errors, function(i, error) {
                        self.error_holder.appendChild(self.theme.getErrorMessage(error.message));
                    });
                }
                // Hide error area
                else {
                    this.error_holder.style.display = 'none';
                }
            }

            // Show errors for child editors
            $each(this.rows, function(i, row) {
                row.showValidationErrors(other_errors);
            });
        }
    });

    JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
        register: function() {
            this._super();
            if (this.rows) {
                for (var i = 0; i < this.rows.length; i++) {
                    this.rows[i].register();
                }
            }
        },
        unregister: function() {
            this._super();
            if (this.rows) {
                for (var i = 0; i < this.rows.length; i++) {
                    this.rows[i].unregister();
                }
            }
        },
        getNumColumns: function() {
            return Math.max(Math.min(12, this.width), 3);
        },
        preBuild: function() {
            var item_schema = this.jsoneditor.expandRefs(this.schema.items || {});

            this.item_title = item_schema.title || 'row';
            this.item_default = item_schema["default"] || null;
            this.item_has_child_editors = item_schema.properties || item_schema.items;
            this.width = 12;
            this._super();
        },
        build: function() {
            var self = this;
            this.table = this.theme.getTable();
            this.container.appendChild(this.table);
            this.thead = this.theme.getTableHead();
            this.table.appendChild(this.thead);
            this.header_row = this.theme.getTableRow();
            this.thead.appendChild(this.header_row);
            this.row_holder = this.theme.getTableBody();
            this.table.appendChild(this.row_holder);

            // Determine the default value of array element
            var tmp = this.getElementEditor(0, true);
            this.item_default = tmp.getDefault();
            this.width = tmp.getNumColumns() + 2;

            if (!this.options.compact) {
                this.title = this.theme.getHeader(this.getTitle());
                this.container.appendChild(this.title);
                this.title_controls = this.theme.getHeaderButtonHolder();
                this.title.appendChild(this.title_controls);
                if (this.schema.description) {
                    this.description = this.theme.getDescription(this.schema.description);
                    this.container.appendChild(this.description);
                }
                this.panel = this.theme.getIndentedPanel();
                this.container.appendChild(this.panel);
                this.error_holder = document.createElement('div');
                this.panel.appendChild(this.error_holder);
            } else {
                this.panel = document.createElement('div');
                this.container.appendChild(this.panel);
            }

            this.panel.appendChild(this.table);
            this.controls = this.theme.getButtonHolder();
            this.panel.appendChild(this.controls);

            if (this.item_has_child_editors) {
                var ce = tmp.getChildEditors();
                var order = tmp.property_order || Object.keys(ce);
                for (var i = 0; i < order.length; i++) {
                    var th = self.theme.getTableHeaderCell(ce[order[i]].getTitle());
                    if (ce[order[i]].options.hidden) th.style.display = 'none';
                    self.header_row.appendChild(th);
                }
            } else {
                self.header_row.appendChild(self.theme.getTableHeaderCell(this.item_title));
            }

            tmp.destroy();
            this.row_holder.innerHTML = '';

            // Row Controls column
            this.controls_header_cell = self.theme.getTableHeaderCell(" ");
            self.header_row.appendChild(this.controls_header_cell);

            // Add controls
            this.addControls();
        },
        onChildEditorChange: function(editor) {
            this.refreshValue();
            this._super();
        },
        getItemDefault: function() {
            return $extend({}, {
                "default": this.item_default
            })["default"];
        },
        getItemTitle: function() {
            return this.item_title;
        },
        getElementEditor: function(i, ignore) {
            var schema_copy = $extend({}, this.schema.items);
            var editor = this.jsoneditor.getEditorClass(schema_copy, this.jsoneditor);
            var row = this.row_holder.appendChild(this.theme.getTableRow());
            var holder = row;
            if (!this.item_has_child_editors) {
                holder = this.theme.getTableCell();
                row.appendChild(holder);
            }

            var ret = this.jsoneditor.createEditor(editor, {
                jsoneditor: this.jsoneditor,
                schema: schema_copy,
                container: holder,
                path: this.path + '.' + i,
                parent: this,
                compact: true,
                table_row: true
            });

            ret.preBuild();
            if (!ignore) {
                ret.build();
                ret.postBuild();

                ret.controls_cell = row.appendChild(this.theme.getTableCell());
                ret.row = row;
                ret.table_controls = this.theme.getButtonHolder();
                ret.controls_cell.appendChild(ret.table_controls);
                ret.table_controls.style.margin = 0;
                ret.table_controls.style.padding = 0;
            }

            return ret;
        },
        destroy: function() {
            this.innerHTML = '';
            if (this.title && this.title.parentNode) this.title.parentNode.removeChild(this.title);
            if (this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);
            if (this.row_holder && this.row_holder.parentNode) this.row_holder.parentNode.removeChild(this.row_holder);
            if (this.table && this.table.parentNode) this.table.parentNode.removeChild(this.table);
            if (this.panel && this.panel.parentNode) this.panel.parentNode.removeChild(this.panel);

            this.rows = this.title = this.description = this.row_holder = this.table = this.panel = null;

            this._super();
        },
        setValue: function(value, initial) {
            // Update the array's value, adding/removing rows when necessary
            value = value || [];

            // Make sure value has between minItems and maxItems items in it
            if (this.schema.minItems) {
                while (value.length < this.schema.minItems) {
                    value.push(this.getItemDefault());
                }
            }
            if (this.schema.maxItems && value.length > this.schema.maxItems) {
                value = value.slice(0, this.schema.maxItems);
            }

            var serialized = JSON.stringify(value);
            if (serialized === this.serialized) return;

            var numrows_changed = false;

            var self = this;
            $each(value, function(i, val) {
                if (self.rows[i]) {
                    // TODO: don't set the row's value if it hasn't changed
                    self.rows[i].setValue(val);
                } else {
                    self.addRow(val);
                    numrows_changed = true;
                }
            });

            for (var j = value.length; j < self.rows.length; j++) {
                var holder = self.rows[j].container;
                if (!self.item_has_child_editors) {
                    self.rows[j].row.parentNode.removeChild(self.rows[j].row);
                }
                self.rows[j].destroy();
                if (holder.parentNode) holder.parentNode.removeChild(holder);
                self.rows[j] = null;
                numrows_changed = true;
            }
            self.rows = self.rows.slice(0, value.length);

            self.refreshValue();
            if (numrows_changed || initial) self.refreshRowButtons();

            self.onChange();

            // TODO: sortable
        },
        refreshRowButtons: function() {
            var self = this;

            // If we currently have minItems items in the array
            var minItems = this.schema.minItems && this.schema.minItems >= this.rows.length;

            var need_row_buttons = false;
            $each(this.rows, function(i, editor) {
                // Hide the move down button for the last row
                if (editor.movedown_button) {
                    if (i === self.rows.length - 1) {
                        editor.movedown_button.style.display = 'none';
                    } else {
                        need_row_buttons = true;
                        editor.movedown_button.style.display = '';
                    }
                }

                // Hide the delete button if we have minItems items
                if (editor.delete_button) {
                    if (minItems) {
                        editor.delete_button.style.display = 'none';
                    } else {
                        need_row_buttons = true;
                        editor.delete_button.style.display = '';
                    }
                }

                if (editor.moveup_button) {
                    need_row_buttons = true;
                }
            });

            // Show/hide controls column in table
            $each(this.rows, function(i, editor) {
                if (need_row_buttons) {
                    editor.controls_cell.style.display = '';
                } else {
                    editor.controls_cell.style.display = 'none';
                }
            });
            if (need_row_buttons) {
                this.controls_header_cell.style.display = '';
            } else {
                this.controls_header_cell.style.display = 'none';
            }

            var controls_needed = false;

            if (!this.value.length) {
                this.delete_last_row_button.style.display = 'none';
                this.remove_all_rows_button.style.display = 'none';
                this.table.style.display = 'none';
            } else if (this.value.length === 1 || this.hide_delete_buttons) {
                this.table.style.display = '';
                this.remove_all_rows_button.style.display = 'none';

                // If there are minItems items in the array, hide the delete button beneath the rows
                if (minItems || this.hide_delete_buttons) {
                    this.delete_last_row_button.style.display = 'none';
                } else {
                    this.delete_last_row_button.style.display = '';
                    controls_needed = true;
                }
            } else {
                this.table.style.display = '';
                // If there are minItems items in the array, hide the delete button beneath the rows
                if (minItems || this.hide_delete_buttons) {
                    this.delete_last_row_button.style.display = 'none';
                    this.remove_all_rows_button.style.display = 'none';
                } else {
                    this.delete_last_row_button.style.display = '';
                    this.remove_all_rows_button.style.display = '';
                    controls_needed = true;
                }
            }

            // If there are maxItems in the array, hide the add button beneath the rows
            if ((this.schema.maxItems && this.schema.maxItems <= this.rows.length) || this.hide_add_button) {
                this.add_row_button.style.display = 'none';
            } else {
                this.add_row_button.style.display = '';
                controls_needed = true;
            }

            if (!controls_needed) {
                this.controls.style.display = 'none';
            } else {
                this.controls.style.display = '';
            }
        },
        refreshValue: function() {
            var self = this;
            this.value = [];

            $each(this.rows, function(i, editor) {
                // Get the value for this editor
                self.value[i] = editor.getValue();
            });
            this.serialized = JSON.stringify(this.value);
        },
        addRow: function(value) {
            var self = this;
            var i = this.rows.length;

            self.rows[i] = this.getElementEditor(i);

            var controls_holder = self.rows[i].table_controls;

            // Buttons to delete row, move row up, and move row down
            if (!this.hide_delete_buttons) {
                self.rows[i].delete_button = this.getButton('', 'delete', 'Delete');
                self.rows[i].delete_button.className += ' delete';
                self.rows[i].delete_button.setAttribute('data-i', i);
                self.rows[i].delete_button.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    var i = this.getAttribute('data-i') * 1;

                    var value = self.getValue();

                    var newval = [];
                    $each(value, function(j, row) {
                        if (j === i) return; // If this is the one we're deleting
                        newval.push(row);
                    });
                    self.setValue(newval);
                    self.onChange(true);
                }, false);
                controls_holder.appendChild(self.rows[i].delete_button);
            }


            if (i && !this.hide_move_buttons) {
                self.rows[i].moveup_button = this.getButton('', 'moveup', 'Move up');
                self.rows[i].moveup_button.className += ' moveup';
                self.rows[i].moveup_button.setAttribute('data-i', i);
                self.rows[i].moveup_button.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    var i = this.getAttribute('data-i') * 1;

                    if (i <= 0) return;
                    var rows = self.getValue();
                    var tmp = rows[i - 1];
                    rows[i - 1] = rows[i];
                    rows[i] = tmp;

                    self.setValue(rows);
                    self.onChange(true);
                }, false);
                controls_holder.appendChild(self.rows[i].moveup_button);
            }

            if (!this.hide_move_buttons) {
                self.rows[i].movedown_button = this.getButton('', 'movedown', 'Move down');
                self.rows[i].movedown_button.className += ' movedown';
                self.rows[i].movedown_button.setAttribute('data-i', i);
                self.rows[i].movedown_button.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    var i = this.getAttribute('data-i') * 1;
                    var rows = self.getValue();
                    if (i >= rows.length - 1) return;
                    var tmp = rows[i + 1];
                    rows[i + 1] = rows[i];
                    rows[i] = tmp;

                    self.setValue(rows);
                    self.onChange(true);
                }, false);
                controls_holder.appendChild(self.rows[i].movedown_button);
            }

            if (value) self.rows[i].setValue(value);
        },
        addControls: function() {
            var self = this;

            this.collapsed = false;
            this.toggle_button = this.getButton('', 'collapse', 'Collapse');
            if (this.title_controls) {
                this.title_controls.appendChild(this.toggle_button);
                this.toggle_button.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();

                    if (self.collapsed) {
                        self.collapsed = false;
                        self.panel.style.display = '';
                        self.setButtonText(this, '', 'collapse', 'Collapse');
                    } else {
                        self.collapsed = true;
                        self.panel.style.display = 'none';
                        self.setButtonText(this, '', 'expand', 'Expand');
                    }
                }, false);

                // If it should start collapsed
                if (this.options.collapsed) {
                    $trigger(this.toggle_button, 'click');
                }

                // Collapse button disabled
                if (this.schema.options && typeof this.schema.options.disable_collapse !== "undefined") {
                    if (this.schema.options.disable_collapse) this.toggle_button.style.display = 'none';
                } else if (this.jsoneditor.options.disable_collapse) {
                    this.toggle_button.style.display = 'none';
                }
            }

            // Add "new row" and "delete last" buttons below editor
            this.add_row_button = this.getButton(this.getItemTitle(), 'add', 'Add ' + this.getItemTitle());
            this.add_row_button.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();

                self.addRow();
                self.refreshValue();
                self.refreshRowButtons();
                self.onChange(true);
            }, false);
            self.controls.appendChild(this.add_row_button);

            this.delete_last_row_button = this.getButton('Last ' + this.getItemTitle(), 'delete', 'Delete Last ' + this.getItemTitle());
            this.delete_last_row_button.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();

                var rows = self.getValue();
                rows.pop();
                self.setValue(rows);
                self.onChange(true);
            }, false);
            self.controls.appendChild(this.delete_last_row_button);

            this.remove_all_rows_button = this.getButton('All', 'delete', 'Delete All');
            this.remove_all_rows_button.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();

                self.setValue([]);
                self.onChange(true);
            }, false);
            self.controls.appendChild(this.remove_all_rows_button);
        }
    });

    // Multiple Editor (for when `type` is an array)
    JSONEditor.defaults.editors.multiple = JSONEditor.AbstractEditor.extend({
        register: function() {
            if (this.editors) {
                for (var i = 0; i < this.editors.length; i++) {
                    if (!this.editors[i]) continue;
                    this.editors[i].unregister();
                }
                if (this.editors[this.type]) this.editors[this.type].register();
            }
            this._super();
        },
        unregister: function() {
            this._super();
            if (this.editors) {
                for (var i = 0; i < this.editors.length; i++) {
                    if (!this.editors[i]) continue;
                    this.editors[i].unregister();
                }
            }
        },
        getNumColumns: function() {
            if (!this.editors[this.type]) return 4;
            return Math.max(this.editors[this.type].getNumColumns(), 4);
        },
        enable: function() {
            if (this.editors) {
                for (var i = 0; i < this.editors.length; i++) {
                    if (!this.editors[i]) continue;
                    this.editors[i].enable();
                }
            }
            this.switcher.disabled = false;
            this._super();
        },
        disable: function() {
            if (this.editors) {
                for (var i = 0; i < this.editors.length; i++) {
                    if (!this.editors[i]) continue;
                    this.editors[i].disable();
                }
            }
            this.switcher.disabled = true;
            this._super();
        },
        switchEditor: function(i) {
            var self = this;

            if (!this.editors[i]) {
                this.buildChildEditor(i);
            }

            self.type = i;

            self.register();

            var current_value = self.getValue();

            $each(self.editors, function(type, editor) {
                if (!editor) return;
                if (self.type === type) {
                    if (self.keep_values) editor.setValue(current_value, true);
                    editor.container.style.display = '';
                } else editor.container.style.display = 'none';
            });
            self.refreshValue();
            self.refreshHeaderText();
        },
        buildChildEditor: function(i) {
            var self = this;
            var type = this.types[i];
            var holder = self.theme.getChildEditorHolder();
            self.editor_holder.appendChild(holder);

            var schema;

            if (typeof type === "string") {
                schema = $extend({}, self.schema);
                schema.type = type;
            } else {
                schema = $extend({}, self.schema, type);
                schema = self.jsoneditor.expandRefs(schema);

                // If we need to merge `required` arrays
                if (type.required && Array.isArray(type.required) && self.schema.required && Array.isArray(self.schema.required)) {
                    schema.required = self.schema.required.concat(type.required);
                }
            }

            var editor = self.jsoneditor.getEditorClass(schema);

            self.editors[i] = self.jsoneditor.createEditor(editor, {
                jsoneditor: self.jsoneditor,
                schema: schema,
                container: holder,
                path: self.path,
                parent: self,
                required: true
            });
            self.editors[i].preBuild();
            self.editors[i].build();
            self.editors[i].postBuild();

            if (self.editors[i].header) self.editors[i].header.style.display = 'none';

            self.editors[i].option = self.switcher_options[i];

            holder.addEventListener('change_header_text', function() {
                self.refreshHeaderText();
            }, false);

            if (i !== self.type) holder.style.display = 'none';
        },
        preBuild: function() {
            var self = this;

            this.types = [];
            this.type = 0;
            this.editors = [];
            this.validators = [];

            this.keep_values = true;
            if (typeof this.jsoneditor.options.keep_oneof_values !== "undefined") this.keep_values = this.jsoneditor.options.keep_oneof_values;
            if (typeof this.options.keep_oneof_values !== "undefined") this.keep_values = this.options.keep_oneof_values;

            if (this.schema.oneOf) {
                this.oneOf = true;
                this.types = this.schema.oneOf;
                $each(this.types, function(i, oneof) {
                    //self.types[i] = self.jsoneditor.expandSchema(oneof);
                });
                delete this.schema.oneOf;
            } else {
                if (!this.schema.type || this.schema.type === "any") {
                    this.types = ['string', 'number', 'integer', 'boolean', 'object', 'array', 'null'];

                    // If any of these primitive types are disallowed
                    if (this.schema.disallow) {
                        var disallow = this.schema.disallow;
                        if (typeof disallow !== 'object' || !(Array.isArray(disallow))) {
                            disallow = [disallow];
                        }
                        var allowed_types = [];
                        $each(this.types, function(i, type) {
                            if (disallow.indexOf(type) === -1) allowed_types.push(type);
                        });
                        this.types = allowed_types;
                    }
                } else if (Array.isArray(this.schema.type)) {
                    this.types = this.schema.type;
                } else {
                    this.types = [this.schema.type];
                }
                delete this.schema.type;
            }

            this.display_text = this.getDisplayText(this.types);
        },
        build: function() {
            var self = this;
            var container = this.container;

            this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
            this.container.appendChild(this.header);

            this.switcher = this.theme.getSwitcher(this.display_text);
            container.appendChild(this.switcher);
            this.switcher.addEventListener('change', function(e) {
                e.preventDefault();
                e.stopPropagation();

                self.switchEditor(self.display_text.indexOf(this.value));
                self.onChange(true);
            }, false);

            this.editor_holder = document.createElement('div');
            container.appendChild(this.editor_holder);


            var validator_options = {};
            if (self.jsoneditor.options.custom_validators) {
                validator_options.custom_validators = self.jsoneditor.options.custom_validators;
            }

            this.switcher_options = this.theme.getSwitcherOptions(this.switcher);
            $each(this.types, function(i, type) {
                self.editors[i] = false;

                var schema;

                if (typeof type === "string") {
                    schema = $extend({}, self.schema);
                    schema.type = type;
                } else {
                    schema = $extend({}, self.schema, type);

                    // If we need to merge `required` arrays
                    if (type.required && Array.isArray(type.required) && self.schema.required && Array.isArray(self.schema.required)) {
                        schema.required = self.schema.required.concat(type.required);
                    }
                }

                self.validators[i] = new JSONEditor.Validator(self.jsoneditor, schema, validator_options);
            });

            this.switchEditor(0);
        },
        onChildEditorChange: function(editor) {
            if (this.editors[this.type]) {
                this.refreshValue();
                this.refreshHeaderText();
            }

            this._super();
        },
        refreshHeaderText: function() {
            var display_text = this.getDisplayText(this.types);
            $each(this.switcher_options, function(i, option) {
                option.textContent = display_text[i];
            });
        },
        refreshValue: function() {
            this.value = this.editors[this.type].getValue();
        },
        setValue: function(val, initial) {
            // Determine type by getting the first one that validates
            var self = this;
            $each(this.validators, function(i, validator) {
                if (!validator.validate(val).length) {
                    self.type = i;
                    self.switcher.value = self.display_text[i];
                    return false;
                }
            });

            this.switchEditor(this.type);

            this.editors[this.type].setValue(val, initial);

            this.refreshValue();
            self.onChange();
        },
        destroy: function() {
            $each(this.editors, function(type, editor) {
                if (editor) editor.destroy();
            });
            if (this.editor_holder && this.editor_holder.parentNode) this.editor_holder.parentNode.removeChild(this.editor_holder);
            if (this.switcher && this.switcher.parentNode) this.switcher.parentNode.removeChild(this.switcher);
            this._super();
        },
        showValidationErrors: function(errors) {
            var self = this;

            // oneOf error paths need to remove the oneOf[i] part before passing to child editors
            if (this.oneOf) {
                $each(this.editors, function(i, editor) {
                    if (!editor) return;
                    var check = self.path + '.oneOf[' + i + ']';
                    var new_errors = [];
                    $each(errors, function(j, error) {
                        if (error.path.substr(0, check.length) === check) {
                            var new_error = $extend({}, error);
                            new_error.path = self.path + new_error.path.substr(check.length);
                            new_errors.push(new_error);
                        }
                    });

                    editor.showValidationErrors(new_errors);
                });
            } else {
                $each(this.editors, function(type, editor) {
                    if (!editor) return;
                    editor.showValidationErrors(errors);
                });
            }
        }
    });

    // Enum Editor (used for objects and arrays with enumerated values)
    JSONEditor.defaults.editors["enum"] = JSONEditor.AbstractEditor.extend({
        getNumColumns: function() {
            return 4;
        },
        build: function() {
            var container = this.container;
            this.title = this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
            this.container.appendChild(this.title);

            this.options.enum_titles = this.options.enum_titles || [];

            this["enum"] = this.schema["enum"];
            this.selected = 0;
            this.select_options = [];
            this.html_values = [];

            var self = this;
            for (var i = 0; i < this["enum"].length; i++) {
                this.select_options[i] = this.options.enum_titles[i] || "Value " + (i + 1);
                this.html_values[i] = this.getHTML(this["enum"][i]);
            }

            // Switcher
            this.switcher = this.theme.getSwitcher(this.select_options);
            this.container.appendChild(this.switcher);

            // Display area
            this.display_area = this.theme.getIndentedPanel();
            this.container.appendChild(this.display_area);

            if (this.options.hide_display) this.display_area.style.display = "none";

            this.switcher.addEventListener('change', function() {
                self.selected = self.select_options.indexOf(this.value);
                self.value = self["enum"][self.selected];
                self.refreshValue();
                self.onChange(true);
            }, false);
            this.value = this["enum"][0];
            this.refreshValue();

            if (this["enum"].length === 1) this.switcher.style.display = 'none';
        },
        refreshValue: function() {
            var self = this;
            self.selected = -1;
            var stringified = JSON.stringify(this.value);
            $each(this["enum"], function(i, el) {
                if (stringified === JSON.stringify(el)) {
                    self.selected = i;
                    return false;
                }
            });

            if (self.selected < 0) {
                self.setValue(self["enum"][0]);
                return;
            }

            this.switcher.value = this.select_options[this.selected];
            this.display_area.innerHTML = this.html_values[this.selected];
        },
        enable: function() {
            if (!this.always_disabled) this.switcher.disabled = false;
            this._super();
        },
        disable: function() {
            this.switcher.disabled = true;
            this._super();
        },
        getHTML: function(el) {
            var self = this;

            if (el === null) {
                return '<em>null</em>';
            }
            // Array or Object
            else if (typeof el === "object") {
                // TODO: use theme
                var ret = '';

                $each(el, function(i, child) {
                    var html = self.getHTML(child);

                    // Add the keys to object children
                    if (!(Array.isArray(el))) {
                        // TODO: use theme
                        html = '<div><em>' + i + '</em>: ' + html + '</div>';
                    }

                    // TODO: use theme
                    ret += '<li>' + html + '</li>';
                });

                if (Array.isArray(el)) ret = '<ol>' + ret + '</ol>';
                else ret = "<ul style='margin-top:0;margin-bottom:0;padding-top:0;padding-bottom:0;'>" + ret + '</ul>';

                return ret;
            }
            // Boolean
            else if (typeof el === "boolean") {
                return el ? 'true' : 'false';
            }
            // String
            else if (typeof el === "string") {
                return el.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
            }
            // Number
            else {
                return el;
            }
        },
        setValue: function(val) {
            if (this.value !== val) {
                this.value = val;
                this.refreshValue();
                this.onChange();
            }
        },
        destroy: function() {
            if (this.display_area && this.display_area.parentNode) this.display_area.parentNode.removeChild(this.display_area);
            if (this.title && this.title.parentNode) this.title.parentNode.removeChild(this.title);
            if (this.switcher && this.switcher.parentNode) this.switcher.parentNode.removeChild(this.switcher);

            this._super();
        }
    });

    JSONEditor.defaults.editors.select = JSONEditor.AbstractEditor.extend({
        setValue: function(value, initial) {
            value = this.typecast(value || '');

            // Sanitize value before setting it
            var sanitized = value;
            if (this.enum_values.indexOf(sanitized) < 0) {
                sanitized = this.enum_values[0];
            }

            if (this.value === sanitized) {
                return;
            }

            this.input.value = this.enum_options[this.enum_values.indexOf(sanitized)];
            if (this.select2) this.select2.select2('val', this.input.value);
            this.value = sanitized;
            this.onChange();
        },
        register: function() {
            this._super();
            if (!this.input) return;
            this.input.setAttribute('name', this.formname);
        },
        unregister: function() {
            this._super();
            if (!this.input) return;
            this.input.removeAttribute('name');
        },
        getNumColumns: function() {
            if (!this.enum_options) return 3;
            var longest_text = this.getTitle().length;
            for (var i = 0; i < this.enum_options.length; i++) {
                longest_text = Math.max(longest_text, this.enum_options[i].length + 4);
            }
            return Math.min(12, Math.max(longest_text / 7, 2));
        },
        typecast: function(value) {
            if (this.schema.type === "boolean") {
                return !!value;
            } else if (this.schema.type === "number") {
                return 1 * value;
            } else if (this.schema.type === "integer") {
                return Math.floor(value * 1);
            } else {
                return "" + value;
            }
        },
        getValue: function() {
            return this.value;
        },
        preBuild: function() {
            var self = this;
            this.input_type = 'select';
            this.enum_options = [];
            this.enum_values = [];
            this.enum_display = [];

            // Enum options enumerated
            if (this.schema["enum"]) {
                var display = this.schema.options && this.schema.options.enum_titles || [];

                $each(this.schema["enum"], function(i, option) {
                    self.enum_options[i] = "" + option;
                    self.enum_display[i] = "" + (display[i] || option);
                    self.enum_values[i] = self.typecast(option);
                });

                if (!this.isRequired()) {
                    self.enum_display.unshift(' ');
                    self.enum_options.unshift('undefined');
                    self.enum_values.unshift(undefined);
                }

            }
            // Boolean
            else if (this.schema.type === "boolean") {
                self.enum_display = this.schema.options && this.schema.options.enum_titles || ['true', 'false'];
                self.enum_options = ['1', ''];
                self.enum_values = [true, false];

                if (!this.isRequired()) {
                    self.enum_display.unshift(' ');
                    self.enum_options.unshift('undefined');
                    self.enum_values.unshift(undefined);
                }

            }
            // Dynamic Enum
            else if (this.schema.enumSource) {
                this.enumSource = [];
                this.enum_display = [];
                this.enum_options = [];
                this.enum_values = [];

                // Shortcut declaration for using a single array
                if (!(Array.isArray(this.schema.enumSource))) {
                    if (this.schema.enumValue) {
                        this.enumSource = [{
                            source: this.schema.enumSource,
                            value: this.schema.enumValue
                        }];
                    } else {
                        this.enumSource = [{
                            source: this.schema.enumSource
                        }];
                    }
                } else {
                    for (i = 0; i < this.schema.enumSource.length; i++) {
                        // Shorthand for watched variable
                        if (typeof this.schema.enumSource[i] === "string") {
                            this.enumSource[i] = {
                                source: this.schema.enumSource[i]
                            };
                        }
                        // Make a copy of the schema
                        else if (!(Array.isArray(this.schema.enumSource[i]))) {
                            this.enumSource[i] = $extend({}, this.schema.enumSource[i]);
                        } else {
                            this.enumSource[i] = this.schema.enumSource[i];
                        }
                    }
                }

                // Now, enumSource is an array of sources
                // Walk through this array and fix up the values
                for (i = 0; i < this.enumSource.length; i++) {
                    if (this.enumSource[i].value) {
                        this.enumSource[i].value = this.jsoneditor.compileTemplate(this.enumSource[i].value, this.template_engine);
                    }
                    if (this.enumSource[i].title) {
                        this.enumSource[i].title = this.jsoneditor.compileTemplate(this.enumSource[i].title, this.template_engine);
                    }
                    if (this.enumSource[i].filter) {
                        this.enumSource[i].filter = this.jsoneditor.compileTemplate(this.enumSource[i].filter, this.template_engine);
                    }
                }
            }
            // Other, not supported
            else {
                throw "'select' editor requires the enum property to be set.";
            }
        },
        build: function() {
            var self = this;
            if (!this.options.compact) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
            if (this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);

            if (this.options.compact) this.container.className += ' compact';

            this.input = this.theme.getSelectInput(this.enum_options);
            this.theme.setSelectOptions(this.input, this.enum_options, this.enum_display);

            if (this.schema.readOnly || this.schema.readonly) {
                this.always_disabled = true;
                this.input.disabled = true;
            }

            this.input.addEventListener('change', function(e) {
                e.preventDefault();
                e.stopPropagation();
                self.onInputChange();
            }, false);

            this.control = this.theme.getFormControl(this.label, this.input, this.description);
            this.container.appendChild(this.control);

            this.value = this.enum_values[0];
        },
        onInputChange: function() {
            var val = this.input.value;

            var new_val;
            // Invalid option, use first option instead
            if (this.enum_options.indexOf(val) === -1) {
                new_val = this.enum_values[0];
            } else {
                new_val = this.enum_values[this.enum_options.indexOf(val)];
            }

            // If valid hasn't changed
            if (new_val === this.value) return;

            // Store new value and propogate change event
            this.value = new_val;
            this.onChange(true);
        },
        setupSelect2: function() {
            // If the Select2 library is loaded use it when we have lots of items
            if (window.jQuery && window.jQuery.fn && window.jQuery.fn.select2 && (this.enum_options.length > 2 || (this.enum_options.length && this.enumSource))) {
                var options = $extend({}, JSONEditor.plugins.select2);
                if (this.schema.options && this.schema.options.select2_options) options = $extend(options, this.schema.options.select2_options);
                this.select2 = window.jQuery(this.input).select2(options);
                var self = this;
                this.select2.on('select2-blur', function() {
                    self.input.value = self.select2.select2('val');
                    self.onInputChange();
                });
                this.select2.on('change', function() {
                    self.input.value = self.select2.select2('val');
                    self.onInputChange();
                });
            } else {
                this.select2 = null;
            }
        },
        postBuild: function() {
            this._super();
            this.theme.afterInputReady(this.input);
            this.setupSelect2();
        },
        onWatchedFieldChange: function() {
            var self = this,
                vars, j;

            // If this editor uses a dynamic select box
            if (this.enumSource) {
                vars = this.getWatchedFieldValues();
                var select_options = [];
                var select_titles = [];

                for (var i = 0; i < this.enumSource.length; i++) {
                    // Constant values
                    if (Array.isArray(this.enumSource[i])) {
                        select_options = select_options.concat(this.enumSource[i]);
                        select_titles = select_titles.concat(this.enumSource[i]);
                    } else {
                        var items = [];
                        // Static list of items
                        if (Array.isArray(this.enumSource[i].source)) {
                            items = this.enumSource[i].source;
                            // A watched field
                        } else {
                            items = vars[this.enumSource[i].source];
                        }

                        if (items) {
                            // Only use a predefined part of the array
                            if (this.enumSource[i].slice) {
                                items = Array.prototype.slice.apply(items, this.enumSource[i].slice);
                            }
                            // Filter the items
                            if (this.enumSource[i].filter) {
                                var new_items = [];
                                for (j = 0; j < items.length; j++) {
                                    if (this.enumSource[i].filter({
                                        i: j,
                                        item: items[j],
                                        watched: vars
                                    })) new_items.push(items[j]);
                                }
                                items = new_items;
                            }

                            var item_titles = [];
                            var item_values = [];
                            for (j = 0; j < items.length; j++) {
                                var item = items[j];

                                // Rendered value
                                if (this.enumSource[i].value) {
                                    item_values[j] = this.enumSource[i].value({
                                        i: j,
                                        item: item
                                    });
                                }
                                // Use value directly
                                else {
                                    item_values[j] = items[j];
                                }

                                // Rendered title
                                if (this.enumSource[i].title) {
                                    item_titles[j] = this.enumSource[i].title({
                                        i: j,
                                        item: item
                                    });
                                }
                                // Use value as the title also
                                else {
                                    item_titles[j] = item_values[j];
                                }
                            }

                            // TODO: sort

                            select_options = select_options.concat(item_values);
                            select_titles = select_titles.concat(item_titles);
                        }
                    }
                }

                var prev_value = this.value;

                this.theme.setSelectOptions(this.input, select_options, select_titles);
                this.enum_options = select_options;
                this.enum_display = select_titles;
                this.enum_values = select_options;

                if (this.select2) {
                    this.select2.select2('destroy');
                }

                // If the previous value is still in the new select options, stick with it
                if (select_options.indexOf(prev_value) !== -1) {
                    this.input.value = prev_value;
                    this.value = prev_value;
                }
                // Otherwise, set the value to the first select option
                else {
                    this.input.value = select_options[0];
                    this.value = select_options[0] || "";
                    if (this.parent) this.parent.onChildEditorChange(this);
                    else this.jsoneditor.onChange();
                    this.jsoneditor.notifyWatchers(this.path);
                }

                this.setupSelect2();
            }

            this._super();
        },
        enable: function() {
            if (!this.always_disabled) {
                this.input.disabled = false;
                if (this.select2) this.select2.select2("enable", true);
            }
            this._super();
        },
        disable: function() {
            this.input.disabled = true;
            if (this.select2) this.select2.select2("enable", false);
            this._super();
        },
        destroy: function() {
            if (this.label && this.label.parentNode) this.label.parentNode.removeChild(this.label);
            if (this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);
            if (this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);
            if (this.select2) {
                this.select2.select2('destroy');
                this.select2 = null;
            }

            this._super();
        }
    });

    JSONEditor.defaults.editors.selectize = JSONEditor.AbstractEditor.extend({
        setValue: function(value, initial) {
            value = this.typecast(value || '');

            // Sanitize value before setting it
            var sanitized = value;
            if (this.enum_values.indexOf(sanitized) < 0) {
                sanitized = this.enum_values[0];
            }

            if (this.value === sanitized) {
                return;
            }

            this.input.value = this.enum_options[this.enum_values.indexOf(sanitized)];

            if (this.selectize) {
                this.selectize[0].selectize.addItem(sanitized);
            }

            this.value = sanitized;
            this.onChange();
        },
        register: function() {
            this._super();
            if (!this.input) return;
            this.input.setAttribute('name', this.formname);
        },
        unregister: function() {
            this._super();
            if (!this.input) return;
            this.input.removeAttribute('name');
        },
        getNumColumns: function() {
            if (!this.enum_options) return 3;
            var longest_text = this.getTitle().length;
            for (var i = 0; i < this.enum_options.length; i++) {
                longest_text = Math.max(longest_text, this.enum_options[i].length + 4);
            }
            return Math.min(12, Math.max(longest_text / 7, 2));
        },
        typecast: function(value) {
            if (this.schema.type === "boolean") {
                return !!value;
            } else if (this.schema.type === "number") {
                return 1 * value;
            } else if (this.schema.type === "integer") {
                return Math.floor(value * 1);
            } else {
                return "" + value;
            }
        },
        getValue: function() {
            return this.value;
        },
        preBuild: function() {
            var self = this;
            this.input_type = 'select';
            this.enum_options = [];
            this.enum_values = [];
            this.enum_display = [];

            // Enum options enumerated
            if (this.schema.enum) {
                var display = this.schema.options && this.schema.options.enum_titles || [];

                $each(this.schema.enum, function(i, option) {
                    self.enum_options[i] = "" + option;
                    self.enum_display[i] = "" + (display[i] || option);
                    self.enum_values[i] = self.typecast(option);
                });
            }
            // Boolean
            else if (this.schema.type === "boolean") {
                self.enum_display = this.schema.options && this.schema.options.enum_titles || ['true', 'false'];
                self.enum_options = ['1', '0'];
                self.enum_values = [true, false];
            }
            // Dynamic Enum
            else if (this.schema.enumSource) {
                this.enumSource = [];
                this.enum_display = [];
                this.enum_options = [];
                this.enum_values = [];

                // Shortcut declaration for using a single array
                if (!(Array.isArray(this.schema.enumSource))) {
                    if (this.schema.enumValue) {
                        this.enumSource = [{
                            source: this.schema.enumSource,
                            value: this.schema.enumValue
                        }];
                    } else {
                        this.enumSource = [{
                            source: this.schema.enumSource
                        }];
                    }
                } else {
                    for (i = 0; i < this.schema.enumSource.length; i++) {
                        // Shorthand for watched variable
                        if (typeof this.schema.enumSource[i] === "string") {
                            this.enumSource[i] = {
                                source: this.schema.enumSource[i]
                            };
                        }
                        // Make a copy of the schema
                        else if (!(Array.isArray(this.schema.enumSource[i]))) {
                            this.enumSource[i] = $extend({}, this.schema.enumSource[i]);
                        } else {
                            this.enumSource[i] = this.schema.enumSource[i];
                        }
                    }
                }

                // Now, enumSource is an array of sources
                // Walk through this array and fix up the values
                for (i = 0; i < this.enumSource.length; i++) {
                    if (this.enumSource[i].value) {
                        this.enumSource[i].value = this.jsoneditor.compileTemplate(this.enumSource[i].value, this.template_engine);
                    }
                    if (this.enumSource[i].title) {
                        this.enumSource[i].title = this.jsoneditor.compileTemplate(this.enumSource[i].title, this.template_engine);
                    }
                    if (this.enumSource[i].filter) {
                        this.enumSource[i].filter = this.jsoneditor.compileTemplate(this.enumSource[i].filter, this.template_engine);
                    }
                }
            }
            // Other, not supported
            else {
                throw "'select' editor requires the enum property to be set.";
            }
        },
        build: function() {
            var self = this;
            if (!this.options.compact) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
            if (this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);

            if (this.options.compact) this.container.className += ' compact';

            this.input = this.theme.getSelectInput(this.enum_options);
            this.theme.setSelectOptions(this.input, this.enum_options, this.enum_display);

            if (this.schema.readOnly || this.schema.readonly) {
                this.always_disabled = true;
                this.input.disabled = true;
            }

            this.input.addEventListener('change', function(e) {
                e.preventDefault();
                e.stopPropagation();
                self.onInputChange();
            }, false);

            this.control = this.theme.getFormControl(this.label, this.input, this.description);
            this.container.appendChild(this.control);

            this.value = this.enum_values[0];
        },
        onInputChange: function() {
            var val = this.input.value;

            var sanitized = val;
            if (this.enum_options.indexOf(val) === -1) {
                sanitized = this.enum_options[0];
            }

            this.value = this.enum_values[this.enum_options.indexOf(val)];
            this.onChange(true);
        },
        setupSelectize: function() {
            // If the Selectize library is loaded use it when we have lots of items
            var self = this;
            if (window.jQuery && window.jQuery.fn && window.jQuery.fn.selectize && (this.enum_options.length >= 2 || (this.enum_options.length && this.enumSource))) {
                var options = $extend({}, JSONEditor.plugins.selectize);
                if (this.schema.options && this.schema.options.selectize_options) options = $extend(options, this.schema.options.selectize_options);
                this.selectize = window.jQuery(this.input).selectize($extend(options, {
                    create: true,
                    onChange: function() {
                        self.onInputChange();
                    }
                }));
            } else {
                this.selectize = null;
            }
        },
        postBuild: function() {
            this._super();
            this.theme.afterInputReady(this.input);
            this.setupSelectize();
        },
        onWatchedFieldChange: function() {
            var self = this,
                vars, j;

            // If this editor uses a dynamic select box
            if (this.enumSource) {
                vars = this.getWatchedFieldValues();
                var select_options = [];
                var select_titles = [];

                for (var i = 0; i < this.enumSource.length; i++) {
                    // Constant values
                    if (Array.isArray(this.enumSource[i])) {
                        select_options = select_options.concat(this.enumSource[i]);
                        select_titles = select_titles.concat(this.enumSource[i]);
                    }
                    // A watched field
                    else if (vars[this.enumSource[i].source]) {
                        var items = vars[this.enumSource[i].source];

                        // Only use a predefined part of the array
                        if (this.enumSource[i].slice) {
                            items = Array.prototype.slice.apply(items, this.enumSource[i].slice);
                        }
                        // Filter the items
                        if (this.enumSource[i].filter) {
                            var new_items = [];
                            for (j = 0; j < items.length; j++) {
                                if (this.enumSource[i].filter({
                                    i: j,
                                    item: items[j]
                                })) new_items.push(items[j]);
                            }
                            items = new_items;
                        }

                        var item_titles = [];
                        var item_values = [];
                        for (j = 0; j < items.length; j++) {
                            var item = items[j];

                            // Rendered value
                            if (this.enumSource[i].value) {
                                item_values[j] = this.enumSource[i].value({
                                    i: j,
                                    item: item
                                });
                            }
                            // Use value directly
                            else {
                                item_values[j] = items[j];
                            }

                            // Rendered title
                            if (this.enumSource[i].title) {
                                item_titles[j] = this.enumSource[i].title({
                                    i: j,
                                    item: item
                                });
                            }
                            // Use value as the title also
                            else {
                                item_titles[j] = item_values[j];
                            }
                        }

                        // TODO: sort

                        select_options = select_options.concat(item_values);
                        select_titles = select_titles.concat(item_titles);
                    }
                }

                var prev_value = this.value;

                this.theme.setSelectOptions(this.input, select_options, select_titles);
                this.enum_options = select_options;
                this.enum_display = select_titles;
                this.enum_values = select_options;

                // If the previous value is still in the new select options, stick with it
                if (select_options.indexOf(prev_value) !== -1) {
                    this.input.value = prev_value;
                    this.value = prev_value;
                }

                // Otherwise, set the value to the first select option
                else {
                    this.input.value = select_options[0];
                    this.value = select_options[0] || "";
                    if (this.parent) this.parent.onChildEditorChange(this);
                    else this.jsoneditor.onChange();
                    this.jsoneditor.notifyWatchers(this.path);
                }

                if (this.selectize) {
                    // Update the Selectize options
                    this.updateSelectizeOptions(select_options);
                } else {
                    this.setupSelectize();
                }

                this._super();
            }
        },
        updateSelectizeOptions: function(select_options) {
            var selectized = this.selectize[0].selectize,
                self = this;

            selectized.off();
            selectized.clearOptions();
            for (var n in select_options) {
                selectized.addOption({
                    value: select_options[n],
                    text: select_options[n]
                });
            }
            selectized.addItem(this.value);
            selectized.on('change', function() {
                self.onInputChange();
            });
        },
        enable: function() {
            if (!this.always_disabled) {
                this.input.disabled = false;
                if (this.selectize) {
                    this.selectize[0].selectize.unlock();
                }
            }
            this._super();
        },
        disable: function() {
            this.input.disabled = true;
            if (this.selectize) {
                this.selectize[0].selectize.lock();
            }
            this._super();
        },
        destroy: function() {
            if (this.label && this.label.parentNode) this.label.parentNode.removeChild(this.label);
            if (this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);
            if (this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);
            if (this.selectize) {
                this.selectize[0].selectize.destroy();
                this.selectize = null;
            }
            this._super();
        }
    });

    JSONEditor.defaults.editors.multiselect = JSONEditor.AbstractEditor.extend({
        preBuild: function() {
            this._super();

            this.select_options = {};
            this.select_values = {};

            var items_schema = this.jsoneditor.expandRefs(this.schema.items || {});

            var e = items_schema["enum"] || [];
            this.option_keys = [];
            for (i = 0; i < e.length; i++) {
                // If the sanitized value is different from the enum value, don't include it
                if (this.sanitize(e[i]) !== e[i]) continue;

                this.option_keys.push(e[i] + "");
                this.select_values[e[i] + ""] = e[i];
            }
        },
        build: function() {
            var self = this,
                i;
            if (!this.options.compact) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
            if (this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);

            if ((!this.schema.format && this.option_keys.length < 8) || this.schema.format === "checkbox") {
                this.input_type = 'checkboxes';

                this.inputs = {};
                this.controls = {};
                for (i = 0; i < this.option_keys.length; i++) {
                    this.inputs[this.option_keys[i]] = this.theme.getCheckbox();
                    this.select_options[this.option_keys[i]] = this.inputs[this.option_keys[i]];
                    var label = this.theme.getCheckboxLabel(this.option_keys[i]);
                    this.controls[this.option_keys[i]] = this.theme.getFormControl(label, this.inputs[this.option_keys[i]]);
                }

                this.control = this.theme.getMultiCheckboxHolder(this.controls, this.label, this.description);
            } else {
                this.input_type = 'select';
                this.input = this.theme.getSelectInput(this.option_keys);
                this.input.multiple = true;
                this.input.size = Math.min(10, this.option_keys.length);

                for (i = 0; i < this.option_keys.length; i++) {
                    this.select_options[this.option_keys[i]] = this.input.children[i];
                }

                if (this.schema.readOnly || this.schema.readonly) {
                    this.always_disabled = true;
                    this.input.disabled = true;
                }

                this.control = this.theme.getFormControl(this.label, this.input, this.description);
            }

            this.container.appendChild(this.control);
            this.control.addEventListener('change', function(e) {
                e.preventDefault();
                e.stopPropagation();

                var new_value = [];
                for (i = 0; i < self.option_keys.length; i++) {
                    if (self.select_options[self.option_keys[i]].selected || self.select_options[self.option_keys[i]].checked) new_value.push(self.select_values[self.option_keys[i]]);
                }

                self.updateValue(new_value);
                self.onChange(true);
            }, false);
        },
        setValue: function(value, initial) {
            var i;
            value = value || [];
            if (typeof value !== "object") value = [value];
            else if (!(Array.isArray(value))) value = [];

            // Make sure we are dealing with an array of strings so we can check for strict equality
            for (i = 0; i < value.length; i++) {
                if (typeof value[i] !== "string") value[i] += "";
            }

            // Update selected status of options
            for (i in this.select_options) {
                if (!this.select_options.hasOwnProperty(i)) continue;

                this.select_options[i][this.input_type === "select" ? "selected" : "checked"] = (value.indexOf(i) !== -1);
            }

            this.updateValue(value);
            this.onChange();
        },
        setupSelect2: function() {
            if (window.jQuery && window.jQuery.fn && window.jQuery.fn.select2) {
                var options = window.jQuery.extend({}, JSONEditor.plugins.select2);
                if (this.schema.options && this.schema.options.select2_options) options = $extend(options, this.schema.options.select2_options);
                this.select2 = window.jQuery(this.input).select2(options);
                var self = this;
                this.select2.on('select2-blur', function() {
                    var val = self.select2.select2('val');
                    self.value = val;
                    self.onChange(true);
                });
            } else {
                this.select2 = null;
            }
        },
        onInputChange: function() {
            this.value = this.input.value;
            this.onChange(true);
        },
        postBuild: function() {
            this._super();
            this.setupSelect2();
        },
        register: function() {
            this._super();
            if (!this.input) return;
            this.input.setAttribute('name', this.formname);
        },
        unregister: function() {
            this._super();
            if (!this.input) return;
            this.input.removeAttribute('name');
        },
        getNumColumns: function() {
            var longest_text = this.getTitle().length;
            for (var i in this.select_values) {
                if (!this.select_values.hasOwnProperty(i)) continue;
                longest_text = Math.max(longest_text, (this.select_values[i] + "").length + 4);
            }

            return Math.min(12, Math.max(longest_text / 7, 2));
        },
        updateValue: function(value) {
            var changed = false;
            var new_value = [];
            for (var i = 0; i < value.length; i++) {
                if (!this.select_options[value[i] + ""]) {
                    changed = true;
                    continue;
                }
                var sanitized = this.sanitize(this.select_values[value[i]]);
                new_value.push(sanitized);
                if (sanitized !== value[i]) changed = true;
            }
            this.value = new_value;
            if (this.select2) this.select2.select2('val', this.value);
            return changed;
        },
        sanitize: function(value) {
            if (this.schema.items.type === "number") {
                return 1 * value;
            } else if (this.schema.items.type === "integer") {
                return Math.floor(value * 1);
            } else {
                return "" + value;
            }
        },
        enable: function() {
            if (!this.always_disabled) {
                if (this.input) {
                    this.input.disabled = false;
                } else if (this.inputs) {
                    for (var i in this.inputs) {
                        if (!this.inputs.hasOwnProperty(i)) continue;
                        this.inputs[i].disabled = false;
                    }
                }
                if (this.select2) this.select2.select2("enable", true);
            }
            this._super();
        },
        disable: function() {
            if (this.input) {
                this.input.disabled = true;
            } else if (this.inputs) {
                for (var i in this.inputs) {
                    if (!this.inputs.hasOwnProperty(i)) continue;
                    this.inputs[i].disabled = true;
                }
            }
            if (this.select2) this.select2.select2("enable", false);
            this._super();
        },
        destroy: function() {
            if (this.select2) {
                this.select2.select2('destroy');
                this.select2 = null;
            }
            this._super();
        }
    });

    JSONEditor.defaults.editors.base64 = JSONEditor.AbstractEditor.extend({
        getNumColumns: function() {
            return 4;
        },
        build: function() {
            var self = this;
            this.title = this.header = this.label = this.theme.getFormInputLabel(this.getTitle());

            // Input that holds the base64 string
            this.input = this.theme.getFormInputField('hidden');
            this.container.appendChild(this.input);

            // Don't show uploader if this is readonly
            if (!this.schema.readOnly && !this.schema.readonly) {
                if (!window.FileReader) throw "FileReader required for base64 editor";

                // File uploader
                this.uploader = this.theme.getFormInputField('file');

                this.uploader.addEventListener('change', function(e) {
                    e.preventDefault();
                    e.stopPropagation();

                    if (this.files && this.files.length) {
                        var fr = new FileReader();
                        fr.onload = function(evt) {
                            self.value = evt.target.result;
                            self.refreshPreview();
                            self.onChange(true);
                            fr = null;
                        };
                        fr.readAsDataURL(this.files[0]);
                    }
                }, false);
            }

            this.preview = this.theme.getFormInputDescription(this.schema.description);
            this.container.appendChild(this.preview);

            this.control = this.theme.getFormControl(this.label, this.uploader || this.input, this.preview);
            this.container.appendChild(this.control);
        },
        refreshPreview: function() {
            if (this.last_preview === this.value) return;
            this.last_preview = this.value;

            this.preview.innerHTML = '';

            if (!this.value) return;

            var mime = this.value.match(/^data:([^;,]+)[;,]/);
            if (mime) mime = mime[1];

            if (!mime) {
                this.preview.innerHTML = '<em>Invalid data URI</em>';
            } else {
                this.preview.innerHTML = '<strong>Type:</strong> ' + mime + ', <strong>Size:</strong> ' + Math.floor((this.value.length - this.value.split(',')[0].length - 1) / 1.33333) + ' bytes';
                if (mime.substr(0, 5) === "image") {
                    this.preview.innerHTML += '<br>';
                    var img = document.createElement('img');
                    img.style.maxWidth = '100%';
                    img.style.maxHeight = '100px';
                    img.src = this.value;
                    this.preview.appendChild(img);
                }
            }
        },
        enable: function() {
            if (this.uploader) this.uploader.disabled = false;
            this._super();
        },
        disable: function() {
            if (this.uploader) this.uploader.disabled = true;
            this._super();
        },
        setValue: function(val) {
            if (this.value !== val) {
                this.value = val;
                this.input.value = this.value;
                this.refreshPreview();
                this.onChange();
            }
        },
        destroy: function() {
            if (this.preview && this.preview.parentNode) this.preview.parentNode.removeChild(this.preview);
            if (this.title && this.title.parentNode) this.title.parentNode.removeChild(this.title);
            if (this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);
            if (this.uploader && this.uploader.parentNode) this.uploader.parentNode.removeChild(this.uploader);

            this._super();
        }
    });

    JSONEditor.defaults.editors.upload = JSONEditor.AbstractEditor.extend({
        getNumColumns: function() {
            return 4;
        },
        build: function() {
            var self = this;
            this.title = this.header = this.label = this.theme.getFormInputLabel(this.getTitle());

            // Input that holds the base64 string
            this.input = this.theme.getFormInputField('hidden');
            this.container.appendChild(this.input);

            // Don't show uploader if this is readonly
            if (!this.schema.readOnly && !this.schema.readonly) {

                if (!this.jsoneditor.options.upload) throw "Upload handler required for upload editor";

                // File uploader
                this.uploader = this.theme.getFormInputField('file');

                this.uploader.addEventListener('change', function(e) {
                    e.preventDefault();
                    e.stopPropagation();

                    if (this.files && this.files.length) {
                        var fr = new FileReader();
                        fr.onload = function(evt) {
                            self.preview_value = evt.target.result;
                            self.refreshPreview();
                            self.onChange(true);
                            fr = null;
                        };
                        fr.readAsDataURL(this.files[0]);
                    }
                }, false);
            }

            var description = this.schema.description;
            if (!description) description = '';

            this.preview = this.theme.getFormInputDescription(description);
            this.container.appendChild(this.preview);

            this.control = this.theme.getFormControl(this.label, this.uploader || this.input, this.preview);
            this.container.appendChild(this.control);
        },
        refreshPreview: function() {
            if (this.last_preview === this.preview_value) return;
            this.last_preview = this.preview_value;

            this.preview.innerHTML = '';

            if (!this.preview_value) return;

            var self = this;

            var mime = this.preview_value.match(/^data:([^;,]+)[;,]/);
            if (mime) mime = mime[1];
            if (!mime) mime = 'unknown';

            var file = this.uploader.files[0];

            this.preview.innerHTML = '<strong>Type:</strong> ' + mime + ', <strong>Size:</strong> ' + file.size + ' bytes';
            if (mime.substr(0, 5) === "image") {
                this.preview.innerHTML += '<br>';
                var img = document.createElement('img');
                img.style.maxWidth = '100%';
                img.style.maxHeight = '100px';
                img.src = this.preview_value;
                this.preview.appendChild(img);
            }

            this.preview.innerHTML += '<br>';
            var uploadButton = this.getButton('Upload', 'upload', 'Upload');
            this.preview.appendChild(uploadButton);
            uploadButton.addEventListener('click', function(event) {
                event.preventDefault();

                uploadButton.setAttribute("disabled", "disabled");
                self.theme.removeInputError(self.uploader);

                if (self.theme.getProgressBar) {
                    self.progressBar = self.theme.getProgressBar();
                    self.preview.appendChild(self.progressBar);
                }

                self.jsoneditor.options.upload(self.path, file, {
                    success: function(url) {
                        self.setValue(url);

                        if (self.parent) self.parent.onChildEditorChange(self);
                        else self.jsoneditor.onChange();

                        if (self.progressBar) self.preview.removeChild(self.progressBar);
                        uploadButton.removeAttribute("disabled");
                    },
                    failure: function(error) {
                        self.theme.addInputError(self.uploader, error);
                        if (self.progressBar) self.preview.removeChild(self.progressBar);
                        uploadButton.removeAttribute("disabled");
                    },
                    updateProgress: function(progress) {
                        if (self.progressBar) {
                            if (progress) self.theme.updateProgressBar(self.progressBar, progress);
                            else self.theme.updateProgressBarUnknown(self.progressBar);
                        }
                    }
                });
            }, false);
        },
        enable: function() {
            if (this.uploader) this.uploader.disabled = false;
            this._super();
        },
        disable: function() {
            if (this.uploader) this.uploader.disabled = true;
            this._super();
        },
        setValue: function(val) {
            if (this.value !== val) {
                this.value = val;
                this.input.value = this.value;
                this.onChange();
            }
        },
        destroy: function() {
            if (this.preview && this.preview.parentNode) this.preview.parentNode.removeChild(this.preview);
            if (this.title && this.title.parentNode) this.title.parentNode.removeChild(this.title);
            if (this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);
            if (this.uploader && this.uploader.parentNode) this.uploader.parentNode.removeChild(this.uploader);

            this._super();
        }
    });

    JSONEditor.defaults.editors.checkbox = JSONEditor.AbstractEditor.extend({
        setValue: function(value, initial) {
            this.value = !! value;
            this.input.checked = this.value;
            this.onChange();
        },
        register: function() {
            this._super();
            if (!this.input) return;
            this.input.setAttribute('name', this.formname);
        },
        unregister: function() {
            this._super();
            if (!this.input) return;
            this.input.removeAttribute('name');
        },
        getNumColumns: function() {
            return Math.min(12, Math.max(this.getTitle().length / 7, 2));
        },
        build: function() {
            var self = this;
            if (!this.options.compact) {
                this.label = this.header = this.theme.getCheckboxLabel(this.getTitle());
            }
            if (this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);
            if (this.options.compact) this.container.className += ' compact';

            this.input = this.theme.getCheckbox();
            this.control = this.theme.getFormControl(this.label, this.input, this.description);

            if (this.schema.readOnly || this.schema.readonly) {
                this.always_disabled = true;
                this.input.disabled = true;
            }

            this.input.addEventListener('change', function(e) {
                e.preventDefault();
                e.stopPropagation();
                self.value = this.checked;
                self.onChange(true);
            }, false);

            this.container.appendChild(this.control);
        },
        enable: function() {
            if (!this.always_disabled) {
                this.input.disabled = false;
            }
            this._super();
        },
        disable: function() {
            this.input.disabled = true;
            this._super();
        },
        destroy: function() {
            if (this.label && this.label.parentNode) this.label.parentNode.removeChild(this.label);
            if (this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);
            if (this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);
            this._super();
        }
    });

    JSONEditor.defaults.editors.arraySelectize = JSONEditor.AbstractEditor.extend({
        build: function() {
            this.title = this.theme.getFormInputLabel(this.getTitle());

            this.title_controls = this.theme.getHeaderButtonHolder();
            this.title.appendChild(this.title_controls);
            this.error_holder = document.createElement('div');

            if (this.schema.description) {
                this.description = this.theme.getDescription(this.schema.description);
            }

            this.input = document.createElement('select');
            this.input.setAttribute('multiple', 'multiple');

            var group = this.theme.getFormControl(this.title, this.input, this.description);

            this.container.appendChild(group);
            this.container.appendChild(this.error_holder);

            window.jQuery(this.input).selectize({
                delimiter: false,
                createOnBlur: true,
                create: true
            });
        },
        postBuild: function() {
            var self = this;
            this.input.selectize.on('change', function(event) {
                self.refreshValue();
                self.onChange(true);
            });
        },
        destroy: function() {
            this.empty(true);
            if (this.title && this.title.parentNode) this.title.parentNode.removeChild(this.title);
            if (this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description);
            if (this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input);

            this._super();
        },
        empty: function(hard) {},
        setValue: function(value, initial) {
            var self = this;
            // Update the array's value, adding/removing rows when necessary
            value = value || [];
            if (!(Array.isArray(value))) value = [value];

            this.input.selectize.clearOptions();
            this.input.selectize.clear(true);

            value.forEach(function(item) {
                self.input.selectize.addOption({
                    text: item,
                    value: item
                });
            });
            this.input.selectize.setValue(value);

            this.refreshValue(initial);
        },
        refreshValue: function(force) {
            this.value = this.input.selectize.getValue();
        },
        showValidationErrors: function(errors) {
            var self = this;

            // Get all the errors that pertain to this editor
            var my_errors = [];
            var other_errors = [];
            $each(errors, function(i, error) {
                if (error.path === self.path) {
                    my_errors.push(error);
                } else {
                    other_errors.push(error);
                }
            });

            // Show errors for this editor
            if (this.error_holder) {

                if (my_errors.length) {
                    var message = [];
                    this.error_holder.innerHTML = '';
                    this.error_holder.style.display = '';
                    $each(my_errors, function(i, error) {
                        self.error_holder.appendChild(self.theme.getErrorMessage(error.message));
                    });
                }
                // Hide error area
                else {
                    this.error_holder.style.display = 'none';
                }
            }
        }
    });

    var matchKey = (function() {
        var elem = document.documentElement;

        if (elem.matches) return 'matches';
        else if (elem.webkitMatchesSelector) return 'webkitMatchesSelector';
        else if (elem.mozMatchesSelector) return 'mozMatchesSelector';
        else if (elem.msMatchesSelector) return 'msMatchesSelector';
        else if (elem.oMatchesSelector) return 'oMatchesSelector';
    })();

    JSONEditor.AbstractTheme = Class.extend({
        getContainer: function() {
            return document.createElement('div');
        },
        getFloatRightLinkHolder: function() {
            var el = document.createElement('div');
            el.setAttribute('style', el.style || {} );
            el.style.cssFloat = 'right';
            el.style.marginLeft = '10px';
            return el;
        },
        getModal: function() {
            var el = document.createElement('div');
            el.style.backgroundColor = 'white';
            el.style.border = '1px solid black';
            el.style.boxShadow = '3px 3px black';
            el.style.position = 'absolute';
            el.style.zIndex = '10';
            el.style.display = 'none';
            return el;
        },
        getGridContainer: function() {
            var el = document.createElement('div');
            return el;
        },
        getGridRow: function() {
            var el = document.createElement('div');
            el.className = 'row';
            return el;
        },
        getGridColumn: function() {
            var el = document.createElement('div');
            return el;
        },
        setGridColumnSize: function(el, size) {

        },
        getLink: function(text) {
            var el = document.createElement('a');
            el.setAttribute('href', '#');
            el.appendChild(document.createTextNode(text));
            return el;
        },
        disableHeader: function(header) {
            header.style.color = '#ccc';
        },
        disableLabel: function(label) {
            label.style.color = '#ccc';
        },
        enableHeader: function(header) {
            header.style.color = '';
        },
        enableLabel: function(label) {
            label.style.color = '';
        },
        getFormInputLabel: function(text) {
            var el = document.createElement('label');
            el.appendChild(document.createTextNode(text));
            return el;
        },
        getCheckboxLabel: function(text) {
            var el = this.getFormInputLabel(text);
            el.style.fontWeight = 'normal';
            return el;
        },
        getHeader: function(text) {
            var el = document.createElement('h3');
            if (typeof text === "string") {
                el.textContent = text;
            } else {
                el.appendChild(text);
            }

            return el;
        },
        getCheckbox: function() {
            var el = this.getFormInputField('checkbox');
            el.style.display = 'inline-block';
            el.style.width = 'auto';
            return el;
        },
        getMultiCheckboxHolder: function(controls, label, description) {
            var el = document.createElement('div');

            if (label) {
                label.style.display = 'block';
                el.appendChild(label);
            }

            for (var i in controls) {
                if (!controls.hasOwnProperty(i)) continue;
                controls[i].style.display = 'inline-block';
                controls[i].style.marginRight = '20px';
                el.appendChild(controls[i]);
            }

            if (description) el.appendChild(description);

            return el;
        },
        getSelectInput: function(options) {
            var select = document.createElement('select');
            if (options) this.setSelectOptions(select, options);
            return select;
        },
        getSwitcher: function(options) {
            var switcher = this.getSelectInput(options);
            switcher.style.backgroundColor = 'transparent';
            switcher.style.display = 'inline-block';
            switcher.style.fontStyle = 'italic';
            switcher.style.fontWeight = 'normal';
            switcher.style.height = 'auto';
            switcher.style.marginBottom = 0;
            switcher.style.marginLeft = '5px';
            switcher.style.padding = '0 0 0 3px';
            switcher.style.width = 'auto';
            return switcher;
        },
        getSwitcherOptions: function(switcher) {
            return switcher.getElementsByTagName('option');
        },
        setSwitcherOptions: function(switcher, options, titles) {
            this.setSelectOptions(switcher, options, titles);
        },
        setSelectOptions: function(select, options, titles) {
            titles = titles || [];
            select.innerHTML = '';
            for (var i = 0; i < options.length; i++) {
                var option = document.createElement('option');
                option.setAttribute('value', options[i]);
                option.textContent = titles[i] || options[i];
                select.appendChild(option);
            }
        },
        getTextareaInput: function() {
            var el = document.createElement('textarea');
            el.setAttribute('style', el.style || {} );
            el.style.width = '100%';
            el.style.height = '300px';
            el.style.boxSizing = 'border-box';
            return el;
        },
        getRangeInput: function(min, max, step) {
            var el = this.getFormInputField('range');
            el.setAttribute('min', min);
            el.setAttribute('max', max);
            el.setAttribute('step', step);
            return el;
        },
        getFormInputField: function(type) {
            var el = document.createElement('input');
            el.setAttribute('type', type);
            return el;
        },
        afterInputReady: function(input) {

        },
        getFormControl: function(label, input, description) {
            var el = document.createElement('div');
            el.className = 'form-control';
            if (label) el.appendChild(label);
            if (input.type === 'checkbox') {
                label.insertBefore(input, label.firstChild);
            } else {
                el.appendChild(input);
            }

            if (description) el.appendChild(description);
            return el;
        },
        getIndentedPanel: function() {
            var el = document.createElement('div');
            el.setAttribute('style', el.style || {} );
            el.style.paddingLeft = '10px';
            el.style.marginLeft = '10px';
            el.style.borderLeft = '1px solid #ccc';
            return el;
        },
        getChildEditorHolder: function() {
            return document.createElement('div');
        },
        getDescription: function(text) {
            var el = document.createElement('p');
            el.innerHTML = text;
            return el;
        },
        getCheckboxDescription: function(text) {
            return this.getDescription(text);
        },
        getFormInputDescription: function(text) {
            return this.getDescription(text);
        },
        getHeaderButtonHolder: function() {
            return this.getButtonHolder();
        },
        getButtonHolder: function() {
            return document.createElement('div');
        },
        getButton: function(text, icon, title) {
            var el = document.createElement('button');
            el.type = 'button';
            this.setButtonText(el, text, icon, title);
            return el;
        },
        setButtonText: function(button, text, icon, title) {
            button.innerHTML = '';
            if (icon) {
                button.appendChild(icon);
                button.innerHTML += ' ';
            }
            button.appendChild(document.createTextNode(text));
            if (title) button.setAttribute('title', title);
        },
        getTable: function() {
            return document.createElement('table');
        },
        getTableRow: function() {
            return document.createElement('tr');
        },
        getTableHead: function() {
            return document.createElement('thead');
        },
        getTableBody: function() {
            return document.createElement('tbody');
        },
        getTableHeaderCell: function(text) {
            var el = document.createElement('th');
            el.textContent = text;
            return el;
        },
        getTableCell: function() {
            var el = document.createElement('td');
            return el;
        },
        getErrorMessage: function(text) {
            var el = document.createElement('p');
            el.setAttribute('style', el.style || {} );
            el.style.color = 'red';
            el.appendChild(document.createTextNode(text));
            return el;
        },
        addInputError: function(input, text) {},
        removeInputError: function(input) {},
        addTableRowError: function(row) {},
        removeTableRowError: function(row) {},
        getTabHolder: function() {
            var el = document.createElement('div');
            el.innerHTML = "<div style='float: left; width: 130px;' class='tabs'></div><div class='content' style='margin-left: 130px;'></div><div style='clear:both;'></div>";
            return el;
        },
        applyStyles: function(el, styles) {
            el.setAttribute('style', el.style || {} );
            for (var i in styles) {
                if (!styles.hasOwnProperty(i)) continue;
                el.style[i] = styles[i];
            }
        },
        closest: function(elem, selector) {
            while (elem && elem !== document) {
                if (matchKey) {
                    if (elem[matchKey](selector)) {
                        return elem;
                    } else {
                        elem = elem.parentNode;
                    }
                } else {
                    return false;
                }
            }
            return false;
        },
        getTab: function(span) {
            var el = document.createElement('div');
            el.appendChild(span);
            el.setAttribute('style', el.style || {} );
            this.applyStyles(el, {
                border: '1px solid #ccc',
                borderWidth: '1px 0 1px 1px',
                textAlign: 'center',
                lineHeight: '30px',
                borderRadius: '5px',
                borderBottomRightRadius: 0,
                borderTopRightRadius: 0,
                fontWeight: 'bold',
                cursor: 'pointer'
            });
            return el;
        },
        getTabContentHolder: function(tab_holder) {
            return tab_holder.children[1];
        },
        getTabContent: function() {
            return this.getIndentedPanel();
        },
        markTabActive: function(tab) {
            this.applyStyles(tab, {
                opacity: 1,
                background: 'white'
            });
        },
        markTabInactive: function(tab) {
            this.applyStyles(tab, {
                opacity: 0.5,
                background: ''
            });
        },
        addTab: function(holder, tab) {
            holder.children[0].appendChild(tab);
        },
        getBlockLink: function() {
            var link = document.createElement('a');
            link.style.display = 'block';
            return link;
        },
        getBlockLinkHolder: function() {
            var el = document.createElement('div');
            return el;
        },
        getLinksHolder: function() {
            var el = document.createElement('div');
            return el;
        },
        createMediaLink: function(holder, link, media) {
            holder.appendChild(link);
            media.style.width = '100%';
            holder.appendChild(media);
        },
        createImageLink: function(holder, link, image) {
            holder.appendChild(link);
            link.appendChild(image);
        }
    });

    JSONEditor.defaults.themes.bootstrap2 = JSONEditor.AbstractTheme.extend({
        getRangeInput: function(min, max, step) {
            // TODO: use bootstrap slider
            return this._super(min, max, step);
        },
        getGridContainer: function() {
            var el = document.createElement('div');
            el.className = 'container-fluid';
            return el;
        },
        getGridRow: function() {
            var el = document.createElement('div');
            el.className = 'row-fluid';
            return el;
        },
        getFormInputLabel: function(text) {
            var el = this._super(text);
            el.style.display = 'inline-block';
            el.style.fontWeight = 'bold';
            return el;
        },
        setGridColumnSize: function(el, size) {
            el.className = 'span' + size;
        },
        getSelectInput: function(options) {
            var input = this._super(options);
            input.style.width = 'auto';
            input.style.maxWidth = '98%';
            return input;
        },
        getFormInputField: function(type) {
            var el = this._super(type);
            el.style.width = '98%';
            return el;
        },
        afterInputReady: function(input) {
            if (input.controlgroup) return;
            input.controlgroup = this.closest(input, '.control-group');
            input.controls = this.closest(input, '.controls');
            if (this.closest(input, '.compact')) {
                input.controlgroup.className = input.controlgroup.className.replace(/control-group/g, '').replace(/[ ]{2,}/g, ' ');
                input.controls.className = input.controlgroup.className.replace(/controls/g, '').replace(/[ ]{2,}/g, ' ');
                input.style.marginBottom = 0;
            }

            // TODO: use bootstrap slider
        },
        getIndentedPanel: function() {
            var el = document.createElement('div');
            el.className = 'well well-small';
            el.style.paddingBottom = 0;
            return el;
        },
        getFormInputDescription: function(text) {
            var el = document.createElement('p');
            el.className = 'help-inline';
            el.textContent = text;
            return el;
        },
        getFormControl: function(label, input, description) {
            var ret = document.createElement('div');
            ret.className = 'control-group';

            var controls = document.createElement('div');
            controls.className = 'controls';

            if (label && input.getAttribute('type') === 'checkbox') {
                ret.appendChild(controls);
                label.className += ' checkbox';
                label.appendChild(input);
                controls.appendChild(label);
                controls.style.height = '30px';
            } else {
                if (label) {
                    label.className += ' control-label';
                    ret.appendChild(label);
                }
                controls.appendChild(input);
                ret.appendChild(controls);
            }

            if (description) controls.appendChild(description);

            return ret;
        },
        getHeaderButtonHolder: function() {
            var el = this.getButtonHolder();
            el.style.marginLeft = '10px';
            return el;
        },
        getButtonHolder: function() {
            var el = document.createElement('div');
            el.className = 'btn-group';
            return el;
        },
        getButton: function(text, icon, title) {
            var el = this._super(text, icon, title);
            el.className += ' btn btn-default';
            return el;
        },
        getTable: function() {
            var el = document.createElement('table');
            el.className = 'table table-bordered';
            el.style.width = 'auto';
            el.style.maxWidth = 'none';
            return el;
        },
        addInputError: function(input, text) {
            if (!input.controlgroup || !input.controls) return;
            input.controlgroup.className += ' error';
            if (!input.errmsg) {
                input.errmsg = document.createElement('p');
                input.errmsg.className = 'help-block errormsg';
                input.controls.appendChild(input.errmsg);
            } else {
                input.errmsg.style.display = '';
            }

            input.errmsg.textContent = text;
        },
        removeInputError: function(input) {
            if (!input.errmsg) return;
            input.errmsg.style.display = 'none';
            input.controlgroup.className = input.controlgroup.className.replace(/\s?error/g, '');
        },
        getTabHolder: function() {
            var el = document.createElement('div');
            el.className = 'tabbable tabs-left';
            el.innerHTML = "<ul class='nav nav-tabs span2' style='margin-right: 0;'></ul><div class='tab-content span10' style='overflow:visible;'></div>";
            return el;
        },
        getTab: function(text) {
            var el = document.createElement('li');
            var a = document.createElement('a');
            a.setAttribute('href', '#');
            a.appendChild(text);
            el.appendChild(a);
            return el;
        },
        getTabContentHolder: function(tab_holder) {
            return tab_holder.children[1];
        },
        getTabContent: function() {
            var el = document.createElement('div');
            el.className = 'tab-pane active';
            return el;
        },
        markTabActive: function(tab) {
            tab.className += ' active';
        },
        markTabInactive: function(tab) {
            tab.className = tab.className.replace(/\s?active/g, '');
        },
        addTab: function(holder, tab) {
            holder.children[0].appendChild(tab);
        },
        getProgressBar: function() {
            var container = document.createElement('div');
            container.className = 'progress';

            var bar = document.createElement('div');
            bar.className = 'bar';
            bar.style.width = '0%';
            container.appendChild(bar);

            return container;
        },
        updateProgressBar: function(progressBar, progress) {
            if (!progressBar) return;

            progressBar.firstChild.style.width = progress + "%";
        },
        updateProgressBarUnknown: function(progressBar) {
            if (!progressBar) return;

            progressBar.className = 'progress progress-striped active';
            progressBar.firstChild.style.width = '100%';
        }
    });

    JSONEditor.defaults.themes.bootstrap3 = JSONEditor.AbstractTheme.extend({
        getSelectInput: function(options) {
            var el = this._super(options);
            el.className += 'form-control';
            //el.style.width = 'auto';
            return el;
        },
        setGridColumnSize: function(el, size) {
            el.className = 'col-md-' + size;
        },
        afterInputReady: function(input) {
            if (input.controlgroup) return;
            input.controlgroup = this.closest(input, '.form-group');
            if (this.closest(input, '.compact')) {
                input.controlgroup.style.marginBottom = 0;
            }

            // TODO: use bootstrap slider
        },
        getTextareaInput: function() {
            var el = document.createElement('textarea');
            el.className = 'form-control';
            return el;
        },
        getRangeInput: function(min, max, step) {
            // TODO: use better slider
            return this._super(min, max, step);
        },
        getFormInputField: function(type) {
            var el = this._super(type);
            if (type !== 'checkbox') {
                el.className += 'form-control';
            }
            return el;
        },
        getFormControl: function(label, input, description) {
            var group = document.createElement('div');

            if (label && input.type === 'checkbox') {
                group.className += ' checkbox';
                label.appendChild(input);
                label.style.fontSize = '14px';
                group.style.marginTop = '0';
                group.appendChild(label);
                input.style.position = 'relative';
                input.style.cssFloat = 'left';
            } else {
                group.className += ' form-group';
                if (label) {
                    label.className += ' control-label';
                    group.appendChild(label);
                }
                group.appendChild(input);
            }

            if (description) group.appendChild(description);

            return group;
        },
        getIndentedPanel: function() {
            var el = document.createElement('div');
            el.className = 'well well-sm';
            el.style.paddingBottom = 0;
            return el;
        },
        getFormInputDescription: function(text) {
            var el = document.createElement('p');
            el.className = 'help-block';
            el.innerHTML = text;
            return el;
        },
        getHeaderButtonHolder: function() {
            var el = this.getButtonHolder();
            el.style.marginLeft = '10px';
            return el;
        },
        getButtonHolder: function() {
            var el = document.createElement('div');
            el.className = 'btn-group';
            return el;
        },
        getButton: function(text, icon, title) {
            var el = this._super(text, icon, title);
            el.className += 'btn btn-default';
            return el;
        },
        getTable: function() {
            var el = document.createElement('table');
            el.className = 'table table-bordered';
            el.style.width = 'auto';
            el.style.maxWidth = 'none';
            return el;
        },

        addInputError: function(input, text) {
            if (!input.controlgroup) return;
            input.controlgroup.className += ' has-error';
            if (!input.errmsg) {
                input.errmsg = document.createElement('p');
                input.errmsg.className = 'help-block errormsg';
                input.controlgroup.appendChild(input.errmsg);
            } else {
                input.errmsg.style.display = '';
            }

            input.errmsg.textContent = text;
        },
        removeInputError: function(input) {
            if (!input.errmsg) return;
            input.errmsg.style.display = 'none';
            input.controlgroup.className = input.controlgroup.className.replace(/\s?has-error/g, '');
        },
        getTabHolder: function() {
            var el = document.createElement('div');
            el.innerHTML = "<div class='tabs list-group col-md-2'></div><div class='col-md-10'></div>";
            el.className = 'rows';
            return el;
        },
        getTab: function(text) {
            var el = document.createElement('a');
            el.className = 'list-group-item';
            el.setAttribute('href', '#');
            el.appendChild(text);
            return el;
        },
        markTabActive: function(tab) {
            tab.className += ' active';
        },
        markTabInactive: function(tab) {
            tab.className = tab.className.replace(/\s?active/g, '');
        },
        getProgressBar: function() {
            var min = 0,
                max = 100,
                start = 0;

            var container = document.createElement('div');
            container.className = 'progress';

            var bar = document.createElement('div');
            bar.className = 'progress-bar';
            bar.setAttribute('role', 'progressbar');
            bar.setAttribute('aria-valuenow', start);
            bar.setAttribute('aria-valuemin', min);
            bar.setAttribute('aria-valuenax', max);
            bar.innerHTML = start + "%";
            container.appendChild(bar);

            return container;
        },
        updateProgressBar: function(progressBar, progress) {
            if (!progressBar) return;

            var bar = progressBar.firstChild;
            var percentage = progress + "%";
            bar.setAttribute('aria-valuenow', progress);
            bar.style.width = percentage;
            bar.innerHTML = percentage;
        },
        updateProgressBarUnknown: function(progressBar) {
            if (!progressBar) return;

            var bar = progressBar.firstChild;
            progressBar.className = 'progress progress-striped active';
            bar.removeAttribute('aria-valuenow');
            bar.style.width = '100%';
            bar.innerHTML = '';
        }
    });

    // Base Foundation theme
    JSONEditor.defaults.themes.foundation = JSONEditor.AbstractTheme.extend({
        getChildEditorHolder: function() {
            var el = document.createElement('div');
            el.style.marginBottom = '15px';
            return el;
        },
        getSelectInput: function(options) {
            var el = this._super(options);
            el.style.minWidth = 'none';
            el.style.padding = '5px';
            el.style.marginTop = '3px';
            return el;
        },
        getSwitcher: function(options) {
            var el = this._super(options);
            el.style.paddingRight = '8px';
            return el;
        },
        afterInputReady: function(input) {
            if (this.closest(input, '.compact')) {
                input.style.marginBottom = 0;
            }
            input.group = this.closest(input, '.form-control');
        },
        getFormInputLabel: function(text) {
            var el = this._super(text);
            el.style.display = 'inline-block';
            return el;
        },
        getFormInputField: function(type) {
            var el = this._super(type);
            el.style.width = '100%';
            el.style.marginBottom = type === 'checkbox' ? '0' : '12px';
            return el;
        },
        getFormInputDescription: function(text) {
            var el = document.createElement('p');
            el.textContent = text;
            el.style.marginTop = '-10px';
            el.style.fontStyle = 'italic';
            return el;
        },
        getIndentedPanel: function() {
            var el = document.createElement('div');
            el.className = 'panel';
            el.style.paddingBottom = 0;
            return el;
        },
        getHeaderButtonHolder: function() {
            var el = this.getButtonHolder();
            el.style.display = 'inline-block';
            el.style.marginLeft = '10px';
            el.style.verticalAlign = 'middle';
            return el;
        },
        getButtonHolder: function() {
            var el = document.createElement('div');
            el.className = 'button-group';
            return el;
        },
        getButton: function(text, icon, title) {
            var el = this._super(text, icon, title);
            el.className += ' small button';
            return el;
        },
        addInputError: function(input, text) {
            if (!input.group) return;
            input.group.className += ' error';

            if (!input.errmsg) {
                input.insertAdjacentHTML('afterend', '<small class="error"></small>');
                input.errmsg = input.parentNode.getElementsByClassName('error')[0];
            } else {
                input.errmsg.style.display = '';
            }

            input.errmsg.textContent = text;
        },
        removeInputError: function(input) {
            if (!input.errmsg) return;
            input.group.className = input.group.className.replace(/ error/g, '');
            input.errmsg.style.display = 'none';
        },
        getProgressBar: function() {
            var progressBar = document.createElement('div');
            progressBar.className = 'progress';

            var meter = document.createElement('span');
            meter.className = 'meter';
            meter.style.width = '0%';
            progressBar.appendChild(meter);
            return progressBar;
        },
        updateProgressBar: function(progressBar, progress) {
            if (!progressBar) return;
            progressBar.firstChild.style.width = progress + '%';
        },
        updateProgressBarUnknown: function(progressBar) {
            if (!progressBar) return;
            progressBar.firstChild.style.width = '100%';
        }
    });

    // Foundation 3 Specific Theme
    JSONEditor.defaults.themes.foundation3 = JSONEditor.defaults.themes.foundation.extend({
        getHeaderButtonHolder: function() {
            var el = this._super();
            el.style.fontSize = '.6em';
            return el;
        },
        getFormInputLabel: function(text) {
            var el = this._super(text);
            el.style.fontWeight = 'bold';
            return el;
        },
        getTabHolder: function() {
            var el = document.createElement('div');
            el.className = 'row';
            el.innerHTML = "<dl class='tabs vertical two columns'></dl><div class='tabs-content ten columns'></div>";
            return el;
        },
        setGridColumnSize: function(el, size) {
            var sizes = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve'];
            el.className = 'columns ' + sizes[size];
        },
        getTab: function(text) {
            var el = document.createElement('dd');
            var a = document.createElement('a');
            a.setAttribute('href', '#');
            a.appendChild(text);
            el.appendChild(a);
            return el;
        },
        getTabContentHolder: function(tab_holder) {
            return tab_holder.children[1];
        },
        getTabContent: function() {
            var el = document.createElement('div');
            el.className = 'content active';
            el.style.paddingLeft = '5px';
            return el;
        },
        markTabActive: function(tab) {
            tab.className += ' active';
        },
        markTabInactive: function(tab) {
            tab.className = tab.className.replace(/\s*active/g, '');
        },
        addTab: function(holder, tab) {
            holder.children[0].appendChild(tab);
        }
    });

    // Foundation 4 Specific Theme
    JSONEditor.defaults.themes.foundation4 = JSONEditor.defaults.themes.foundation.extend({
        getHeaderButtonHolder: function() {
            var el = this._super();
            el.style.fontSize = '.6em';
            return el;
        },
        setGridColumnSize: function(el, size) {
            el.className = 'columns large-' + size;
        },
        getFormInputDescription: function(text) {
            var el = this._super(text);
            el.style.fontSize = '.8rem';
            return el;
        },
        getFormInputLabel: function(text) {
            var el = this._super(text);
            el.style.fontWeight = 'bold';
            return el;
        }
    });

    // Foundation 5 Specific Theme
    JSONEditor.defaults.themes.foundation5 = JSONEditor.defaults.themes.foundation.extend({
        getFormInputDescription: function(text) {
            var el = this._super(text);
            el.style.fontSize = '.8rem';
            return el;
        },
        setGridColumnSize: function(el, size) {
            el.className = 'columns medium-' + size;
        },
        getButton: function(text, icon, title) {
            var el = this._super(text, icon, title);
            el.className = el.className.replace(/\s*small/g, '') + ' tiny';
            return el;
        },
        getTabHolder: function() {
            var el = document.createElement('div');
            el.innerHTML = "<dl class='tabs vertical'></dl><div class='tabs-content vertical'></div>";
            return el;
        },
        getTab: function(text) {
            var el = document.createElement('dd');
            var a = document.createElement('a');
            a.setAttribute('href', '#');
            a.appendChild(text);
            el.appendChild(a);
            return el;
        },
        getTabContentHolder: function(tab_holder) {
            return tab_holder.children[1];
        },
        getTabContent: function() {
            var el = document.createElement('div');
            el.className = 'content active';
            el.style.paddingLeft = '5px';
            return el;
        },
        markTabActive: function(tab) {
            tab.className += ' active';
        },
        markTabInactive: function(tab) {
            tab.className = tab.className.replace(/\s*active/g, '');
        },
        addTab: function(holder, tab) {
            holder.children[0].appendChild(tab);
        }
    });

    JSONEditor.defaults.themes.html = JSONEditor.AbstractTheme.extend({
        getFormInputLabel: function(text) {
            var el = this._super(text);
            el.style.display = 'block';
            el.style.marginBottom = '3px';
            el.style.fontWeight = 'bold';
            return el;
        },
        getFormInputDescription: function(text) {
            var el = this._super(text);
            el.style.fontSize = '.8em';
            el.style.margin = 0;
            el.style.display = 'inline-block';
            el.style.fontStyle = 'italic';
            return el;
        },
        getIndentedPanel: function() {
            var el = this._super();
            el.style.border = '1px solid #ddd';
            el.style.padding = '5px';
            el.style.margin = '5px';
            el.style.borderRadius = '3px';
            return el;
        },
        getChildEditorHolder: function() {
            var el = this._super();
            el.style.marginBottom = '8px';
            return el;
        },
        getHeaderButtonHolder: function() {
            var el = this.getButtonHolder();
            el.style.display = 'inline-block';
            el.style.marginLeft = '10px';
            el.style.fontSize = '.8em';
            el.style.verticalAlign = 'middle';
            return el;
        },
        getTable: function() {
            var el = this._super();
            el.style.borderBottom = '1px solid #ccc';
            el.style.marginBottom = '5px';
            return el;
        },
        addInputError: function(input, text) {
            input.style.borderColor = 'red';

            if (!input.errmsg) {
                var group = this.closest(input, '.form-control');
                input.errmsg = document.createElement('div');
                input.errmsg.setAttribute('class', 'errmsg');
                input.errmsg.style.cssText = input.errmsg.style.cssText || {};
                input.errmsg.style.color = 'red';
                group.appendChild(input.errmsg);
            } else {
                input.errmsg.style.display = 'block';
            }

            input.errmsg.innerHTML = '';
            input.errmsg.appendChild(document.createTextNode(text));
        },
        removeInputError: function(input) {
            input.style.borderColor = '';
            if (input.errmsg) input.errmsg.style.display = 'none';
        },
        getProgressBar: function() {
            var max = 100,
                start = 0;

            var progressBar = document.createElement('progress');
            progressBar.setAttribute('max', max);
            progressBar.setAttribute('value', start);
            return progressBar;
        },
        updateProgressBar: function(progressBar, progress) {
            if (!progressBar) return;
            progressBar.setAttribute('value', progress);
        },
        updateProgressBarUnknown: function(progressBar) {
            if (!progressBar) return;
            progressBar.removeAttribute('value');
        }
    });

    JSONEditor.defaults.themes.jqueryui = JSONEditor.AbstractTheme.extend({
        getTable: function() {
            var el = this._super();
            el.setAttribute('cellpadding', 5);
            el.setAttribute('cellspacing', 0);
            return el;
        },
        getTableHeaderCell: function(text) {
            var el = this._super(text);
            el.className = 'ui-state-active';
            el.style.fontWeight = 'bold';
            return el;
        },
        getTableCell: function() {
            var el = this._super();
            el.className = 'ui-widget-content';
            return el;
        },
        getHeaderButtonHolder: function() {
            var el = this.getButtonHolder();
            el.style.marginLeft = '10px';
            el.style.fontSize = '.6em';
            el.style.display = 'inline-block';
            return el;
        },
        getFormInputDescription: function(text) {
            var el = this.getDescription(text);
            el.style.marginLeft = '10px';
            el.style.display = 'inline-block';
            return el;
        },
        getFormControl: function(label, input, description) {
            var el = this._super(label, input, description);
            if (input.type === 'checkbox') {
                el.style.lineHeight = '25px';

                el.style.padding = '3px 0';
            } else {
                el.style.padding = '4px 0 8px 0';
            }
            return el;
        },
        getDescription: function(text) {
            var el = document.createElement('span');
            el.style.fontSize = '.8em';
            el.style.fontStyle = 'italic';
            el.textContent = text;
            return el;
        },
        getButtonHolder: function() {
            var el = document.createElement('div');
            el.className = 'ui-buttonset';
            el.style.fontSize = '.7em';
            return el;
        },
        getFormInputLabel: function(text) {
            var el = document.createElement('label');
            el.style.fontWeight = 'bold';
            el.style.display = 'block';
            el.textContent = text;
            return el;
        },
        getButton: function(text, icon, title) {
            var button = document.createElement("button");
            button.className = 'ui-button ui-widget ui-state-default ui-corner-all';

            // Icon only
            if (icon && !text) {
                button.className += ' ui-button-icon-only';
                icon.className += ' ui-button-icon-primary ui-icon-primary';
                button.appendChild(icon);
            }
            // Icon and Text
            else if (icon) {
                button.className += ' ui-button-text-icon-primary';
                icon.className += ' ui-button-icon-primary ui-icon-primary';
                button.appendChild(icon);
            }
            // Text only
            else {
                button.className += ' ui-button-text-only';
            }

            var el = document.createElement('span');
            el.className = 'ui-button-text';
            el.textContent = text || title || ".";
            button.appendChild(el);

            button.setAttribute('title', title);

            return button;
        },
        setButtonText: function(button, text, icon, title) {
            button.innerHTML = '';
            button.className = 'ui-button ui-widget ui-state-default ui-corner-all';

            // Icon only
            if (icon && !text) {
                button.className += ' ui-button-icon-only';
                icon.className += ' ui-button-icon-primary ui-icon-primary';
                button.appendChild(icon);
            }
            // Icon and Text
            else if (icon) {
                button.className += ' ui-button-text-icon-primary';
                icon.className += ' ui-button-icon-primary ui-icon-primary';
                button.appendChild(icon);
            }
            // Text only
            else {
                button.className += ' ui-button-text-only';
            }

            var el = document.createElement('span');
            el.className = 'ui-button-text';
            el.textContent = text || title || ".";
            button.appendChild(el);

            button.setAttribute('title', title);
        },
        getIndentedPanel: function() {
            var el = document.createElement('div');
            el.className = 'ui-widget-content ui-corner-all';
            el.style.padding = '1em 1.4em';
            el.style.marginBottom = '20px';
            return el;
        },
        afterInputReady: function(input) {
            if (input.controls) return;
            input.controls = this.closest(input, '.form-control');
        },
        addInputError: function(input, text) {
            if (!input.controls) return;
            if (!input.errmsg) {
                input.errmsg = document.createElement('div');
                input.errmsg.className = 'ui-state-error';
                input.controls.appendChild(input.errmsg);
            } else {
                input.errmsg.style.display = '';
            }

            input.errmsg.textContent = text;
        },
        removeInputError: function(input) {
            if (!input.errmsg) return;
            input.errmsg.style.display = 'none';
        },
        markTabActive: function(tab) {
            tab.className = tab.className.replace(/\s*ui-widget-header/g, '') + ' ui-state-active';
        },
        markTabInactive: function(tab) {
            tab.className = tab.className.replace(/\s*ui-state-active/g, '') + ' ui-widget-header';
        }
    });

    JSONEditor.AbstractIconLib = Class.extend({
        mapping: {
            collapse: '',
            expand: '',
            "delete": '',
            edit: '',
            add: '',
            cancel: '',
            save: '',
            moveup: '',
            movedown: ''
        },
        icon_prefix: '',
        getIconClass: function(key) {
            if (this.mapping[key]) return this.icon_prefix + this.mapping[key];
            else return null;
        },
        getIcon: function(key) {
            var iconclass = this.getIconClass(key);

            if (!iconclass) return null;

            var i = document.createElement('i');
            i.className = iconclass;
            return i;
        }
    });

    JSONEditor.defaults.iconlibs.bootstrap2 = JSONEditor.AbstractIconLib.extend({
        mapping: {
            collapse: 'chevron-down',
            expand: 'chevron-up',
            "delete": 'trash',
            edit: 'pencil',
            add: 'plus',
            cancel: 'ban-circle',
            save: 'ok',
            moveup: 'arrow-up',
            movedown: 'arrow-down'
        },
        icon_prefix: 'icon-'
    });

    JSONEditor.defaults.iconlibs.bootstrap3 = JSONEditor.AbstractIconLib.extend({
        mapping: {
            collapse: 'chevron-down',
            expand: 'chevron-right',
            "delete": 'remove',
            edit: 'pencil',
            add: 'plus',
            cancel: 'floppy-remove',
            save: 'floppy-saved',
            moveup: 'arrow-up',
            movedown: 'arrow-down'
        },
        icon_prefix: 'glyphicon glyphicon-'
    });

    JSONEditor.defaults.iconlibs.fontawesome3 = JSONEditor.AbstractIconLib.extend({
        mapping: {
            collapse: 'chevron-down',
            expand: 'chevron-right',
            "delete": 'remove',
            edit: 'pencil',
            add: 'plus',
            cancel: 'ban-circle',
            save: 'save',
            moveup: 'arrow-up',
            movedown: 'arrow-down'
        },
        icon_prefix: 'icon-'
    });

    JSONEditor.defaults.iconlibs.fontawesome4 = JSONEditor.AbstractIconLib.extend({
        mapping: {
            collapse: 'caret-square-o-down',
            expand: 'caret-square-o-right',
            "delete": 'times',
            edit: 'pencil',
            add: 'plus',
            cancel: 'ban',
            save: 'save',
            moveup: 'arrow-up',
            movedown: 'arrow-down'
        },
        icon_prefix: 'fa fa-'
    });

    JSONEditor.defaults.iconlibs.foundation2 = JSONEditor.AbstractIconLib.extend({
        mapping: {
            collapse: 'minus',
            expand: 'plus',
            "delete": 'remove',
            edit: 'edit',
            add: 'add-doc',
            cancel: 'error',
            save: 'checkmark',
            moveup: 'up-arrow',
            movedown: 'down-arrow'
        },
        icon_prefix: 'foundicon-'
    });

    JSONEditor.defaults.iconlibs.foundation3 = JSONEditor.AbstractIconLib.extend({
        mapping: {
            collapse: 'minus',
            expand: 'plus',
            "delete": 'x',
            edit: 'pencil',
            add: 'page-add',
            cancel: 'x-circle',
            save: 'save',
            moveup: 'arrow-up',
            movedown: 'arrow-down'
        },
        icon_prefix: 'fi-'
    });

    JSONEditor.defaults.iconlibs.jqueryui = JSONEditor.AbstractIconLib.extend({
        mapping: {
            collapse: 'triangle-1-s',
            expand: 'triangle-1-e',
            "delete": 'trash',
            edit: 'pencil',
            add: 'plusthick',
            cancel: 'closethick',
            save: 'disk',
            moveup: 'arrowthick-1-n',
            movedown: 'arrowthick-1-s'
        },
        icon_prefix: 'ui-icon ui-icon-'
    });

    JSONEditor.defaults.templates["default"] = function() {
        return {
            compile: function(template) {
                var matches = template.match(/{{\s*([a-zA-Z0-9\-_ \.]+)\s*}}/g);
                var l = matches && matches.length;

                // Shortcut if the template contains no variables
                if (!l) return function() {
                    return template;
                };

                // Pre-compute the search/replace functions
                // This drastically speeds up template execution
                var replacements = [];
                var get_replacement = function(i) {
                    var p = matches[i].replace(/[{}]+/g, '').trim().split('.');
                    var n = p.length;
                    var func;

                    if (n > 1) {
                        var cur;
                        func = function(vars) {
                            cur = vars;
                            for (i = 0; i < n; i++) {
                                cur = cur[p[i]];
                                if (!cur) break;
                            }
                            return cur;
                        };
                    } else {
                        p = p[0];
                        func = function(vars) {
                            return vars[p];
                        };
                    }

                    replacements.push({
                        s: matches[i],
                        r: func
                    });
                };
                for (var i = 0; i < l; i++) {
                    get_replacement(i);
                }

                // The compiled function
                return function(vars) {
                    var ret = template + "";
                    var r;
                    for (i = 0; i < l; i++) {
                        r = replacements[i];
                        ret = ret.replace(r.s, r.r(vars));
                    }
                    return ret;
                };
            }
        };
    };

    JSONEditor.defaults.templates.ejs = function() {
        if (!window.EJS) return false;

        return {
            compile: function(template) {
                var compiled = new window.EJS({
                    text: template
                });

                return function(context) {
                    return compiled.render(context);
                };
            }
        };
    };

    JSONEditor.defaults.templates.handlebars = function() {
        return window.Handlebars;
    };

    JSONEditor.defaults.templates.hogan = function() {
        if (!window.Hogan) return false;

        return {
            compile: function(template) {
                var compiled = window.Hogan.compile(template);
                return function(context) {
                    return compiled.render(context);
                };
            }
        };
    };

    JSONEditor.defaults.templates.markup = function() {
        if (!window.Mark || !window.Mark.up) return false;

        return {
            compile: function(template) {
                return function(context) {
                    return window.Mark.up(template, context);
                };
            }
        };
    };

    JSONEditor.defaults.templates.mustache = function() {
        if (!window.Mustache) return false;

        return {
            compile: function(template) {
                return function(view) {
                    return window.Mustache.render(template, view);
                };
            }
        };
    };

    JSONEditor.defaults.templates.swig = function() {
        return window.swig;
    };

    JSONEditor.defaults.templates.underscore = function() {
        if (!window._) return false;

        return {
            compile: function(template) {
                return function(context) {
                    return window._.template(template, context);
                };
            }
        };
    };

    // Set the default theme
    JSONEditor.defaults.theme = 'html';

    // Set the default template engine
    JSONEditor.defaults.template = 'default';

    // Default options when initializing JSON Editor
    JSONEditor.defaults.options = {};

    // String translate function
    JSONEditor.defaults.translate = function(key, variables) {
        var lang = JSONEditor.defaults.languages[JSONEditor.defaults.language];
        if (!lang) throw "Unknown language " + JSONEditor.defaults.language;

        var string = lang[key] || JSONEditor.defaults.languages[JSONEditor.defaults.default_language][key];

        if (typeof string === "undefined") throw "Unknown translate string " + key;

        if (variables) {
            for (var i = 0; i < variables.length; i++) {
                string = string.replace(new RegExp('\\{\\{' + i + '}}', 'g'), variables[i]);
            }
        }

        return string;
    };

    // Translation strings and default languages
    JSONEditor.defaults.default_language = 'en';
    JSONEditor.defaults.language = JSONEditor.defaults.default_language;
    JSONEditor.defaults.languages.en = {
        /**
         * When a property is not set
         */
        error_notset: "Property must be set",
        /**
         * When a string must not be empty
         */
        error_notempty: "Value required",
        /**
         * When a value is not one of the enumerated values
         */
        error_enum: "Value must be one of the enumerated values",
        /**
         * When a value doesn't validate any schema of a 'anyOf' combination
         */
        error_anyOf: "Value must validate against at least one of the provided schemas",
        /**
         * When a value doesn't validate
         * @variables This key takes one variable: The number of schemas the value does not validate
         */
        error_oneOf: 'Value must validate against exactly one of the provided schemas. It currently validates against {{0}} of the schemas.',
        /**
         * When a value does not validate a 'not' schema
         */
        error_not: "Value must not validate against the provided schema",
        /**
         * When a value does not match any of the provided types
         */
        error_type_union: "Value must be one of the provided types",
        /**
         * When a value does not match the given type
         * @variables This key takes one variable: The type the value should be of
         */
        error_type: "Value must be of type {{0}}",
        /**
         *  When the value validates one of the disallowed types
         */
        error_disallow_union: "Value must not be one of the provided disallowed types",
        /**
         *  When the value validates a disallowed type
         * @variables This key takes one variable: The type the value should not be of
         */
        error_disallow: "Value must not be of type {{0}}",
        /**
         * When a value is not a multiple of or divisible by a given number
         * @variables This key takes one variable: The number mentioned above
         */
        error_multipleOf: "Value must be a multiple of {{0}}",
        /**
         * When a value is greater than it's supposed to be (exclusive)
         * @variables This key takes one variable: The maximum
         */
        error_maximum_excl: "Value must be less than {{0}}",
        /**
         * When a value is greater than it's supposed to be (inclusive
         * @variables This key takes one variable: The maximum
         */
        error_maximum_incl: "Value must be at most {{0}}",
        /**
         * When a value is lesser than it's supposed to be (exclusive)
         * @variables This key takes one variable: The minimum
         */
        error_minimum_excl: "Value must be greater than {{0}}",
        /**
         * When a value is lesser than it's supposed to be (inclusive)
         * @variables This key takes one variable: The minimum
         */
        error_minimum_incl: "Value must be at least {{0}}",
        /**
         * When a value have too many characters
         * @variables This key takes one variable: The maximum character count
         */
        error_maxLength: "Value must be at most {{0}} characters long",
        /**
         * When a value does not have enough characters
         * @variables This key takes one variable: The minimum character count
         */
        error_minLength: "Value must be at least {{0}} characters long",
        /**
         * When a value does not match a given pattern
         */
        error_pattern: "Value must match the provided pattern",
        /**
         * When an array has additional items whereas it is not supposed to
         */
        error_additionalItems: "No additional items allowed in this array",
        /**
         * When there are to many items in an array
         * @variables This key takes one variable: The maximum item count
         */
        error_maxItems: "Value must have at most {{0}} items",
        /**
         * When there are not enough items in an array
         * @variables This key takes one variable: The minimum item count
         */
        error_minItems: "Value must have at least {{0}} items",
        /**
         * When an array is supposed to have unique items but has duplicates
         */
        error_uniqueItems: "Array must have unique items",
        /**
         * When there are too many properties in an object
         * @variables This key takes one variable: The maximum property count
         */
        error_maxProperties: "Object must have at most {{0}} properties",
        /**
         * When there are not enough properties in an object
         * @variables This key takes one variable: The minimum property count
         */
        error_minProperties: "Object must have at least {{0}} properties",
        /**
         * When a required property is not defined
         * @variables This key takes one variable: The name of the missing property
         */
        error_required: "Object is missing the required property '{{0}}'",
        /**
         * When there is an additional property is set whereas there should be none
         * @variables This key takes one variable: The name of the additional property
         */
        error_additional_properties: "No additional properties allowed, but property {{0}} is set",
        /**
         * When a dependency is not resolved
         * @variables This key takes one variable: The name of the missing property for the dependency
         */
        error_dependency: "Must have property {{0}}"
    };

    // Miscellaneous Plugin Settings
    JSONEditor.plugins = {
        ace: {
            theme: ''
        },
        epiceditor: {

        },
        sceditor: {

        },
        select2: {

        },
        selectize: {}
    };

    // Default per-editor options
    for (var i in JSONEditor.defaults.editors) {
        if (!JSONEditor.defaults.editors.hasOwnProperty(i)) continue;
        JSONEditor.defaults.editors[i].options = JSONEditor.defaults.editors.options || {};
    }

    // Set the default resolvers
    // Use "multiple" as a fall back for everything
    JSONEditor.defaults.resolvers.unshift(function(schema) {
        if (typeof schema.type !== "string") return "multiple";
    });
    // If the type is not set but properties are defined, we can infer the type is actually object
    JSONEditor.defaults.resolvers.unshift(function(schema) {
        // If the schema is a simple type
        if (!schema.type && schema.properties) return "object";
    });
    // If the type is set and it's a basic type, use the primitive editor
    JSONEditor.defaults.resolvers.unshift(function(schema) {
        // If the schema is a simple type
        if (typeof schema.type === "string") return schema.type;
    });
    // Boolean editors
    JSONEditor.defaults.resolvers.unshift(function(schema) {
        if (schema.type === 'boolean') {
            // If explicitly set to 'checkbox', use that
            if (schema.format === "checkbox" || (schema.options && schema.options.checkbox)) {
                return "checkbox";
            }
            // Otherwise, default to select menu
            return (JSONEditor.plugins.selectize.enable) ? 'selectize' : 'select';
        }
    });
    // Use the multiple editor for schemas where the `type` is set to "any"
    JSONEditor.defaults.resolvers.unshift(function(schema) {
        // If the schema can be of any type
        if (schema.type === "any") return "multiple";
    });
    // Editor for base64 encoded files
    JSONEditor.defaults.resolvers.unshift(function(schema) {
        // If the schema can be of any type
        if (schema.type === "string" && schema.media && schema.media.binaryEncoding === "base64") {
            return "base64";
        }
    });
    // Editor for uploading files
    JSONEditor.defaults.resolvers.unshift(function(schema) {
        if (schema.type === "string" && schema.format === "url" && schema.options && schema.options.upload === true) {
            if (window.FileReader) return "upload";
        }
    });
    // Use the table editor for arrays with the format set to `table`
    JSONEditor.defaults.resolvers.unshift(function(schema) {
        // Type `array` with format set to `table`
        if (schema.type == "array" && schema.format == "table") {
            return "table";
        }
    });
    // Use the `select` editor for dynamic enumSource enums
    JSONEditor.defaults.resolvers.unshift(function(schema) {
        if (schema.enumSource) return (JSONEditor.plugins.selectize.enable) ? 'selectize' : 'select';
    });
    // Use the `enum` or `select` editors for schemas with enumerated properties
    JSONEditor.defaults.resolvers.unshift(function(schema) {
        if (schema["enum"]) {
            if (schema.type === "array" || schema.type === "object") {
                return "enum";
            } else if (schema.type === "number" || schema.type === "integer" || schema.type === "string") {
                return (JSONEditor.plugins.selectize.enable) ? 'selectize' : 'select';
            }
        }
    });
    // Specialized editors for arrays of strings
    JSONEditor.defaults.resolvers.unshift(function(schema) {
        if (schema.type === "array" && schema.items && !(Array.isArray(schema.items)) && schema.uniqueItems && ['string', 'number', 'integer'].indexOf(schema.items.type) >= 0) {
            // For enumerated strings, number, or integers
            if (schema.items.enum) {
                return 'multiselect';
            }
            // For non-enumerated strings (tag editor)
            else if (JSONEditor.plugins.selectize.enable && schema.items.type === "string") {
                return 'arraySelectize';
            }
        }
    });
    // Use the multiple editor for schemas with `oneOf` set
    JSONEditor.defaults.resolvers.unshift(function(schema) {
        // If this schema uses `oneOf`
        if (schema.oneOf) return "multiple";
    });

    /**
     * This is a small wrapper for using JSON Editor like a typical jQuery plugin.
     */
    (function() {
        if (window.jQuery || window.Zepto) {
            var $ = window.jQuery || window.Zepto;
            $.jsoneditor = JSONEditor.defaults;

            $.fn.jsoneditor = function(options) {
                var self = this;
                var editor = this.data('jsoneditor');
                if (options === 'value') {
                    if (!editor) throw "Must initialize jsoneditor before getting/setting the value";

                    // Set value
                    if (arguments.length > 1) {
                        editor.setValue(arguments[1]);
                    }
                    // Get value
                    else {
                        return editor.getValue();
                    }
                } else if (options === 'validate') {
                    if (!editor) throw "Must initialize jsoneditor before validating";

                    // Validate a specific value
                    if (arguments.length > 1) {
                        return editor.validate(arguments[1]);
                    }
                    // Validate current value
                    else {
                        return editor.validate();
                    }
                } else if (options === 'destroy') {
                    if (editor) {
                        editor.destroy();
                        this.data('jsoneditor', null);
                    }
                } else {
                    // Destroy first
                    if (editor) {
                        editor.destroy();
                    }

                    // Create editor
                    editor = new JSONEditor(this.get(0), options);
                    this.data('jsoneditor', editor);

                    // Setup event listeners
                    editor.on('change', function() {
                        self.trigger('change');
                    });
                    editor.on('ready', function() {
                        self.trigger('ready');
                    });
                }

                return this;
            };
        }
    })();

    window.JSONEditor = JSONEditor;
})();

//# sourceMappingURL=jsoneditor.js.map
