anchor.diff:    @override
     visitListConcatenation(ListConcatenation node) {
       // Only occurs inside unevaluated constants.
  -    throw new UnsupportedError("List concatenation");
  +    List<JS.Expression> entries = [];
  +    _concatenate(Expression node) {
  +      if (node is ListConcatenation)
  +        node.lists.forEach(_concatenate);
  +      else {
  +        node.accept(this);
  +        if (node is ConstantExpression) {
  +          var list = node.constant as ListConstant;
  +          entries.addAll(list.entries.map(visitConstant));
  +        } else if (node is ListLiteral) {
  +          entries.addAll(node.expressions.map(_visitExpression));
  +        }
  +      }
  +    }
  +
  +    node.lists.forEach(_concatenate);
  +    return _emitConstList(node.typeArgument, entries);
     }
   
     @override
     visitSetConcatenation(SetConcatenation node) {
       // Only occurs inside unevaluated constants.
  -    throw new UnsupportedError("Set concatenation");
  +    List<JS.Expression> entries = [];
  +    _concatenate(Expression node) {
  +      if (node is SetConcatenation)
  +        node.sets.forEach(_concatenate);
  +      else {
  +        node.accept(this);
  +        if (node is ConstantExpression) {
  +          var set = node.constant as SetConstant;
  +          entries.addAll(set.entries.map(visitConstant));
  +        } else if (node is SetLiteral) {
  +          entries.addAll(node.expressions.map(_visitExpression));
  +        }
  +      }
  +    }
  +
  +    node.sets.forEach(_concatenate);
  +    return _emitConstSet(node.typeArgument, entries);
     }
   
     @override
     visitMapConcatenation(MapConcatenation node) {
       // Only occurs inside unevaluated constants.
  -    throw new UnsupportedError("Map concatenation");
  +    List<JS.Expression> entries = [];
  +    _concatenate(Expression node) {
  +      if (node is MapConcatenation)
  +        node.maps.forEach(_concatenate);
  +      else {
  +        node.accept(this);
  +        if (node is ConstantExpression) {
  +          var map = node.constant as MapConstant;
  +          for (var entry in map.entries) {
  +            entries.add(visitConstant(entry.key));
  +            entries.add(visitConstant(entry.value));
  +          }
  +        } else if (node is MapLiteral) {
  +          for (var entry in node.entries) {
  +            entries.add(_visitExpression(entry.key));
  +            entries.add(_visitExpression(entry.value));
  +          }
  +        }
  +      }
  +    }
  +
  +    node.maps.forEach(_concatenate);
  +    return _emitConstMap(node.keyType, node.valueType, entries);
     }
   
     @override
  
positive.code:     return _emitConstList(elementType, elements);
    }
  
    @override
    visitSetLiteral(SetLiteral node) {
      // TODO(markzipan): remove const check when we use front-end const eval
  
negative.code: 
    @override
    visitSetConstant(node) {
      return _emitConstSet(
          node.typeArgument, node.entries.map(visitConstant).toList());
    }
  
    @override
  