//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
#[cfg(feature = "objc2-core-foundation")]
use objc2_core_foundation::*;

use crate::*;

extern_class!(
    /// **************    Immutable Array        ***************
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsarray?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(PartialEq, Eq, Hash)]
    pub struct NSArray<ObjectType: ?Sized = AnyObject>;
);

#[cfg(feature = "objc2-core-foundation")]
impl<ObjectType: ?Sized + Message> AsRef<NSArray<ObjectType>> for CFArray<ObjectType> {
    #[inline]
    fn as_ref(&self) -> &NSArray<ObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

#[cfg(feature = "objc2-core-foundation")]
impl<ObjectType: ?Sized + Message> AsRef<CFArray<ObjectType>> for NSArray<ObjectType> {
    #[inline]
    fn as_ref(&self) -> &CFArray<ObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

impl<ObjectType: ?Sized + Message> NSArray<ObjectType> {
    /// Unchecked conversion of the generic parameter.
    ///
    /// # Safety
    ///
    /// The generic must be valid to reinterpret as the given type.
    #[inline]
    pub unsafe fn cast_unchecked<NewObjectType: ?Sized + Message>(
        &self,
    ) -> &NSArray<NewObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized + NSCoding> NSCoding for NSArray<ObjectType> {}
);

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSCopying for NSArray<ObjectType> {}
);

#[cfg(feature = "NSObject")]
unsafe impl<ObjectType: ?Sized + Message> CopyingHelper for NSArray<ObjectType> {
    type Result = Self;
}

#[cfg(feature = "NSEnumerator")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSFastEnumeration for NSArray<ObjectType> {}
);

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSMutableCopying for NSArray<ObjectType> {}
);

#[cfg(feature = "NSObject")]
unsafe impl<ObjectType: ?Sized + Message> MutableCopyingHelper for NSArray<ObjectType> {
    type Result = NSMutableArray<ObjectType>;
}

extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSObjectProtocol for NSArray<ObjectType> {}
);

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized + NSSecureCoding> NSSecureCoding for NSArray<ObjectType> {}
);

impl<ObjectType: Message> NSArray<ObjectType> {
    extern_methods!(
        #[unsafe(method(count))]
        #[unsafe(method_family = none)]
        pub fn count(&self) -> NSUInteger;

        #[unsafe(method(objectAtIndex:))]
        #[unsafe(method_family = none)]
        pub fn objectAtIndex(&self, index: NSUInteger) -> Retained<ObjectType>;

        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        /// # Safety
        ///
        /// `objects` must be a valid pointer or null.
        #[unsafe(method(initWithObjects:count:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithObjects_count(
            this: Allocated<Self>,
            objects: *mut NonNull<ObjectType>,
            cnt: NSUInteger,
        ) -> Retained<Self>;

        #[cfg(feature = "NSCoder")]
        /// # Safety
        ///
        /// `coder` possibly has further requirements.
        #[unsafe(method(initWithCoder:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithCoder(
            this: Allocated<Self>,
            coder: &NSCoder,
        ) -> Option<Retained<Self>>;
    );
}

/// Methods declared on superclass `NSObject`.
impl<ObjectType: Message> NSArray<ObjectType> {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

impl<ObjectType: Message> DefaultRetained for NSArray<ObjectType> {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsbinarysearchingoptions?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSBinarySearchingOptions(pub NSUInteger);
bitflags::bitflags! {
    impl NSBinarySearchingOptions: NSUInteger {
        #[doc(alias = "NSBinarySearchingFirstEqual")]
        const FirstEqual = 1<<8;
        #[doc(alias = "NSBinarySearchingLastEqual")]
        const LastEqual = 1<<9;
        #[doc(alias = "NSBinarySearchingInsertionIndex")]
        const InsertionIndex = 1<<10;
    }
}

unsafe impl Encode for NSBinarySearchingOptions {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for NSBinarySearchingOptions {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// NSExtendedArray.
impl<ObjectType: Message> NSArray<ObjectType> {
    extern_methods!(
        #[unsafe(method(arrayByAddingObject:))]
        #[unsafe(method_family = none)]
        pub fn arrayByAddingObject(&self, an_object: &ObjectType) -> Retained<NSArray<ObjectType>>;

        #[unsafe(method(arrayByAddingObjectsFromArray:))]
        #[unsafe(method_family = none)]
        pub fn arrayByAddingObjectsFromArray(
            &self,
            other_array: &NSArray<ObjectType>,
        ) -> Retained<NSArray<ObjectType>>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(componentsJoinedByString:))]
        #[unsafe(method_family = none)]
        pub fn componentsJoinedByString(&self, separator: &NSString) -> Retained<NSString>;

