| Index: pkg/polymer/lib/src/utils.dart | 
| diff --git a/pkg/polymer/lib/src/utils.dart b/pkg/polymer/lib/src/utils.dart | 
| index da79dc2478dfff2db0e557b7b6d063a6fa28db3c..59fdc737c31bf698bf1e3eb26de654cf52c9ef2e 100644 | 
| --- a/pkg/polymer/lib/src/utils.dart | 
| +++ b/pkg/polymer/lib/src/utils.dart | 
| @@ -1,177 +1,34 @@ | 
| -// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 
| +// 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. | 
|  | 
| library polymer.src.utils; | 
|  | 
| -import 'dart:async'; | 
| -import 'package:path/path.dart' show Builder; | 
| -export 'utils_observe.dart' show toCamelCase, toHyphenedName; | 
| - | 
| -/** | 
| - * An instance of the pathos library builder. We could just use the default | 
| - * builder in pathos, but we add this indirection to make it possible to run | 
| - * unittest for windows paths. | 
| - */ | 
| -Builder path = new Builder(); | 
| - | 
| -/** Convert a OS specific path into a url. */ | 
| -String pathToUrl(String relPath) => | 
| -  (path.separator == '/') ? relPath : path.split(relPath).join('/'); | 
| - | 
| -/** | 
| - * Invokes [callback], logs how long it took to execute in ms, and returns | 
| - * whatever [callback] returns. The log message will be printed if [printTime] | 
| - * is true. | 
| - */ | 
| -time(String logMessage, callback(), | 
| -     {bool printTime: false, bool useColors: false}) { | 
| -  final watch = new Stopwatch(); | 
| -  watch.start(); | 
| -  var result = callback(); | 
| -  watch.stop(); | 
| -  final duration = watch.elapsedMilliseconds; | 
| -  if (printTime) { | 
| -    _printMessage(logMessage, duration, useColors); | 
| -  } | 
| -  return result; | 
| -} | 
| - | 
| -/** | 
| - * Invokes [callback], logs how long it takes from the moment [callback] is | 
| - * executed until the future it returns is completed. Returns the future | 
| - * returned by [callback]. The log message will be printed if [printTime] | 
| - * is true. | 
| - */ | 
| -Future asyncTime(String logMessage, Future callback(), | 
| -                 {bool printTime: false, bool useColors: false}) { | 
| -  final watch = new Stopwatch(); | 
| -  watch.start(); | 
| -  return callback()..then((_) { | 
| -    watch.stop(); | 
| -    final duration = watch.elapsedMilliseconds; | 
| -    if (printTime) { | 
| -      _printMessage(logMessage, duration, useColors); | 
| -    } | 
| -  }); | 
| -} | 
| - | 
| -void _printMessage(String logMessage, int duration, bool useColors) { | 
| -  var buf = new StringBuffer(); | 
| -  buf.write(logMessage); | 
| -  for (int i = logMessage.length; i < 60; i++) buf.write(' '); | 
| -  buf.write(' -- '); | 
| -  if (useColors) { | 
| -    buf.write(GREEN_COLOR); | 
| -  } | 
| -  if (duration < 10) buf.write(' '); | 
| -  if (duration < 100) buf.write(' '); | 
| -  buf..write(duration)..write(' ms'); | 
| -  if (useColors) { | 
| -    buf.write(NO_COLOR); | 
| -  } | 
| -  print(buf.toString()); | 
| -} | 
| - | 
| -// Color constants used for generating messages. | 
| -final String GREEN_COLOR = '\u001b[32m'; | 
| -final String RED_COLOR = '\u001b[31m'; | 
| -final String MAGENTA_COLOR = '\u001b[35m'; | 
| -final String NO_COLOR = '\u001b[0m'; | 
| - | 
| -/** A future that waits until all added [Future]s complete. */ | 
| -// TODO(sigmund): this should be part of the futures/core libraries. | 
| -class FutureGroup { | 
| -  static const _FINISHED = -1; | 
| - | 
| -  int _pending = 0; | 
| -  Future _failedTask; | 
| -  final Completer<List> _completer = new Completer<List>(); | 
| -  final List results = []; | 
| - | 
| -  /** Gets the task that failed, if any. */ | 
| -  Future get failedTask => _failedTask; | 
| - | 
| -  /** | 
| -   * Wait for [task] to complete. | 
| -   * | 
| -   * If this group has already been marked as completed, you'll get a | 
| -   * [StateError]. | 
| -   * | 
| -   * If this group has a [failedTask], new tasks will be ignored, because the | 
| -   * error has already been signaled. | 
| -   */ | 
| -  void add(Future task) { | 
| -    if (_failedTask != null) return; | 
| -    if (_pending == _FINISHED) throw new StateError("Future already completed"); | 
| - | 
| -    _pending++; | 
| -    var i = results.length; | 
| -    results.add(null); | 
| -    task.then((res) { | 
| -      results[i] = res; | 
| -      if (_failedTask != null) return; | 
| -      _pending--; | 
| -      if (_pending == 0) { | 
| -        _pending = _FINISHED; | 
| -        _completer.complete(results); | 
| -      } | 
| -    }, onError: (e) { | 
| -      if (_failedTask != null) return; | 
| -      _failedTask = task; | 
| -      _completer.completeError(e, getAttachedStackTrace(e)); | 
| -    }); | 
| -  } | 
| - | 
| -  Future<List> get future => _completer.future; | 
| -} | 
| - | 
| - | 
| /** | 
| - * Escapes [text] for use in a Dart string. | 
| - * [single] specifies single quote `'` vs double quote `"`. | 
| - * [triple] indicates that a triple-quoted string, such as `'''` or `"""`. | 
| + * Converts a string name with hyphens into an identifier, by removing hyphens | 
| + * and capitalizing the following letter. Optionally [startUppercase] to | 
| + * captialize the first letter. | 
| */ | 
| -String escapeDartString(String text, {bool single: true, bool triple: false}) { | 
| -  // Note: don't allocate anything until we know we need it. | 
| -  StringBuffer result = null; | 
| - | 
| -  for (int i = 0; i < text.length; i++) { | 
| -    int code = text.codeUnitAt(i); | 
| -    var replace = null; | 
| -    switch (code) { | 
| -      case 92/*'\\'*/: replace = r'\\'; break; | 
| -      case 36/*r'$'*/: replace = r'\$'; break; | 
| -      case 34/*'"'*/:  if (!single) replace = r'\"'; break; | 
| -      case 39/*"'"*/:  if (single) replace = r"\'"; break; | 
| -      case 10/*'\n'*/: if (!triple) replace = r'\n'; break; | 
| -      case 13/*'\r'*/: if (!triple) replace = r'\r'; break; | 
| - | 
| -      // Note: we don't escape unicode characters, under the assumption that | 
| -      // writing the file in UTF-8 will take care of this. | 
| - | 
| -      // TODO(jmesserly): do we want to replace any other non-printable | 
| -      // characters (such as \f) for readability? | 
| -    } | 
| - | 
| -    if (replace != null && result == null) { | 
| -      result = new StringBuffer(text.substring(0, i)); | 
| +String toCamelCase(String hyphenedName, {bool startUppercase: false}) { | 
| +  var segments = hyphenedName.split('-'); | 
| +  int start = startUppercase ? 0 : 1; | 
| +  for (int i = start; i < segments.length; i++) { | 
| +    var segment = segments[i]; | 
| +    if (segment.length > 0) { | 
| +      // Character between 'a'..'z' mapped to 'A'..'Z' | 
| +      segments[i] = '${segment[0].toUpperCase()}${segment.substring(1)}'; | 
| } | 
| - | 
| -    if (result != null) result.write(replace != null ? replace : text[i]); | 
| } | 
| - | 
| -  return result == null ? text : result.toString(); | 
| +  return segments.join(''); | 
| } | 
|  | 
| -/** Iterates through an infinite sequence, starting from zero. */ | 
| -class IntIterator implements Iterator<int> { | 
| -  int _next = -1; | 
| - | 
| -  int get current => _next < 0 ? null : _next; | 
| - | 
| -  bool moveNext() { | 
| -    _next++; | 
| -    return true; | 
| +/** Reverse of [toCamelCase]. */ | 
| +String toHyphenedName(String word) { | 
| +  var sb = new StringBuffer(); | 
| +  for (int i = 0; i < word.length; i++) { | 
| +    var lower = word[i].toLowerCase(); | 
| +    if (word[i] != lower && i > 0) sb.write('-'); | 
| +    sb.write(lower); | 
| } | 
| +  return sb.toString(); | 
| } | 
|  |