
//  Donated by Henry Krempel <krempel@chezhank.com>

#import "NSDictionary+WriteCopy.h"
#import <Foundation/Foundation.h>

@implementation NSDictionary(WriteCopy)

- deepMutableCopyWithZone:(NSZone *)z;
{
	int count = [self count];
	NSMutableDictionary *out = [[NSMutableDictionary allocWithZone:z] initWithCapacity:count];

	if( count > 0 )
	{
		id keyEnumerator, objectEnumerator;
		id key, value;
		keyEnumerator = [self keyEnumerator];
		objectEnumerator = [self objectEnumerator];
		while ((key = [keyEnumerator nextObject]) && 
			(value = [objectEnumerator nextObject]))
		{
			id newValue = nil;
			if ([value isKindOfClass:[NSDictionary class]])
				newValue = [value deepMutableCopyWithZone:z];
			else if ([value respondsToSelector:@selector(deepMutableCopyWithZone:)])
				newValue = [value deepMutableCopyWithZone:z];
			else if ([value respondsToSelector:@selector(mutableCopyWithZone:)])
				newValue = [value mutableCopyWithZone:z];
			else
				newValue = value;
			[out setObject:newValue forKey:key];
            [newValue release];
		}
	}
	return out;
}
	
- deepMutableCopy;
{
	return [self deepMutableCopyWithZone:[self zone]];
}

@end

@implementation NSArray(WriteCopy)

- deepMutableCopyWithZone:(NSZone *)z;
{
	int count = [self count];
	NSMutableArray *out = [[NSMutableArray allocWithZone:z] initWithCapacity:count];

	if( count > 0 )
	{
		NSEnumerator *objectEnumerator;
		id value;
		objectEnumerator = [self objectEnumerator];
		while ((value = [objectEnumerator nextObject]))
		{
			id newValue = nil;
			if ([value isKindOfClass:[NSArray class]])
				newValue = [value deepMutableCopyWithZone:z];
			else if ([value respondsToSelector:@selector(deepMutableCopyWithZone:)])
				newValue = [value deepMutableCopyWithZone:z];
			else if ([value respondsToSelector:@selector(mutableCopyWithZone:)])
				newValue = [value mutableCopyWithZone:z];
			else
				newValue = value;
			[out addObject:newValue];
            [newValue release];
		}
	}
	return out;
}
	
- deepMutableCopy;
{
	return [self deepMutableCopyWithZone:[self zone]];
}

@end
