#import <Foundation/Foundation.h>
@interface TestInvocationRecorder: NSObject
{
	NSInvocation *invocationOne;
	NSInvocation *invocationTwo;
}
@end

@implementation TestInvocationRecorder
- (id) init
{
	if (nil == (self = [super init]))
	{
		return nil;
	}
	invocationOne = nil;
	invocationTwo = nil;
	return self;
}

- (void) dealloc
{
	[invocationOne release];
	[invocationTwo release];
	[super dealloc];
}

- (id)_playback
{
	NSString *stringOne = [[[NSString alloc] initWithString: @"foo"] autorelease];
	NSString *stringTwo = [[[NSString alloc] initWithString: @"bar"] autorelease];
	[invocationOne invokeWithTarget: stringOne];
	[invocationTwo invokeWithTarget: stringTwo];
	[invocationOne invokeWithTarget: stringOne];
	return self;
}

- (NSMethodSignature *) methodSignatureForSelector: (SEL) aSelector
{
	NSString *aString = [[[NSString alloc] init] autorelease];
	if ([aString respondsToSelector: aSelector])
	{
		return [aString methodSignatureForSelector: aSelector];
	}
	else if ([NSStringFromSelector(aSelector) isEqual: @"playback"])
	{
		//retain has the same type signature.
		return [super methodSignatureForSelector: @selector(retain)];
	}
	return [super methodSignatureForSelector: aSelector];
}

- (void) forwardInvocation: (NSInvocation *)anInvocation
{
	[anInvocation retainArguments];
	NSString *selector = NSStringFromSelector([anInvocation selector]);
	if ((nil == invocationOne)
		&& [selector isEqual: @"uppercaseString"])
	{
		invocationOne = [anInvocation retain];
	}
	else if ((nil == invocationTwo)
			 && [selector isEqual: @"isEqualToString:"])
	{
		invocationTwo = [anInvocation retain];
	}
	else if ([selector isEqual: @"playback"])
	{
		[self _playback];
	}
	
	if ([selector isEqual: @"isEqualToString:"])
	{
		BOOL isYes = YES;
		[anInvocation setReturnValue: &isYes];
	}
	else
	{
		[anInvocation setReturnValue: &self];
	}
}
@end
int main (void)
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	TestInvocationRecorder *rec = [[TestInvocationRecorder alloc] init];
	[[rec uppercaseString] isEqualToString: @"bar"];
	//Goes to -forwardInvocation: and crashes:
	[rec playback];
	//[rec _playback] would work.
	[rec release];
	[pool release];
	return 0;
}
