anchor.diff:      //   $call3(x, y, z) { return self[name](x, y, z); }
       // }
   
  -    // TODO(floitsch): share the closure classes with other classes
  -    // if they share methods with the same signature. Currently we do this only
  -    // if there are no optional parameters. Closures with optional parameters
  -    // are more difficult to canonicalize because they would need to have the
  -    // same default values.
  -
       bool hasOptionalParameters = member.optionalParameterCount(compiler) != 0;
       int parameterCount = member.parameterCount(compiler);
   
  -    Map<int, String> cache;
       // Intercepted methods take an extra parameter, which is the
       // receiver of the call.
       bool inInterceptor = backend.isInterceptedMethod(member);
  -    if (inInterceptor) {
  -      cache = interceptorClosureCache;
  -    } else {
  -      cache = boundClosureCache;
  -    }
       List<String> fieldNames = <String>[];
       compiler.boundClosureClass.forEachInstanceField((_, Element field) {
         fieldNames.add(namer.getNameOfInstanceMember(field));
       });
   
  +    ClassElement classElement = member.getEnclosingClass();
  +    String name = inInterceptor
  +        ? 'BoundClosure\$i${parameterCount}'
  +        : 'BoundClosure\$${parameterCount}';
  +
  +    ClassElement closureClassElement = new ClosureClassElement(
  +        null, new SourceString(name), compiler, member,
  +        member.getCompilationUnit());
  +    String superName = namer.getNameOfClass(closureClassElement.superclass);
  +
  +    // Define the constructor with a name so that Object.toString can
  +    // find the class name of the closure class.
  +    ClassBuilder boundClosureBuilder = new ClassBuilder();
  +    boundClosureBuilder.addProperty('',
  +        js.string("$superName;${fieldNames.join(',')}"));
  +    // Now add the methods on the closure class. The instance method does not
  +    // have the correct name. Since [addParameterStubs] use the name to create
  +    // its stubs we simply create a fake element with the correct name.
  +    // Note: the callElement will not have any enclosingElement.
  +    FunctionElement callElement = new ClosureInvocationElement(
  +        namer.closureInvocationSelectorName, member);
  +
  +    String invocationName = namer.instanceMethodName(callElement);
  +
  +    List<String> parameters = <String>[];
  +    List<jsAst.Expression> arguments =
  +        <jsAst.Expression>[js('this')[fieldNames[0]]];
  +    if (inInterceptor) {
  +      arguments.add(js('this')[fieldNames[2]]);
  +    }
  +    for (int i = 0; i < parameterCount; i++) {
  +      String name = 'p$i';
  +      parameters.add(name);
  +      arguments.add(js(name));
  +    }
  +
  +    jsAst.Expression fun = js.fun(
  +        parameters,
  +        js.return_(
  +            js('this')[fieldNames[1]]['call'](arguments)));
  +    boundClosureBuilder.addProperty(invocationName, fun);
  +
  +    addParameterStubs(callElement, boundClosureBuilder.addProperty);
  +
  +    void emitFunctionTypeSignature(Element method, FunctionType methodType) {
  +      jsAst.Expression encoding = backend.rti.getSignatureEncoding(
  +          methodType, js('this')[fieldNames[0]]);
  +      String operatorSignature = namer.operatorSignature();
  +      boundClosureBuilder.addProperty(operatorSignature, encoding);
  +    }
  +
  +    void emitIsFunctionTypeTest(FunctionType functionType) {
  +      String operator = namer.operatorIsType(functionType);
  +      boundClosureBuilder.addProperty(operator,
  +          new jsAst.LiteralBool(true));
  +    }
  +
       DartType memberType = member.computeType(compiler);
       Map<FunctionType, bool> functionTypeChecks =
           getFunctionTypeChecksOn(memberType);
  -    bool hasFunctionTypeChecks = !functionTypeChecks.isEmpty;
  -
  -    bool canBeShared = !hasOptionalParameters && !hasFunctionTypeChecks;
  -
  -    ClassElement classElement = member.getEnclosingClass();
  -    String closureClass = canBeShared ? cache[parameterCount] : null;
  -    if (closureClass == null) {
  -      // Either the class was not cached yet, or there are optional parameters.
  -      // Create a new closure class.
  -      String name;
  -      if (canBeShared) {
  -        if (inInterceptor) {
  -          name = 'BoundClosure\$i${parameterCount}';
  -        } else {
  -          name = 'BoundClosure\$${parameterCount}';
  -        }
  -      } else {
  -        name = 'Bound_${member.name.slowToString()}'
  -            '_${member.enclosingElement.name.slowToString()}';
  -      }
  -
  -      ClassElement closureClassElement = new ClosureClassElement(
  -          null, new SourceString(name), compiler, member,
  -          member.getCompilationUnit());
  -      String mangledName = namer.getNameOfClass(closureClassElement);
  -      String superName = namer.getNameOfClass(closureClassElement.superclass);
  -
  -      // Define the constructor with a name so that Object.toString can
  -      // find the class name of the closure class.
  -      ClassBuilder boundClosureBuilder = new ClassBuilder();
  -      emitClosureClassHeader(
  -          mangledName, superName, fieldNames, boundClosureBuilder);
  -      // Now add the methods on the closure class. The instance method does not
  -      // have the correct name. Since [addParameterStubs] use the name to create
  -      // its stubs we simply create a fake element with the correct name.
  -      // Note: the callElement will not have any enclosingElement.
  -      FunctionElement callElement =
  -          new ClosureInvocationElement(namer.closureInvocationSelectorName,
  -                                       member);
  -
  -      String invocationName = namer.instanceMethodName(callElement);
  -
  -      List<String> parameters = <String>[];
  -      List<jsAst.Expression> arguments = <jsAst.Expression>[];
  -      arguments.add(js('this')[fieldNames[0]]);
  -      if (inInterceptor) {
  -        arguments.add(js('this')[fieldNames[2]]);
  -      }
  -      for (int i = 0; i < parameterCount; i++) {
  -        String name = 'p$i';
  -        parameters.add(name);
  -        arguments.add(js(name));
  -      }
  -
  -      jsAst.Expression fun = js.fun(
  -          parameters,
  -          js.return_(
  -              js('this')[fieldNames[1]]['call'](arguments)));
  -      boundClosureBuilder.addProperty(invocationName, fun);
  -
  -      addParameterStubs(callElement, boundClosureBuilder.addProperty);
  -
  -      void emitFunctionTypeSignature(Element method, FunctionType methodType) {
  -        jsAst.Expression encoding = backend.rti.getSignatureEncoding(
  -            methodType, js('this')[fieldNames[0]]);
  -        String operatorSignature = namer.operatorSignature();
  -        boundClosureBuilder.addProperty(operatorSignature, encoding);
  -      }
  -
  -      void emitIsFunctionTypeTest(FunctionType functionType) {
  -        String operator = namer.operatorIsType(functionType);
  -        boundClosureBuilder.addProperty(operator,
  -            new jsAst.LiteralBool(true));
  -      }
  -
  -      generateFunctionTypeTests(member, memberType, functionTypeChecks,
  -          emitFunctionTypeSignature, emitIsFunctionTypeTest);
  -
  -      boundClosures.add(
  -          js('$classesCollector.$mangledName = #',
  -             js('[${namer.globalObjectFor(closureClassElement)}, #]',
  -                boundClosureBuilder.toObjectInitializer())));
  -
  -      closureClass = namer.isolateAccess(closureClassElement);
  -
  -      // Cache it.
  -      if (canBeShared) {
  -        cache[parameterCount] = closureClass;
  -      }
  -    }
  +
  +    generateFunctionTypeTests(member, memberType, functionTypeChecks,
  +        emitFunctionTypeSignature, emitIsFunctionTypeTest);
  +
  +    closureClassElement =
  +        addClosureIfNew(boundClosureBuilder, closureClassElement, fieldNames);
  +
  +    String closureClass = namer.isolateAccess(closureClassElement);
   
       // And finally the getter.
       String getterName = namer.getterName(member);
       String targetName = namer.instanceMethodName(member);
   
  -    List<String> parameters = <String>[];
  -    List<jsAst.Expression> arguments = <jsAst.Expression>[];
  -    arguments.add(js('this'));
  +    parameters = <String>[];
       jsAst.PropertyAccess method =
           backend.namer.elementAccess(classElement)['prototype'][targetName];
  -
  -    arguments.add(method);
  +    arguments = <jsAst.Expression>[js('this'), method];
  +
       if (inInterceptor) {
         String receiverArg = fieldNames[2];
         parameters.add(receiverArg);
  
positive.code:       }
  
        // Emit native classes on [nativeBuffer].
        // Might create boundClosures.
        final CodeBuffer nativeBuffer = new CodeBuffer();
        if (!nativeClasses.isEmpty) {
          addComment('Native classes', nativeBuffer);
  
negative.code:       nativeEmitter.finishGenerateNativeClasses();
        nativeEmitter.assembleCode(nativeBuffer);
  
        // Might create methodClosures.
        if (!deferredClasses.isEmpty) {
          for (ClassElement element in deferredClasses) {
            generateClass(element, bufferForElement(element, mainBuffer));
  