text:
@interface CUCompactMutableArrayTests : XCTestCase

@end

@implementation CUCompactMutableArrayTests

#pragma mark -

- (void)setUp
{
    [super setUp];
}

- (void)tearDown
{
    [super tearDown];
}

#pragma mark - utility methods

- (NSMutableArray *)sampleArray
{
    NSArray *array = @[@"0",
                       @"1",
                       [NSNull null],
                       @"2",
                       [NSNull null],
                       @"3"];
    return array.mutableCopy;
}

#pragma mark - test cases

#pragma mark - initializers

- (void)testArray
{
    NSMutableArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
}

- (void)testNestedArray
{
    NSArray *array = @[@"0",
                       @"1",
                       [NSNull null],
                       @"2",
                       @[@"0",
                         [NSNull null],
                         @"1",
                         [NSNull null],
                         @"2"],
                       @"4"];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)5);
    XCTAssertEqual([compactArray[3] count], (NSUInteger)3);
}

#pragma mark - primitive instance methods

- (void)testCount
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
}

- (void)testObjectAtIndex
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqualObjects([compactArray objectAtIndex:0], @"0");
    XCTAssertEqualObjects([compactArray objectAtIndex:1], @"1");
    XCTAssertEqualObjects([compactArray objectAtIndex:2], @"2");
    XCTAssertEqualObjects([compactArray objectAtIndex:3], @"3");
}

#pragma mark -

- (void)testArrayByAddingObject
{
    NSArray *array = [self sampleArray];
    NSArray *compactArray = [[array cu_compactArray] mutableCopy];

    compactArray = [compactArray arrayByAddingObject:@"4"];
    compactArray = [compactArray arrayByAddingObject:[NSNull null]];
    compactArray = [compactArray arrayByAddingObject:nil];

    XCTAssertEqualObjects([compactArray objectAtIndex:0], @"0");
    XCTAssertEqualObjects([compactArray objectAtIndex:1], @"1");
    XCTAssertEqualObjects([compactArray objectAtIndex:2], @"2");
    XCTAssertEqualObjects([compactArray objectAtIndex:3], @"3");
    XCTAssertEqualObjects([compactArray objectAtIndex:4], @"4");

    NSArray *copyOfCompactArray = [compactArray copy];
    [compactArray arrayByAddingObject:@"5"];
    XCTAssertEqualObjects(copyOfCompactArray, compactArray, @"`-arrayByAddingObject:` should not modify receiver.");
}

- (void)testArrayByAddingObjectsFromArray
{
    NSArray *array = [self sampleArray];
    NSArray *compactArray = [[array cu_compactArray] mutableCopy];

    compactArray = [compactArray arrayByAddingObjectsFromArray:@[@"4", [NSNull null]]];

    XCTAssertEqualObjects([compactArray objectAtIndex:0], @"0");
    XCTAssertEqualObjects([compactArray objectAtIndex:1], @"1");
    XCTAssertEqualObjects([compactArray objectAtIndex:2], @"2");
    XCTAssertEqualObjects([compactArray objectAtIndex:3], @"3");
    XCTAssertEqualObjects([compactArray objectAtIndex:4], @"4");
}

- (void)testComponentsJoinedByString
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSString *string = [compactArray componentsJoinedByString:@", "];
    XCTAssertEqualObjects(string, @"0, 1, 2, 3");
}

- (void)testContainsObject
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertTrue([compactArray containsObject:@"0"]);
    XCTAssertTrue([compactArray containsObject:@"1"]);
    XCTAssertTrue([compactArray containsObject:@"2"]);
    XCTAssertTrue([compactArray containsObject:@"3"]);

    XCTAssertFalse([compactArray containsObject:@"4"]);
    XCTAssertFalse([compactArray containsObject:[NSNull null]]);
    XCTAssertFalse([compactArray containsObject:nil]);
}

- (void)testFirstObjectCommonWithArray
{
    NSArray *array = @[@"1", @"2", @"3", @"4", [NSNull null], @"5", @"6"];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqualObjects([compactArray firstObjectCommonWithArray:@[@"2"]], @"2");
    XCTAssertEqualObjects([compactArray firstObjectCommonWithArray:(@[@"3", @"5"])], @"3");
    XCTAssertEqualObjects([compactArray firstObjectCommonWithArray:(@[@"3", @"5", [NSNull null]])], @"3");
    XCTAssertNil([compactArray firstObjectCommonWithArray:@[@"7"]]);
    XCTAssertNil([compactArray firstObjectCommonWithArray:@[[NSNull null]]]);
    XCTAssertNil([compactArray firstObjectCommonWithArray:(@[@"7", [NSNull null]])]);
}

- (void)testGetObjects
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    id __unsafe_unretained objects[3];
    [compactArray getObjects:objects range:NSMakeRange(1, 3)];

    XCTAssertEqualObjects(objects[0], @"1");
    XCTAssertEqualObjects(objects[1], @"2");
    XCTAssertEqualObjects(objects[2], @"3");
}

- (void)testIndexOfObject
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual([compactArray indexOfObject:@"0"], (NSUInteger)0);
    XCTAssertEqual([compactArray indexOfObject:@"1"], (NSUInteger)1);
    XCTAssertEqual([compactArray indexOfObject:@"2"], (NSUInteger)2);
    XCTAssertEqual([compactArray indexOfObject:@"3"], (NSUInteger)3);
    XCTAssertEqual([compactArray indexOfObject:@"4"], (NSUInteger)NSNotFound);
    XCTAssertEqual([compactArray indexOfObject:[NSNull null]], (NSUInteger)NSNotFound);
    XCTAssertEqual([compactArray indexOfObject:nil], (NSUInteger)NSNotFound);

    XCTAssertEqual([compactArray indexOfObject:@"0" inRange:NSMakeRange(0, 3)], (NSUInteger)0);
    XCTAssertEqual([compactArray indexOfObject:@"1" inRange:NSMakeRange(0, 3)], (NSUInteger)1);
    XCTAssertEqual([compactArray indexOfObject:@"2" inRange:NSMakeRange(0, 3)], (NSUInteger)2);
    XCTAssertEqual([compactArray indexOfObject:@"3" inRange:NSMakeRange(0, 3)], (NSUInteger)NSNotFound);
}

- (void)testIndexOfObjectIdenticalTo
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual([compactArray indexOfObjectIdenticalTo:@"0"], (NSUInteger)0);
    XCTAssertEqual([compactArray indexOfObjectIdenticalTo:@"1"], (NSUInteger)1);
    XCTAssertEqual([compactArray indexOfObjectIdenticalTo:@"2"], (NSUInteger)2);
    XCTAssertEqual([compactArray indexOfObjectIdenticalTo:@"3"], (NSUInteger)3);
    XCTAssertEqual([compactArray indexOfObjectIdenticalTo:@"4"], (NSUInteger)NSNotFound);

    XCTAssertEqual([compactArray indexOfObjectIdenticalTo:@"0" inRange:NSMakeRange(0, 3)], (NSUInteger)0);
    XCTAssertEqual([compactArray indexOfObjectIdenticalTo:@"1" inRange:NSMakeRange(0, 3)], (NSUInteger)1);
    XCTAssertEqual([compactArray indexOfObjectIdenticalTo:@"2" inRange:NSMakeRange(0, 3)], (NSUInteger)2);
    XCTAssertEqual([compactArray indexOfObjectIdenticalTo:@"3" inRange:NSMakeRange(0, 3)], (NSUInteger)NSNotFound);
}

- (void)testIsEqualToArray
{
    NSArray *array = @[@"0", @"1", [NSNull null], @"2", [NSNull null], @"3"];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertTrue([compactArray isEqualToArray:(@[@"0", @"1", @"2", @"3"])]);
}

- (void)testFirstObject
{
    NSArray *array = @[[NSNull null], @"1", [NSNull null], @"2", [NSNull null], @"3"];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqualObjects(compactArray.firstObject, @"1");
}

- (void)testLastObject
{
    NSArray *array = @[@"1", @"2", [NSNull null], @"3", [NSNull null]];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqualObjects(compactArray.lastObject, @"3");
}

- (void)testObjectEnumerator
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSEnumerator *enumerator = compactArray.objectEnumerator;
    id object = nil;
    NSInteger i = 0;
    while ((object = enumerator.nextObject)) {
        if (i == 0) {
            XCTAssertEqualObjects(object, @"0");
        }
        if (i == 1) {
            XCTAssertEqualObjects(object, @"1");
        }
        if (i == 2) {
            XCTAssertEqualObjects(object, @"2");
        }
        if (i == 3) {
            XCTAssertEqualObjects(object, @"3");
        }
        i++;
    }
}

- (void)testReverseObjectEnumerator
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSEnumerator *enumerator = compactArray.reverseObjectEnumerator;
    id object = nil;
    NSInteger i = 0;
    while ((object = enumerator.nextObject)) {
        if (i == 0) {
            XCTAssertEqualObjects(object, @"3");
        }
        if (i == 1) {
            XCTAssertEqualObjects(object, @"2");
        }
        if (i == 2) {
            XCTAssertEqualObjects(object, @"1");
        }
        if (i == 3) {
            XCTAssertEqualObjects(object, @"0");
        }
        i++;
    }
}

static NSComparisonResult stringSort(id str1, id str2, void *context)
{
    return [str1 compare:str2];
}

- (void)testSortedArrayUsingFunction
{
    NSArray *array = @[@"2", @"1", [NSNull null], @"0", [NSNull null], @"3"];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSArray *sortedArray = [compactArray sortedArrayUsingFunction:stringSort context:NULL];

    XCTAssertEqualObjects(sortedArray[0], @"0");
    XCTAssertEqualObjects(sortedArray[1], @"1");
    XCTAssertEqualObjects(sortedArray[2], @"2");
    XCTAssertEqualObjects(sortedArray[3], @"3");
}

- (void)testSortedArrayUsingSelector
{
    NSArray *array = @[@"2", @"1", [NSNull null], @"0", [NSNull null], @"3"];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSArray *sortedArray = [compactArray sortedArrayUsingSelector:@selector(compare:)];

    XCTAssertEqualObjects(sortedArray[0], @"0");
    XCTAssertEqualObjects(sortedArray[1], @"1");
    XCTAssertEqualObjects(sortedArray[2], @"2");
    XCTAssertEqualObjects(sortedArray[3], @"3");
}