        #[unsafe(method(containsObject:))]
        #[unsafe(method_family = none)]
        pub fn containsObject(&self, an_object: &ObjectType) -> bool;

        #[cfg(feature = "NSString")]
        #[unsafe(method(description))]
        #[unsafe(method_family = none)]
        pub fn description(&self) -> Retained<NSString>;

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// `locale` should be of the correct type.
        #[unsafe(method(descriptionWithLocale:))]
        #[unsafe(method_family = none)]
        pub unsafe fn descriptionWithLocale(
            &self,
            locale: Option<&AnyObject>,
        ) -> Retained<NSString>;

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// `locale` should be of the correct type.
        #[unsafe(method(descriptionWithLocale:indent:))]
        #[unsafe(method_family = none)]
        pub unsafe fn descriptionWithLocale_indent(
            &self,
            locale: Option<&AnyObject>,
            level: NSUInteger,
        ) -> Retained<NSString>;

        #[unsafe(method(firstObjectCommonWithArray:))]
        #[unsafe(method_family = none)]
        pub fn firstObjectCommonWithArray(
            &self,
            other_array: &NSArray<ObjectType>,
        ) -> Option<Retained<ObjectType>>;

        #[cfg(feature = "NSRange")]
        /// # Safety
        ///
        /// `objects` must be a valid pointer.
        #[unsafe(method(getObjects:range:))]
        #[unsafe(method_family = none)]
        pub unsafe fn getObjects_range(
            &self,
            objects: NonNull<NonNull<ObjectType>>,
            range: NSRange,
        );

        #[unsafe(method(indexOfObject:))]
        #[unsafe(method_family = none)]
        pub fn indexOfObject(&self, an_object: &ObjectType) -> NSUInteger;

        #[cfg(feature = "NSRange")]
        #[unsafe(method(indexOfObject:inRange:))]
        #[unsafe(method_family = none)]
        pub fn indexOfObject_inRange(&self, an_object: &ObjectType, range: NSRange) -> NSUInteger;

        #[unsafe(method(indexOfObjectIdenticalTo:))]
        #[unsafe(method_family = none)]
        pub fn indexOfObjectIdenticalTo(&self, an_object: &ObjectType) -> NSUInteger;

        #[cfg(feature = "NSRange")]
        #[unsafe(method(indexOfObjectIdenticalTo:inRange:))]
        #[unsafe(method_family = none)]
        pub fn indexOfObjectIdenticalTo_inRange(
            &self,
            an_object: &ObjectType,
            range: NSRange,
        ) -> NSUInteger;

        #[unsafe(method(isEqualToArray:))]
        #[unsafe(method_family = none)]
        pub fn isEqualToArray(&self, other_array: &NSArray<ObjectType>) -> bool;

        #[unsafe(method(firstObject))]
        #[unsafe(method_family = none)]
        pub fn firstObject(&self) -> Option<Retained<ObjectType>>;

        #[unsafe(method(lastObject))]
        #[unsafe(method_family = none)]
        pub fn lastObject(&self) -> Option<Retained<ObjectType>>;

        #[cfg(feature = "NSEnumerator")]
        /// # Safety
        ///
        /// The returned enumerator's underlying collection should not be mutated while in use.
        #[unsafe(method(objectEnumerator))]
        #[unsafe(method_family = none)]
        pub unsafe fn objectEnumerator(&self) -> Retained<NSEnumerator<ObjectType>>;

        #[cfg(feature = "NSEnumerator")]
        /// # Safety
        ///
        /// The returned enumerator's underlying collection should not be mutated while in use.
        #[unsafe(method(reverseObjectEnumerator))]
        #[unsafe(method_family = none)]
        pub unsafe fn reverseObjectEnumerator(&self) -> Retained<NSEnumerator<ObjectType>>;

        #[cfg(feature = "NSData")]
        #[unsafe(method(sortedArrayHint))]
        #[unsafe(method_family = none)]
        pub fn sortedArrayHint(&self) -> Retained<NSData>;

        /// # Safety
        ///
        /// - `comparator` must be implemented correctly.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(sortedArrayUsingFunction:context:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sortedArrayUsingFunction_context(
            &self,
            comparator: unsafe extern "C-unwind" fn(
                NonNull<ObjectType>,
                NonNull<ObjectType>,
                *mut c_void,
            ) -> NSInteger,
            context: *mut c_void,
        ) -> Retained<NSArray<ObjectType>>;

