anchor.diff:                currentTypeParameters.length - type.paramReference]
             .type;
       } else {
  -      LinkedReference referenceResolution =
  -          linkedUnit.references[type.reference];
  -      String name;
  -      if (type.reference < unlinkedUnit.references.length) {
  -        name = unlinkedUnit.references[type.reference].name;
  -      } else {
  -        name = referenceResolution.name;
  -      }
  -      ElementLocationImpl location;
  -      if (referenceResolution.dependency != 0) {
  -        location = getReferencedLocation(
  -            linkedLibrary.dependencies[referenceResolution.dependency],
  -            referenceResolution.unit,
  -            name);
  -      } else if (referenceResolution.kind == ReferenceKind.unresolved) {
  -        return summaryResynthesizer.typeProvider.undefinedType;
  -      } else if (name == 'dynamic') {
  -        return summaryResynthesizer.typeProvider.dynamicType;
  -      } else if (name == 'void') {
  -        return VoidTypeImpl.instance;
  -      } else {
  -        String referencedLibraryUri = librarySource.uri.toString();
  -        String partUri;
  -        if (referenceResolution.unit != 0) {
  -          String uri = unlinkedUnits[0].publicNamespace.parts[
  -              referenceResolution.unit - 1];
  -          Source partSource =
  -              summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
  -          partUri = partSource.uri.toString();
  +      DartType getTypeParameter(int i) {
  +        if (i < type.typeArguments.length) {
  +          return buildType(type.typeArguments[i]);
           } else {
  -          partUri = referencedLibraryUri;
  +          return summaryResynthesizer.typeProvider.dynamicType;
           }
  -        location = new ElementLocationImpl.con3(
  -            <String>[referencedLibraryUri, partUri, name]);
  -      }
  -      List<DartType> typeArguments = const <DartType>[];
  -      if (referenceResolution.numTypeParameters != 0) {
  -        typeArguments = <DartType>[];
  -        for (int i = 0; i < referenceResolution.numTypeParameters; i++) {
  -          if (i < type.typeArguments.length) {
  -            typeArguments.add(buildType(type.typeArguments[i]));
  -          } else {
  -            typeArguments.add(summaryResynthesizer.typeProvider.dynamicType);
  -          }
  -        }
  -      }
  -      switch (referenceResolution.kind) {
  -        case ReferenceKind.classOrEnum:
  -          return new InterfaceTypeImpl.elementWithNameAndArgs(
  -              new ClassElementHandle(summaryResynthesizer, location),
  -              name,
  -              typeArguments);
  -        case ReferenceKind.typedef:
  -          return new FunctionTypeImpl.elementWithNameAndArgs(
  -              new FunctionTypeAliasElementHandle(
  -                  summaryResynthesizer, location),
  -              name,
  -              typeArguments,
  -              typeArguments.isNotEmpty);
  -        default:
  -          // TODO(paulberry): figure out how to handle this case (which should
  -          // only occur in the event of erroneous code).
  -          throw new UnimplementedError();
  -      }
  +      }
  +      _ReferenceInfo referenceInfo = referenceInfos[type.reference];
  +      return referenceInfo.buildType(getTypeParameter);
       }
     }
   
  
positive.code:   }
  
    /**
     * Populate a [CompilationUnitElement] by deserializing all the elements
     * contained in it.
     */
  
negative.code:     linkedUnit = null;
      unlinkedUnit = null;
      linkedTypeMap = null;
      referenceInfos = null;
    }
  }
  
  /**
   * Data structure used during resynthesis to record all the information that is
   * known about how to reserialize a single entry in [LinkedUnit.references]
   * (and its associated entry in [UnlinkedUnit.references], if it exists).
   */
  class _ReferenceInfo {
    /**
     * The name of the entity referred to by this reference.
     */
    final String name;
  
    /**
     * The element referred to by this reference, or `null` if there is no
     * associated element (e.g. because it is a reference to an undefined
     * entity).
     */
    final ElementHandle element;
  
    /**
     * If this reference refers to a non-generic type, the type it refers to.
     * Otherwise `null`.
     */
    DartType type;
  
    /**
     * The number of type parameters accepted by the entity referred to by this
     * reference, or zero if it doesn't accept any type parameters.
     */
    final int numTypeParameters;
  
    /**
     * Create a new [_ReferenceInfo] object referring to an element called [name]
     * via the element handle [elementHandle], and having [numTypeParameters]
     * type parameters.
     *
     * For the special types `dynamic` and `void`, [specialType] should point to
     * the type itself.  Otherwise, pass `null` and the type will be computed
     * when appropriate.
     */
    _ReferenceInfo(
        this.name, this.element, DartType specialType, this.numTypeParameters) {
      if (specialType != null) {
        type = specialType;
      } else if (numTypeParameters == 0) {
        // We can precompute the type because it doesn't depend on type
        // parameters.
        type = _buildType(null);
      }
    }
  
    /**
     * Build a [DartType] corresponding to the result of applying some type
     * arguments to the entity referred to by this [_ReferenceInfo].  The type
     * arguments are retrieved by calling [getTypeArgument].
     *
     * If the entity referred to by this [_ReferenceInfo] is not a type, `null`
     * is returned.
     */
    DartType buildType(DartType getTypeArgument(int i)) {
      DartType result =
          numTypeParameters == 0 ? type : _buildType(getTypeArgument);
      if (result == null) {
        // TODO(paulberry): figure out how to handle this case (which should
        // only occur in the event of erroneous code).
        throw new UnimplementedError();
      }
      return result;
    }
  
    /**
     * If this reference refers to a type, build a [DartType] which instantiates
     * it with type arguments returned by [getTypeArgument].  Otherwise return
     * `null`.
     */
    DartType _buildType(DartType getTypeArgument(int i)) {
      List<DartType> typeArguments = const <DartType>[];
      if (numTypeParameters != 0) {
        typeArguments = <DartType>[];
        for (int i = 0; i < numTypeParameters; i++) {
          typeArguments.add(getTypeArgument(i));
        }
      }
      ElementHandle element = this.element; // To allow type promotion
      if (element is ClassElementHandle) {
        return new InterfaceTypeImpl.elementWithNameAndArgs(
            element, name, typeArguments);
      } else if (element is FunctionTypeAliasElementHandle) {
        return new FunctionTypeImpl.elementWithNameAndArgs(
            element, name, typeArguments, typeArguments.isNotEmpty);
      } else {
        return null;
      }
    }
  }
  