- (void)testSubarrayWithRange
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSArray *subArray1 = [compactArray subarrayWithRange:NSMakeRange(0, 2)];
    NSArray *subArray2 = [compactArray subarrayWithRange:NSMakeRange(1, 3)];

    XCTAssertEqualObjects(subArray1[0], @"0");
    XCTAssertEqualObjects(subArray1[1], @"1");

    XCTAssertEqualObjects(subArray2[0], @"1");
    XCTAssertEqualObjects(subArray2[1], @"2");
    XCTAssertEqualObjects(subArray2[2], @"3");
}

- (void)testWriteToFile
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSString *temporaryDirectory = NSTemporaryDirectory();
    NSString *path = [temporaryDirectory stringByAppendingPathComponent:@"array.temp"];

    XCTAssertFalse([array writeToFile:path atomically:YES]);
    XCTAssertFalse([array writeToURL:[NSURL fileURLWithPath:path] atomically:YES]);

    XCTAssertTrue([compactArray writeToFile:path atomically:YES]);
    XCTAssertTrue([compactArray writeToURL:[NSURL fileURLWithPath:path] atomically:YES]);
}

- (void)testMakeObjectsPerformSelector
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertThrows([array makeObjectsPerformSelector:@selector(length)]);
    XCTAssertThrows([array makeObjectsPerformSelector:@selector(compare:) withObject:@"1"]);

    XCTAssertNoThrow([compactArray makeObjectsPerformSelector:@selector(length)]);
    XCTAssertNoThrow([compactArray makeObjectsPerformSelector:@selector(compare:) withObject:@"1"]);
}

- (void)testObjectsAtIndexes
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
    [indexSet addIndex:0];
    [indexSet addIndex:2];
    [indexSet addIndex:3];

    NSArray *subarray = [compactArray objectsAtIndexes:indexSet];

    XCTAssertEqualObjects(subarray[0], @"0");
    XCTAssertEqualObjects(subarray[1], @"2");
    XCTAssertEqualObjects(subarray[2], @"3");
}

- (void)testObjectAtIndexedSubscript
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");
}

- (void)testEnumerateObjectsUsingBlock
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    [compactArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if (idx == 0) {
            XCTAssertEqualObjects(obj, @"0");
        }
        if (idx == 1) {
            XCTAssertEqualObjects(obj, @"1");
        }
        if (idx == 2) {
            XCTAssertEqualObjects(obj, @"2");
        }
        if (idx == 3) {
            XCTAssertEqualObjects(obj, @"3");
        }
    }];

    [compactArray enumerateObjectsWithOptions:NSEnumerationConcurrent | NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if (idx == 0) {
            XCTAssertEqualObjects(obj, @"0");
        }
        if (idx == 1) {
            XCTAssertEqualObjects(obj, @"1");
        }
        if (idx == 2) {
            XCTAssertEqualObjects(obj, @"2");
        }
        if (idx == 3) {
            XCTAssertEqualObjects(obj, @"3");
        }
    }];

    NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
    [indexSet addIndex:0];
    [indexSet addIndex:2];
    [indexSet addIndex:3];

    [compactArray enumerateObjectsAtIndexes:indexSet options:kNilOptions usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if (idx == 0) {
            XCTAssertEqualObjects(obj, @"0");
        }
        if (idx == 1) {
            XCTFail(@"Should not reach here.");
        }
        if (idx == 2) {
            XCTAssertEqualObjects(obj, @"2");
        }
        if (idx == 3) {
            XCTAssertEqualObjects(obj, @"3");
        }
    }];

    [compactArray enumerateObjectsAtIndexes:indexSet options:NSEnumerationConcurrent | NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if (idx == 0) {
            XCTAssertEqualObjects(obj, @"0");
        }
        if (idx == 1) {
            XCTFail(@"Should not reach here.");
        }
        if (idx == 2) {
            XCTAssertEqualObjects(obj, @"2");
        }
        if (idx == 3) {
            XCTAssertEqualObjects(obj, @"3");
        }
    }];
}

- (void)testIndexOfObjectPassingTest
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSUInteger index = NSNotFound;
    index = [compactArray indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        NSString *str = obj;
        return [str isEqualToString:@"2"];
    }];

    XCTAssertEqual(index, (NSUInteger)2);

    index = [compactArray indexOfObjectWithOptions:NSEnumerationConcurrent | NSEnumerationReverse passingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        NSString *str = obj;
        return [str isEqualToString:@"2"];
    }];

    XCTAssertEqual(index, (NSUInteger)2);

    NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
    [indexSet addIndex:0];
    [indexSet addIndex:2];
    [indexSet addIndex:3];

    index = [compactArray indexOfObjectAtIndexes:indexSet options:NSEnumerationConcurrent | NSEnumerationReverse passingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        NSString *str = obj;
        return [str isEqualToString:@"2"];
    }];

    XCTAssertEqual(index, (NSUInteger)2);
}

- (void)testIndexesOfObjectsPassingTest
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSMutableIndexSet *expectedIndexSet = [NSMutableIndexSet indexSet];
    [expectedIndexSet addIndex:2];
    [expectedIndexSet addIndex:3];

    NSIndexSet *indexes = nil;
    indexes = [compactArray indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        NSString *str = obj;
        return [str isEqualToString:@"2"] || [str isEqualToString:@"3"];
    }];

    XCTAssertEqualObjects(indexes, expectedIndexSet);

    indexes = [compactArray indexesOfObjectsWithOptions:NSEnumerationConcurrent | NSEnumerationReverse passingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        NSString *str = obj;
        return [str isEqualToString:@"2"] || [str isEqualToString:@"3"];
    }];

    XCTAssertEqualObjects(indexes, expectedIndexSet);

    NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
    [indexSet addIndex:0];
    [indexSet addIndex:2];
    [indexSet addIndex:3];

    indexes = [compactArray indexesOfObjectsAtIndexes:indexSet options:NSEnumerationConcurrent | NSEnumerationReverse passingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        NSString *str = obj;
        return [str isEqualToString:@"2"] || [str isEqualToString:@"3"];
    }];

    XCTAssertEqualObjects(indexes, expectedIndexSet);
}

- (void)testFastEnumeration
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSInteger counter = 0;
    for (id object in compactArray) {
        if (counter == 0) {
            XCTAssertEqualObjects(object, @"0");
        }
        if (counter == 1) {
            XCTAssertEqualObjects(object, @"1");
        }
        if (counter == 2) {
            XCTAssertEqualObjects(object, @"2");
        }
        if (counter == 3) {
            XCTAssertEqualObjects(object, @"3");
        }
        counter++;
    }
}

- (void)testSortedArrayUsingComparator
{
    NSArray *array = @[@"2", @"1", [NSNull null], @"0", [NSNull null], @"3"];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSArray *sortedArray = [compactArray sortedArrayWithOptions:NSSortStable usingComparator:^NSComparisonResult(id obj1, id obj2) {
        NSString *str1 = obj1;
        NSString *str2 = obj2;
        return [str1 compare:str2];
    }];

    XCTAssertEqualObjects(sortedArray[0], @"0");
    XCTAssertEqualObjects(sortedArray[1], @"1");
    XCTAssertEqualObjects(sortedArray[2], @"2");
    XCTAssertEqualObjects(sortedArray[3], @"3");
}

- (void)testBinarySearch
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSUInteger index = NSNotFound;
    index = [compactArray indexOfObject:@"3" inSortedRange:NSMakeRange(0, compactArray.count) options:NSBinarySearchingFirstEqual usingComparator:^NSComparisonResult(id obj1, id obj2) {
        NSString *str1 = obj1;
        NSString *str2 = obj2;
        return [str1 compare:str2];
    }];

    XCTAssertEqual(index, (NSUInteger)3);
}

#pragma mark - NSCopying

- (void)testCopy
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];
    NSArray *copied = compactArray.copy;

    XCTAssertEqualObjects(copied, compactArray);
}

#pragma mark - NSMutableCopying

- (void)testMutableCopy
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];
    NSArray *copied = compactArray.mutableCopy;

    XCTAssertTrue([copied isKindOfClass:[NSMutableArray class]]);
    XCTAssertEqualObjects(copied, compactArray);
}

#pragma mark - NSCoding

- (void)testArchiveObject
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:compactArray];
    NSArray *unarchived = [NSKeyedUnarchiver unarchiveObjectWithData:data];

    XCTAssertEqualObjects(unarchived, compactArray);

    XCTAssertEqualObjects(unarchived[0], @"0");
    XCTAssertEqualObjects(unarchived[1], @"1");
    XCTAssertEqualObjects(unarchived[2], @"2");
    XCTAssertEqualObjects(unarchived[3], @"3");
}

#pragma mark -

- (void)testAddObject
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    [compactArray addObject:@"4"];
    [compactArray addObject:[NSNull null]];
    [compactArray addObject:nil];
    [compactArray addObject:@"5"];

    XCTAssertEqualObjects([compactArray objectAtIndex:0], @"0");
    XCTAssertEqualObjects([compactArray objectAtIndex:1], @"1");
    XCTAssertEqualObjects([compactArray objectAtIndex:2], @"2");
    XCTAssertEqualObjects([compactArray objectAtIndex:3], @"3");
    XCTAssertEqualObjects([compactArray objectAtIndex:4], @"4");
    XCTAssertEqualObjects([compactArray objectAtIndex:5], @"5");
}

- (void)testInsertObject
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    [compactArray insertObject:@"4" atIndex:1];
    [compactArray insertObject:[NSNull null] atIndex:1];
    [compactArray insertObject:nil atIndex:1];
    [compactArray insertObject:@"5" atIndex:1];

    XCTAssertEqualObjects([compactArray objectAtIndex:0], @"0");
    XCTAssertEqualObjects([compactArray objectAtIndex:1], @"5");
    XCTAssertEqualObjects([compactArray objectAtIndex:2], @"4");
    XCTAssertEqualObjects([compactArray objectAtIndex:3], @"1");
    XCTAssertEqualObjects([compactArray objectAtIndex:4], @"2");
    XCTAssertEqualObjects([compactArray objectAtIndex:5], @"3");
}

