//! 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::*;

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 = "NSObject")]
unsafe impl<ObjectType: ?Sized + NSCoding> NSCoding for NSArray<ObjectType> {}

#[cfg(feature = "NSObject")]
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")]
unsafe impl<ObjectType: ?Sized> NSFastEnumeration for NSArray<ObjectType> {}

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

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

unsafe impl<ObjectType: ?Sized> NSObjectProtocol for NSArray<ObjectType> {}

#[cfg(feature = "NSObject")]
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>;

        #[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")]
        #[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 unsafe fn arrayByAddingObject(
            &self,
            an_object: &ObjectType,
        ) -> Retained<NSArray<ObjectType>>;

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

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

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

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

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

        #[cfg(feature = "NSString")]
        #[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 unsafe fn firstObjectCommonWithArray(
            &self,
            other_array: &NSArray<ObjectType>,
        ) -> Option<Retained<ObjectType>>;

        #[cfg(feature = "NSRange")]
        #[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 unsafe fn indexOfObject(&self, an_object: &ObjectType) -> NSUInteger;

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

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

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

        #[unsafe(method(isEqualToArray:))]
        #[unsafe(method_family = none)]
        pub unsafe 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")]
        #[unsafe(method(objectEnumerator))]
        #[unsafe(method_family = none)]
        pub unsafe fn objectEnumerator(&self) -> Retained<NSEnumerator<ObjectType>>;

        #[cfg(feature = "NSEnumerator")]
        #[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 unsafe fn sortedArrayHint(&self) -> Retained<NSData>;

        #[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")]
        #[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>>;

        #[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 unsafe 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>>;

        #[unsafe(method(makeObjectsPerformSelector:))]
        #[unsafe(method_family = none)]
        pub unsafe fn makeObjectsPerformSelector(&self, a_selector: Sel);

        #[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 unsafe fn objectsAtIndexes(
            &self,
            indexes: &NSIndexSet,
        ) -> Retained<NSArray<ObjectType>>;

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

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

        #[cfg(all(feature = "NSObjCRuntime", feature = "block2"))]
        #[unsafe(method(enumerateObjectsWithOptions:usingBlock:))]
        #[unsafe(method_family = none)]
        pub unsafe fn enumerateObjectsWithOptions_usingBlock(
            &self,
            opts: NSEnumerationOptions,
            block: &block2::Block<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 unsafe fn enumerateObjectsAtIndexes_options_usingBlock(
            &self,
            s: &NSIndexSet,
            opts: NSEnumerationOptions,
            block: &block2::Block<dyn Fn(NonNull<ObjectType>, NSUInteger, NonNull<Bool>) + '_>,
        );

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

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

        #[cfg(all(feature = "NSIndexSet", feature = "block2"))]
        #[unsafe(method(indexesOfObjectsPassingTest:))]
        #[unsafe(method_family = none)]
        pub unsafe fn indexesOfObjectsPassingTest(
            &self,
            predicate: &block2::Block<
                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 unsafe fn indexesOfObjectsWithOptions_passingTest(
            &self,
            opts: NSEnumerationOptions,
            predicate: &block2::Block<
                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 unsafe fn indexesOfObjectsAtIndexes_options_passingTest(
            &self,
            s: &NSIndexSet,
            opts: NSEnumerationOptions,
            predicate: &block2::Block<
                dyn Fn(NonNull<ObjectType>, NSUInteger, NonNull<Bool>) -> Bool + '_,
            >,
        ) -> Retained<NSIndexSet>;

        #[cfg(all(feature = "NSObjCRuntime", feature = "block2"))]
        #[unsafe(method(sortedArrayUsingComparator:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sortedArrayUsingComparator(
            &self,
            cmptr: NSComparator,
        ) -> Retained<NSArray<ObjectType>>;

        #[cfg(all(feature = "NSObjCRuntime", feature = "block2"))]
        #[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"))]
        #[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 unsafe fn array() -> Retained<Self>;

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

        #[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 unsafe fn arrayWithArray(array: &NSArray<ObjectType>) -> Retained<Self>;

        #[unsafe(method(initWithArray:))]
        #[unsafe(method_family = init)]
        pub unsafe 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 unsafe fn array() -> Retained<Self>;

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

        #[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 unsafe fn arrayWithArray(array: &NSArray<ObjectType>) -> Retained<Self>;

        #[unsafe(method(initWithArray:))]
        #[unsafe(method_family = init)]
        pub unsafe 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 unsafe fn differenceFromArray_withOptions_usingEquivalenceTest(
            &self,
            other: &NSArray<ObjectType>,
            options: NSOrderedCollectionDifferenceCalculationOptions,
            block: &block2::Block<dyn Fn(NonNull<ObjectType>, NonNull<ObjectType>) -> Bool + '_>,
        ) -> Retained<NSOrderedCollectionDifference<ObjectType>>;

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

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

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

/// NSDeprecated.
impl<ObjectType: Message> NSArray<ObjectType> {
    extern_methods!(
        #[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 = "NSObject")]
unsafe impl<ObjectType: ?Sized + NSCoding> NSCoding for NSMutableArray<ObjectType> {}

#[cfg(feature = "NSObject")]
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")]
unsafe impl<ObjectType: ?Sized> NSFastEnumeration for NSMutableArray<ObjectType> {}

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

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

unsafe impl<ObjectType: ?Sized> NSObjectProtocol for NSMutableArray<ObjectType> {}

#[cfg(feature = "NSObject")]
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")]
        #[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!(
        #[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 unsafe fn addObjectsFromArray(&self, other_array: &NSArray<ObjectType>);

        #[unsafe(method(exchangeObjectAtIndex:withObjectAtIndex:))]
        #[unsafe(method_family = none)]
        pub unsafe 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 unsafe 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 unsafe fn removeObjectIdenticalTo_inRange(
            &self,
            an_object: &ObjectType,
            range: NSRange,
        );

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

        #[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 unsafe fn removeObjectsInArray(&self, other_array: &NSArray<ObjectType>);

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

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

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

        #[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,
        );

        #[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 unsafe fn insertObjects_atIndexes(
            &self,
            objects: &NSArray<ObjectType>,
            indexes: &NSIndexSet,
        );

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

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

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

        #[cfg(all(feature = "NSObjCRuntime", feature = "block2"))]
        #[unsafe(method(sortUsingComparator:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sortUsingComparator(&self, cmptr: NSComparator);

        #[cfg(all(feature = "NSObjCRuntime", feature = "block2"))]
        #[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 unsafe 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 unsafe fn applyDifference(
            &self,
            difference: &NSOrderedCollectionDifference<ObjectType>,
        );
    );
}
