define([

"../core",
"../core/access",
"./support"

], function( jQuery, access, support ) {

var rfocusable = /^(?:input|select|textarea|button)$/i;

jQuery.fn.extend({

prop: function( name, value ) {
        return access( this, jQuery.prop, name, value, arguments.length > 1 );
},

removeProp: function( name ) {
        return this.each(function() {
                delete this[ jQuery.propFix[ name ] || name ];
        });
}

});

jQuery.extend({

propFix: {
        "for": "htmlFor",
        "class": "className"
},

prop: function( elem, name, value ) {
        var ret, hooks, notxml,
                nType = elem.nodeType;

        // Don't get/set properties on text, comment and attribute nodes
        if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
                return;
        }

        notxml = nType !== 1 || !jQuery.isXMLDoc( elem );

        if ( notxml ) {
                // Fix name and attach hooks
                name = jQuery.propFix[ name ] || name;
                hooks = jQuery.propHooks[ name ];
        }

        if ( value !== undefined ) {
                return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
                        ret :
                        ( elem[ name ] = value );

        } else {
                return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
                        ret :
                        elem[ name ];
        }
},

propHooks: {
        tabIndex: {
                get: function( elem ) {
                        return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
                                elem.tabIndex :
                                -1;
                }
        }
}

});

if ( !support.optSelected ) {

jQuery.propHooks.selected = {
        get: function( elem ) {
                var parent = elem.parentNode;
                if ( parent && parent.parentNode ) {
                        parent.parentNode.selectedIndex;
                }
                return null;
        }
};

}

jQuery.each([

"tabIndex",
"readOnly",
"maxLength",
"cellSpacing",
"cellPadding",
"rowSpan",
"colSpan",
"useMap",
"frameBorder",
"contentEditable"

], function() {

jQuery.propFix[ this.toLowerCase() ] = this;

});

});