- (void)testRemoveLastObject
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray.lastObject, @"3");

    [compactArray removeLastObject];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray.lastObject, @"2");

    [compactArray removeLastObject];

    XCTAssertEqual(compactArray.count, (NSUInteger)2);
    XCTAssertEqualObjects(compactArray.lastObject, @"1");

    [compactArray removeLastObject];

    XCTAssertEqual(compactArray.count, (NSUInteger)1);
    XCTAssertEqualObjects(compactArray.lastObject, @"0");

    [compactArray removeLastObject];

    XCTAssertEqual(compactArray.count, (NSUInteger)0);
}

- (void)testRemoveObjectAtIndex
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray removeObjectAtIndex:1];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"2");
    XCTAssertEqualObjects(compactArray[2], @"3");

    [compactArray removeObjectAtIndex:1];

    XCTAssertEqual(compactArray.count, (NSUInteger)2);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"3");
}

- (void)testReplaceObjectAtIndex
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray replaceObjectAtIndex:1 withObject:@"4"];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"4");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray replaceObjectAtIndex:2 withObject:@"5"];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"4");
    XCTAssertEqualObjects(compactArray[2], @"5");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray replaceObjectAtIndex:2 withObject:nil];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"4");
    XCTAssertEqualObjects(compactArray[2], @"3");

    [compactArray replaceObjectAtIndex:1 withObject:[NSNull null]];

    XCTAssertEqual(compactArray.count, (NSUInteger)2);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"3");
}

- (void)testAddObjectsFromArray
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray addObjectsFromArray:array.copy];

    XCTAssertEqual(compactArray.count, (NSUInteger)8);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");
    XCTAssertEqualObjects(compactArray[4], @"0");
    XCTAssertEqualObjects(compactArray[5], @"1");
    XCTAssertEqualObjects(compactArray[6], @"2");
    XCTAssertEqualObjects(compactArray[7], @"3");
}

- (void)testExchangeObjectAtIndexWithObjectAtIndex
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray exchangeObjectAtIndex:1 withObjectAtIndex:2];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"2");
    XCTAssertEqualObjects(compactArray[2], @"1");
    XCTAssertEqualObjects(compactArray[3], @"3");
}

- (void)testRemoveAllObjects
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);

    [compactArray removeAllObjects];

    XCTAssertEqual(compactArray.count, (NSUInteger)0);
}

- (void)testRemoveObjectInRange
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray removeObject:@"2" inRange:NSMakeRange(1, 2)];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"3");

    [compactArray removeObject:nil inRange:NSMakeRange(1, 2)];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"3");

    [compactArray removeObject:[NSNull null] inRange:NSMakeRange(1, 2)];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"3");
}

- (void)testRemoveObject
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray removeObject:@"2"];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"3");

    [compactArray removeObject:nil];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"3");

    [compactArray removeObject:[NSNull null]];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"3");
}

- (void)testRemoveObjectIdenticalTo
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray removeObjectIdenticalTo:@"2"];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"3");

    [compactArray removeObjectIdenticalTo:nil];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"3");

    [compactArray removeObjectIdenticalTo:[NSNull null]];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"3");
}

- (void)testRemoveObjectIdenticalToInRange
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray removeObjectIdenticalTo:@"2" inRange:NSMakeRange(1, 2)];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"3");

    [compactArray removeObjectIdenticalTo:nil inRange:NSMakeRange(1, 2)];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"3");

    [compactArray removeObjectIdenticalTo:[NSNull null] inRange:NSMakeRange(1, 2)];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"3");
}

- (void)testRemoveObjectsFromIndicesNumIndices
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    NSUInteger indices[2];
    indices[0] = 1;
    indices[1] = 2;

    [compactArray removeObjectsFromIndices:indices numIndices:2];

    XCTAssertEqual(compactArray.count, (NSUInteger)2);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"3");
}

- (void)testRemoveObjectsInArray
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray removeObjectsInArray:@[@"0", @"2", [NSNull null]]];

    XCTAssertEqual(compactArray.count, (NSUInteger)2);
    XCTAssertEqualObjects(compactArray[0], @"1");
    XCTAssertEqualObjects(compactArray[1], @"3");
}

- (void)testRemoveObjectsInRange
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray removeObjectsInRange:NSMakeRange(1, 2)];

    XCTAssertEqual(compactArray.count, (NSUInteger)2);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"3");
}

- (void)testReplaceObjectsInRangeWithObjectsFromArray
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray replaceObjectsInRange:NSMakeRange(1, 2) withObjectsFromArray:@[@"4", [NSNull null], @"5", @"6", @"7"]];

    XCTAssertEqual(compactArray.count, (NSUInteger)6);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"4");
    XCTAssertEqualObjects(compactArray[2], @"5");
    XCTAssertEqualObjects(compactArray[3], @"6");
    XCTAssertEqualObjects(compactArray[4], @"7");
    XCTAssertEqualObjects(compactArray[5], @"3");
}

- (void)testReplaceObjectsInRangeWithObjectsFromArrayRange
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray replaceObjectsInRange:NSMakeRange(1, 2) withObjectsFromArray:@[@"4", [NSNull null], @"5", @"6", @"7"] range:NSMakeRange(0, 3)];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"4");
    XCTAssertEqualObjects(compactArray[2], @"5");
    XCTAssertEqualObjects(compactArray[3], @"3");
}

- (void)testSetArray
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    [compactArray setArray:@[@"4", [NSNull null], @"5", @"6"]];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"4");
    XCTAssertEqualObjects(compactArray[1], @"5");
    XCTAssertEqualObjects(compactArray[2], @"6");
}

- (void)testSortUsingFunction
{
    NSArray *array = @[@"2", @"1", [NSNull null], @"0", [NSNull null], @"3"];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    [compactArray sortUsingFunction:stringSort context:NULL];

    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");
}

- (void)testSortUsingSelector
{
    NSArray *array = @[@"2", @"1", [NSNull null], @"0", [NSNull null], @"3"];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    [compactArray sortUsingSelector:@selector(compare:)];

    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");
}

- (void)testInsertObjectsAtIndexes1
{
    NSArray *array = @[@"one", @"two", [NSNull null], @"three", [NSNull null], @"four"];
    NSArray *newAdditions = @[@"a", @"b"];

    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    [indexes addIndex:1];
    [indexes addIndex:3];

    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    [compactArray insertObjects:newAdditions atIndexes:indexes];

    XCTAssertEqual(compactArray.count, (NSUInteger)6);
    XCTAssertEqualObjects(compactArray[0], @"one");
    XCTAssertEqualObjects(compactArray[1], @"a");
    XCTAssertEqualObjects(compactArray[2], @"two");
    XCTAssertEqualObjects(compactArray[3], @"b");
    XCTAssertEqualObjects(compactArray[4], @"three");
    XCTAssertEqualObjects(compactArray[5], @"four");
}

- (void)testInsertObjectsAtIndexes2
{
    NSArray *array = @[@"one", @"two", [NSNull null], @"three", [NSNull null], @"four"];
    NSArray *newAdditions = @[@"a", [NSNull null], @"b", [NSNull null]];

    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    [indexes addIndex:1];
    [indexes addIndex:3];
    [indexes addIndex:4];
    [indexes addIndex:5];

    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    [compactArray insertObjects:newAdditions atIndexes:indexes];

    XCTAssertEqual(compactArray.count, (NSUInteger)6);
    XCTAssertEqualObjects(compactArray[0], @"one");
    XCTAssertEqualObjects(compactArray[1], @"a");
    XCTAssertEqualObjects(compactArray[2], @"two");
    XCTAssertEqualObjects(compactArray[3], @"b");
    XCTAssertEqualObjects(compactArray[4], @"three");
    XCTAssertEqualObjects(compactArray[5], @"four");
}

- (void)testInsertObjectsAtIndexes3
{
    NSArray *array = @[@"one", @"two", [NSNull null], @"three", [NSNull null], @"four"];
    NSArray *newAdditions = @[@"a", @"b"];

    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    [indexes addIndex:4];
    [indexes addIndex:5];

    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    [compactArray insertObjects:newAdditions atIndexes:indexes];

    XCTAssertEqual(compactArray.count, (NSUInteger)6);
    XCTAssertEqualObjects(compactArray[0], @"one");
    XCTAssertEqualObjects(compactArray[1], @"two");
    XCTAssertEqualObjects(compactArray[2], @"three");
    XCTAssertEqualObjects(compactArray[3], @"four");
    XCTAssertEqualObjects(compactArray[4], @"a");
    XCTAssertEqualObjects(compactArray[5], @"b");
}

- (void)testInsertObjectsAtIndexes4
{
    NSArray *array = @[@"one", @"two", [NSNull null], @"three", [NSNull null], @"four"];
    NSArray *newAdditions = @[@"a", [NSNull null], @"b", [NSNull null]];

    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    [indexes addIndex:4];
    [indexes addIndex:5];
    [indexes addIndex:6];
    [indexes addIndex:7];

    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    [compactArray insertObjects:newAdditions atIndexes:indexes];

    XCTAssertEqual(compactArray.count, (NSUInteger)6);
    XCTAssertEqualObjects(compactArray[0], @"one");
    XCTAssertEqualObjects(compactArray[1], @"two");
    XCTAssertEqualObjects(compactArray[2], @"three");
    XCTAssertEqualObjects(compactArray[3], @"four");
    XCTAssertEqualObjects(compactArray[4], @"a");
    XCTAssertEqualObjects(compactArray[5], @"b");
}