        #[cfg(feature = "NSData")]
        /// # Safety
        ///
        /// - `comparator` must be implemented correctly.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(sortedArrayUsingFunction:context:hint:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sortedArrayUsingFunction_context_hint(
            &self,
            comparator: unsafe extern "C-unwind" fn(
                NonNull<ObjectType>,
                NonNull<ObjectType>,
                *mut c_void,
            ) -> NSInteger,
            context: *mut c_void,
            hint: Option<&NSData>,
        ) -> Retained<NSArray<ObjectType>>;

        /// # Safety
        ///
        /// `comparator` must be a valid selector.
        #[unsafe(method(sortedArrayUsingSelector:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sortedArrayUsingSelector(
            &self,
            comparator: Sel,
        ) -> Retained<NSArray<ObjectType>>;

        #[cfg(feature = "NSRange")]
        #[unsafe(method(subarrayWithRange:))]
        #[unsafe(method_family = none)]
        pub fn subarrayWithRange(&self, range: NSRange) -> Retained<NSArray<ObjectType>>;

        #[cfg(all(feature = "NSError", feature = "NSURL"))]
        #[unsafe(method(writeToURL:error:_))]
        #[unsafe(method_family = none)]
        pub unsafe fn writeToURL_error(&self, url: &NSURL) -> Result<(), Retained<NSError>>;

        /// # Safety
        ///
        /// `a_selector` must be a valid selector.
        #[unsafe(method(makeObjectsPerformSelector:))]
        #[unsafe(method_family = none)]
        pub unsafe fn makeObjectsPerformSelector(&self, a_selector: Sel);

        /// # Safety
        ///
        /// - `a_selector` must be a valid selector.
        /// - `argument` should be of the correct type.
        #[unsafe(method(makeObjectsPerformSelector:withObject:))]
        #[unsafe(method_family = none)]
        pub unsafe fn makeObjectsPerformSelector_withObject(
            &self,
            a_selector: Sel,
            argument: Option<&AnyObject>,
        );

        #[cfg(feature = "NSIndexSet")]
        #[unsafe(method(objectsAtIndexes:))]
        #[unsafe(method_family = none)]
        pub fn objectsAtIndexes(&self, indexes: &NSIndexSet) -> Retained<NSArray<ObjectType>>;

        #[unsafe(method(objectAtIndexedSubscript:))]
        #[unsafe(method_family = none)]
        pub fn objectAtIndexedSubscript(&self, idx: NSUInteger) -> Retained<ObjectType>;

        #[cfg(feature = "block2")]
        #[unsafe(method(enumerateObjectsUsingBlock:))]
        #[unsafe(method_family = none)]
        pub fn enumerateObjectsUsingBlock(
            &self,
            block: &block2::DynBlock<dyn Fn(NonNull<ObjectType>, NSUInteger, NonNull<Bool>) + '_>,
        );

        #[cfg(all(feature = "NSObjCRuntime", feature = "block2"))]
        #[unsafe(method(enumerateObjectsWithOptions:usingBlock:))]
        #[unsafe(method_family = none)]
        pub fn enumerateObjectsWithOptions_usingBlock(
            &self,
            opts: NSEnumerationOptions,
            block: &block2::DynBlock<dyn Fn(NonNull<ObjectType>, NSUInteger, NonNull<Bool>) + '_>,
        );

        #[cfg(all(feature = "NSIndexSet", feature = "NSObjCRuntime", feature = "block2"))]
        #[unsafe(method(enumerateObjectsAtIndexes:options:usingBlock:))]
        #[unsafe(method_family = none)]
        pub fn enumerateObjectsAtIndexes_options_usingBlock(
            &self,
            s: &NSIndexSet,
            opts: NSEnumerationOptions,
            block: &block2::DynBlock<dyn Fn(NonNull<ObjectType>, NSUInteger, NonNull<Bool>) + '_>,
        );

        #[cfg(feature = "block2")]
        #[unsafe(method(indexOfObjectPassingTest:))]
        #[unsafe(method_family = none)]
        pub fn indexOfObjectPassingTest(
            &self,
            predicate: &block2::DynBlock<
                dyn Fn(NonNull<ObjectType>, NSUInteger, NonNull<Bool>) -> Bool + '_,
            >,
        ) -> NSUInteger;

        #[cfg(all(feature = "NSObjCRuntime", feature = "block2"))]
        #[unsafe(method(indexOfObjectWithOptions:passingTest:))]
        #[unsafe(method_family = none)]
        pub fn indexOfObjectWithOptions_passingTest(
            &self,
            opts: NSEnumerationOptions,
            predicate: &block2::DynBlock<
                dyn Fn(NonNull<ObjectType>, NSUInteger, NonNull<Bool>) -> Bool + '_,
            >,
        ) -> NSUInteger;

