| Index: pkg/compiler/lib/src/serialization/equivalence.dart | 
| diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart | 
| index 5bc9d23bb8b85996ca9bbb5ae583135fbc08deae..f9b77dea1521200bc991e8442169a23dc28886e2 100644 | 
| --- a/pkg/compiler/lib/src/serialization/equivalence.dart | 
| +++ b/pkg/compiler/lib/src/serialization/equivalence.dart | 
| @@ -19,11 +19,8 @@ bool equality(a, b) => a == b; | 
|  | 
| /// Returns `true` if the elements in [a] and [b] are pair-wise equivalent | 
| /// according to [elementEquivalence]. | 
| -bool areListsEquivalent( | 
| -    List a, | 
| -    List b, | 
| +bool areListsEquivalent(List a, List b, | 
| [bool elementEquivalence(a, b) = equality]) { | 
| - | 
| if (a.length != b.length) return false; | 
| for (int i = 0; i < a.length && i < b.length; i++) { | 
| if (!elementEquivalence(a[i], b[i])) { | 
| @@ -35,9 +32,7 @@ bool areListsEquivalent( | 
|  | 
| /// Returns `true` if the elements in [a] and [b] are equivalent as sets using | 
| /// [elementEquivalence] to determine element equivalence. | 
| -bool areSetsEquivalent( | 
| -    Iterable set1, | 
| -    Iterable set2, | 
| +bool areSetsEquivalent(Iterable set1, Iterable set2, | 
| [bool elementEquivalence(a, b) = equality]) { | 
| Set remaining = set2.toSet(); | 
| for (var element1 in set1) { | 
| @@ -88,23 +83,23 @@ bool areTypeListsEquivalent(List<DartType> a, List<DartType> b) { | 
| } | 
|  | 
| /// Returns `true` if the lists of constants, [a] and [b], are equivalent. | 
| -bool areConstantListsEquivalent(List<ConstantExpression> a, | 
| -                                List<ConstantExpression> b) { | 
| +bool areConstantListsEquivalent( | 
| +    List<ConstantExpression> a, List<ConstantExpression> b) { | 
| return areListsEquivalent(a, b, areConstantsEquivalent); | 
| } | 
|  | 
| /// Returns `true` if the selectors [a] and [b] are equivalent. | 
| bool areSelectorsEquivalent(Selector a, Selector b) { | 
| return a.kind == b.kind && | 
| -         a.callStructure == b.callStructure && | 
| -         areNamesEquivalent(a.memberName, b.memberName); | 
| +      a.callStructure == b.callStructure && | 
| +      areNamesEquivalent(a.memberName, b.memberName); | 
| } | 
|  | 
| /// Returns `true` if the names [a] and [b] are equivalent. | 
| bool areNamesEquivalent(Name a, Name b) { | 
| return a.text == b.text && | 
| -         a.isSetter == b.isSetter && | 
| -         areElementsEquivalent(a.library, b.library); | 
| +      a.isSetter == b.isSetter && | 
| +      areElementsEquivalent(a.library, b.library); | 
| } | 
|  | 
| /// Returns `true` if the dynamic uses [a] and [b] are equivalent. | 
| @@ -114,28 +109,26 @@ bool areDynamicUsesEquivalent(DynamicUse a, DynamicUse b) { | 
|  | 
| /// Returns `true` if the static uses [a] and [b] are equivalent. | 
| bool areStaticUsesEquivalent(StaticUse a, StaticUse b) { | 
| -  return a.kind == b.kind && | 
| -         areElementsEquivalent(a.element, b.element); | 
| +  return a.kind == b.kind && areElementsEquivalent(a.element, b.element); | 
| } | 
|  | 
| /// Returns `true` if the type uses [a] and [b] are equivalent. | 
| bool areTypeUsesEquivalent(TypeUse a, TypeUse b) { | 
| -  return a.kind == b.kind && | 
| -         areTypesEquivalent(a.type, b.type); | 
| +  return a.kind == b.kind && areTypesEquivalent(a.type, b.type); | 
| } | 
|  | 
| /// Returns `true` if the list literal uses [a] and [b] are equivalent. | 
| bool areListLiteralUsesEquivalent(ListLiteralUse a, ListLiteralUse b) { | 
| return areTypesEquivalent(a.type, b.type) && | 
| -         a.isConstant == b.isConstant && | 
| -         a.isEmpty == b.isEmpty; | 
| +      a.isConstant == b.isConstant && | 
| +      a.isEmpty == b.isEmpty; | 
| } | 
|  | 
| /// Returns `true` if the map literal uses [a] and [b] are equivalent. | 
| bool areMapLiteralUsesEquivalent(MapLiteralUse a, MapLiteralUse b) { | 
| return areTypesEquivalent(a.type, b.type) && | 
| -         a.isConstant == b.isConstant && | 
| -         a.isEmpty == b.isEmpty; | 
| +      a.isConstant == b.isConstant && | 
| +      a.isEmpty == b.isEmpty; | 
| } | 
|  | 
| /// Strategy for testing equivalence. | 
| @@ -149,50 +142,41 @@ class TestStrategy { | 
| } | 
|  | 
| bool testLists( | 
| -      Object object1, Object object2, String property, | 
| -      List list1, List list2, | 
| +      Object object1, Object object2, String property, List list1, List list2, | 
| [bool elementEquivalence(a, b) = equality]) { | 
| return areListsEquivalent(list1, list2, elementEquivalence); | 
| } | 
|  | 
| bool testSets( | 
| -      var object1, var object2, String property, | 
| -      Iterable set1, Iterable set2, | 
| +      var object1, var object2, String property, Iterable set1, Iterable set2, | 
| [bool elementEquivalence(a, b) = equality]) { | 
| return areSetsEquivalent(set1, set2, elementEquivalence); | 
| } | 
|  | 
| -  bool testElements( | 
| -      Object object1, Object object2, String property, | 
| +  bool testElements(Object object1, Object object2, String property, | 
| Element element1, Element element2) { | 
| return areElementsEquivalent(element1, element2); | 
| } | 
|  | 
| -  bool testTypes( | 
| -      Object object1, Object object2, String property, | 
| +  bool testTypes(Object object1, Object object2, String property, | 
| DartType type1, DartType type2) { | 
| return areTypesEquivalent(type1, type2); | 
| } | 
|  | 
| -  bool testConstants( | 
| -      Object object1, Object object2, String property, | 
| +  bool testConstants(Object object1, Object object2, String property, | 
| ConstantExpression exp1, ConstantExpression exp2) { | 
| return areConstantsEquivalent(exp1, exp2); | 
| } | 
|  | 
| -  bool testTypeLists( | 
| -      Object object1, Object object2, String property, | 
| +  bool testTypeLists(Object object1, Object object2, String property, | 
| List<DartType> list1, List<DartType> list2) { | 
| return areTypeListsEquivalent(list1, list2); | 
| } | 
|  | 
| -  bool testConstantLists( | 
| -      Object object1, Object object2, String property, | 
| -      List<ConstantExpression> list1, | 
| -      List<ConstantExpression> list2) { | 
| +  bool testConstantLists(Object object1, Object object2, String property, | 
| +      List<ConstantExpression> list1, List<ConstantExpression> list2) { | 
| return areConstantListsEquivalent(list1, list2); | 
| } | 
| - | 
| } | 
|  | 
| /// Visitor that checks for equivalence of [Element]s. | 
| @@ -212,10 +196,8 @@ class ElementIdentityEquivalence extends BaseElementVisitor<bool, Element> { | 
| if (element1 == element2) { | 
| return true; | 
| } | 
| -    return | 
| -        strategy.test( | 
| -            element1, element2, 'kind', | 
| -            element1.kind, element2.kind) && | 
| +    return strategy.test( | 
| +            element1, element2, 'kind', element1.kind, element2.kind) && | 
| element1.accept(this, element2); | 
| } | 
|  | 
| @@ -226,34 +208,28 @@ class ElementIdentityEquivalence extends BaseElementVisitor<bool, Element> { | 
|  | 
| @override | 
| bool visitLibraryElement(LibraryElement element1, LibraryElement element2) { | 
| -    return | 
| -        strategy.test(element1, element2, | 
| -            'canonicalUri', | 
| -            element1.canonicalUri, element2.canonicalUri); | 
| +    return strategy.test(element1, element2, 'canonicalUri', | 
| +        element1.canonicalUri, element2.canonicalUri); | 
| } | 
|  | 
| @override | 
| -  bool visitCompilationUnitElement(CompilationUnitElement element1, | 
| -                                   CompilationUnitElement element2) { | 
| -    return | 
| -        strategy.test(element1, element2, | 
| -            'name', | 
| -            element1.name, element2.name) && | 
| +  bool visitCompilationUnitElement( | 
| +      CompilationUnitElement element1, CompilationUnitElement element2) { | 
| +    return strategy.test( | 
| +            element1, element2, 'name', element1.name, element2.name) && | 
| visit(element1.library, element2.library); | 
| } | 
|  | 
| @override | 
| bool visitClassElement(ClassElement element1, ClassElement element2) { | 
| -    return | 
| -        strategy.test(element1, element2, | 
| -            'name', | 
| -            element1.name, element2.name) && | 
| +    return strategy.test( | 
| +            element1, element2, 'name', element1.name, element2.name) && | 
| visit(element1.library, element2.library); | 
| } | 
|  | 
| bool checkMembers(Element element1, Element element2) { | 
| -    if (!strategy.test(element1, element2, 'name', | 
| -                       element1.name, element2.name)) { | 
| +    if (!strategy.test( | 
| +        element1, element2, 'name', element1.name, element2.name)) { | 
| return false; | 
| } | 
| if (element1.enclosingClass != null || element2.enclosingClass != null) { | 
| @@ -269,95 +245,81 @@ class ElementIdentityEquivalence extends BaseElementVisitor<bool, Element> { | 
| } | 
|  | 
| @override | 
| -  bool visitConstructorElement(ConstructorElement element1, | 
| -                               ConstructorElement element2) { | 
| +  bool visitConstructorElement( | 
| +      ConstructorElement element1, ConstructorElement element2) { | 
| return checkMembers(element1, element2); | 
| } | 
|  | 
| @override | 
| -  bool visitMethodElement(MethodElement element1, | 
| -                          MethodElement element2) { | 
| +  bool visitMethodElement(MethodElement element1, MethodElement element2) { | 
| return checkMembers(element1, element2); | 
| } | 
|  | 
| @override | 
| -  bool visitGetterElement(GetterElement element1, | 
| -                          GetterElement element2) { | 
| +  bool visitGetterElement(GetterElement element1, GetterElement element2) { | 
| return checkMembers(element1, element2); | 
| } | 
|  | 
| @override | 
| -  bool visitSetterElement(SetterElement element1, | 
| -                          SetterElement element2) { | 
| +  bool visitSetterElement(SetterElement element1, SetterElement element2) { | 
| return checkMembers(element1, element2); | 
| } | 
|  | 
| @override | 
| -  bool visitLocalFunctionElement(LocalFunctionElement element1, | 
| -                                 LocalFunctionElement element2) { | 
| +  bool visitLocalFunctionElement( | 
| +      LocalFunctionElement element1, LocalFunctionElement element2) { | 
| // TODO(johnniwinther): Define an equivalence on locals. | 
| return checkMembers(element1.memberContext, element2.memberContext); | 
| } | 
|  | 
| -  bool visitAbstractFieldElement(AbstractFieldElement element1, | 
| -                                 AbstractFieldElement element2) { | 
| +  bool visitAbstractFieldElement( | 
| +      AbstractFieldElement element1, AbstractFieldElement element2) { | 
| return checkMembers(element1, element2); | 
| } | 
|  | 
| @override | 
| -  bool visitTypeVariableElement(TypeVariableElement element1, | 
| -                                TypeVariableElement element2) { | 
| -    return | 
| -        strategy.test( | 
| -            element1, element2, 'name', | 
| -            element1.name, element2.name) && | 
| +  bool visitTypeVariableElement( | 
| +      TypeVariableElement element1, TypeVariableElement element2) { | 
| +    return strategy.test( | 
| +            element1, element2, 'name', element1.name, element2.name) && | 
| visit(element1.typeDeclaration, element2.typeDeclaration); | 
| } | 
|  | 
| @override | 
| bool visitTypedefElement(TypedefElement element1, TypedefElement element2) { | 
| -    return | 
| -        strategy.test( | 
| -            element1, element2, 'name', | 
| -            element1.name, element2.name) && | 
| +    return strategy.test( | 
| +            element1, element2, 'name', element1.name, element2.name) && | 
| visit(element1.library, element2.library); | 
| } | 
|  | 
| @override | 
| -  bool visitParameterElement(ParameterElement element1, | 
| -                             ParameterElement element2) { | 
| -    return | 
| -        strategy.test( | 
| -            element1, element2, 'name', | 
| -            element1.name, element2.name) && | 
| +  bool visitParameterElement( | 
| +      ParameterElement element1, ParameterElement element2) { | 
| +    return strategy.test( | 
| +            element1, element2, 'name', element1.name, element2.name) && | 
| visit(element1.functionDeclaration, element2.functionDeclaration); | 
| } | 
|  | 
| @override | 
| bool visitImportElement(ImportElement element1, ImportElement element2) { | 
| -    return | 
| -        visit(element1.importedLibrary, element2.importedLibrary) && | 
| +    return visit(element1.importedLibrary, element2.importedLibrary) && | 
| visit(element1.library, element2.library); | 
| } | 
|  | 
| @override | 
| bool visitExportElement(ExportElement element1, ExportElement element2) { | 
| -    return | 
| -        visit(element1.exportedLibrary, element2.exportedLibrary) && | 
| +    return visit(element1.exportedLibrary, element2.exportedLibrary) && | 
| visit(element1.library, element2.library); | 
| } | 
|  | 
| @override | 
| bool visitPrefixElement(PrefixElement element1, PrefixElement element2) { | 
| -    return | 
| -        strategy.test( | 
| -            element1, element2, 'name', | 
| -            element1.name, element2.name) && | 
| +    return strategy.test( | 
| +            element1, element2, 'name', element1.name, element2.name) && | 
| visit(element1.library, element2.library); | 
| } | 
| } | 
|  | 
| - | 
| /// Visitor that checks for equivalence of [DartType]s. | 
| class TypeEquivalence implements DartTypeVisitor<bool, DartType> { | 
| final TestStrategy strategy; | 
| @@ -365,8 +327,7 @@ class TypeEquivalence implements DartTypeVisitor<bool, DartType> { | 
| const TypeEquivalence([this.strategy = const TestStrategy()]); | 
|  | 
| bool visit(DartType type1, DartType type2) { | 
| -    return | 
| -        strategy.test(type1, type2, 'kind', type1.kind, type2.kind) && | 
| +    return strategy.test(type1, type2, 'kind', type1.kind, type2.kind) && | 
| type1.accept(this, type2); | 
| } | 
|  | 
| @@ -375,29 +336,21 @@ class TypeEquivalence implements DartTypeVisitor<bool, DartType> { | 
|  | 
| @override | 
| bool visitFunctionType(FunctionType type, FunctionType other) { | 
| -    return | 
| -        strategy.testTypeLists( | 
| -            type, other, 'parameterTypes', | 
| +    return strategy.testTypeLists(type, other, 'parameterTypes', | 
| type.parameterTypes, other.parameterTypes) && | 
| -        strategy.testTypeLists( | 
| -            type, other, 'optionalParameterTypes', | 
| +        strategy.testTypeLists(type, other, 'optionalParameterTypes', | 
| type.optionalParameterTypes, other.optionalParameterTypes) && | 
| -        strategy.testTypeLists( | 
| -            type, other, 'namedParameterTypes', | 
| +        strategy.testTypeLists(type, other, 'namedParameterTypes', | 
| type.namedParameterTypes, other.namedParameterTypes) && | 
| -        strategy.testLists( | 
| -            type, other, 'namedParameters', | 
| -            type.namedParameters, other.namedParameters); | 
| +        strategy.testLists(type, other, 'namedParameters', type.namedParameters, | 
| +            other.namedParameters); | 
| } | 
|  | 
| bool visitGenericType(GenericType type, GenericType other) { | 
| -    return | 
| -        strategy.testElements( | 
| -            type, other, 'element', | 
| -            type.element, other.element) && | 
| -        strategy.testTypeLists( | 
| -            type, other, 'typeArguments', | 
| -            type.typeArguments, other.typeArguments); | 
| +    return strategy.testElements( | 
| +            type, other, 'element', type.element, other.element) && | 
| +        strategy.testTypeLists(type, other, 'typeArguments', type.typeArguments, | 
| +            other.typeArguments); | 
| } | 
|  | 
| @override | 
| @@ -410,10 +363,8 @@ class TypeEquivalence implements DartTypeVisitor<bool, DartType> { | 
|  | 
| @override | 
| bool visitTypeVariableType(TypeVariableType type, TypeVariableType other) { | 
| -    return | 
| -        strategy.testElements( | 
| -            type, other, 'element', | 
| -            type.element, other.element); | 
| +    return strategy.testElements( | 
| +        type, other, 'element', type.element, other.element); | 
| } | 
|  | 
| @override | 
| @@ -440,34 +391,30 @@ class ConstantEquivalence | 
| @override | 
| bool visit(ConstantExpression exp1, ConstantExpression exp2) { | 
| if (identical(exp1, exp2)) return true; | 
| -    return | 
| -        strategy.test(exp1, exp2, 'kind', exp1.kind, exp2.kind) && | 
| +    return strategy.test(exp1, exp2, 'kind', exp1.kind, exp2.kind) && | 
| exp1.accept(this, exp2); | 
| } | 
|  | 
| @override | 
| -  bool visitBinary(BinaryConstantExpression exp1, | 
| -                   BinaryConstantExpression exp2) { | 
| -    return | 
| -        strategy.test(exp1, exp2, 'operator', exp1.operator, exp2.operator) && | 
| +  bool visitBinary( | 
| +      BinaryConstantExpression exp1, BinaryConstantExpression exp2) { | 
| +    return strategy.test( | 
| +            exp1, exp2, 'operator', exp1.operator, exp2.operator) && | 
| strategy.testConstants(exp1, exp2, 'left', exp1.left, exp2.left) && | 
| strategy.testConstants(exp1, exp2, 'right', exp1.right, exp2.right); | 
| } | 
|  | 
| @override | 
| -  bool visitConcatenate(ConcatenateConstantExpression exp1, | 
| -                   ConcatenateConstantExpression exp2) { | 
| -    return | 
| -        strategy.testConstantLists( | 
| -            exp1, exp2, 'expressions', | 
| -            exp1.expressions, exp2.expressions); | 
| +  bool visitConcatenate( | 
| +      ConcatenateConstantExpression exp1, ConcatenateConstantExpression exp2) { | 
| +    return strategy.testConstantLists( | 
| +        exp1, exp2, 'expressions', exp1.expressions, exp2.expressions); | 
| } | 
|  | 
| @override | 
| -  bool visitConditional(ConditionalConstantExpression exp1, | 
| -                   ConditionalConstantExpression exp2) { | 
| -    return | 
| -        strategy.testConstants( | 
| +  bool visitConditional( | 
| +      ConditionalConstantExpression exp1, ConditionalConstantExpression exp2) { | 
| +    return strategy.testConstants( | 
| exp1, exp2, 'condition', exp1.condition, exp2.condition) && | 
| strategy.testConstants( | 
| exp1, exp2, 'trueExp', exp1.trueExp, exp2.trueExp) && | 
| @@ -476,62 +423,43 @@ class ConstantEquivalence | 
| } | 
|  | 
| @override | 
| -  bool visitConstructed(ConstructedConstantExpression exp1, | 
| -                   ConstructedConstantExpression exp2) { | 
| -    return | 
| -        strategy.testTypes( | 
| -            exp1, exp2, 'type', | 
| -            exp1.type, exp2.type) && | 
| -        strategy.testElements( | 
| -            exp1, exp2, 'target', | 
| -            exp1.target, exp2.target) && | 
| +  bool visitConstructed( | 
| +      ConstructedConstantExpression exp1, ConstructedConstantExpression exp2) { | 
| +    return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type) && | 
| +        strategy.testElements(exp1, exp2, 'target', exp1.target, exp2.target) && | 
| strategy.testConstantLists( | 
| -            exp1, exp2, 'arguments', | 
| -            exp1.arguments, exp2.arguments) && | 
| -        strategy.test(exp1, exp2, 'callStructure', | 
| -             exp1.callStructure, exp2.callStructure); | 
| +            exp1, exp2, 'arguments', exp1.arguments, exp2.arguments) && | 
| +        strategy.test(exp1, exp2, 'callStructure', exp1.callStructure, | 
| +            exp2.callStructure); | 
| } | 
|  | 
| @override | 
| -  bool visitFunction(FunctionConstantExpression exp1, | 
| -                FunctionConstantExpression exp2) { | 
| -    return | 
| -        strategy.testElements( | 
| -            exp1, exp2, 'element', | 
| -            exp1.element, exp2.element); | 
| +  bool visitFunction( | 
| +      FunctionConstantExpression exp1, FunctionConstantExpression exp2) { | 
| +    return strategy.testElements( | 
| +        exp1, exp2, 'element', exp1.element, exp2.element); | 
| } | 
|  | 
| @override | 
| -  bool visitIdentical(IdenticalConstantExpression exp1, | 
| -                 IdenticalConstantExpression exp2) { | 
| -    return | 
| -        strategy.testConstants(exp1, exp2, 'left', exp1.left, exp2.left) && | 
| +  bool visitIdentical( | 
| +      IdenticalConstantExpression exp1, IdenticalConstantExpression exp2) { | 
| +    return strategy.testConstants(exp1, exp2, 'left', exp1.left, exp2.left) && | 
| strategy.testConstants(exp1, exp2, 'right', exp1.right, exp2.right); | 
| } | 
|  | 
| @override | 
| bool visitList(ListConstantExpression exp1, ListConstantExpression exp2) { | 
| -    return | 
| -        strategy.testTypes( | 
| -            exp1, exp2, 'type', | 
| -            exp1.type, exp2.type) && | 
| +    return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type) && | 
| strategy.testConstantLists( | 
| -            exp1, exp2, 'values', | 
| -            exp1.values, exp2.values); | 
| +            exp1, exp2, 'values', exp1.values, exp2.values); | 
| } | 
|  | 
| @override | 
| bool visitMap(MapConstantExpression exp1, MapConstantExpression exp2) { | 
| -    return | 
| -        strategy.testTypes( | 
| -            exp1, exp2, 'type', | 
| -            exp1.type, exp2.type) && | 
| +    return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type) && | 
| +        strategy.testConstantLists(exp1, exp2, 'keys', exp1.keys, exp2.keys) && | 
| strategy.testConstantLists( | 
| -            exp1, exp2, 'keys', | 
| -            exp1.keys, exp2.keys) && | 
| -        strategy.testConstantLists( | 
| -            exp1, exp2, 'values', | 
| -            exp1.values, exp2.values); | 
| +            exp1, exp2, 'values', exp1.values, exp2.values); | 
| } | 
|  | 
| @override | 
| @@ -540,14 +468,14 @@ class ConstantEquivalence | 
| } | 
|  | 
| @override | 
| -  bool visitPositional(PositionalArgumentReference exp1, | 
| -                  PositionalArgumentReference exp2) { | 
| +  bool visitPositional( | 
| +      PositionalArgumentReference exp1, PositionalArgumentReference exp2) { | 
| return strategy.test(exp1, exp2, 'index', exp1.index, exp2.index); | 
| } | 
|  | 
| @override | 
| -  bool visitSymbol(SymbolConstantExpression exp1, | 
| -                   SymbolConstantExpression exp2) { | 
| +  bool visitSymbol( | 
| +      SymbolConstantExpression exp1, SymbolConstantExpression exp2) { | 
| // TODO: implement visitSymbol | 
| return true; | 
| } | 
| @@ -559,44 +487,36 @@ class ConstantEquivalence | 
|  | 
| @override | 
| bool visitUnary(UnaryConstantExpression exp1, UnaryConstantExpression exp2) { | 
| -    return | 
| -        strategy.test(exp1, exp2, 'operator', exp1.operator, exp2.operator) && | 
| +    return strategy.test( | 
| +            exp1, exp2, 'operator', exp1.operator, exp2.operator) && | 
| strategy.testConstants( | 
| exp1, exp2, 'expression', exp1.expression, exp2.expression); | 
| } | 
|  | 
| @override | 
| -  bool visitVariable(VariableConstantExpression exp1, | 
| -                VariableConstantExpression exp2) { | 
| -    return | 
| -        strategy.testElements( | 
| -            exp1, exp2, 'element', | 
| -            exp1.element, exp2.element); | 
| +  bool visitVariable( | 
| +      VariableConstantExpression exp1, VariableConstantExpression exp2) { | 
| +    return strategy.testElements( | 
| +        exp1, exp2, 'element', exp1.element, exp2.element); | 
| } | 
|  | 
| @override | 
| bool visitBool(BoolConstantExpression exp1, BoolConstantExpression exp2) { | 
| -    return | 
| -        strategy.test( | 
| -            exp1, exp2, 'primitiveValue', | 
| -            exp1.primitiveValue, exp2.primitiveValue); | 
| +    return strategy.test( | 
| +        exp1, exp2, 'primitiveValue', exp1.primitiveValue, exp2.primitiveValue); | 
| } | 
|  | 
| @override | 
| -  bool visitDouble(DoubleConstantExpression exp1, | 
| -                   DoubleConstantExpression exp2) { | 
| -    return | 
| -        strategy.test( | 
| -            exp1, exp2, 'primitiveValue', | 
| -            exp1.primitiveValue, exp2.primitiveValue); | 
| +  bool visitDouble( | 
| +      DoubleConstantExpression exp1, DoubleConstantExpression exp2) { | 
| +    return strategy.test( | 
| +        exp1, exp2, 'primitiveValue', exp1.primitiveValue, exp2.primitiveValue); | 
| } | 
|  | 
| @override | 
| bool visitInt(IntConstantExpression exp1, IntConstantExpression exp2) { | 
| -    return | 
| -        strategy.test( | 
| -            exp1, exp2, 'primitiveValue', | 
| -            exp1.primitiveValue, exp2.primitiveValue); | 
| +    return strategy.test( | 
| +        exp1, exp2, 'primitiveValue', exp1.primitiveValue, exp2.primitiveValue); | 
| } | 
|  | 
| @override | 
| @@ -605,57 +525,46 @@ class ConstantEquivalence | 
| } | 
|  | 
| @override | 
| -  bool visitString(StringConstantExpression exp1, | 
| -                   StringConstantExpression exp2) { | 
| -    return | 
| -        strategy.test( | 
| -            exp1, exp2, 'primitiveValue', | 
| -            exp1.primitiveValue, exp2.primitiveValue); | 
| +  bool visitString( | 
| +      StringConstantExpression exp1, StringConstantExpression exp2) { | 
| +    return strategy.test( | 
| +        exp1, exp2, 'primitiveValue', exp1.primitiveValue, exp2.primitiveValue); | 
| } | 
|  | 
| @override | 
| bool visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp1, | 
| -                                BoolFromEnvironmentConstantExpression exp2) { | 
| -    return | 
| -        strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) && | 
| +      BoolFromEnvironmentConstantExpression exp2) { | 
| +    return strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) && | 
| strategy.testConstants( | 
| -            exp1, exp2, 'defaultValue', | 
| -            exp1.defaultValue, exp2.defaultValue); | 
| +            exp1, exp2, 'defaultValue', exp1.defaultValue, exp2.defaultValue); | 
| } | 
|  | 
| @override | 
| bool visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp1, | 
| -                               IntFromEnvironmentConstantExpression exp2) { | 
| -    return | 
| -        strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) && | 
| +      IntFromEnvironmentConstantExpression exp2) { | 
| +    return strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) && | 
| strategy.testConstants( | 
| -            exp1, exp2, 'defaultValue', | 
| -            exp1.defaultValue, exp2.defaultValue); | 
| +            exp1, exp2, 'defaultValue', exp1.defaultValue, exp2.defaultValue); | 
| } | 
|  | 
| @override | 
| -  bool visitStringFromEnvironment( | 
| -      StringFromEnvironmentConstantExpression exp1, | 
| +  bool visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp1, | 
| StringFromEnvironmentConstantExpression exp2) { | 
| -    return | 
| -        strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) && | 
| +    return strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) && | 
| strategy.testConstants( | 
| -            exp1, exp2, 'defaultValue', | 
| -            exp1.defaultValue, exp2.defaultValue); | 
| +            exp1, exp2, 'defaultValue', exp1.defaultValue, exp2.defaultValue); | 
| } | 
|  | 
| @override | 
| bool visitStringLength(StringLengthConstantExpression exp1, | 
| -                    StringLengthConstantExpression exp2) { | 
| -    return | 
| -        strategy.testConstants( | 
| -            exp1, exp2, 'expression', | 
| -            exp1.expression, exp2.expression); | 
| +      StringLengthConstantExpression exp2) { | 
| +    return strategy.testConstants( | 
| +        exp1, exp2, 'expression', exp1.expression, exp2.expression); | 
| } | 
|  | 
| @override | 
| -  bool visitDeferred(DeferredConstantExpression exp1, | 
| -                DeferredConstantExpression exp2) { | 
| +  bool visitDeferred( | 
| +      DeferredConstantExpression exp1, DeferredConstantExpression exp2) { | 
| // TODO: implement visitDeferred | 
| return true; | 
| } | 
| @@ -663,38 +572,27 @@ class ConstantEquivalence | 
|  | 
| /// Tests the equivalence of [impact1] and [impact2] using [strategy]. | 
| bool testResolutionImpactEquivalence( | 
| -    ResolutionImpact impact1, | 
| -    ResolutionImpact impact2, | 
| +    ResolutionImpact impact1, ResolutionImpact impact2, | 
| [TestStrategy strategy = const TestStrategy()]) { | 
| -  return | 
| -      strategy.testSets( | 
| -          impact1, impact2, 'constSymbolNames', | 
| +  return strategy.testSets(impact1, impact2, 'constSymbolNames', | 
| impact1.constSymbolNames, impact2.constSymbolNames) && | 
| strategy.testSets( | 
| -          impact1, impact2, 'constantLiterals', | 
| -          impact1.constantLiterals, impact2.constantLiterals, | 
| +          impact1, | 
| +          impact2, | 
| +          'constantLiterals', | 
| +          impact1.constantLiterals, | 
| +          impact2.constantLiterals, | 
| areConstantsEquivalent) && | 
| +      strategy.testSets(impact1, impact2, 'dynamicUses', impact1.dynamicUses, | 
| +          impact2.dynamicUses, areDynamicUsesEquivalent) && | 
| strategy.testSets( | 
| -          impact1, impact2, 'dynamicUses', | 
| -          impact1.dynamicUses, impact2.dynamicUses, | 
| -          areDynamicUsesEquivalent) && | 
| -      strategy.testSets( | 
| -          impact1, impact2, 'features', | 
| -          impact1.features, impact2.features) && | 
| -      strategy.testSets( | 
| -          impact1, impact2, 'listLiterals', | 
| -          impact1.listLiterals, impact2.listLiterals, | 
| -          areListLiteralUsesEquivalent) && | 
| -      strategy.testSets( | 
| -          impact1, impact2, 'mapLiterals', | 
| -          impact1.mapLiterals, impact2.mapLiterals, | 
| -          areMapLiteralUsesEquivalent) && | 
| -      strategy.testSets( | 
| -          impact1, impact2, 'staticUses', | 
| -          impact1.staticUses, impact2.staticUses, | 
| -          areStaticUsesEquivalent) && | 
| -      strategy.testSets( | 
| -          impact1, impact2, 'typeUses', | 
| -          impact1.typeUses, impact2.typeUses, | 
| -          areTypeUsesEquivalent); | 
| +          impact1, impact2, 'features', impact1.features, impact2.features) && | 
| +      strategy.testSets(impact1, impact2, 'listLiterals', impact1.listLiterals, | 
| +          impact2.listLiterals, areListLiteralUsesEquivalent) && | 
| +      strategy.testSets(impact1, impact2, 'mapLiterals', impact1.mapLiterals, | 
| +          impact2.mapLiterals, areMapLiteralUsesEquivalent) && | 
| +      strategy.testSets(impact1, impact2, 'staticUses', impact1.staticUses, | 
| +          impact2.staticUses, areStaticUsesEquivalent) && | 
| +      strategy.testSets(impact1, impact2, 'typeUses', impact1.typeUses, | 
| +          impact2.typeUses, areTypeUsesEquivalent); | 
| } | 
|  |