anchor.diff:      name = _unminifyOrTag(name);
       var arguments = Rti._getInterfaceTypeArguments(rti);
       if (arguments.length != 0) {
  -      name += '<';
  -      for (int i = 0; i < arguments.length; i++) {
  -        if (i > 0) name += ', ';
  -        name += _rtiToString(_castToRti(arguments[i]), genericContext);
  -      }
  -      name += '>';
  +      name += '<' + _rtiArrayToString(arguments, genericContext) + '>';
       }
       return name;
     }
   
     if (kind == Rti.kindFunction) {
  -    // TODO(fishythefish): Support required named parameters.
  -    Rti returnType = Rti._getReturnType(rti);
  -    var parameters = Rti._getFunctionParameters(rti);
  -    var requiredPositional =
  -        _FunctionParameters._getRequiredPositional(parameters);
  -    var requiredPositionalLength = _Utils.arrayLength(requiredPositional);
  -    var optionalPositional =
  -        _FunctionParameters._getOptionalPositional(parameters);
  -    var optionalPositionalLength = _Utils.arrayLength(optionalPositional);
  -    var optionalNamed = _FunctionParameters._getOptionalNamed(parameters);
  -    var optionalNamedLength = _Utils.arrayLength(optionalNamed);
  -    assert(optionalPositionalLength == 0 || optionalNamedLength == 0);
  -
  -    String s = _rtiToString(returnType, genericContext) + '(';
  -    String sep = '';
  -    for (int i = 0; i < requiredPositionalLength; i++) {
  -      s += sep +
  -          _rtiToString(_castToRti(_Utils.arrayAt(requiredPositional, i)),
  -              genericContext);
  -      sep = ', ';
  -    }
  -
  -    if (optionalPositionalLength > 0) {
  -      s += sep + '[';
  -      sep = '';
  -      for (int i = 0; i < optionalPositionalLength; i++) {
  -        s += sep +
  -            _rtiToString(_castToRti(_Utils.arrayAt(optionalPositional, i)),
  -                genericContext);
  -        sep = ', ';
  -      }
  -      s += ']';
  -    }
  -
  -    if (optionalNamedLength > 0) {
  -      s += sep + '{';
  -      sep = '';
  -      for (int i = 0; i < optionalNamedLength; i += 2) {
  -        s += sep +
  -            _Utils.asString(_Utils.arrayAt(optionalNamed, i)) +
  -            ': ' +
  -            _rtiToString(_castToRti(_Utils.arrayAt(optionalNamed, i + 1)),
  -                genericContext);
  -        sep = ', ';
  -      }
  -      s += '}';
  -    }
  -
  -    s += ')';
  -    return s;
  +    return _functionRtiToString(rti, genericContext);
  +  }
  +
  +  if (kind == Rti.kindGenericFunction) {
  +    Rti baseFunctionType = Rti._getGenericFunctionBase(rti);
  +    Object bounds = Rti._getGenericFunctionBounds(rti);
  +    return _functionRtiToString(baseFunctionType, genericContext,
  +        bounds: bounds);
  +  }
  +
  +  if (kind == Rti.kindGenericFunctionParameter) {
  +    int index = Rti._getGenericFunctionParameterIndex(rti);
  +    return genericContext[genericContext.length - 1 - index];
     }
   
     return '?';
  
positive.code:   throw _TypeError.forType(object, 'String');
  }
  
  String _rtiToString(Rti rti, List<String> genericContext) {
    int kind = Rti._getKind(rti);
  
  
negative.code:     if (_Utils.arrayLength(arguments) == 0) {
        return 'interface("$name")';
      } else {
        return 'interface("$name", ${_rtiArrayToDebugString(arguments)})';
      }
    }
  
    if (kind == Rti.kindBinding) {
      var base = Rti._getBindingBase(rti);
      var arguments = Rti._getBindingArguments(rti);
      return 'binding(${_rtiToDebugString(base)}, ${_rtiArrayToDebugString(arguments)})';
    }
  
    if (kind == Rti.kindFunction) {
      var returnType = Rti._getReturnType(rti);
      var parameters = Rti._getFunctionParameters(rti);
      return 'function(${_rtiToDebugString(returnType)}, ${functionParametersToString(parameters)})';
    }
  
    if (kind == Rti.kindGenericFunction) {
      Rti baseFunctionType = Rti._getGenericFunctionBase(rti);
      Object bounds = Rti._getGenericFunctionBounds(rti);
      return 'genericFunction(${_rtiToDebugString(baseFunctionType)}, ${_rtiArrayToDebugString(bounds)})';
    }
  
    if (kind == Rti.kindGenericFunctionParameter) {
      int index = Rti._getGenericFunctionParameterIndex(rti);
      return 'genericFunctionParameter($index)';
    }
  
    return 'other(kind=$kind)';
  