//! 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 Dictionary    ***************
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsdictionary?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(PartialEq, Eq, Hash)]
    pub struct NSDictionary<KeyType: ?Sized = AnyObject, ObjectType: ?Sized = AnyObject>;
);

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

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

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

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

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

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

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

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

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

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

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

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

        #[unsafe(method(objectForKey:))]
        #[unsafe(method_family = none)]
        pub fn objectForKey(&self, a_key: &KeyType) -> Option<Retained<ObjectType>>;

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

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

        #[cfg(feature = "NSObject")]
        /// # Safety
        ///
        /// - `objects` must be a valid pointer or null.
        /// - `keys` must be a valid pointer or null.
        #[unsafe(method(initWithObjects:forKeys:count:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithObjects_forKeys_count(
            this: Allocated<Self>,
            objects: *mut NonNull<ObjectType>,
            keys: *mut NonNull<ProtocolObject<dyn NSCopying>>,
            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<KeyType: Message, ObjectType: Message> NSDictionary<KeyType, ObjectType> {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

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

/// NSExtendedDictionary.
impl<KeyType: Message, ObjectType: Message> NSDictionary<KeyType, ObjectType> {
    extern_methods!(
        #[cfg(feature = "NSArray")]
        #[unsafe(method(allKeys))]
        #[unsafe(method_family = none)]
        pub fn allKeys(&self) -> Retained<NSArray<KeyType>>;

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

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

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

        #[cfg(feature = "NSString")]
        #[unsafe(method(descriptionInStringsFileFormat))]
        #[unsafe(method_family = none)]
        pub fn descriptionInStringsFileFormat(&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(isEqualToDictionary:))]
        #[unsafe(method_family = none)]
        pub fn isEqualToDictionary(
            &self,
            other_dictionary: &NSDictionary<KeyType, ObjectType>,
        ) -> bool;

        #[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 = "NSArray")]
        #[unsafe(method(objectsForKeys:notFoundMarker:))]
        #[unsafe(method_family = none)]
        pub fn objectsForKeys_notFoundMarker(
            &self,
            keys: &NSArray<KeyType>,
            marker: &ObjectType,
        ) -> 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>>;

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

        /// # Safety
        ///
        /// - `objects` must be a valid pointer or null.
        /// - `keys` must be a valid pointer or null.
        #[unsafe(method(getObjects:andKeys:count:))]
        #[unsafe(method_family = none)]
        pub unsafe fn getObjects_andKeys_count(
            &self,
            objects: *mut NonNull<ObjectType>,
            keys: *mut NonNull<KeyType>,
            count: NSUInteger,
        );

        #[unsafe(method(objectForKeyedSubscript:))]
        #[unsafe(method_family = none)]
        pub fn objectForKeyedSubscript(&self, key: &KeyType) -> Option<Retained<ObjectType>>;

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

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

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

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

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

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

/// NSDeprecated.
impl<KeyType: Message, ObjectType: Message> NSDictionary<KeyType, ObjectType> {
    extern_methods!(
        /// This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:andKeys:count:
        ///
        /// # Safety
        ///
        /// - `objects` must be a valid pointer or null.
        /// - `keys` must be a valid pointer or null.
        #[deprecated = "Use -getObjects:andKeys:count: instead"]
        #[unsafe(method(getObjects:andKeys:))]
        #[unsafe(method_family = none)]
        pub unsafe fn getObjects_andKeys(
            &self,
            objects: *mut NonNull<ObjectType>,
            keys: *mut NonNull<KeyType>,
        );

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

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

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

        #[cfg(feature = "NSURL")]
        #[deprecated]
        #[unsafe(method(initWithContentsOfURL:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithContentsOfURL(
            this: Allocated<Self>,
            url: &NSURL,
        ) -> Option<Retained<NSDictionary<KeyType, 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;
    );
}

/// NSDictionaryCreation.
impl<KeyType: Message, ObjectType: Message> NSDictionary<KeyType, ObjectType> {
    extern_methods!(
        #[unsafe(method(dictionary))]
        #[unsafe(method_family = none)]
        pub fn dictionary() -> Retained<Self>;

        #[cfg(feature = "NSObject")]
        /// # Safety
        ///
        /// `key` should be of the correct type.
        #[unsafe(method(dictionaryWithObject:forKey:))]
        #[unsafe(method_family = none)]
        pub unsafe fn dictionaryWithObject_forKey(
            object: &ObjectType,
            key: &ProtocolObject<dyn NSCopying>,
        ) -> Retained<Self>;

        #[cfg(feature = "NSObject")]
        /// # Safety
        ///
        /// - `objects` must be a valid pointer or null.
        /// - `keys` must be a valid pointer or null.
        #[unsafe(method(dictionaryWithObjects:forKeys:count:))]
        #[unsafe(method_family = none)]
        pub unsafe fn dictionaryWithObjects_forKeys_count(
            objects: *mut NonNull<ObjectType>,
            keys: *mut NonNull<ProtocolObject<dyn NSCopying>>,
            cnt: NSUInteger,
        ) -> Retained<Self>;

        #[unsafe(method(dictionaryWithDictionary:))]
        #[unsafe(method_family = none)]
        pub fn dictionaryWithDictionary(dict: &NSDictionary<KeyType, ObjectType>)
            -> Retained<Self>;

        #[cfg(all(feature = "NSArray", feature = "NSObject"))]
        /// # Safety
        ///
        /// `keys` generic should be of the correct type.
        #[unsafe(method(dictionaryWithObjects:forKeys:))]
        #[unsafe(method_family = none)]
        pub unsafe fn dictionaryWithObjects_forKeys(
            objects: &NSArray<ObjectType>,
            keys: &NSArray<ProtocolObject<dyn NSCopying>>,
        ) -> Retained<Self>;

        #[unsafe(method(initWithDictionary:))]
        #[unsafe(method_family = init)]
        pub fn initWithDictionary(
            this: Allocated<Self>,
            other_dictionary: &NSDictionary<KeyType, ObjectType>,
        ) -> Retained<Self>;

        #[unsafe(method(initWithDictionary:copyItems:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithDictionary_copyItems(
            this: Allocated<Self>,
            other_dictionary: &NSDictionary<KeyType, ObjectType>,
            flag: bool,
        ) -> Retained<Self>;

        #[cfg(all(feature = "NSArray", feature = "NSObject"))]
        /// # Safety
        ///
        /// `keys` generic should be of the correct type.
        #[unsafe(method(initWithObjects:forKeys:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithObjects_forKeys(
            this: Allocated<Self>,
            objects: &NSArray<ObjectType>,
            keys: &NSArray<ProtocolObject<dyn NSCopying>>,
        ) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSDictionary`.
///
/// NSDictionaryCreation.
impl<KeyType: Message, ObjectType: Message> NSMutableDictionary<KeyType, ObjectType> {
    extern_methods!(
        #[unsafe(method(dictionary))]
        #[unsafe(method_family = none)]
        pub fn dictionary() -> Retained<Self>;

        #[cfg(feature = "NSObject")]
        /// # Safety
        ///
        /// `key` should be of the correct type.
        #[unsafe(method(dictionaryWithObject:forKey:))]
        #[unsafe(method_family = none)]
        pub unsafe fn dictionaryWithObject_forKey(
            object: &ObjectType,
            key: &ProtocolObject<dyn NSCopying>,
        ) -> Retained<Self>;

        #[cfg(feature = "NSObject")]
        /// # Safety
        ///
        /// - `objects` must be a valid pointer or null.
        /// - `keys` must be a valid pointer or null.
        #[unsafe(method(dictionaryWithObjects:forKeys:count:))]
        #[unsafe(method_family = none)]
        pub unsafe fn dictionaryWithObjects_forKeys_count(
            objects: *mut NonNull<ObjectType>,
            keys: *mut NonNull<ProtocolObject<dyn NSCopying>>,
            cnt: NSUInteger,
        ) -> Retained<Self>;

        #[unsafe(method(dictionaryWithDictionary:))]
        #[unsafe(method_family = none)]
        pub fn dictionaryWithDictionary(dict: &NSDictionary<KeyType, ObjectType>)
            -> Retained<Self>;

        #[cfg(all(feature = "NSArray", feature = "NSObject"))]
        /// # Safety
        ///
        /// `keys` generic should be of the correct type.
        #[unsafe(method(dictionaryWithObjects:forKeys:))]
        #[unsafe(method_family = none)]
        pub unsafe fn dictionaryWithObjects_forKeys(
            objects: &NSArray<ObjectType>,
            keys: &NSArray<ProtocolObject<dyn NSCopying>>,
        ) -> Retained<Self>;

        #[unsafe(method(initWithDictionary:))]
        #[unsafe(method_family = init)]
        pub fn initWithDictionary(
            this: Allocated<Self>,
            other_dictionary: &NSDictionary<KeyType, ObjectType>,
        ) -> Retained<Self>;

        #[unsafe(method(initWithDictionary:copyItems:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithDictionary_copyItems(
            this: Allocated<Self>,
            other_dictionary: &NSDictionary<KeyType, ObjectType>,
            flag: bool,
        ) -> Retained<Self>;

        #[cfg(all(feature = "NSArray", feature = "NSObject"))]
        /// # Safety
        ///
        /// `keys` generic should be of the correct type.
        #[unsafe(method(initWithObjects:forKeys:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithObjects_forKeys(
            this: Allocated<Self>,
            objects: &NSArray<ObjectType>,
            keys: &NSArray<ProtocolObject<dyn NSCopying>>,
        ) -> Retained<Self>;
    );
}

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

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

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

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

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

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

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

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

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

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

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

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

impl<KeyType: Message, ObjectType: Message> NSMutableDictionary<KeyType, ObjectType> {
    extern_methods!(
        #[unsafe(method(removeObjectForKey:))]
        #[unsafe(method_family = none)]
        pub fn removeObjectForKey(&self, a_key: &KeyType);

        #[cfg(feature = "NSObject")]
        /// # Safety
        ///
        /// `a_key` should be of the correct type.
        #[unsafe(method(setObject:forKey:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setObject_forKey(
            &self,
            an_object: &ObjectType,
            a_key: &ProtocolObject<dyn NSCopying>,
        );

        #[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 `NSDictionary`.
impl<KeyType: Message, ObjectType: Message> NSMutableDictionary<KeyType, ObjectType> {
    extern_methods!(
        #[cfg(feature = "NSObject")]
        /// # Safety
        ///
        /// - `objects` must be a valid pointer or null.
        /// - `keys` must be a valid pointer or null.
        #[unsafe(method(initWithObjects:forKeys:count:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithObjects_forKeys_count(
            this: Allocated<Self>,
            objects: *mut NonNull<ObjectType>,
            keys: *mut NonNull<ProtocolObject<dyn NSCopying>>,
            cnt: NSUInteger,
        ) -> Retained<Self>;
    );
}

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

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

/// NSExtendedMutableDictionary.
impl<KeyType: Message, ObjectType: Message> NSMutableDictionary<KeyType, ObjectType> {
    extern_methods!(
        #[unsafe(method(addEntriesFromDictionary:))]
        #[unsafe(method_family = none)]
        pub fn addEntriesFromDictionary(
            &self,
            other_dictionary: &NSDictionary<KeyType, ObjectType>,
        );

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

        #[cfg(feature = "NSArray")]
        #[unsafe(method(removeObjectsForKeys:))]
        #[unsafe(method_family = none)]
        pub fn removeObjectsForKeys(&self, key_array: &NSArray<KeyType>);

        #[unsafe(method(setDictionary:))]
        #[unsafe(method_family = none)]
        pub fn setDictionary(&self, other_dictionary: &NSDictionary<KeyType, ObjectType>);

        #[cfg(feature = "NSObject")]
        /// # Safety
        ///
        /// `key` should be of the correct type.
        #[unsafe(method(setObject:forKeyedSubscript:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setObject_forKeyedSubscript(
            &self,
            obj: Option<&ObjectType>,
            key: &ProtocolObject<dyn NSCopying>,
        );
    );
}

/// NSMutableDictionaryCreation.
impl<KeyType: Message, ObjectType: Message> NSMutableDictionary<KeyType, ObjectType> {
    extern_methods!(
        #[unsafe(method(dictionaryWithCapacity:))]
        #[unsafe(method_family = none)]
        pub fn dictionaryWithCapacity(num_items: NSUInteger) -> Retained<Self>;

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

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

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

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

/// NSSharedKeySetDictionary.
impl<KeyType: Message, ObjectType: Message> NSDictionary<KeyType, ObjectType> {
    extern_methods!(
        #[cfg(all(feature = "NSArray", feature = "NSObject"))]
        /// # Safety
        ///
        /// `keys` generic should be of the correct type.
        #[unsafe(method(sharedKeySetForKeys:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sharedKeySetForKeys(
            keys: &NSArray<ProtocolObject<dyn NSCopying>>,
        ) -> Retained<AnyObject>;
    );
}

/// NSSharedKeySetDictionary.
impl<KeyType: Message, ObjectType: Message> NSMutableDictionary<KeyType, ObjectType> {
    extern_methods!(
        /// # Safety
        ///
        /// `keyset` should be of the correct type.
        #[unsafe(method(dictionaryWithSharedKeySet:))]
        #[unsafe(method_family = none)]
        pub unsafe fn dictionaryWithSharedKeySet(
            keyset: &AnyObject,
        ) -> Retained<NSMutableDictionary<KeyType, ObjectType>>;
    );
}