        #[cfg(all(feature = "NSIndexSet", feature = "NSObjCRuntime", feature = "block2"))]
        #[unsafe(method(indexOfObjectAtIndexes:options:passingTest:))]
        #[unsafe(method_family = none)]
        pub fn indexOfObjectAtIndexes_options_passingTest(
            &self,
            s: &NSIndexSet,
            opts: NSEnumerationOptions,
            predicate: &block2::DynBlock<
                dyn Fn(NonNull<ObjectType>, NSUInteger, NonNull<Bool>) -> Bool + '_,
            >,
        ) -> NSUInteger;

        #[cfg(all(feature = "NSIndexSet", feature = "block2"))]
        #[unsafe(method(indexesOfObjectsPassingTest:))]
        #[unsafe(method_family = none)]
        pub fn indexesOfObjectsPassingTest(
            &self,
            predicate: &block2::DynBlock<
                dyn Fn(NonNull<ObjectType>, NSUInteger, NonNull<Bool>) -> Bool + '_,
            >,
        ) -> Retained<NSIndexSet>;

        #[cfg(all(feature = "NSIndexSet", feature = "NSObjCRuntime", feature = "block2"))]
        #[unsafe(method(indexesOfObjectsWithOptions:passingTest:))]
        #[unsafe(method_family = none)]
        pub fn indexesOfObjectsWithOptions_passingTest(
            &self,
            opts: NSEnumerationOptions,
            predicate: &block2::DynBlock<
                dyn Fn(NonNull<ObjectType>, NSUInteger, NonNull<Bool>) -> Bool + '_,
            >,
        ) -> Retained<NSIndexSet>;

        #[cfg(all(feature = "NSIndexSet", feature = "NSObjCRuntime", feature = "block2"))]
        #[unsafe(method(indexesOfObjectsAtIndexes:options:passingTest:))]
        #[unsafe(method_family = none)]
        pub fn indexesOfObjectsAtIndexes_options_passingTest(
            &self,
            s: &NSIndexSet,
            opts: NSEnumerationOptions,
            predicate: &block2::DynBlock<
                dyn Fn(NonNull<ObjectType>, NSUInteger, NonNull<Bool>) -> Bool + '_,
            >,
        ) -> Retained<NSIndexSet>;

        #[cfg(all(feature = "NSObjCRuntime", feature = "block2"))]
        /// # Safety
        ///
        /// `cmptr` must be a valid pointer.
        #[unsafe(method(sortedArrayUsingComparator:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sortedArrayUsingComparator(
            &self,
            cmptr: NSComparator,
        ) -> Retained<NSArray<ObjectType>>;

        #[cfg(all(feature = "NSObjCRuntime", feature = "block2"))]
        /// # Safety
        ///
        /// `cmptr` must be a valid pointer.
        #[unsafe(method(sortedArrayWithOptions:usingComparator:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sortedArrayWithOptions_usingComparator(
            &self,
            opts: NSSortOptions,
            cmptr: NSComparator,
        ) -> Retained<NSArray<ObjectType>>;

        #[cfg(all(feature = "NSObjCRuntime", feature = "NSRange", feature = "block2"))]
        /// # Safety
        ///
        /// `cmp` must be a valid pointer.
        #[unsafe(method(indexOfObject:inSortedRange:options:usingComparator:))]
        #[unsafe(method_family = none)]
        pub unsafe fn indexOfObject_inSortedRange_options_usingComparator(
            &self,
            obj: &ObjectType,
            r: NSRange,
            opts: NSBinarySearchingOptions,
            cmp: NSComparator,
        ) -> NSUInteger;
    );
}

/// NSArrayCreation.
impl<ObjectType: Message> NSArray<ObjectType> {
    extern_methods!(
        #[unsafe(method(array))]
        #[unsafe(method_family = none)]
        pub fn array() -> Retained<Self>;

        #[unsafe(method(arrayWithObject:))]
        #[unsafe(method_family = none)]
        pub fn arrayWithObject(an_object: &ObjectType) -> Retained<Self>;

        /// # Safety
        ///
        /// `objects` must be a valid pointer.
        #[unsafe(method(arrayWithObjects:count:))]
        #[unsafe(method_family = none)]
        pub unsafe fn arrayWithObjects_count(
            objects: NonNull<NonNull<ObjectType>>,
            cnt: NSUInteger,
        ) -> Retained<Self>;

        #[unsafe(method(arrayWithArray:))]
        #[unsafe(method_family = none)]
        pub fn arrayWithArray(array: &NSArray<ObjectType>) -> Retained<Self>;

        #[unsafe(method(initWithArray:))]
        #[unsafe(method_family = init)]
        pub fn initWithArray(this: Allocated<Self>, array: &NSArray<ObjectType>) -> Retained<Self>;

        #[unsafe(method(initWithArray:copyItems:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithArray_copyItems(
            this: Allocated<Self>,
            array: &NSArray<ObjectType>,
            flag: bool,
        ) -> Retained<Self>;

