text: // TEST_CFLAGS -framework Foundation
  
  #import <Foundation/Foundation.h>
  #import <Foundation/NSDictionary.h>
  #import <objc/runtime.h>
  #import <objc/objc-abi.h>
  #include "test.h"
  
  @interface TestIndexed : NSObject <NSFastEnumeration> {
      NSMutableArray *indexedValues;
  }
  @property(readonly) NSUInteger count;
  - (id)objectAtIndexedSubscript:(NSUInteger)index;
  - (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index;
  @end
  
  @implementation TestIndexed
  
  - (id)init {
      if ((self = [super init])) {
          indexedValues = [NSMutableArray new];
      }
      return self;
  }
  
  #if !__has_feature(objc_arc)
  - (void)dealloc {
      [indexedValues release];
      [super dealloc];
  }
  #endif
  
  - (NSUInteger)count { return [indexedValues count]; }
  - (id)objectAtIndexedSubscript:(NSUInteger)index { return [indexedValues objectAtIndex:index]; }
  - (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index {
      if (index == NSNotFound)
          [indexedValues addObject:object];
      else
          [indexedValues replaceObjectAtIndex:index withObject:object];
  }
  
  - (NSString *)description {
      return [NSString stringWithFormat:@"indexedValues = %@", indexedValues];
  }
  
  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained [])buffer count:(NSUInteger)len {
      return [indexedValues countByEnumeratingWithState:state objects:buffer count:len];
  }
  
  
  @end
  
  @interface TestKeyed : NSObject <NSFastEnumeration> {
      NSMutableDictionary *keyedValues;
  }
  @property(readonly) NSUInteger count;
  - (id)objectForKeyedSubscript:(id)key;
  - (void)setObject:(id)object forKeyedSubscript:(id)key;
  @end
  
  @implementation TestKeyed
  
  - (id)init {
      if ((self = [super init])) {
          keyedValues = [NSMutableDictionary new];
      }
      return self;
  }
  
  #if !__has_feature(objc_arc)
  - (void)dealloc {
      [keyedValues release];
      [super dealloc];
  }
  #endif
  
  - (NSUInteger)count { return [keyedValues count]; }
  - (id)objectForKeyedSubscript:(id)key { return [keyedValues objectForKey:key]; }
  - (void)setObject:(id)object forKeyedSubscript:(id)key {
      [keyedValues setObject:object forKey:key];
  }
  
  - (NSString *)description {
      return [NSString stringWithFormat:@"keyedValues = %@", keyedValues];
  }
  
  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained [])buffer count:(NSUInteger)len {
      return [keyedValues countByEnumeratingWithState:state objects:buffer count:len];
  }
  
  @end
  
  int main() {
      PUSH_POOL {
  
  #if __has_feature(objc_bool)    // placeholder until we get a more precise macro.
          TestIndexed *testIndexed = [TestIndexed new];
          id objects[] = { @1, @2, @3, @4, @5 };
          size_t i, count = sizeof(objects) / sizeof(id);
          for (i = 0; i < count; ++i) {
              testIndexed[NSNotFound] = objects[i];
          }
          for (i = 0; i < count; ++i) {
              id object = testIndexed[i];
              testassert(object == objects[i]);
          }
          if (testverbose()) {
              i = 0;
              for (id object in testIndexed) {
                  NSString *message = [NSString stringWithFormat:@"testIndexed[%zu] = %@\n", i++, object];
                  testprintf([message UTF8String]);
              }
          }
  
          TestKeyed *testKeyed = [TestKeyed new];
          id keys[] = { @"One", @"Two", @"Three", @"Four", @"Five" };
          for (i = 0; i < count; ++i) {
              id key = keys[i];
              testKeyed[key] = objects[i];
          }
          for (i = 0; i < count; ++i) {
              id key = keys[i];
              id object = testKeyed[key];
              testassert(object == objects[i]);
          }
          if (testverbose()) {
              for (id key in testKeyed) {
                  NSString *message = [NSString stringWithFormat:@"testKeyed[@\"%@\"] = %@\n", key, testKeyed[key]];
                  testprintf([message UTF8String]);
              }
          }
  #endif
          
      } POP_POOL;
  
      succeed(__FILE__);
  
      return 0;
  }
  