anchor.diff:      return result;
     }
   
  +  @override
     apply(left, right) => identical(left, right);
   }
   
   class IfNullOperation implements BinaryOperation {
  +  @override
     final String name = '??';
  +
     const IfNullOperation();
  +
  +  @override
     ConstantValue fold(ConstantValue left, ConstantValue right) {
       if (left.isNull) return right;
       return left;
     }
   
  +  @override
     apply(left, right) => left ?? right;
   }
   
   class CodeUnitAtOperation implements BinaryOperation {
  -  String get name => 'charCodeAt';
  +  @override
  +  final String name = 'charCodeAt';
  +
     const CodeUnitAtOperation();
  -  ConstantValue fold(ConstantValue left, ConstantValue right) => null;
  -  apply(left, right) => left.codeUnitAt(right);
  -}
  -
  -class CodeUnitAtRuntimeOperation extends CodeUnitAtOperation {
  -  const CodeUnitAtRuntimeOperation();
  +
  +  @override
     IntConstantValue fold(ConstantValue left, ConstantValue right) {
       if (left.isString && right.isInt) {
         StringConstantValue stringConstant = left;
  
positive.code:     }
      return null;
    }
  }
  
  class JavaScriptRoundOperation implements UnaryOperation {
    const JavaScriptRoundOperation();
    String get name => round.name;
    ConstantValue fold(ConstantValue constant) {
      // Be careful to round() only values that do not throw on either the host or
      // target platform.
  
negative.code:   foldNums(num left, num right);
  }
  
  class SubtractOperation extends ArithmeticNumOperation {
    @override
    final String name = '-';
  
    const SubtractOperation();
  
    @override
    BigInt foldInts(BigInt left, BigInt right) => left - right;
  
    @override
    num foldNums(num left, num right) => left - right;
  
    @override
    apply(left, right) => left - right;
  }
  
  class MultiplyOperation extends ArithmeticNumOperation {
    @override
    final String name = '*';
  
    const MultiplyOperation();
  
    @override
    BigInt foldInts(BigInt left, BigInt right) => left * right;
  
    @override
    num foldNums(num left, num right) => left * right;
  
    @override
    apply(left, right) => left * right;
  }
  
  class ModuloOperation extends ArithmeticNumOperation {
    @override
    final String name = '%';
  
    const ModuloOperation();
  
    @override
    BigInt foldInts(BigInt left, BigInt right) {
      if (right == BigInt.zero) return null;
      return left % right;
    }
  
    @override
    num foldNums(num left, num right) => left % right;
  
    @override
    apply(left, right) => left % right;
  }
  
  class RemainderOperation extends ArithmeticNumOperation {
    @override
    final String name = 'remainder';
  
    const RemainderOperation();
  
    @override
    BigInt foldInts(BigInt left, BigInt right) {
      if (right == BigInt.zero) return null;
      return left.remainder(right);
    }
  
    @override
    num foldNums(num left, num right) => left.remainder(right);
  
    @override
    apply(left, right) => left.remainder(right);
  }
  
  class TruncatingDivideOperation extends ArithmeticNumOperation {
    @override
    final String name = '~/';
  
    const TruncatingDivideOperation();
  
    @override
    BigInt foldInts(BigInt left, BigInt right) {
      if (right == BigInt.zero) return null;
      return left ~/ right;
    }
  
    @override
    BigInt foldNums(num left, num right) {
      num ratio = left / right;
      if (ratio.isNaN || ratio.isInfinite) return null;
      return new BigInt.from(ratio.truncate().toInt());
    }
  
    @override
    apply(left, right) => left ~/ right;
  
    @override
    bool isTruncatingDivide() => true;
  }
  
  class DivideOperation extends ArithmeticNumOperation {
    @override
    final String name = '/';
  
    const DivideOperation();
  
    @override
    double foldInts(BigInt left, BigInt right) => left / right;
  
    @override
    num foldNums(num left, num right) => left / right;
  
    @override
    bool isDivide() => true;
  
    @override
    apply(left, right) => left / right;
  }
  
  class AddOperation implements BinaryOperation {
    @override
    final String name = '+';
  
    const AddOperation();
  
    @override
    ConstantValue fold(ConstantValue left, ConstantValue right) {
      ConstantValue _fold(ConstantValue left, ConstantValue right) {
        if (left.isInt && right.isInt) {
          IntConstantValue leftInt = left;
          IntConstantValue rightInt = right;
          BigInt result = leftInt.intValue + rightInt.intValue;
          return createInt(result);
        } else if (left.isNum && right.isNum) {
          NumConstantValue leftNum = left;
          NumConstantValue rightNum = right;
          double result = leftNum.doubleValue + rightNum.doubleValue;
          return createDouble(result);
        } else if (left.isString && right.isString) {
          StringConstantValue leftString = left;
          StringConstantValue rightString = right;
          String result = leftString.stringValue + rightString.stringValue;
          return createString(result);
        } else {
          return null;
        }
      }
  
      ConstantValue result = _fold(left, right);
      if (result != null && result.isNum) {
        return _convertToJavaScriptConstant(result);
      }
      return result;
    }
  
    @override
    apply(left, right) => left + right;
  }
  
  abstract class RelationalNumOperation implements BinaryOperation {
    const RelationalNumOperation();
  
    @override
    ConstantValue fold(ConstantValue left, ConstantValue right) {
      if (!left.isNum || !right.isNum) return null;
      bool foldedValue;
  