        #[cfg(all(feature = "NSError", feature = "NSURL"))]
        #[unsafe(method(initWithContentsOfURL:error:_))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithContentsOfURL_error(
            this: Allocated<Self>,
            url: &NSURL,
        ) -> Result<Retained<NSArray<ObjectType>>, Retained<NSError>>;

        #[cfg(all(feature = "NSError", feature = "NSURL"))]
        #[unsafe(method(arrayWithContentsOfURL:error:_))]
        #[unsafe(method_family = none)]
        pub unsafe fn arrayWithContentsOfURL_error(
            url: &NSURL,
        ) -> Result<Retained<NSArray<ObjectType>>, Retained<NSError>>;
    );
}

/// Methods declared on superclass `NSArray`.
///
/// NSArrayCreation.
impl<ObjectType: Message> NSMutableArray<ObjectType> {
    extern_methods!(
        #[unsafe(method(array))]
        #[unsafe(method_family = none)]
        pub fn array() -> Retained<Self>;

        #[unsafe(method(arrayWithObject:))]
        #[unsafe(method_family = none)]
        pub fn arrayWithObject(an_object: &ObjectType) -> Retained<Self>;

        /// # Safety
        ///
        /// `objects` must be a valid pointer.
        #[unsafe(method(arrayWithObjects:count:))]
        #[unsafe(method_family = none)]
        pub unsafe fn arrayWithObjects_count(
            objects: NonNull<NonNull<ObjectType>>,
            cnt: NSUInteger,
        ) -> Retained<Self>;

        #[unsafe(method(arrayWithArray:))]
        #[unsafe(method_family = none)]
        pub fn arrayWithArray(array: &NSArray<ObjectType>) -> Retained<Self>;

        #[unsafe(method(initWithArray:))]
        #[unsafe(method_family = init)]
        pub fn initWithArray(this: Allocated<Self>, array: &NSArray<ObjectType>) -> Retained<Self>;

        #[unsafe(method(initWithArray:copyItems:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithArray_copyItems(
            this: Allocated<Self>,
            array: &NSArray<ObjectType>,
            flag: bool,
        ) -> Retained<Self>;
    );
}

/// NSArrayDiffing.
impl<ObjectType: Message> NSArray<ObjectType> {
    extern_methods!(
        #[cfg(all(feature = "NSOrderedCollectionDifference", feature = "block2"))]
        #[unsafe(method(differenceFromArray:withOptions:usingEquivalenceTest:))]
        #[unsafe(method_family = none)]
        pub fn differenceFromArray_withOptions_usingEquivalenceTest(
            &self,
            other: &NSArray<ObjectType>,
            options: NSOrderedCollectionDifferenceCalculationOptions,
            block: &block2::DynBlock<dyn Fn(NonNull<ObjectType>, NonNull<ObjectType>) -> Bool + '_>,
        ) -> Retained<NSOrderedCollectionDifference<ObjectType>>;

        #[cfg(feature = "NSOrderedCollectionDifference")]
        #[unsafe(method(differenceFromArray:withOptions:))]
        #[unsafe(method_family = none)]
        pub fn differenceFromArray_withOptions(
            &self,
            other: &NSArray<ObjectType>,
            options: NSOrderedCollectionDifferenceCalculationOptions,
        ) -> Retained<NSOrderedCollectionDifference<ObjectType>>;

        #[cfg(feature = "NSOrderedCollectionDifference")]
        #[unsafe(method(differenceFromArray:))]
        #[unsafe(method_family = none)]
        pub fn differenceFromArray(
            &self,
            other: &NSArray<ObjectType>,
        ) -> Retained<NSOrderedCollectionDifference<ObjectType>>;

        #[cfg(feature = "NSOrderedCollectionDifference")]
        #[unsafe(method(arrayByApplyingDifference:))]
        #[unsafe(method_family = none)]
        pub fn arrayByApplyingDifference(
            &self,
            difference: &NSOrderedCollectionDifference<ObjectType>,
        ) -> Option<Retained<NSArray<ObjectType>>>;
    );
}

