#import <Cocoa/Cocoa.h>
#import <CoreFoundation/CoreFoundation.h>

@interface TestObject : NSObject {} @end
@implementation TestObject
- copyWithZone: (NSZone *)zone
{
    NSLog(@"%s: %@", __func__, self);
    return [self retain];
}
@end

static const void *RetainAndLog(CFAllocatorRef allocator, const void *value)
{
    NSLog(@"%s: %@", __func__, value);
    return [(id)value retain];
}

static void ReleaseAndLog(CFAllocatorRef allocator, const void *value)
{
    NSLog(@"%s: %@", __func__, value);
    [(id)value release];
}

int main(void)
{
    CFDictionaryKeyCallBacks myCallBacks = kCFTypeDictionaryKeyCallBacks;
    myCallBacks.retain = RetainAndLog;
    myCallBacks.release = ReleaseAndLog;

    CFMutableDictionaryRef cfdict = CFDictionaryCreateMutable(NULL, 0, &myCallBacks, &kCFTypeDictionaryValueCallBacks);
    NSMutableDictionary *nsdict = (NSMutableDictionary *)cfdict;
    
    id value = [[TestObject alloc] init];
    id key = [[TestObject alloc] init];
    
    NSLog(@"Setting with CF, removing with NS");
    CFDictionarySetValue(cfdict, key, value);
    [nsdict removeObjectForKey:key];

    NSLog(@"Setting with NS, removing with CF");
    [nsdict setObject:value forKey:key];
    CFDictionaryRemoveValue(cfdict, key);

    return 0;
}
