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 {
  -  @override
  -  final String name = 'charCodeAt';
  -
  +  String get name => 'charCodeAt';
     const CodeUnitAtOperation();
  -
  -  @override
  +  ConstantValue fold(ConstantValue left, ConstantValue right) => null;
  +  apply(left, right) => left.codeUnitAt(right);
  +}
  +
  +class CodeUnitAtRuntimeOperation extends CodeUnitAtOperation {
  +  const CodeUnitAtRuntimeOperation();
     IntConstantValue fold(ConstantValue left, ConstantValue right) {
       if (left.isString && right.isInt) {
         StringConstantValue stringConstant = left;
  
positive.code: }
  
  class BitNotOperation implements UnaryOperation {
    @override
    final String name = '~';
  
    const BitNotOperation();
  
    @override
    ConstantValue fold(ConstantValue constant) {
      if (isInt(constant)) {
        // In JavaScript we don't check for -0 and treat it as if it was zero.
  
negative.code:   foldNums(num left, num right);
  }
  
  class JavaScriptBinaryArithmeticOperation implements BinaryOperation {
    final BinaryOperation dartArithmeticOperation;
  
    const JavaScriptBinaryArithmeticOperation(this.dartArithmeticOperation);
  
    String get name => dartArithmeticOperation.name;
  
    ConstantValue fold(ConstantValue left, ConstantValue right) {
      ConstantValue result = dartArithmeticOperation.fold(left, right);
      if (result == null) return result;
      return _convertToJavaScriptConstant(result);
    }
  
    apply(left, right) => dartArithmeticOperation.apply(left, right);
  }
  
  class SubtractOperation extends ArithmeticNumOperation {
    final String name = '-';
    const SubtractOperation();
    BigInt foldInts(BigInt left, BigInt right) => left - right;
    num foldNums(num left, num right) => left - right;
    apply(left, right) => left - right;
  }
  
  class MultiplyOperation extends ArithmeticNumOperation {
    final String name = '*';
    const MultiplyOperation();
    BigInt foldInts(BigInt left, BigInt right) => left * right;
    num foldNums(num left, num right) => left * right;
    apply(left, right) => left * right;
  }
  
  class ModuloOperation extends ArithmeticNumOperation {
    final String name = '%';
    const ModuloOperation();
    BigInt foldInts(BigInt left, BigInt right) {
      if (right == BigInt.zero) return null;
      return left % right;
    }
  
    num foldNums(num left, num right) => left % right;
    apply(left, right) => left % right;
  }
  
  class JavaScriptRemainderOperation extends ArithmeticNumOperation {
    String get name => 'remainder';
  
    const JavaScriptRemainderOperation();
  
    BigInt foldInts(BigInt left, BigInt right) {
      if (right == BigInt.zero) return null;
      return left.remainder(right);
    }
  
    num foldNums(num left, num right) => left.remainder(right);
    apply(left, right) => left.remainder(right);
  }
  
  class TruncatingDivideOperation extends ArithmeticNumOperation {
    final String name = '~/';
    const TruncatingDivideOperation();
    BigInt foldInts(BigInt left, BigInt right) {
      if (right == BigInt.zero) return null;
      return left ~/ right;
    }
  
    BigInt foldNums(num left, num right) {
      num ratio = left / right;
      if (ratio.isNaN || ratio.isInfinite) return null;
      return new BigInt.from(ratio.truncate().toInt());
    }
  
    apply(left, right) => left ~/ right;
    bool isTruncatingDivide() => true;
  }
  
  class DivideOperation extends ArithmeticNumOperation {
    final String name = '/';
    const DivideOperation();
    double foldInts(BigInt left, BigInt right) => left / right;
    num foldNums(num left, num right) => left / right;
    bool isDivide() => true;
    apply(left, right) => left / right;
  }
  
  class AddOperation implements BinaryOperation {
    final String name = '+';
    const AddOperation();
    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;
      }
    }
  
    apply(left, right) => left + right;
  }
  
  class JavaScriptAddOperation implements BinaryOperation {
    final _addOperation = const AddOperation();
    String get name => _addOperation.name;
  
    const JavaScriptAddOperation();
  
    ConstantValue fold(ConstantValue left, ConstantValue right) {
      ConstantValue result = _addOperation.fold(left, right);
      if (result != null && result.isNum) {
        return _convertToJavaScriptConstant(result);
      }
      return result;
    }
  
    apply(left, right) => _addOperation.apply(left, right);
  }
  
  abstract class RelationalNumOperation implements BinaryOperation {
    const RelationalNumOperation();
    ConstantValue fold(ConstantValue left, ConstantValue right) {
      if (!left.isNum || !right.isNum) return null;
      bool foldedValue;
  