hunk.code_window:     if ([self _areDevToolsEnabledWithManifest:cachedManifest]) {
         [self _resolveManifestAndBundleWithTimeout:NO length:0];
         return;
       } else {
         id updates = _confirmedManifest[@"updates"];
         if (updates && [updates isKindOfClass:[NSDictionary class]]) {
           NSDictionary *updatesDict = (NSDictionary *)updates;
           id checkAutomaticallyVal = updatesDict[@"checkAutomatically"];
           if (checkAutomaticallyVal && [checkAutomaticallyVal isKindOfClass:[NSString class]] && [(NSString *)checkAutomaticallyVal isEqualToString:@"never"]) {
  
hunk.labels: keep keep keep keep add keep keep keep keep
hunk.after_edit:       id ios = _confirmedManifest[@"ios"];
  
hunk.file_path: ios/Exponent/Kernel/AppLoader/EXKernelAppLoader.m
hunk.type: add
file: /**
   * Copyright (c) 2015-present, Facebook, Inc.
   * All rights reserved.
   *
   * This source code is licensed under the BSD-style license found in the
   * LICENSE file in the root directory of this source tree. An additional grant
   * of patent rights can be found in the PATENTS file in the same directory.
   */
  
  #import "ABI23_0_0RCTParserUtils.h"
  
  #import "ABI23_0_0RCTLog.h"
  
  @implementation ABI23_0_0RCTParserUtils
  
  BOOL ABI23_0_0RCTReadChar(const char **input, char c)
  {
    if (**input == c) {
      (*input)++;
      return YES;
    }
    return NO;
  }
  
  BOOL ABI23_0_0RCTReadString(const char **input, const char *string)
  {
    int i;
    for (i = 0; string[i] != 0; i++) {
      if (string[i] != (*input)[i]) {
        return NO;
      }
    }
    *input += i;
    return YES;
  }
  
  void ABI23_0_0RCTSkipWhitespace(const char **input)
  {
    while (isspace(**input)) {
      (*input)++;
    }
  }
  
  static BOOL ABI23_0_0RCTIsIdentifierHead(const char c)
  {
    return isalpha(c) || c == '_';
  }
  
  static BOOL ABI23_0_0RCTIsIdentifierTail(const char c)
  {
    return isalnum(c) || c == '_';
  }
  
  BOOL ABI23_0_0RCTParseArgumentIdentifier(const char **input, NSString **string)
  {
    const char *start = *input;
  
    do {
      if (!ABI23_0_0RCTIsIdentifierHead(**input)) {
        return NO;
      }
      (*input)++;
  
      while (ABI23_0_0RCTIsIdentifierTail(**input)) {
        (*input)++;
      }
  
    // allow namespace resolution operator
    } while (ABI23_0_0RCTReadString(input, "::"));
  
    if (string) {
      *string = [[NSString alloc] initWithBytes:start
                                         length:(NSInteger)(*input - start)
                                       encoding:NSASCIIStringEncoding];
    }
    return YES;
  }
  
  BOOL ABI23_0_0RCTParseSelectorIdentifier(const char **input, NSString **string)
  {
    const char *start = *input;
    if (!ABI23_0_0RCTIsIdentifierHead(**input)) {
      return NO;
    }
    (*input)++;
    while (ABI23_0_0RCTIsIdentifierTail(**input)) {
      (*input)++;
    }
    if (string) {
      *string = [[NSString alloc] initWithBytes:start
                                         length:(NSInteger)(*input - start)
                                       encoding:NSASCIIStringEncoding];
    }
    return YES;
  }
  
  static BOOL ABI23_0_0RCTIsCollectionType(NSString *type)
  {
    static NSSet *collectionTypes;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
      collectionTypes = [[NSSet alloc] initWithObjects:
                         @"NSArray", @"NSSet", @"NSDictionary", nil];
    });
    return [collectionTypes containsObject:type];
  }
  
  NSString *ABI23_0_0RCTParseType(const char **input)
  {
    NSString *type;
    ABI23_0_0RCTParseArgumentIdentifier(input, &type);
    ABI23_0_0RCTSkipWhitespace(input);
    if (ABI23_0_0RCTReadChar(input, '<')) {
      ABI23_0_0RCTSkipWhitespace(input);
      NSString *subtype = ABI23_0_0RCTParseType(input);
      if (ABI23_0_0RCTIsCollectionType(type)) {
        if ([type isEqualToString:@"NSDictionary"]) {
          // Dictionaries have both a key *and* value type, but the key type has
          // to be a string for JSON, so we only care about the value type
          if (ABI23_0_0RCT_DEBUG && ![subtype isEqualToString:@"NSString"]) {
            ABI23_0_0RCTLogError(@"%@ is not a valid key type for a JSON dictionary", subtype);
          }
          ABI23_0_0RCTSkipWhitespace(input);
          ABI23_0_0RCTReadChar(input, ',');
          ABI23_0_0RCTSkipWhitespace(input);
          subtype = ABI23_0_0RCTParseType(input);
        }
        if (![subtype isEqualToString:@"id"]) {
          type = [type stringByReplacingCharactersInRange:(NSRange){0, 2 /* "NS" */}
                                               withString:subtype];
        }
      } else {
        // It's a protocol rather than a generic collection - ignore it
      }
      ABI23_0_0RCTSkipWhitespace(input);
      ABI23_0_0RCTReadChar(input, '>');
    }
    ABI23_0_0RCTSkipWhitespace(input);
    if (!ABI23_0_0RCTReadChar(input, '*')) {
      ABI23_0_0RCTReadChar(input, '&');
    }
    return type;
  }
  
  @end
  