Merge branch 'simon-void.master'

Closes #20
Closes #31
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 559e810..de42222 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.7.0
+
+* Add a `const UnmodifiableSetView.empty()` constructor.
+
 ## 1.6.0
 
 * Add a `UnionSet` class that provides a view of the union of a set of sets.
diff --git a/lib/src/empty_unmodifiable_set.dart b/lib/src/empty_unmodifiable_set.dart
new file mode 100644
index 0000000..581532f
--- /dev/null
+++ b/lib/src/empty_unmodifiable_set.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+import 'unmodifiable_wrappers.dart';
+
+// Unfortunately, we can't use UnmodifiableSetMixin here, since const classes
+// can't use mixins.
+/// An unmodifiable, empty set that can have a const constructor.
+class EmptyUnmodifiableSet<E> extends IterableBase<E>
+    implements UnmodifiableSetView<E> {
+  static /*=T*/ _throw/*<T>*/() {
+    throw new UnsupportedError("Cannot modify an unmodifiable Set");
+  }
+
+  Iterator<E> get iterator => new Iterable<E>.empty().iterator;
+  int get length => 0;
+
+  const EmptyUnmodifiableSet();
+
+  bool contains(Object element) => false;
+  bool containsAll(Iterable<Object> other) => other.isEmpty;
+  E lookup(Object element) => null;
+  Set<E> toSet() => new Set();
+  Set<E> union(Set<E> other) => new Set.from(other);
+  Set<E> intersection(Set<Object> other) => new Set();
+  Set<E> difference(Set<Object> other) => new Set();
+
+  bool add(E value) => _throw();
+  void addAll(Iterable<E> elements) => _throw();
+  void clear() => _throw();
+  bool remove(Object element) => _throw();
+  void removeAll(Iterable<Object> elements) => _throw();
+  void removeWhere(bool test(E element)) => _throw();
+  void retainWhere(bool test(E element)) => _throw();
+  void retainAll(Iterable<Object> elements) => _throw();
+}
+
diff --git a/lib/src/unmodifiable_wrappers.dart b/lib/src/unmodifiable_wrappers.dart
index 6003286..5efbee4 100644
--- a/lib/src/unmodifiable_wrappers.dart
+++ b/lib/src/unmodifiable_wrappers.dart
@@ -5,6 +5,7 @@
 export "dart:collection" show UnmodifiableListView, UnmodifiableMapView;
 
 import 'wrappers.dart';
+import 'empty_unmodifiable_set.dart';
 
 /// A fixed-length list.
 ///
@@ -91,8 +92,14 @@
 /// such as [add] and [remove], throw an [UnsupportedError].
 /// Permitted operations defer to the wrapped set.
 class UnmodifiableSetView<E> extends DelegatingSet<E>
-                             with UnmodifiableSetMixin<E> {
+    with UnmodifiableSetMixin<E> {
   UnmodifiableSetView(Set<E> setBase) : super(setBase);
+
+  /// An unmodifiable empty set.
+  ///
+  /// This is the same as `new UnmodifiableSetView(new Set())`, except that it
+  /// can be used in const contexts.
+  const factory UnmodifiableSetView.empty() = EmptyUnmodifiableSet<E>;
 }
 
 /// Mixin class that implements a throwing version of all set operations that
diff --git a/pubspec.yaml b/pubspec.yaml
index 992e7ae..7c88550 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: collection
-version: 1.6.0
+version: 1.7.0
 author: Dart Team <misc@dartlang.org>
 description: Collections and utilities functions and classes related to collections.
 homepage: https://www.github.com/dart-lang/collection
diff --git a/test/unmodifiable_collection_test.dart b/test/unmodifiable_collection_test.dart
index 682a406..cdb5101 100644
--- a/test/unmodifiable_collection_test.dart
+++ b/test/unmodifiable_collection_test.dart
@@ -35,6 +35,8 @@
 
   Set aSet = new Set();
   testUnmodifiableSet(aSet, new UnmodifiableSetView(aSet), "empty");
+  aSet = new Set();
+  testUnmodifiableSet(aSet, const UnmodifiableSetView.empty(), "const empty");
   aSet = new Set.from([42]);
   testUnmodifiableSet(aSet, new UnmodifiableSetView(aSet), "single-42");
   aSet = new Set.from([7]);