| Index: sdk/lib/collection/linked_list.dart | 
| diff --git a/sdk/lib/collection/linked_list.dart b/sdk/lib/collection/linked_list.dart | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..a653126d927566aad914dbb0608d9402127c76ea | 
| --- /dev/null | 
| +++ b/sdk/lib/collection/linked_list.dart | 
| @@ -0,0 +1,232 @@ | 
| +// Copyright (c) 2013, 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. | 
| + | 
| +part of dart.collection; | 
| + | 
| + | 
| +/** | 
| + * A linked list implementation, providing O(1) removal(unlink) of elements and | 
| + * manual traversal through [next] and [previous]. | 
| + * | 
| + * The list elements must extend [LinkedListEntry]. | 
| + */ | 
| +class LinkedList<E extends LinkedListEntry<E>> | 
| +    extends IterableBase<E> | 
| +    implements _LinkedListLink { | 
| +  int _modificationCount = 0; | 
| +  int _length = 0; | 
| +  _LinkedListLink _next; | 
| +  _LinkedListLink _previous; | 
| + | 
| +  /** | 
| +   * Construct a new empty linked list. | 
| +   */ | 
| +  LinkedList() { | 
| +    _next = _previous = this; | 
| +  } | 
| + | 
| +  /** | 
| +   * Add [entry] to the beginning of the list. | 
| +   */ | 
| +  void addFirst(E entry) { | 
| +    _insertAfter(this, entry); | 
| +  } | 
| + | 
| +  /** | 
| +   * Add [entry] to the end of the list. | 
| +   */ | 
| +  void add(E entry) { | 
| +    _insertAfter(_previous, entry); | 
| +  } | 
| + | 
| +  /** | 
| +   * Add [entries] to the end of the list. | 
| +   */ | 
| +  void addAll(Iterable<E> entries) { | 
| +    entries.forEach((entry) => _insertAfter(_previous, entry)); | 
| +  } | 
| + | 
| +  /** | 
| +   * Remove [entry] from the list. This is the same as calling `entry.unlink()`. | 
| +   * | 
| +   * If [entry] is not in the list, `false` is returned. | 
| +   */ | 
| +  bool remove(E entry) { | 
| +    if (entry._list != this) return false; | 
| +    _unlink(entry);  // Unlink will decrement length. | 
| +    return true; | 
| +  } | 
| + | 
| +  Iterator<E> get iterator => new _LinkedListIterator<E>(this); | 
| + | 
| +  String toString() => ToString.iterableToString(this); | 
| + | 
| +  int get length => _length; | 
| + | 
| +  void clear() { | 
| +    _modificationCount++; | 
| +    _LinkedListLink next = _next; | 
| +    while (!identical(next, this)) { | 
| +      _LinkedListLink entry = next; | 
| +      next = entry._next; | 
| +      entry._next = entry._previous = entry._list = null; | 
| +    } | 
| +    _next = _previous = this; | 
| +    _length = 0; | 
| +  } | 
| + | 
| +  E get first { | 
| +    if (identical(_next, this)) { | 
| +      throw new StateError('No such element'); | 
| +    } | 
| +    return _next; | 
| +  } | 
| + | 
| +  E get last { | 
| +    if (identical(_previous, this)) { | 
| +      throw new StateError('No such element'); | 
| +    } | 
| +    return _previous; | 
| +  } | 
| + | 
| +  E get single { | 
| +    if (identical(_previous, this)) { | 
| +      throw new StateError('No such element'); | 
| +    } | 
| +    if (!identical(_previous, _next)) { | 
| +      throw new StateError('Too many elements'); | 
| +    } | 
| +    return _next; | 
| +  } | 
| + | 
| +  /** | 
| +   * Call [action] with each entry in the list. | 
| +   * | 
| +   * It's an error if [action] modify the list. | 
| +   */ | 
| +  void forEach(void action(E entry)) { | 
| +    int modificationCount = _modificationCount; | 
| +    _LinkedListLink current = _next; | 
| +    while (!identical(current, this)) { | 
| +      action(current); | 
| +      if (modificationCount != _modificationCount) { | 
| +        throw new ConcurrentModificationError(this); | 
| +      } | 
| +      current = current._next; | 
| +    } | 
| +  } | 
| + | 
| +  bool get isEmpty => _length == 0; | 
| + | 
| +  void _insertAfter(_LinkedListLink entry, E newEntry) { | 
| +    if (newEntry.list != null) { | 
| +      throw new StateError( | 
| +          'LinkedListEntry is already in a LinkedList'); | 
| +    } | 
| +    _modificationCount++; | 
| +    newEntry._list = this; | 
| +    var predecessor = entry; | 
| +    var successor = entry._next; | 
| +    successor._previous = newEntry; | 
| +    newEntry._previous = predecessor; | 
| +    newEntry._next = successor; | 
| +    predecessor._next = newEntry; | 
| +    _length++; | 
| +  } | 
| + | 
| +  void _unlink(E entry) { | 
| +    _modificationCount++; | 
| +    entry._next._previous = entry._previous; | 
| +    entry._previous._next = entry._next; | 
| +    _length--; | 
| +    entry._list = entry._next = entry._previous = null; | 
| +  } | 
| +} | 
| + | 
| + | 
| +class _LinkedListIterator<E extends LinkedListEntry> | 
| +    implements Iterator<E> { | 
| +  final LinkedList<E> _list; | 
| +  final int _modificationCount; | 
| +  E _current; | 
| +  _LinkedListLink _next; | 
| + | 
| +  _LinkedListIterator(LinkedList<E> list) | 
| +    : _list = list, | 
| +      _modificationCount = list._modificationCount, | 
| +      _next = list._next; | 
| + | 
| +  E get current => _current; | 
| + | 
| +  bool moveNext() { | 
| +    if (identical(_next, _list)) { | 
| +      _current = null; | 
| +      return false; | 
| +    } | 
| +    if (_modificationCount != _list._modificationCount) { | 
| +      throw new ConcurrentModificationError(this); | 
| +    } | 
| +    _current = _next; | 
| +    _next = _next._next; | 
| +    return true; | 
| +  } | 
| +} | 
| + | 
| + | 
| +class _LinkedListLink { | 
| +  _LinkedListLink _next; | 
| +  _LinkedListLink _previous; | 
| +} | 
| + | 
| + | 
| +/** | 
| + * Entry element for a [LinkedList]. Any entry must extend this class. | 
| + */ | 
| +abstract class LinkedListEntry<E> implements _LinkedListLink { | 
| +  LinkedList<E> _list; | 
| +  _LinkedListLink _next; | 
| +  _LinkedListLink _previous; | 
| + | 
| +  /** | 
| +   * Get the list containing this element. | 
| +   */ | 
| +  LinkedList<E> get list => _list; | 
| + | 
| +  /** | 
| +   * Unlink the element from the list. | 
| +   */ | 
| +  void unlink() { | 
| +    _list._unlink(this); | 
| +  } | 
| + | 
| +  /** | 
| +   * Return the succeeding element in the list. | 
| +   */ | 
| +  E get next { | 
| +    if (_next == _list) return null; | 
| +    return _next; | 
| +  } | 
| + | 
| +  /** | 
| +   * Return the preceeding element in the list. | 
| +   */ | 
| +  E get previous { | 
| +    if (_previous == _list) return null; | 
| +    return _previous; | 
| +  } | 
| + | 
| +  /** | 
| +   * insert an element after this. | 
| +   */ | 
| +  void insertAfter(E entry) { | 
| +    _list._insertAfter(this, entry); | 
| +  } | 
| + | 
| +  /** | 
| +   * Insert an element before this. | 
| +   */ | 
| +  void insertBefore(E entry) { | 
| +    _list._insertAfter(_previous, entry); | 
| +  } | 
| +} | 
|  |