- (void)testInsertObjectsAtIndexes5
{
    NSArray *array = @[@"one", @"two", [NSNull null], @"three", [NSNull null], @"four"];
    NSArray *newAdditions = @[@"a", @"b", @"c"];

    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    [indexes addIndex:1];
    [indexes addIndex:2];
    [indexes addIndex:4];

    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    [compactArray insertObjects:newAdditions atIndexes:indexes];

    XCTAssertEqual(compactArray.count, (NSUInteger)7);
    XCTAssertEqualObjects(compactArray[0], @"one");
    XCTAssertEqualObjects(compactArray[1], @"a");
    XCTAssertEqualObjects(compactArray[2], @"b");
    XCTAssertEqualObjects(compactArray[3], @"two");
    XCTAssertEqualObjects(compactArray[4], @"c");
    XCTAssertEqualObjects(compactArray[5], @"three");
    XCTAssertEqualObjects(compactArray[6], @"four");
}

- (void)testInsertObjectsAtIndexes6
{
    NSArray *array = @[@"one", @"two", [NSNull null], @"three", [NSNull null], @"four"];
    NSArray *newAdditions = @[@"a", @"b", [NSNull null], @"c"];

    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    [indexes addIndex:1];
    [indexes addIndex:2];
    [indexes addIndex:3];
    [indexes addIndex:4];

    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    [compactArray insertObjects:newAdditions atIndexes:indexes];

    XCTAssertEqual(compactArray.count, (NSUInteger)7);
    XCTAssertEqualObjects(compactArray[0], @"one");
    XCTAssertEqualObjects(compactArray[1], @"a");
    XCTAssertEqualObjects(compactArray[2], @"b");
    XCTAssertEqualObjects(compactArray[3], @"c");
    XCTAssertEqualObjects(compactArray[4], @"two");
    XCTAssertEqualObjects(compactArray[5], @"three");
    XCTAssertEqualObjects(compactArray[6], @"four");
}

- (void)testRemoveObjectsAtIndexes
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    [indexes addIndex:1];
    [indexes addIndex:3];

    [compactArray removeObjectsAtIndexes:indexes];

    XCTAssertEqual(compactArray.count, (NSUInteger)2);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"2");
}

- (void)testReplaceObjectsAtIndexesWithObjects
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    [indexes addIndex:1];
    [indexes addIndex:2];
    [indexes addIndex:3];

    [compactArray replaceObjectsAtIndexes:indexes withObjects:@[@"a", [NSNull null], @"b"]];

    XCTAssertEqual(compactArray.count, (NSUInteger)3);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"a");
    XCTAssertEqualObjects(compactArray[2], @"b");
}

- (void)testSetObjectAtIndexedSubscript
{
    NSArray *array = [self sampleArray];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");

    compactArray[2] = @"two";

    XCTAssertEqual(compactArray.count, (NSUInteger)4);
    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"two");
    XCTAssertEqualObjects(compactArray[3], @"3");
}

- (void)testSortUsingComparator
{
    NSArray *array = @[@"2", @"1", [NSNull null], @"0", [NSNull null], @"3"];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    [compactArray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        NSString *str1 = obj1;
        NSString *str2 = obj2;
        return [str1 compare:str2];
    }];

    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");
}

- (void)testSortWithOptionsUsingComparator
{
    NSArray *array = @[@"2", @"1", [NSNull null], @"0", [NSNull null], @"3"];
    NSMutableArray *compactArray = [[array cu_compactArray] mutableCopy];

    [compactArray sortWithOptions:NSSortConcurrent | NSSortStable usingComparator:^NSComparisonResult(id obj1, id obj2) {
        NSString *str1 = obj1;
        NSString *str2 = obj2;
        return [str1 compare:str2];
    }];

    XCTAssertEqualObjects(compactArray[0], @"0");
    XCTAssertEqualObjects(compactArray[1], @"1");
    XCTAssertEqualObjects(compactArray[2], @"2");
    XCTAssertEqualObjects(compactArray[3], @"3");
}

- (void)testReplaceValueToNestedArray
{
    NSArray *array = @[@"0",
                       @"1",
                       [NSNull null],
                       @"2",
                       @[@"0",
                         [NSNull null],
                         @"1",
                         [NSNull null],
                         @"2"],
                       @"4"];

    NSMutableArray *mutableArray = [array mutableCopy];
    NSMutableArray *compactMutableArray = [mutableArray cu_compactArray];

    NSString *replace = @"replaced";
    compactMutableArray[3][1] = replace;
    XCTAssertEqualObjects(compactMutableArray[3][1], replace);
}

@end


text:
Test environment
================

Those files are used to build a test environment for this bundle. For now, only Symfony4.3 is available.

redpajama_set_name: RedPajamaGithub


text:
<<-EXAMPLE
tabs can be generated using
{% tabs %}
**Note: tabs are linked to a predifined group named `default`, using `tab-group`
you can define multiple linked tab groups.**
@input tab-group optional, string
@input type optional, pill|tabs

Create individual pane in your tab using

@input active optional, adds active class to tab
@input label optional, tab visual label

Pane contents should come after each corresponding pane.
<% My pane content %>

<%Awesome content for second pane!%>
use end block when you are finished with your tab
{% endtabs %}
EXAMPLE
###
# Gloabl scope variable in order to eliminate chance of accidental tab id
if !defined?($idInc)
    $idInc = 1
end

module Jekyll
    class RenderTabs < Liquid::Block
        # regexp pattern to generate key values out of user input
        InputPattern = /(.*?):([A-Za-z0-9\- \.]+)(?:,|$| )/m
        IdPattern = /(.*?):([A-Za-z0-9\-]+)(?:,|$| )/m

        def initialize(tag_name, text, tokens)
            super

            @header = createHash(text)
            checkMandatories(@header)
            # by default we will fall back to `tabs` https://getbootstrap.com/docs/4.0/components/navs/#tabs
            if @header.key?("type") == false || @header["type"].match(/tabs|pills/) == false
                @header["type"] = "tabs"
            end
        end

        # function checks mandatory items that are needed to implement tabs
        def checkMandatories(items)
            # exception handeling if user not gave any id
            if items.key?("id") == false || items["id"].match(IdPattern) == false
                items["id"] = "tabplugin-#{$idInc}"
                $idInc += 1
            end
        end

        # convert input parameters to hash
        def createHash(items)
            hash = {}
            items.scan(InputPattern) do |key, value|
                hash[key] = value.strip
            end
            return hash
        end

        def render(context)
            text = super

            # tab global header
            result = "
"
            # user input should follow this format
            # tabs : <key:value>
            # content: <% content %>
            tmpdata = text.scan(/<(.*?)>(?:.*?)<\%(.*?)\%>/m)

            # registering tab_group flag used in `_layouts/docwithnav.html` to decied
            # when to include js/tabs.js in a page.
            context.registers[:page]["tab_group"] = true

            # headers and contents are two temporary variables used to generate last result
            headers = ""
            contents = "

