#import "NSObject-ObjcUnitAdditions.h"
#ifdef APPLE
#import <objc/objc-class.h>
#else
#import <objc/objc-api.h>
#endif

@interface NSObject (ObjcUnitAdditions_Privates)
+ (void)addInstanceMethodNamesForClass:(Class)aClass toArray:(NSMutableArray *)array;
#ifdef APPLE
+ (void)addInstanceMethodNamesForMethodList:(struct objc_method_list *)mlist toArray:(NSMutableArray *)array;
#endif
@end

@implementation NSObject (ObjcUnitAdditions)

+ (NSArray *)instanceMethodNames {
    NSMutableArray *instanceMethodNames = [NSMutableArray array];
    id each;
    NSEnumerator *enumerator;
    
    for (each = [self class]; each != nil; each = [each superclass]) {
        [self addInstanceMethodNamesForClass:each toArray:instanceMethodNames];
    }
    
    enumerator = [instanceMethodNames reverseObjectEnumerator];
    instanceMethodNames = [NSMutableArray array];
    while (each = [enumerator nextObject]) {
        [instanceMethodNames addObject:each];
    }
    return instanceMethodNames;
}

@end

@implementation NSObject (ObjcUnitAdditions_Privates)

+ (void)addInstanceMethodNamesForClass:(Class)aClass toArray:(NSMutableArray *)array {
    void *iterator = 0;
    struct objc_method_list *each;

#ifdef APPLE    
    while (each = class_nextMethodList(aClass, &iterator)) {
        [self addInstanceMethodNamesForMethodList:each toArray:array];
    }
#else
    each = aClass->methods;
    while (each != NULL)
    {
        int i;
        
        for (i = 0; i < each->method_count; i++)
        {
            NSString *name;
            
            name = NSStringFromSelector(each->method_list[i].method_name);
            if ([array containsObject:name] == NO)
            {
                [array addObject:name];
            }
        }
        each = each->method_next;
    }
#endif
}

#ifdef APPLE
+ (void)addInstanceMethodNamesForMethodList:(struct objc_method_list *)mlist toArray:(NSMutableArray *)array {
    int i;
    Method aMethod;
    NSString *methodName;

    for (i = 0; i < mlist->method_count; i++) {
        aMethod = &(mlist->method_list[i]);
        if (aMethod == NULL) continue;
        methodName = NSStringFromSelector(aMethod->method_name);
        if ([array containsObject:methodName]) continue;
        [array addObject:methodName];
    }
}
#endif

@end