/// NSDeprecated.
impl<ObjectType: Message> NSArray<ObjectType> {
    extern_methods!(
        /// # Safety
        ///
        /// `objects` must be a valid pointer.
        #[deprecated = "Use -getObjects:range: instead"]
        #[unsafe(method(getObjects:))]
        #[unsafe(method_family = none)]
        pub unsafe fn getObjects(&self, objects: NonNull<NonNull<ObjectType>>);

        #[cfg(feature = "NSString")]
        #[deprecated]
        #[unsafe(method(arrayWithContentsOfFile:))]
        #[unsafe(method_family = none)]
        pub unsafe fn arrayWithContentsOfFile(
            path: &NSString,
        ) -> Option<Retained<NSArray<ObjectType>>>;

        #[cfg(feature = "NSURL")]
        #[deprecated]
        #[unsafe(method(arrayWithContentsOfURL:))]
        #[unsafe(method_family = none)]
        pub unsafe fn arrayWithContentsOfURL(url: &NSURL) -> Option<Retained<NSArray<ObjectType>>>;

        #[cfg(feature = "NSString")]
        #[deprecated]
        #[unsafe(method(initWithContentsOfFile:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithContentsOfFile(
            this: Allocated<Self>,
            path: &NSString,
        ) -> Option<Retained<NSArray<ObjectType>>>;

        #[cfg(feature = "NSURL")]
        #[deprecated]
        #[unsafe(method(initWithContentsOfURL:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithContentsOfURL(
            this: Allocated<Self>,
            url: &NSURL,
        ) -> Option<Retained<NSArray<ObjectType>>>;

        #[cfg(feature = "NSString")]
        #[deprecated]
        #[unsafe(method(writeToFile:atomically:))]
        #[unsafe(method_family = none)]
        pub unsafe fn writeToFile_atomically(
            &self,
            path: &NSString,
            use_auxiliary_file: bool,
        ) -> bool;

        #[cfg(feature = "NSURL")]
        #[deprecated]
        #[unsafe(method(writeToURL:atomically:))]
        #[unsafe(method_family = none)]
        pub unsafe fn writeToURL_atomically(&self, url: &NSURL, atomically: bool) -> bool;
    );
}

extern_class!(
    /// **************    Mutable Array        ***************
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsmutablearray?language=objc)
    #[unsafe(super(NSArray<ObjectType>, NSObject))]
    #[derive(PartialEq, Eq, Hash)]
    pub struct NSMutableArray<ObjectType: ?Sized = AnyObject>;
);

#[cfg(feature = "objc2-core-foundation")]
impl<ObjectType: ?Sized + Message> AsRef<NSMutableArray<ObjectType>>
    for CFMutableArray<ObjectType>
{
    #[inline]
    fn as_ref(&self) -> &NSMutableArray<ObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

#[cfg(feature = "objc2-core-foundation")]
impl<ObjectType: ?Sized + Message> AsRef<CFMutableArray<ObjectType>>
    for NSMutableArray<ObjectType>
{
    #[inline]
    fn as_ref(&self) -> &CFMutableArray<ObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

impl<ObjectType: ?Sized + Message> NSMutableArray<ObjectType> {
    /// Unchecked conversion of the generic parameter.
    ///
    /// # Safety
    ///
    /// The generic must be valid to reinterpret as the given type.
    #[inline]
    pub unsafe fn cast_unchecked<NewObjectType: ?Sized + Message>(
        &self,
    ) -> &NSMutableArray<NewObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized + NSCoding> NSCoding for NSMutableArray<ObjectType> {}
);

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSCopying for NSMutableArray<ObjectType> {}
);

#[cfg(feature = "NSObject")]
unsafe impl<ObjectType: ?Sized + Message> CopyingHelper for NSMutableArray<ObjectType> {
    type Result = NSArray<ObjectType>;
}

#[cfg(feature = "NSEnumerator")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSFastEnumeration for NSMutableArray<ObjectType> {}
);

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSMutableCopying for NSMutableArray<ObjectType> {}
);

#[cfg(feature = "NSObject")]
unsafe impl<ObjectType: ?Sized + Message> MutableCopyingHelper for NSMutableArray<ObjectType> {
    type Result = Self;
}

extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSObjectProtocol for NSMutableArray<ObjectType> {}
);

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized + NSSecureCoding> NSSecureCoding for NSMutableArray<ObjectType> {}
);