"

            for item in tmpdata
                # temporary dictionary to gather header key,values
                dict = createHash(item[0])
                checkMandatories(dict)
                # monkey patch to fix visual bug if user provided multiple active panes.
                if headers.scan(/(active)">/m).length() > 1
                    dict["active"] = false
                    print("\t** WARN: Detected multiple active tabs. **\n")
                end

                headers += "
"
                headers += "#{dict["label"]}
"

                contents += "
#{item[1]}\n
"

            end
            # final result is ready
            result += headers + contents + "
"

            return result

        end
    end
end
# register tag into jekyll
Liquid::Template.register_tag('tabs', Jekyll::RenderTabs)


text:
#ifndef ART_RUNTIME_SCOPED_THREAD_STATE_CHANGE_H_
#define ART_RUNTIME_SCOPED_THREAD_STATE_CHANGE_H_

#include "base/casts.h"
#include "java_vm_ext.h"
#include "jni_env_ext-inl.h"
#include "art_field.h"
#include "read_barrier.h"
#include "thread-inl.h"
#include "verify_object.h"

namespace art {

// Scoped change into and out of a particular state. Handles Runnable transitions that require
// more complicated suspension checking. The subclasses ScopedObjectAccessUnchecked and
// ScopedObjectAccess are used to handle the change into Runnable to Get direct access to objects,
// the unchecked variant doesn't aid annotalysis.
class ScopedThreadStateChange : public ValueObject {
 public:
  ScopedThreadStateChange(Thread* self, ThreadState new_thread_state)
      REQUIRES(!Locks::thread_suspend_count_lock_) ALWAYS_INLINE
      : self_(self), thread_state_(new_thread_state), expected_has_no_thread_(false) {
    if (UNLIKELY(self_ == nullptr)) {
      // Value chosen arbitrarily and won't be used in the destructor since thread_ == null.
      old_thread_state_ = kTerminated;
      Runtime* runtime = Runtime::Current();
      CHECK(runtime == nullptr || !runtime->IsStarted() || runtime->IsShuttingDown(self_));
    } else {
      DCHECK_EQ(self, Thread::Current());
      // Read state without locks, ok as state is effectively thread local and we're not interested
      // in the suspend count (this will be handled in the runnable transitions).
      old_thread_state_ = self->GetState();
      if (old_thread_state_ != new_thread_state) {
        if (new_thread_state == kRunnable) {
          self_->TransitionFromSuspendedToRunnable();
        } else if (old_thread_state_ == kRunnable) {
          self_->TransitionFromRunnableToSuspended(new_thread_state);
        } else {
          // A suspended transition to another effectively suspended transition, ok to use Unsafe.
          self_->SetState(new_thread_state);
        }
      }
    }
  }

  ~ScopedThreadStateChange() REQUIRES(!Locks::thread_suspend_count_lock_) ALWAYS_INLINE {
    if (UNLIKELY(self_ == nullptr)) {
      if (!expected_has_no_thread_) {
        Runtime* runtime = Runtime::Current();
        bool shutting_down = (runtime == nullptr) || runtime->IsShuttingDown(nullptr);
        CHECK(shutting_down);
      }
    } else {
      if (old_thread_state_ != thread_state_) {
        if (old_thread_state_ == kRunnable) {
          self_->TransitionFromSuspendedToRunnable();
        } else if (thread_state_ == kRunnable) {
          self_->TransitionFromRunnableToSuspended(old_thread_state_);
        } else {
          // A suspended transition to another effectively suspended transition, ok to use Unsafe.
          self_->SetState(old_thread_state_);
        }
      }
    }
  }

  Thread* Self() const {
    return self_;
  }

 protected:
  // Constructor used by ScopedJniThreadState for an unattached thread that has access to the VM*.
  ScopedThreadStateChange()
      : self_(nullptr), thread_state_(kTerminated), old_thread_state_(kTerminated),
        expected_has_no_thread_(true) {}

  Thread* const self_;
  const ThreadState thread_state_;

 private:
  ThreadState old_thread_state_;
  const bool expected_has_no_thread_;

  friend class ScopedObjectAccessUnchecked;
  DISALLOW_COPY_AND_ASSIGN(ScopedThreadStateChange);
};

// Assumes we are already runnable.
class ScopedObjectAccessAlreadyRunnable : public ValueObject {
 public:
  Thread* Self() const {
    return self_;
  }

  JNIEnvExt* Env() const {
    return env_;
  }

  JavaVMExt* Vm() const {
    return vm_;
  }

  bool ForceCopy() const {
    return vm_->ForceCopy();
  }

  /*
   * Add a local reference for an object to the indirect reference table associated with the
   * current stack frame.  When the native function returns, the reference will be discarded.
   *
   * We need to allow the same reference to be added multiple times, and cope with nullptr.
   *
   * This will be called on otherwise unreferenced objects. We cannot do GC allocations here, and
   * it's best if we don't grab a mutex.
   */
  template<typename T>
  T AddLocalReference(mirror::Object* obj) const SHARED_REQUIRES(Locks::mutator_lock_) {
    Locks::mutator_lock_->AssertSharedHeld(Self());
    DCHECK(IsRunnable());  // Don't work with raw objects in non-runnable states.
    DCHECK_NE(obj, Runtime::Current()->GetClearedJniWeakGlobal());
    return obj == nullptr ? nullptr : Env()->AddLocalReference<T>(obj);
  }

  template<typename T>
  T Decode(jobject obj) const
      SHARED_REQUIRES(Locks::mutator_lock_) {
    Locks::mutator_lock_->AssertSharedHeld(Self());
    DCHECK(IsRunnable());  // Don't work with raw objects in non-runnable states.
    return down_cast<T>(Self()->DecodeJObject(obj));
  }

  ArtField* DecodeField(jfieldID fid) const
      SHARED_REQUIRES(Locks::mutator_lock_) {
    Locks::mutator_lock_->AssertSharedHeld(Self());
    DCHECK(IsRunnable());  // Don't work with raw objects in non-runnable states.
    return reinterpret_cast<ArtField*>(fid);
  }

  jfieldID EncodeField(ArtField* field) const SHARED_REQUIRES(Locks::mutator_lock_) {
    Locks::mutator_lock_->AssertSharedHeld(Self());
    DCHECK(IsRunnable());  // Don't work with raw objects in non-runnable states.
    return reinterpret_cast<jfieldID>(field);
  }

  ArtMethod* DecodeMethod(jmethodID mid) const SHARED_REQUIRES(Locks::mutator_lock_) {
    Locks::mutator_lock_->AssertSharedHeld(Self());
    DCHECK(IsRunnable());  // Don't work with raw objects in non-runnable states.
    return reinterpret_cast<ArtMethod*>(mid);
  }

  jmethodID EncodeMethod(ArtMethod* method) const SHARED_REQUIRES(Locks::mutator_lock_) {
    Locks::mutator_lock_->AssertSharedHeld(Self());
    DCHECK(IsRunnable());  // Don't work with raw objects in non-runnable states.
    return reinterpret_cast<jmethodID>(method);
  }

  bool IsRunnable() const {
    return self_->GetState() == kRunnable;
  }

 protected:
  explicit ScopedObjectAccessAlreadyRunnable(JNIEnv* env)
      REQUIRES(!Locks::thread_suspend_count_lock_) ALWAYS_INLINE
      : self_(ThreadForEnv(env)), env_(down_cast<JNIEnvExt*>(env)), vm_(env_->vm) {
  }

  explicit ScopedObjectAccessAlreadyRunnable(Thread* self)
      REQUIRES(!Locks::thread_suspend_count_lock_) ALWAYS_INLINE
      : self_(self), env_(down_cast<JNIEnvExt*>(self->GetJniEnv())),
        vm_(env_ != nullptr ? env_->vm : nullptr) {
  }

  // Used when we want a scoped JNI thread state but have no thread/JNIEnv. Consequently doesn't
  // change into Runnable or acquire a share on the mutator_lock_.
  explicit ScopedObjectAccessAlreadyRunnable(JavaVM* vm)
      : self_(nullptr), env_(nullptr), vm_(down_cast<JavaVMExt*>(vm)) {}

  // Here purely to force inlining.
  ~ScopedObjectAccessAlreadyRunnable() ALWAYS_INLINE {
  }

  // Self thread, can be null.
  Thread* const self_;
  // The full JNIEnv.
  JNIEnvExt* const env_;
  // The full JavaVM.
  JavaVMExt* const vm_;
};

class ScopedObjectAccessNoAssertion {
 public:
  Thread* Self() const {
    return self_;
  }

  JNIEnvExt* Env() const {
    return env_;
  }

  JavaVMExt* Vm() const {
    return vm_;
  }

  template<typename T>
  T Decode(jobject obj) const NO_THREAD_SAFETY_ANALYSIS {
    return down_cast<T>(Self()->DecodeJObject(obj));
  }

  ArtField* DecodeField(jfieldID fid) const {
    return reinterpret_cast<ArtField*>(fid);
  }

  jfieldID EncodeField(ArtField* field) const {
    return reinterpret_cast<jfieldID>(field);
  }

  ArtMethod* DecodeMethod(jmethodID mid) const
      NO_THREAD_SAFETY_ANALYSIS {
    return reinterpret_cast<ArtMethod*>(mid);
  }

  jmethodID EncodeMethod(ArtMethod* method) const {
    return reinterpret_cast<jmethodID>(method);
  }

 protected:
  explicit ScopedObjectAccessNoAssertion(JNIEnv* env) ALWAYS_INLINE
      : self_(ThreadForEnv(env)), env_(down_cast<JNIEnvExt*>(env)), vm_(env_->vm) {
  }

  // Here purely to force inlining.
  ~ScopedObjectAccessNoAssertion() ALWAYS_INLINE {
  }

  // Self thread, can be null.
  Thread* const self_;
  // The full JNIEnv.
  JNIEnvExt* const env_;
  // The full JavaVM.
  JavaVMExt* const vm_;
};

class ScopedFastObjectAccess : public ScopedObjectAccessNoAssertion {
 public:
  explicit ScopedFastObjectAccess(JNIEnv* env) ALWAYS_INLINE
      : ScopedObjectAccessNoAssertion(env) {}

  ~ScopedFastObjectAccess() ALWAYS_INLINE {}

 private:
  DISALLOW_COPY_AND_ASSIGN(ScopedFastObjectAccess);
};

// Entry/exit processing for transitions from Native to Runnable (ie within JNI functions).
//
// This class performs the necessary thread state switching to and from Runnable and lets us
// amortize the cost of working out the current thread. Additionally it lets us check (and repair)
// apps that are using a JNIEnv on the wrong thread. The class also decodes and encodes Objects
// into jobjects via methods of this class. Performing this here enforces the Runnable thread state
// for use of Object, thereby inhibiting the Object being modified by GC whilst native or VM code
// is also manipulating the Object.
//
// The destructor transitions back to the previous thread state, typically Native. In this state
// GC and thread suspension may occur.
//
// For annotalysis the subclass ScopedObjectAccess (below) makes it explicit that a shared of
// the mutator_lock_ will be acquired on construction.
class ScopedObjectAccessUnchecked : public ScopedObjectAccessAlreadyRunnable {
 public:
  explicit ScopedObjectAccessUnchecked(JNIEnv* env)
      REQUIRES(!Locks::thread_suspend_count_lock_) ALWAYS_INLINE
      : ScopedObjectAccessAlreadyRunnable(env), tsc_(Self(), kRunnable) {
    Self()->VerifyStack();
    Locks::mutator_lock_->AssertSharedHeld(Self());
  }

  explicit ScopedObjectAccessUnchecked(Thread* self)
      REQUIRES(!Locks::thread_suspend_count_lock_) ALWAYS_INLINE
      : ScopedObjectAccessAlreadyRunnable(self), tsc_(self, kRunnable) {
    Self()->VerifyStack();
    Locks::mutator_lock_->AssertSharedHeld(Self());
  }

  // Used when we want a scoped JNI thread state but have no thread/JNIEnv. Consequently doesn't
  // change into Runnable or acquire a share on the mutator_lock_.
  explicit ScopedObjectAccessUnchecked(JavaVM* vm) ALWAYS_INLINE
      : ScopedObjectAccessAlreadyRunnable(vm), tsc_() {}

 private:
  // The scoped thread state change makes sure that we are runnable and restores the thread state
  // in the destructor.
  const ScopedThreadStateChange tsc_;

  DISALLOW_COPY_AND_ASSIGN(ScopedObjectAccessUnchecked);
};

// Annotalysis helping variant of the above.
class ScopedObjectAccess : public ScopedObjectAccessUnchecked {
 public:
  explicit ScopedObjectAccess(JNIEnv* env)
      REQUIRES(!Locks::thread_suspend_count_lock_)
      SHARED_LOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE
      : ScopedObjectAccessUnchecked(env) {
  }

  explicit ScopedObjectAccess(Thread* self)
      REQUIRES(!Locks::thread_suspend_count_lock_)
      SHARED_LOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE
      : ScopedObjectAccessUnchecked(self) {
  }

  ~ScopedObjectAccess() UNLOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE {
    // Base class will release share of lock. Invoked after this destructor.
  }

 private:
  // TODO: remove this constructor. It is used by check JNI's ScopedCheck to make it believe that
  //       routines operating with just a VM are sound, they are not, but when you have just a VM
  //       you cannot call the unsound routines.
  explicit ScopedObjectAccess(JavaVM* vm)
      SHARED_LOCK_FUNCTION(Locks::mutator_lock_)
      : ScopedObjectAccessUnchecked(vm) {}

  friend class ScopedCheck;
  DISALLOW_COPY_AND_ASSIGN(ScopedObjectAccess);
};

// Annotalysis helper for going to a suspended state from runnable.
class ScopedThreadSuspension : public ValueObject {
 public:
  explicit ScopedThreadSuspension(Thread* self, ThreadState suspended_state)
      REQUIRES(!Locks::thread_suspend_count_lock_, !Roles::uninterruptible_)
      UNLOCK_FUNCTION(Locks::mutator_lock_)
      ALWAYS_INLINE
      : self_(self), suspended_state_(suspended_state) {
    DCHECK(self_ != nullptr);
    self_->TransitionFromRunnableToSuspended(suspended_state);
  }

  ~ScopedThreadSuspension() SHARED_LOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE {
    DCHECK_EQ(self_->GetState(), suspended_state_);
    self_->TransitionFromSuspendedToRunnable();
  }

 private:
  Thread* const self_;
  const ThreadState suspended_state_;
  DISALLOW_COPY_AND_ASSIGN(ScopedThreadSuspension);
};

}  // namespace art

#endif  // ART_RUNTIME_SCOPED_THREAD_STATE_CHANGE_H_


text:
package android.support.v4.view;

import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;

// Referenced classes of package android.support.v4.view:
//            ViewGroupCompatHC, ViewGroupCompatIcs, ViewGroupCompatJellybeanMR2

public class ViewGroupCompat
{
    static class ViewGroupCompatHCImpl extends ViewGroupCompatStubImpl
    {

        public void setMotionEventSplittingEnabled(ViewGroup viewgroup, boolean flag)
        {
            ViewGroupCompatHC.setMotionEventSplittingEnabled(viewgroup, flag);
        }

        ViewGroupCompatHCImpl()
        {
        }
    }

    static class ViewGroupCompatIcsImpl extends ViewGroupCompatHCImpl
    {

        public boolean onRequestSendAccessibilityEvent(ViewGroup viewgroup, View view, AccessibilityEvent accessibilityevent)
        {
            return ViewGroupCompatIcs.onRequestSendAccessibilityEvent(viewgroup, view, accessibilityevent);
        }

        ViewGroupCompatIcsImpl()
        {
        }
    }

    static interface ViewGroupCompatImpl
    {

        public abstract int getLayoutMode(ViewGroup viewgroup);

        public abstract boolean onRequestSendAccessibilityEvent(ViewGroup viewgroup, View view, AccessibilityEvent accessibilityevent);

        public abstract void setLayoutMode(ViewGroup viewgroup, int i);

        public abstract void setMotionEventSplittingEnabled(ViewGroup viewgroup, boolean flag);
    }

    static class ViewGroupCompatJellybeanMR2Impl extends ViewGroupCompatIcsImpl
    {

        public int getLayoutMode(ViewGroup viewgroup)
        {
            return ViewGroupCompatJellybeanMR2.getLayoutMode(viewgroup);
        }

        public void setLayoutMode(ViewGroup viewgroup, int i)
        {
            ViewGroupCompatJellybeanMR2.setLayoutMode(viewgroup, i);
        }

        ViewGroupCompatJellybeanMR2Impl()
        {
        }
    }

    static class ViewGroupCompatStubImpl
        implements ViewGroupCompatImpl
    {

        public int getLayoutMode(ViewGroup viewgroup)
        {
            return 0;
        }

        public boolean onRequestSendAccessibilityEvent(ViewGroup viewgroup, View view, AccessibilityEvent accessibilityevent)
        {
            return true;
        }

        public void setLayoutMode(ViewGroup viewgroup, int i)
        {
        }

        public void setMotionEventSplittingEnabled(ViewGroup viewgroup, boolean flag)
        {
        }

        ViewGroupCompatStubImpl()
        {
        }
    }

    static final ViewGroupCompatImpl IMPL;
    public static final int LAYOUT_MODE_CLIP_BOUNDS = 0;
    public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1;

    private ViewGroupCompat()
    {
    }

    public static int getLayoutMode(ViewGroup viewgroup)
    {
        return IMPL.getLayoutMode(viewgroup);
    }

    public static boolean onRequestSendAccessibilityEvent(ViewGroup viewgroup, View view, AccessibilityEvent accessibilityevent)
    {
        return IMPL.onRequestSendAccessibilityEvent(viewgroup, view, accessibilityevent);
    }

    public static void setLayoutMode(ViewGroup viewgroup, int i)
    {
        IMPL.setLayoutMode(viewgroup, i);
    }

    public static void setMotionEventSplittingEnabled(ViewGroup viewgroup, boolean flag)
    {
        IMPL.setMotionEventSplittingEnabled(viewgroup, flag);
    }

    static
    {
        int i = android.os.Build.VERSION.SDK_INT;
        if (i >= 18)
        {
            IMPL = new ViewGroupCompatJellybeanMR2Impl();
        } else
        if (i >= 14)
        {
            IMPL = new ViewGroupCompatIcsImpl();
        } else
        if (i >= 11)
        {
            IMPL = new ViewGroupCompatHCImpl();
        } else
        {
            IMPL = new ViewGroupCompatStubImpl();
        }
    }
}


text:
//
//  main.m
//  PhotoMapper
//
//  Created by Neil Goodman on 7/15/12.
//  Copyright __MyCompanyName__ 2012. All rights reserved.
//

#import <UIKit/UIKit.h>

int main(int argc, char *argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");
    [pool release];
    return retVal;
}


text:
#pragma once
#include <aws/network-firewall/NetworkFirewall_EXPORTS.h>
#include <aws/core/utils/memory/stl/AWSString.h>

namespace Aws
{
namespace NetworkFirewall
{
namespace Model
{
  enum class GeneratedRulesType
  {
    NOT_SET,
    ALLOWLIST,
    DENYLIST
  };

namespace GeneratedRulesTypeMapper
{
AWS_NETWORKFIREWALL_API GeneratedRulesType GetGeneratedRulesTypeForName(const Aws::String& name);

AWS_NETWORKFIREWALL_API Aws::String GetNameForGeneratedRulesType(GeneratedRulesType value);
} // namespace GeneratedRulesTypeMapper
} // namespace Model
} // namespace NetworkFirewall
} // namespace Aws


text:
require 'ipayout/service_param'

module Ipayout
  # Custom error class for rescuing from all eWallet errors
  class Service
    attr_accessor :name, :response_parameters, :parameters

    # Initializes new ServiceParam object
    #
    # @param [String] name
    # @param [Array] request_param_names
    # @param [Array] response_param_names
    # @return [Ipayout::Service]
    # @instantiate Ipayout::Service.new("eWallet_GetCustomerDetails")

    def initialize(name)
      @name = name
      @request_param_names = []
      @response_param_names = []

      # Hash of this service's parameters
      # wherein the key is the parameter name
      # and the value is the actual Ipayout::ServiceParam object
      # parameters['eWallet_GetCustomerDetails'] =
      #             <Object Ipayout::ServiceParam>
      @parameters = {}

      # This is a list of keys to use when referencing the API response
      @response_parameters = []
    end

    def to_s
      @name
    end

    # return an array of param names
    # expected for this service call
    def request_param_list
      @parameters.keys
    end

    # our native parameters hash holds service_param
    # objects.  This returns the param_name => param_value hash
    def param_hash
      param_hash = {}
      @parameters.each do |param_name, param_obj|
        param_hash[param_name] = param_obj.value
      end
      param_hash
    end

    # This is a shortcut method for adding parameters
    # without having to instantiate the ServiceParam
    # outside of this class.
    def add_param(param_name, expected_type, required)
      unless @parameters.key? param_name
        param = Ipayout::ServiceParam.new(param_name,
                                          expected_type,
                                          required)
        @parameters[param_name] = param
      end
    end
  end
end


text:
package ru.stqa.pft.addressbook.generators;

import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import ru.stqa.pft.addressbook.model.ContactData;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

public class ContactDataGeneartor {

    @Parameter(names="-c",description="Contact count")
    public int count;

    @Parameter(names="-f", description="Target file")
    public String file;

    @Parameter(names="-d", description="Data format")
    public String format;

    public static void main(String[] args) throws IOException {
        ContactDataGeneartor generator = new ContactDataGeneartor();
        JCommander jCommander = new JCommander(generator);
        try {
            jCommander.parse(args);
        } catch (ParameterException ex) {
            jCommander.usage();
            return;
        }
        generator.run();
    }

    private void run() throws IOException {
        List contacts = generateContacts(count);
        if (format.equals("json")) {
            saveAsJson(contacts, new File(file));
        } else {
            System.out.println("Unrecognized format " + format);
        }
    }
    private void saveAsJson(List contacts, File file) throws IOException {
        Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
        String json = gson.toJson(contacts);
        try (Writer writer = new FileWriter(file)){
            writer.write(json);
        }
    }
    private List<ContactData> generateContacts(int count) {
        List<ContactData> contacts = new ArrayList<ContactData>();
        for (int i = 0; i < count; i++){
            contacts.add(new ContactData().withFirstname(String.format("test %s", i))
                    .withLastname(String.format("lastname %s", i))
                    .withAddress(String.format("address %s", i))
                    .withEmail(String.format("email%s@example.com", i))
                    .withHome(String.format("555-%s", i)));
        }
        return contacts;
    }

}


text:
*********
salterror
*********

.. automodule:: salterror
   :members:
   :undoc-members:
   :show-inheritance:


text:
package org.apache.synapse.mediators.template;

import org.apache.synapse.ContinuationState;
import org.apache.synapse.ManagedLifecycle;
import org.apache.synapse.Mediator;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseLog;
import org.apache.synapse.continuation.ContinuationStackManager;
import org.apache.synapse.continuation.ReliantContinuationState;
import org.apache.synapse.core.SynapseEnvironment;
import org.apache.synapse.mediators.AbstractMediator;
import org.apache.synapse.mediators.FlowContinuableMediator;
import org.apache.synapse.mediators.Value;
import org.apache.synapse.mediators.eip.EIPUtils;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * This class handles invocation of a synapse function template. <invoke
 * target=""> <parameter name="p1" value="{expr} | {{expr}} | value" />* ..
 * </invoke>
 */
public class InvokeMediator extends AbstractMediator implements
                                                     ManagedLifecycle,FlowContinuableMediator {
	/**
	 * refers to the target template this is going to invoke this is a read only
	 * attribute of the mediator
	 */
	private String targetTemplate;

	/**
	 * Refers to the parent package qualified reference
	 *
	 */
	private String packageName;

	/**
	 * maps each parameter name to a Expression/Value this is a read only
	 * attribute of the mediator
	 */
	private Map<String, Value> pName2ExpressionMap;

	private boolean dynamicMediator = false;

	/** The local registry key which is used to pick a sequence definition */
	private Value key = null;

    /** Reference to the synapse environment */
    private SynapseEnvironment synapseEnv;

	public InvokeMediator() {
		// LinkedHashMap is used to preserve tag order
		pName2ExpressionMap = new LinkedHashMap<String, Value>();
	}

    public boolean mediate(MessageContext synCtx) {
        return mediate(synCtx, true);
    }

	private boolean mediate(MessageContext synCtx, boolean executePreFetchingSequence) {
		SynapseLog synLog = getLog(synCtx);

		if (synLog.isTraceOrDebugEnabled()) {
			synLog.traceOrDebug("Invoking Target EIP Sequence " + targetTemplate +
			                    " paramNames : " + pName2ExpressionMap.keySet());
			if (synLog.isTraceTraceEnabled()) {
				synLog.traceTrace("Message : " + synCtx.getEnvelope());
			}
		}
		// get the target function template and invoke by passing populated
		// parameters
		Mediator mediator = synCtx.getSequenceTemplate(targetTemplate);

		if (this.isDynamicMediator() && mediator ==null) {
			handleException("Failed to locate the configure element for connector [" +
			                targetTemplate + "]", synCtx);
		}

		// executing key reference if found defined at configuration.
		if (executePreFetchingSequence && key != null) {
			String defaultConfiguration = key.evaluateValue(synCtx);
			Mediator m = synCtx.getDefaultConfiguration(defaultConfiguration);
			if (m == null) {
				handleException("Sequence named " + key + " cannot be found", synCtx);

			} else {
				if (synLog.isTraceOrDebugEnabled()) {
					synLog.traceOrDebug("Executing with key " + key);
				}
                ContinuationStackManager.addReliantContinuationState(
                        synCtx, 1, getMediatorPosition());
				boolean result = m.mediate(synCtx);

                if (result) {
                    ContinuationStackManager.removeReliantContinuationState(synCtx);
                } else {
                    return false;
                }
            }
		}

		if (mediator != null && mediator instanceof TemplateMediator) {
			populateParameters(synCtx, ((TemplateMediator) mediator).getName());
            if (executePreFetchingSequence) {
                ContinuationStackManager.addReliantContinuationState(
                        synCtx, 0, getMediatorPosition());
            }
            boolean result = mediator.mediate(synCtx);
			if (result && executePreFetchingSequence) {
				ContinuationStackManager.removeReliantContinuationState(synCtx);
			}
			return result;
		}
		return false;
	}

    public boolean mediate(MessageContext synCtx, ContinuationState continuationState) {
        SynapseLog synLog = getLog(synCtx);

        if (synLog.isTraceOrDebugEnabled()) {
            synLog.traceOrDebug("Invoke mediator : Mediating from ContinuationState");
        }

        boolean result;
        int subBranch = ((ReliantContinuationState) continuationState).getSubBranch();

        if (subBranch == 0) {
             // Default flow
            TemplateMediator templateMediator =
                                        (TemplateMediator) synCtx.getSequenceTemplate(targetTemplate);

            if (!continuationState.hasChild()) {
                result = templateMediator.mediate(synCtx, continuationState.getPosition() + 1);
                if (result) {
                    templateMediator.popFuncContextFrom(synCtx);
                }
            } else {
                FlowContinuableMediator mediator =
                        (FlowContinuableMediator) templateMediator.getChild(
                                continuationState.getPosition());
                result = mediator.mediate(synCtx, continuationState.getChildContState());
            }
        } else {
            // Pre fetching invoke mediator flow
            String prefetchInvokeKey = key.evaluateValue(synCtx);
            InvokeMediator prefetchInvoke =
                    (InvokeMediator) synCtx.getDefaultConfiguration(prefetchInvokeKey);

            ContinuationState childContinuationState = continuationState.getChildContState();
            result = prefetchInvoke.mediate(synCtx, childContinuationState);

            if (result && !childContinuationState.hasChild()) {
                // Pre fetching invoke mediator flow completed.
                // Remove ContinuationState represent the prefetchInvoke mediator and
                // flip the subbranch to default flow
                continuationState.removeLeafChild();
                ((ReliantContinuationState) continuationState).setSubBranch(0);
                // after prefetch invoke mediator flow, execute default flow
                result = mediate(synCtx, false);
            }
        }
        return result;
    }

	/**
	 * poplulate declared parameters on temp synapse properties
	 *
	 * @param synCtx
	 * @param templateQualifiedName
	 */
	private void populateParameters(MessageContext synCtx, String templateQualifiedName) {
		Iterator<String> params = pName2ExpressionMap.keySet().iterator();
		while (params.hasNext()) {
			String parameter = params.next();
			if (!"".equals(parameter)) {
				Value expression = pName2ExpressionMap.get(parameter);
				if (expression != null) {
					EIPUtils.createSynapseEIPTemplateProperty(synCtx, templateQualifiedName,
					                                          parameter, expression);
				}
			}
		}
	}

	public String getTargetTemplate() {
		return targetTemplate;
	}

	public void setTargetTemplate(String targetTemplate) {
		this.targetTemplate = targetTemplate;
	}

	public Map<String, Value> getpName2ExpressionMap() {
		return pName2ExpressionMap;
	}

	public void addExpressionForParamName(String pName, Value expr) {
		pName2ExpressionMap.put(pName, expr);
	}

	public boolean isDynamicMediator() {
		return dynamicMediator;
	}

	public void setDynamicMediator(boolean dynamicMediator) {
		this.dynamicMediator = dynamicMediator;
	}

	public Value getKey() {
		return key;
	}

	public void setKey(Value key) {
		this.key = key;
	}

	public String getPackageName() {
		return packageName;
	}

	public void setPackageName(String packageName) {
		this.packageName = packageName;
	}

    public void init(SynapseEnvironment se) {
        synapseEnv = se;

        TemplateMediator templateMediator =
                se.getSynapseConfiguration().getSequenceTemplate(targetTemplate);
        if (templateMediator == null || templateMediator.isDynamic()) {
            // undefined or dynamic templates are treated as unavailable
            // in the environment.
            // At the time of their initialization, these will be marked as available.
            se.addUnavailableArtifactRef(targetTemplate);
        }
    }

    public void destroy() {
        TemplateMediator templateMediator =
                synapseEnv.getSynapseConfiguration().getSequenceTemplate(targetTemplate);
        if (templateMediator == null || templateMediator.isDynamic()) {
            synapseEnv.removeUnavailableArtifactRef(targetTemplate);
        }
    }
}


text:
from distutils.core import setup
#from setuptools import setup
import sys, os, os.path
import zipfile

import config
config = config.Config()

version = str(config.version)

### this manifest enables the standard Windows XP-looking theme
##manifest = """
##<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
##<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
##manifestVersion="1.0">
##<assemblyIdentity
##    version="0.64.1.0"
##    processorArchitecture="x86"
##    name="Controls"
##    type="win32"
##/>
##<description>Picalo</description>
##<dependency>
##    <dependentAssembly>
##        <assemblyIdentity
##            type="win32"
##            name="Microsoft.Windows.Common-Controls"
##            version="6.0.0.0"
##            processorArchitecture="X86"
##            publicKeyToken="6595b64144ccf1df"
##            language="*"
##        />
##    </dependentAssembly>
##</dependency>
##</assembly>
##"""
##
# returns a list of all the files in a directory tree
def walk_dir(dirname):
    files = []
    ret = (dirname, files)
    for name in os.listdir(dirname):
        fullname = os.path.join(dirname, name)
        if os.path.isdir(fullname) and os.path.split(fullname)[1] != ".svn":
            ret.extend(walk_dir(fullname))
        else:
            if os.path.split(fullname)[1] != ".svn":
                files.append(fullname)
    return ret

# Generic options
options = {
    "name":             "TileCutter",
    "version":          version,
    "description":      "Simutrans Building Editor",
    "long_description": "",
    "author":           "Timothy Baldock",
    "author_email":     "timothy@baldock.me",
    "url":              "http://timothy.baldock.me/tilecutter",
    "zipfile":          "python\\library.zip",
    "data_files":       [
                         ("", ["licence.txt", "test.png"]),
                         walk_dir("languages"),
                         ]
}

# Pre-setup actions (py2exe, py2app & source preparation)

# Source distribution specific
if len(sys.argv) >= 2 and sys.argv[1] == "source":
    print "Running source distribution"
    try:
        import shutil
    except ImportError:
        print "Could not import shutil module. Aborting source distribution creation"
        sys.exit(1)

    dist_dir = os.path.join("..", "dist", "src_dist_%s" % version)
    dist_zip = os.path.join("..", "dist", "TileCutter_src_%s.zip" % version)

    for recdir in ["translator", "languages", "tcui"]:
        print "Copying contents of: %s/" % recdir
        shutil.copytree(recdir, os.path.join(dist_dir, recdir), ignore=shutil.ignore_patterns(".svn", "tmp*", "*.pyc", "*.py~", "*.tab~"))

    for distfile in ["config.py", "imres.py", "licence.txt", "environment.py", "logger.py", "tcp.py", "tc.py", "project.py", "tcproject.py", "test.png", "tilecutter.py", "tilecutter.pyw", "main.py"]:
        print "Copying file: %s" % distfile
        shutil.copy(distfile, dist_dir)

    # After building this, run post-setup actions (e.g. creating distribution packages etc.)
    # Produce .zip file
    print "Adding distribution files to .zip..."
    zip = zipfile.ZipFile(dist_zip, "w", zipfile.ZIP_DEFLATED)
    for root, dirs, files in os.walk(dist_dir):
        for name in files:
            fn = os.path.join(root, name)
            rel_fn = os.path.relpath(os.path.join(root, name), dist_dir)
            print "  Adding \"%s\" to zip as \"%s\"" % (fn, rel_fn)
            zip.write(fn, rel_fn)
    zip.close()

# Windows specific
if len(sys.argv) >= 2 and sys.argv[1] == "py2exe":
    print "Running py2exe distribution"
    try:
        import py2exe
    except ImportError:
        print "Could not import py2exe. Aborting windows exe output"
        sys.exit(1)

    dist_dir = os.path.join("..", "dist", "win_dist_%s" % version)
    dist_zip = os.path.join("..", "dist", "TileCutter_win_%s.zip" % version)
    dist_msi = os.path.join("..", "dist", "TileCutter_win_%s.msi" % version)

    options["windows"] = [
        {
        "script":"tilecutter.py",
        "windows":"tilecutter.py",
        "icon_resources": [(1, "graphics/tilecutter.ico"),(42, "graphics/tcp.ico")],
        "copyright": "2008-2012 Timothy Baldock. All Rights Reserved.",
        },
    ]
#    options["data_files"] += [("", ["../dist/msvcp71.dll"]]
    options["options"] = {
        # Bundling of .dlls into the zip results in massively bigger package?!
        # Option 1 creates corrupt zip, option 2 adds dlls and makes them uncompressible
        "py2exe": {"dist_dir": dist_dir,
            "bundle_files": 3,
            "excludes": ["difflib", "doctest", "calendar", "pdb", "inspect",
                        "Tkconstants", "Tkinter", "tcl"],
            "dll_excludes": ["w9xpopen.exe",],
        },
    }

    # run the setup
    setup(**options)

    # After building this, run post-setup actions (e.g. creating distribution packages etc.)
    # Produce .zip file
    print "Adding distribution files to .zip..."
    zip = zipfile.ZipFile(dist_zip, "w", zipfile.ZIP_DEFLATED)
    for root, dirs, files in os.walk(dist_dir):
        for name in files:
            fn = os.path.join(root, name)
            rel_fn = os.path.relpath(os.path.join(root, name), dist_dir)
            print "  Adding \"%s\" to zip as \"%s\"" % (fn, rel_fn)
            zip.write(fn, rel_fn)
    zip.close()

    # Next, create MSI distribution

# OSX specific
if len(sys.argv) >= 2 and sys.argv[1] == "py2app":
    print "Running py2app distribution"
    try:
        import py2app
    except ImportError:
        print "Could not import py2app.   Mac bundle could not be built."
        sys.exit(1)

    dist_dir = os.path.join("..", "dist", "osx_dist_%s" % version)
    dist_dmg = os.path.join("..", "dist", "TileCutter_osx_%s.dmg" % version)

    # See: http://developer.apple.com/library/mac/#documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html
    # http://stackoverflow.com/questions/1771601/registering-an-icon-for-my-applications-document-type

    # Bindings to allow drag+drop of project files onto icon
    # Also registers filetype with OSX
    plist = {
                "CFBundleIdentifier": u"uk.me.entropy.tilecutter",
                "CFBundleGetInfoString": u"Simutrans Building Editor",
                "NSHumanReadableCopyright": u"Copyright © 2008-2012 Timothy Baldock. All Rights Reserved.",
                "CFBundleDocumentTypes": [
                    {
                        "CFBundleTypeName": u"TileCutter Project Document",
                        "CFBundleTypeRole": u"Editor",
                        "CFBundleTypeExtensions": [u"tcp",],
                        "LSItemContentTypes": [u"uk.me.entropy.tcp",],
                        "CFBundleTypeIconFile": u"tcp.icns",
                    },
                ],
                "UTExportedTypeDeclarations": [
                    {
                        "UTTypeIdentifier": u"uk.me.entropy.tcp",
                        "UTTypeReferenceURL": u"http://entropy.me.uk/tilecutter/docs/tcpformat/",
                        "UTTypeDescription": u"TileCutter Project File",
                        "UTTypeIconFile": u"tcp.icns",
                        "UTTypeConformsTo": [u"public.data",],
                        "UTTypeTagSpecification": {
                            "com.apple.ostype": u"TCPF",
                            "public.filename-extension": [u"tcp",],
                            "public.mimetype": u"application/x-tilecutter-project",
                        },
                    },
                ],
            }

    # mac-specific options
    options["app"] = ["tilecutter.py"]
    options["options"] = {
        "py2app": {
            "arch": "i386",
            "dist_dir": dist_dir,
            "argv_emulation": True,
            "iconfile": "graphics/tilecutter.icns",
            "packages": [],
            "excludes": ["difflib", "doctest", "calendar", "pdb", "inspect",
                        "Tkconstants", "Tkinter", "tcl"],
            "site_packages": True,
            "resources": ["graphics/tcp.icns",],
            "plist": plist,
            }
    }
    options["setup_requires"] = ["py2app"]
    # run the setup
    setup(**options)

    # See: http://digital-sushi.org/entry/how-to-create-a-disk-image-installer-for-apple-mac-os-x/

    # Next run shell commands to interact with the .dmg package
    # Copy .dmg from location in source control to dist directory
    # Convert to sparseimage
    # Remove .dmg from dist
    # Mount sparseimage
    # Copy application bundle into sparseimage (to replace placeholder)
    # Unmount sparseimage
    # Convert to .dmg + compress


text:
Works with [Bootstrap](http://getbootstrap.com/). Works with IE8 and above, must include [Respond.js](https://github.com/scottjehl/Respond) for IE8 to work:

```
	<!--[if lt IE 9]>
	  <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
	  <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
	<![endif]-->
```

Getting Started
======

To install Angular Mosaic, you can simply use bower:

```
bower install angular-mosaic --save
```

Inject angular-mosaic module into your angular app
```
angular.module('myApp', ['codinghitchhiker.mosaic']);
```

Mosaic works very similarly to [ng-repeat](https://code.angularjs.org/1.3.4/docs/api/ng/directive/ngRepeat), except that it doesn't repeat the element that it's on, instead it uses the transcluded element(s) within mosaic.  A quick example of this:

```
$scope.entities = ['one', 'two', 'three', 'four']
```

Then in your template file, add a simple iterator

```
	<ul mosaic="entity in entities">
		<li>{{entity}}</li>
	</ul>
```

This will work the same as an ng-repeat since it will only have one column because the css file hasn't been set.  For Mosaic to be compatible with all browsers and to exclude the need for javascript to duplicate css media queries logic, a 'layout' element is added within Mosaic.  Depending on the width of this layout element, it will set the amount of columns to display within mosaic

Example
======

[You can play with it via this JSFiddle](https://jsfiddle.net/yzr9oevn/7/)


text:
using OpenSage.Data.Ini;

namespace OpenSage.Logic.Object
{
    [AddedIn(SageGame.Bfme)]
    public sealed class DominateEnemySpecialPowerModuleData : SpecialPowerModuleData
    {
        internal static new DominateEnemySpecialPowerModuleData Parse(IniParser parser) => parser.ParseBlock(FieldParseTable);

        private static new readonly IniParseTable<DominateEnemySpecialPowerModuleData> FieldParseTable = SpecialPowerModuleData.FieldParseTable
            .Concat(new IniParseTable<DominateEnemySpecialPowerModuleData>
            {
                { "UnpackingVariation", (parser, x) => x.UnpackingVariation = parser.ParseInteger() },
                { "StartAbilityRange", (parser, x) => x.StartAbilityRange = parser.ParseFloat() },
                { "DominateRadius", (parser, x) => x.DominateRadius = parser.ParseInteger() },
                { "DominatedFX", (parser, x) => x.DominatedFX = parser.ParseAssetReference() },
                { "UnpackTime", (parser, x) => x.UnpackTime = parser.ParseInteger() },
                { "PreparationTime", (parser, x) => x.PreparationTime = parser.ParseInteger() },
                { "FreezeAfterTriggerDuration", (parser, x) => x.FreezeAfterTriggerDuration = parser.ParseInteger() },
                { "PermanentlyConvert", (parser, x) => x.PermanentlyConvert = parser.ParseBoolean() },
                { "TriggerSound", (parser, x) => x.TriggerSound = parser.ParseAssetReference() },
                { "TriggerModelCondition", (parser, x) => x.TriggerModelCondition = parser.ParseAttributeEnum<ModelConditionFlag>("ModelConditionState") },
                { "TriggerModelConditionDuration", (parser, x) => x.TriggerModelConditionDuration = parser.ParseInteger() }
            });

        public int UnpackingVariation { get; private set; }
        public float StartAbilityRange { get; private set; }
        public int DominateRadius { get; private set; }
        public string DominatedFX { get; private set; }
        public int UnpackTime { get; private set; }
        public int PreparationTime { get; private set; }
        public int FreezeAfterTriggerDuration { get; private set; }

        [AddedIn(SageGame.Bfme2)]
        public bool PermanentlyConvert { get; private set; }

        [AddedIn(SageGame.Bfme2)]
        public string TriggerSound { get; private set; }

        [AddedIn(SageGame.Bfme2Rotwk)]
        public ModelConditionFlag TriggerModelCondition { get; private set; }

        [AddedIn(SageGame.Bfme2Rotwk)]
        public int TriggerModelConditionDuration { get; private set; }
    }
}


text:
trait A { }

impl A for isize {
    const BAR: () = (); //~ ERROR const `BAR` is not a member of trait `A`
    type Baz = (); //~ ERROR type `Baz` is not a member of trait `A`
    fn foo(&self) { } //~ ERROR method `foo` is not a member of trait `A`
}

fn main() { }


text:
@implementation KintoneFieldCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        //
    }
    return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (void)setValueWithKintoneField:(KintoneField *)field form:(NSDictionary *)form
{
    self.textLabel.text = @"(unsupported field)";
}

- (CGFloat)height:(CGSize)maxSize
{
    return self.frame.size.height;
}

@end


text:
@interface WBSPostCell : UITableViewCell

@property (nonatomic, strong) WBSPostModel *postModel;  //!< 单条数据

@property (nonatomic, assign) CGFloat cellHeight;  //!< cell高度

@end