anchor.diff:    return false;
   }
   
  -Token skipTypeVariables(Token token) {
  -  assert(optional('<', token));
  -  Token endGroup = token.endGroup;
  -  if (endGroup == null) {
  -    return null;
  -  }
  -
  -  // The scanner sets the endGroup in situations like this: C<T && T>U;
  -  // Scan the type arguments to assert there are no operators.
  -  // TODO(danrubel): Fix the scanner to do this scanning.
  -  token = token.next;
  -  while (token != endGroup) {
  -    if (token.isKeywordOrIdentifier ||
  -        optional(',', token) ||
  -        optional('.', token) ||
  -        optional('<', token) ||
  -        optional('>', token) ||
  -        optional('>>', token) ||
  -        optional('@', token)) {
  -      // ok
  -    } else if (optional('(', token)) {
  -      token = token.endGroup;
  -    } else {
  -      return null;
  -    }
  -    token = token.next;
  -  }
  -  return endGroup;
  -}
  -
   /// Instances of [ComplexTypeInfo] are returned by [computeType] to represent
   /// type references that cannot be represented by the constants above.
   class ComplexTypeInfo implements TypeInfo {
  
positive.code:     }
  
      for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
        parser.parseTypeVariablesOpt(t.head);
        parser.listener.beginFunctionType(start);
      }
  
  
negative.code:   /// The last token in the type reference.
    Token end;
  
    /// The `Function` tokens before the start of type variables of function types
    /// as seen during analysis.
    Link<Token> typeVariableStarters = const Link<Token>();
  
    /// If the receiver represents a generalized function type then this indicates
  