impl<ObjectType: Message> NSMutableArray<ObjectType> {
    extern_methods!(
        #[unsafe(method(addObject:))]
        #[unsafe(method_family = none)]
        pub fn addObject(&self, an_object: &ObjectType);

        #[unsafe(method(insertObject:atIndex:))]
        #[unsafe(method_family = none)]
        pub fn insertObject_atIndex(&self, an_object: &ObjectType, index: NSUInteger);

        #[unsafe(method(removeLastObject))]
        #[unsafe(method_family = none)]
        pub fn removeLastObject(&self);

        #[unsafe(method(removeObjectAtIndex:))]
        #[unsafe(method_family = none)]
        pub fn removeObjectAtIndex(&self, index: NSUInteger);

        #[unsafe(method(replaceObjectAtIndex:withObject:))]
        #[unsafe(method_family = none)]
        pub fn replaceObjectAtIndex_withObject(&self, index: NSUInteger, an_object: &ObjectType);

        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(initWithCapacity:))]
        #[unsafe(method_family = init)]
        pub fn initWithCapacity(this: Allocated<Self>, num_items: NSUInteger) -> Retained<Self>;

        #[cfg(feature = "NSCoder")]
        /// # Safety
        ///
        /// `coder` possibly has further requirements.
        #[unsafe(method(initWithCoder:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithCoder(
            this: Allocated<Self>,
            coder: &NSCoder,
        ) -> Option<Retained<Self>>;
    );
}

