    /*

    Siesta 5.3.0
    Copyright(c) 2009-2019 Bryntum AB
    https://bryntum.com/contact
    https://bryntum.com/products/siesta/license

    */
    Class('Siesta.Test.SimulatorExtJS', {

        isa : Siesta.Test.Simulator,

        has : {
            simulateEventsWith      : {
                is      : 'rw',
                lazy    : function () {
                    var isIE9           = navigator.userAgent.match(/MSIE 9.0;/)
                    var Ext             = this.global.Ext

                    // no Ext or Ext3, should use standard "dispatchEvent" method
                    if (!Ext || !Ext.getVersion) return 'dispatchEvent'

                    var extVersion      = Ext.getVersion('extjs')

                    // the "Ext.getVersion('extjs')" is just "true" in Ext3? (when testing SA)
                    var isBelowExt421   = Boolean((extVersion && extVersion.isLessThan && extVersion.isLessThan('4.2.1.883')))

                    var div             = document.createElement('div')

                    return div.attachEvent && (isIE9 || isBelowExt421) ? 'fireEvent' : 'dispatchEvent'
                }
            }
        },

        methods : {

            // Overridden to deal with the different event firing mechanisms in Ext JS 3 vs 4
            // This code is required because in IE events are simulated using fireEvent instead of dispatchEvent and it seems fireEvent will
            // will not update a checkbox 'checked' state properly so we're forcing the toggle to solve this situation.
            // This issue is only relevant in IE + Ext.
            //
            // Test case: 507_form_checkbox.t.js
            simulateMouseClick: function (clickInfo, options) {
                var me      = this
                var el      = clickInfo.el
                var Ext     = this.global.Ext

                var isExt5  = Ext && Ext.getVersion && Ext.getVersion('extjs') && Ext.getVersion('extjs').major == 5

                // Force check toggle for input checkboxes
                if (
                    (this.getSimulateEventsWith() === 'fireEvent' || isExt5)
                        &&
                    (el.type === 'checkbox' || el.type === 'radio') && !el.disabled && !el.readOnly
                ) {
                    var oldState = el.checked;

                    return this.SUPER(clickInfo, options).then(function () {
                        if (el.checked === oldState) {
                            el.checked = !oldState;

                            var optionsWithBubble       = Joose.O.copy(options)
                            optionsWithBubble.bubbles   = true

                            me.simulateEvent(el, 'change', optionsWithBubble)
                        }
                    });
                } else {
                    return this.SUPERARG(arguments);
                }
            }
        }
    })