#import <Foundation/Foundation.h>

@interface A : NSObject
@end

@implementation A

- (void)release
{
  NSLog(@"Releasing A %p (count before %lu)", self, [self retainCount]);

#if GS_WITH_GC
    NSLog(@"Wait, it thinks it's GCing?");
#endif
#if defined(GSATOMICREAD)
    NSLog(@"Atomic reads");
#endif

    [super release];
}

- (void)dealloc
{
  NSLog(@"Dealloc A %p", self);
  [super dealloc];
}

- (id)retain
{
  NSLog(@"Retaining A %p (count before %lu)", self, [self retainCount]);
  return [super retain];
}

+ (id)allocWithZone:(NSZone *)z
{
  id a = [super allocWithZone:z];
  NSLog(@"Allocing A %p", a);
  return a;
}

@end

@interface B : NSObject
- (void)test:(id)obj;
@end

@implementation B

- (void)test:(id)obj
{
  A *a = [[A alloc] init];
  [a release];
}

@end

int main (int argc, char **argv)
{
  NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
  
  NSLog(@"Testing outside thread");
  B *b = [[[B alloc] init] autorelease];
  [b test:nil];

  NSLog(@"");
  NSLog(@"Testing inside thread");
  NSThread *t = [[NSThread alloc] initWithTarget:[[[B alloc] init] autorelease] selector:@selector(test:) object:nil];
  [t start];
  while (![t isFinished])
  {
  }
  [t release];

  NSLog(@"");
  NSLog(@"Testing outside thread again");
  [b test:nil];

  [p release];

  return 1;
}