/// Methods declared on superclass `NSArray`.
impl<ObjectType: Message> NSMutableArray<ObjectType> {
    extern_methods!(
        /// # Safety
        ///
        /// `objects` must be a valid pointer or null.
        #[unsafe(method(initWithObjects:count:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithObjects_count(
            this: Allocated<Self>,
            objects: *mut NonNull<ObjectType>,
            cnt: NSUInteger,
        ) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSObject`.
impl<ObjectType: Message> NSMutableArray<ObjectType> {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

impl<ObjectType: Message> DefaultRetained for NSMutableArray<ObjectType> {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

/// NSExtendedMutableArray.
impl<ObjectType: Message> NSMutableArray<ObjectType> {
    extern_methods!(
        #[unsafe(method(addObjectsFromArray:))]
        #[unsafe(method_family = none)]
        pub fn addObjectsFromArray(&self, other_array: &NSArray<ObjectType>);

        #[unsafe(method(exchangeObjectAtIndex:withObjectAtIndex:))]
        #[unsafe(method_family = none)]
        pub fn exchangeObjectAtIndex_withObjectAtIndex(&self, idx1: NSUInteger, idx2: NSUInteger);

        #[unsafe(method(removeAllObjects))]
        #[unsafe(method_family = none)]
        pub fn removeAllObjects(&self);

        #[cfg(feature = "NSRange")]
        #[unsafe(method(removeObject:inRange:))]
        #[unsafe(method_family = none)]
        pub fn removeObject_inRange(&self, an_object: &ObjectType, range: NSRange);

        #[unsafe(method(removeObject:))]
        #[unsafe(method_family = none)]
        pub fn removeObject(&self, an_object: &ObjectType);

        #[cfg(feature = "NSRange")]
        #[unsafe(method(removeObjectIdenticalTo:inRange:))]
        #[unsafe(method_family = none)]
        pub fn removeObjectIdenticalTo_inRange(&self, an_object: &ObjectType, range: NSRange);

        #[unsafe(method(removeObjectIdenticalTo:))]
        #[unsafe(method_family = none)]
        pub fn removeObjectIdenticalTo(&self, an_object: &ObjectType);

        /// # Safety
        ///
        /// `indices` must be a valid pointer.
        #[deprecated = "Not supported"]
        #[unsafe(method(removeObjectsFromIndices:numIndices:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removeObjectsFromIndices_numIndices(
            &self,
            indices: NonNull<NSUInteger>,
            cnt: NSUInteger,
        );

        #[unsafe(method(removeObjectsInArray:))]
        #[unsafe(method_family = none)]
        pub fn removeObjectsInArray(&self, other_array: &NSArray<ObjectType>);

        #[cfg(feature = "NSRange")]
        #[unsafe(method(removeObjectsInRange:))]
        #[unsafe(method_family = none)]
        pub fn removeObjectsInRange(&self, range: NSRange);

        #[cfg(feature = "NSRange")]
        #[unsafe(method(replaceObjectsInRange:withObjectsFromArray:range:))]
        #[unsafe(method_family = none)]
        pub fn replaceObjectsInRange_withObjectsFromArray_range(
            &self,
            range: NSRange,
            other_array: &NSArray<ObjectType>,
            other_range: NSRange,
        );

        #[cfg(feature = "NSRange")]
        #[unsafe(method(replaceObjectsInRange:withObjectsFromArray:))]
        #[unsafe(method_family = none)]
        pub fn replaceObjectsInRange_withObjectsFromArray(
            &self,
            range: NSRange,
            other_array: &NSArray<ObjectType>,
        );

        #[unsafe(method(setArray:))]
        #[unsafe(method_family = none)]
        pub fn setArray(&self, other_array: &NSArray<ObjectType>);

        /// # Safety
        ///
        /// - `compare` must be implemented correctly.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(sortUsingFunction:context:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sortUsingFunction_context(
            &self,
            compare: unsafe extern "C-unwind" fn(
                NonNull<ObjectType>,
                NonNull<ObjectType>,
                *mut c_void,
            ) -> NSInteger,
            context: *mut c_void,
        );

        /// # Safety
        ///
        /// `comparator` must be a valid selector.
        #[unsafe(method(sortUsingSelector:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sortUsingSelector(&self, comparator: Sel);

        #[cfg(feature = "NSIndexSet")]
        #[unsafe(method(insertObjects:atIndexes:))]
        #[unsafe(method_family = none)]
        pub fn insertObjects_atIndexes(&self, objects: &NSArray<ObjectType>, indexes: &NSIndexSet);

        #[cfg(feature = "NSIndexSet")]
        #[unsafe(method(removeObjectsAtIndexes:))]
        #[unsafe(method_family = none)]
        pub fn removeObjectsAtIndexes(&self, indexes: &NSIndexSet);

        #[cfg(feature = "NSIndexSet")]
        #[unsafe(method(replaceObjectsAtIndexes:withObjects:))]
        #[unsafe(method_family = none)]
        pub fn replaceObjectsAtIndexes_withObjects(
            &self,
            indexes: &NSIndexSet,
            objects: &NSArray<ObjectType>,
        );

        #[unsafe(method(setObject:atIndexedSubscript:))]
        #[unsafe(method_family = none)]
        pub fn setObject_atIndexedSubscript(&self, obj: &ObjectType, idx: NSUInteger);

        #[cfg(all(feature = "NSObjCRuntime", feature = "block2"))]
        /// # Safety
        ///
        /// `cmptr` must be a valid pointer.
        #[unsafe(method(sortUsingComparator:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sortUsingComparator(&self, cmptr: NSComparator);

        #[cfg(all(feature = "NSObjCRuntime", feature = "block2"))]
        /// # Safety
        ///
        /// `cmptr` must be a valid pointer.
        #[unsafe(method(sortWithOptions:usingComparator:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sortWithOptions_usingComparator(
            &self,
            opts: NSSortOptions,
            cmptr: NSComparator,
        );
    );
}

/// NSMutableArrayCreation.
impl<ObjectType: Message> NSMutableArray<ObjectType> {
    extern_methods!(
        #[unsafe(method(arrayWithCapacity:))]
        #[unsafe(method_family = none)]
        pub fn arrayWithCapacity(num_items: NSUInteger) -> Retained<Self>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(arrayWithContentsOfFile:))]
        #[unsafe(method_family = none)]
        pub unsafe fn arrayWithContentsOfFile(
            path: &NSString,
        ) -> Option<Retained<NSMutableArray<ObjectType>>>;

        #[cfg(feature = "NSURL")]
        #[unsafe(method(arrayWithContentsOfURL:))]
        #[unsafe(method_family = none)]
        pub unsafe fn arrayWithContentsOfURL(
            url: &NSURL,
        ) -> Option<Retained<NSMutableArray<ObjectType>>>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(initWithContentsOfFile:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithContentsOfFile(
            this: Allocated<Self>,
            path: &NSString,
        ) -> Option<Retained<NSMutableArray<ObjectType>>>;

        #[cfg(feature = "NSURL")]
        #[unsafe(method(initWithContentsOfURL:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithContentsOfURL(
            this: Allocated<Self>,
            url: &NSURL,
        ) -> Option<Retained<NSMutableArray<ObjectType>>>;
    );
}

/// NSMutableArrayDiffing.
impl<ObjectType: Message> NSMutableArray<ObjectType> {
    extern_methods!(
        #[cfg(feature = "NSOrderedCollectionDifference")]
        #[unsafe(method(applyDifference:))]
        #[unsafe(method_family = none)]
        pub fn applyDifference(&self, difference: &NSOrderedCollectionDifference<ObjectType>);
    );
}
