// Copyright (c) 2012, 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 csslib.parser;

import 'dart:math' as math;

import 'package:source_span/source_span.dart';

import "visitor.dart";
import 'src/messages.dart';
import 'src/options.dart';

part 'src/analyzer.dart';
part 'src/polyfill.dart';
part 'src/property.dart';
part 'src/token.dart';
part 'src/tokenizer_base.dart';
part 'src/tokenizer.dart';
part 'src/tokenkind.dart';


/** Used for parser lookup ahead (used for nested selectors Less support). */
class ParserState extends TokenizerState {
  final Token peekToken;
  final Token previousToken;

  ParserState(this.peekToken, this.previousToken, Tokenizer tokenizer)
      : super(tokenizer);
}

// TODO(jmesserly): this should not be global
void _createMessages({List<Message> errors, List<String> options}) {
  if (errors == null) errors = [];

  if (options == null) {
    options = ['--no-colors', 'memory'];
  }
  var opt = PreprocessorOptions.parse(options);
  messages = new Messages(options: opt, printHandler: errors.add);
}

/** CSS checked mode enabled. */
bool get isChecked => messages.options.checked;

// TODO(terry): Remove nested name parameter.
/** Parse and analyze the CSS file. */
StyleSheet compile(input, {List<Message> errors, List<String> options,
    bool nested: true,
    bool polyfill: false,
    List<StyleSheet> includes: null}) {

  if (includes == null) {
    includes = [];
  }

  var source = _inputAsString(input);

  _createMessages(errors: errors, options: options);

  var file = new SourceFile(source);

  var tree = new _Parser(file, source).parse();

  analyze([tree], errors: errors, options: options);

  if (polyfill) {
    var processCss = new PolyFill(messages, true);
    processCss.process(tree, includes: includes);
  }

  return tree;
}

/** Analyze the CSS file. */
void analyze(List<StyleSheet> styleSheets,
    {List<Message> errors, List<String> options}) {

  _createMessages(errors: errors, options: options);
  new Analyzer(styleSheets, messages).run();
}

/**
 * Parse the [input] CSS stylesheet into a tree. The [input] can be a [String],
 * or [List<int>] of bytes and returns a [StyleSheet] AST.  The optional
 * [errors] list will contain each error/warning as a [Message].
 */
StyleSheet parse(input, {List<Message> errors, List<String> options}) {
  var source = _inputAsString(input);

  _createMessages(errors: errors, options: options);

  var file = new SourceFile(source);
  return new _Parser(file, source).parse();
}

/**
 * Parse the [input] CSS selector into a tree. The [input] can be a [String],
 * or [List<int>] of bytes and returns a [StyleSheet] AST.  The optional
 * [errors] list will contain each error/warning as a [Message].
 */
// TODO(jmesserly): should rename "parseSelector" and return Selector
StyleSheet selector(input, {List<Message> errors}) {
  var source = _inputAsString(input);

  _createMessages(errors: errors);

  var file = new SourceFile(source);
  return (new _Parser(file, source)
      ..tokenizer.inSelector = true)
      .parseSelector();
}

SelectorGroup parseSelectorGroup(input, {List<Message> errors}) {
  var source = _inputAsString(input);

  _createMessages(errors: errors);

  var file = new SourceFile(source);
  return (new _Parser(file, source)
      // TODO(jmesserly): this fix should be applied to the parser. It's tricky
      // because by the time the flag is set one token has already been fetched.
      ..tokenizer.inSelector = true)
      .processSelectorGroup();
}

String _inputAsString(input) {
  String source;

  if (input is String) {
    source = input;
  } else if (input is List<int>) {
    // TODO(terry): The parse function needs an "encoding" argument and will
    //              default to whatever encoding CSS defaults to.
    //
    // Here's some info about CSS encodings:
    // http://www.w3.org/International/questions/qa-css-charset.en.php
    //
    // As JMesserly suggests it will probably need a "preparser" html5lib
    // (encoding_parser.dart) that interprets the bytes as ASCII and scans for
    // @charset. But for now an "encoding" argument would work.  Often the
    // HTTP header will indicate the correct encoding.
    //
    // See encoding helpers at: package:html5lib/lib/src/char_encodings.dart
    // These helpers can decode in different formats given an encoding name
    // (mostly unicode, ascii, windows-1252 which is html5 default encoding).
    source = new String.fromCharCodes(input);
  } else {
    // TODO(terry): Support RandomAccessFile using console.
    throw new ArgumentError("'source' must be a String or "
        "List<int> (of bytes). RandomAccessFile not supported from this "
        "simple interface");
  }

  return source;
}

// TODO(terry): Consider removing this class when all usages can be eliminated
//               or replaced with compile API.
/** Public parsing interface for csslib. */
class Parser {
  final _Parser _parser;

  // TODO(jmesserly): having file and text is redundant.
  Parser(SourceFile file, String text, {int start: 0, String baseUrl}) :
    _parser = new _Parser(file, text, start: start, baseUrl: baseUrl);

  StyleSheet parse() => _parser.parse();
}

/** A simple recursive descent parser for CSS. */
class _Parser {
  final Tokenizer tokenizer;

  /** Base url of CSS file. */
  final String _baseUrl;

  /**
   * File containing the source being parsed, used to report errors with
   * source-span locations.
   */
  final SourceFile file;

  Token _previousToken;
  Token _peekToken;

  _Parser(SourceFile file, String text, {int start: 0, String baseUrl})
      : this.file = file,
        _baseUrl = baseUrl,
        tokenizer = new Tokenizer(file, text, true, start) {
    _peekToken = tokenizer.next();
  }

  /** Main entry point for parsing an entire CSS file. */
  StyleSheet parse() {
    List<TreeNode> productions = [];

    var start = _peekToken.span;
    while (!_maybeEat(TokenKind.END_OF_FILE) && !_peekKind(TokenKind.RBRACE)) {
      // TODO(terry): Need to handle charset.
      var directive = processDirective();
      if (directive != null) {
        productions.add(directive);
        _maybeEat(TokenKind.SEMICOLON);
      } else {
        RuleSet ruleset = processRuleSet();
        if (ruleset != null) {
          productions.add(ruleset);
        } else {
          break;
        }
      }
    }

    checkEndOfFile();

    return new StyleSheet(productions, _makeSpan(start));
  }

  /** Main entry point for parsing a simple selector sequence. */
  StyleSheet parseSelector() {
    List<TreeNode> productions = [];

    var start = _peekToken.span;
    while (!_maybeEat(TokenKind.END_OF_FILE) && !_peekKind(TokenKind.RBRACE)) {
      var selector = processSelector();
      if (selector != null) {
        productions.add(selector);
      }
    }

    checkEndOfFile();

    return new StyleSheet.selector(productions, _makeSpan(start));
  }

  /** Generate an error if [file] has not been completely consumed. */
  void checkEndOfFile() {
    if (!(_peekKind(TokenKind.END_OF_FILE) ||
        _peekKind(TokenKind.INCOMPLETE_COMMENT))) {
      _error('premature end of file unknown CSS', _peekToken.span);
    }
  }

  /** Guard to break out of parser when an unexpected end of file is found. */
  // TODO(jimhug): Failure to call this method can lead to inifinite parser
  //   loops.  Consider embracing exceptions for more errors to reduce
  //   the danger here.
  bool isPrematureEndOfFile() {
    if (_maybeEat(TokenKind.END_OF_FILE)) {
      _error('unexpected end of file', _peekToken.span);
      return true;
    } else {
      return false;
    }
  }

  ///////////////////////////////////////////////////////////////////
  // Basic support methods
  ///////////////////////////////////////////////////////////////////
  int _peek() {
    return _peekToken.kind;
  }

  Token _next({unicodeRange : false}) {
    _previousToken = _peekToken;
    _peekToken = tokenizer.next(unicodeRange: unicodeRange);
    return _previousToken;
  }

  bool _peekKind(int kind) {
    return _peekToken.kind == kind;
  }

  /* Is the next token a legal identifier?  This includes pseudo-keywords. */
  bool _peekIdentifier() {
    return TokenKind.isIdentifier(_peekToken.kind);
  }

  /** Marks the parser/tokenizer look ahead to support Less nested selectors. */
  ParserState get _mark =>
      new ParserState(_peekToken, _previousToken, tokenizer);

  /** Restores the parser/tokenizer state to state remembered by _mark. */
  void _restore(ParserState markedData) {
    tokenizer.restore(markedData);
    _peekToken = markedData.peekToken;
    _previousToken = markedData.previousToken;
  }

  bool _maybeEat(int kind, {unicodeRange : false}) {
    if (_peekToken.kind == kind) {
      _previousToken = _peekToken;
      _peekToken = tokenizer.next(unicodeRange: unicodeRange);
      return true;
    } else {
      return false;
    }
  }

  void _eat(int kind, {unicodeRange : false}) {
    if (!_maybeEat(kind, unicodeRange: unicodeRange)) {
      _errorExpected(TokenKind.kindToString(kind));
    }
  }

  void _eatSemicolon() {
    _eat(TokenKind.SEMICOLON);
  }

  void _errorExpected(String expected) {
    var tok = _next();
    var message;
    try {
      message = 'expected $expected, but found $tok';
    } catch (e) {
      message = 'parsing error expected $expected';
    }
    _error(message, tok.span);
  }

  void _error(String message, SourceSpan location) {
    if (location == null) {
      location = _peekToken.span;
    }
    messages.error(message, location);
  }

  void _warning(String message, SourceSpan location) {
    if (location == null) {
      location = _peekToken.span;
    }
    messages.warning(message, location);
  }

  SourceSpan _makeSpan(FileSpan start) {
    // TODO(terry): there are places where we are creating spans before we eat
    // the tokens, so using _previousToken is not always valid.
    // TODO(nweiz): use < rather than compareTo when SourceSpan supports it.
    if (_previousToken == null || _previousToken.span.compareTo(start) < 0) {
      return start;
    }
    return start.expand(_previousToken.span);
  }

  ///////////////////////////////////////////////////////////////////
  // Top level productions
  ///////////////////////////////////////////////////////////////////

  /**
   * The media_query_list production below replaces the media_list production
   * from CSS2 the new grammar is:
   *
   *   media_query_list
   *    : S* [media_query [ ',' S* media_query ]* ]?
   *   media_query
   *    : [ONLY | NOT]? S* media_type S* [ AND S* expression ]*
   *    | expression [ AND S* expression ]*
   *   media_type
   *    : IDENT
   *   expression
   *    : '(' S* media_feature S* [ ':' S* expr ]? ')' S*
   *   media_feature
   *    : IDENT
   */
  List<MediaQuery> processMediaQueryList() {
    var mediaQueries = [];

    bool firstTime = true;
    var mediaQuery;
    do {
      mediaQuery = processMediaQuery(firstTime == true);
      if (mediaQuery != null) {
        mediaQueries.add(mediaQuery);
        firstTime = false;
        continue;
      }

      // Any more more media types separated by comma.
      if (!_maybeEat(TokenKind.COMMA)) break;

      // Yep more media types start again.
      firstTime = true;
    } while ((!firstTime && mediaQuery != null) || firstTime);

    return mediaQueries;
  }

  MediaQuery processMediaQuery([bool startQuery = true]) {
    // Grammar: [ONLY | NOT]? S* media_type S*
    //          [ AND S* MediaExpr ]* | MediaExpr [ AND S* MediaExpr ]*

    var start = _peekToken.span;

    // Is it a unary media operator?
    var op = _peekToken.text;
    var opLen = op.length;
    var unaryOp = TokenKind.matchMediaOperator(op, 0, opLen);
    if (unaryOp != -1) {
      if (isChecked) {
        if (startQuery &&
            unaryOp != TokenKind.MEDIA_OP_NOT ||
            unaryOp != TokenKind.MEDIA_OP_ONLY) {
          _warning("Only the unary operators NOT and ONLY allowed",
              _makeSpan(start));
        }
        if (!startQuery && unaryOp != TokenKind.MEDIA_OP_AND) {
          _warning("Only the binary AND operator allowed", _makeSpan(start));
        }
      }
      _next();
      start = _peekToken.span;
    }

    var type;
    if (startQuery && unaryOp != TokenKind.MEDIA_OP_AND) {
      // Get the media type.
      if (_peekIdentifier()) type = identifier();
    }

    var exprs = [];

    if (unaryOp == -1 || unaryOp == TokenKind.MEDIA_OP_AND) {
      var andOp = false;
      while (true) {
        var expr = processMediaExpression(andOp);
        if (expr == null) break;

        exprs.add(expr);
        op = _peekToken.text;
        opLen = op.length;
        andOp = TokenKind.matchMediaOperator(op, 0, opLen) ==
            TokenKind.MEDIA_OP_AND;
        if (!andOp) break;
        _next();
      }
    }

    if (unaryOp != -1 || type != null || exprs.length > 0) {
      return new MediaQuery(unaryOp, type, exprs, _makeSpan(start));
    }
  }

  MediaExpression processMediaExpression([bool andOperator = false]) {
    var start = _peekToken.span;

    // Grammar: '(' S* media_feature S* [ ':' S* expr ]? ')' S*
    if (_maybeEat(TokenKind.LPAREN)) {
      if (_peekIdentifier()) {
        var feature = identifier();           // Media feature.
        while (_maybeEat(TokenKind.COLON)) {
          var startExpr = _peekToken.span;
          var exprs = processExpr();
          if (_maybeEat(TokenKind.RPAREN)) {
            return new MediaExpression(andOperator, feature, exprs,
                _makeSpan(startExpr));
          } else if (isChecked) {
            _warning("Missing parenthesis around media expression",
                _makeSpan(start));
            return null;
          }
        }
      } else if (isChecked) {
        _warning("Missing media feature in media expression", _makeSpan(start));
        return null;
      }
    }
  }

  /**
   * Directive grammar:
   *
   *  import:             '@import' [string | URI] media_list?
   *  media:              '@media' media_query_list '{' ruleset '}'
   *  page:               '@page' [':' IDENT]? '{' declarations '}'
   *  stylet:             '@stylet' IDENT '{' ruleset '}'
   *  media_query_list:   IDENT [',' IDENT]
   *  keyframes:          '@-webkit-keyframes ...' (see grammar below).
   *  font_face:          '@font-face' '{' declarations '}'
   *  namespace:          '@namespace name url("xmlns")
   *  host:               '@host '{' ruleset '}'
   *  mixin:              '@mixin name [(args,...)] '{' declarations/ruleset '}'
   *  include:            '@include name [(@arg,@arg1)]
   *                      '@include name [(@arg...)]
   *  content             '@content'
   */
  processDirective() {
    var start = _peekToken.span;

    var tokId = processVariableOrDirective();
    if (tokId is VarDefinitionDirective) return tokId;
    switch (tokId) {
      case TokenKind.DIRECTIVE_IMPORT:
        _next();

        // @import "uri_string" or @import url("uri_string") are identical; only
        // a url can follow an @import.
        String importStr;
        if (_peekIdentifier()) {
          var func = processFunction(identifier());
          if (func is UriTerm) {
            importStr = func.text;
          }
        } else {
          importStr = processQuotedString(false);
        }

        // Any medias?
        var medias = processMediaQueryList();

        if (importStr == null) {
          _error('missing import string', _peekToken.span);
        }

        return new ImportDirective(importStr.trim(), medias, _makeSpan(start));

      case TokenKind.DIRECTIVE_MEDIA:
        _next();

        // Any medias?
        var media = processMediaQueryList();

        List<TreeNode> rulesets = [];
        if (_maybeEat(TokenKind.LBRACE)) {
          while (!_maybeEat(TokenKind.END_OF_FILE)) {
            RuleSet ruleset = processRuleSet();
            if (ruleset == null) break;
            rulesets.add(ruleset);
          }

          if (!_maybeEat(TokenKind.RBRACE)) {
            _error('expected } after ruleset for @media', _peekToken.span);
          }
        } else {
          _error('expected { after media before ruleset', _peekToken.span);
        }
        return new MediaDirective(media, rulesets, _makeSpan(start));

      case TokenKind.DIRECTIVE_HOST:
        _next();

        List<TreeNode> rulesets = [];
        if (_maybeEat(TokenKind.LBRACE)) {
          while (!_maybeEat(TokenKind.END_OF_FILE)) {
            RuleSet ruleset = processRuleSet();
            if (ruleset == null) break;
            rulesets.add(ruleset);
          }

          if (!_maybeEat(TokenKind.RBRACE)) {
            _error('expected } after ruleset for @host', _peekToken.span);
          }
        } else {
          _error('expected { after host before ruleset', _peekToken.span);
        }
        return new HostDirective(rulesets, _makeSpan(start));

      case TokenKind.DIRECTIVE_PAGE:
        /*
         * @page S* IDENT? pseudo_page?
         *      S* '{' S*
         *      [ declaration | margin ]?
         *      [ ';' S* [ declaration | margin ]? ]* '}' S*
         *
         * pseudo_page :
         *      ':' [ "left" | "right" | "first" ]
         *
         * margin :
         *      margin_sym S* '{' declaration [ ';' S* declaration? ]* '}' S*
         *
         * margin_sym : @top-left-corner, @top-left, @bottom-left, etc.
         *
         * See http://www.w3.org/TR/css3-page/#CSS21
         */
        _next();

        // Page name
        var name;
        if (_peekIdentifier()) {
          name = identifier();
        }

        // Any pseudo page?
        var pseudoPage;
        if (_maybeEat(TokenKind.COLON)) {
          if (_peekIdentifier()) {
            pseudoPage = identifier();
            // TODO(terry): Normalize pseudoPage to lowercase.
            if (isChecked &&
                !(pseudoPage.name == 'left' ||
                  pseudoPage.name == 'right' ||
                  pseudoPage.name == 'first')) {
              _warning("Pseudo page must be left, top or first",
                  pseudoPage.span);
              return null;
            }
          }
        }

        String pseudoName = pseudoPage is Identifier ? pseudoPage.name : '';
        String ident = name is Identifier ? name.name : '';
        return new PageDirective(ident, pseudoName,
            processMarginsDeclarations(), _makeSpan(start));

      case TokenKind.DIRECTIVE_CHARSET:
        // @charset S* STRING S* ';'
        _next();

        var charEncoding = processQuotedString(false);
        if (isChecked && charEncoding == null) {
          // Missing character encoding.
          _warning('missing character encoding string', _makeSpan(start));
        }

        return new CharsetDirective(charEncoding, _makeSpan(start));

      // TODO(terry): Workaround Dart2js bug continue not implemented in switch
      //              see https://code.google.com/p/dart/issues/detail?id=8270
      /*
      case TokenKind.DIRECTIVE_MS_KEYFRAMES:
        // TODO(terry): For now only IE 10 (are base level) supports @keyframes,
        // -moz- has only been optional since Oct 2012 release of Firefox, not
        // all versions of webkit support @keyframes and opera doesn't yet
        // support w/o -o- prefix.  Add more warnings for other prefixes when
        // they become optional.
        if (isChecked) {
          _warning('@-ms-keyframes should be @keyframes', _makeSpan(start));
        }
        continue keyframeDirective;

      keyframeDirective:
      */
      case TokenKind.DIRECTIVE_KEYFRAMES:
      case TokenKind.DIRECTIVE_WEB_KIT_KEYFRAMES:
      case TokenKind.DIRECTIVE_MOZ_KEYFRAMES:
      case TokenKind.DIRECTIVE_O_KEYFRAMES:
      // TODO(terry): Remove workaround when bug 8270 is fixed.
      case TokenKind.DIRECTIVE_MS_KEYFRAMES:
        if (tokId == TokenKind.DIRECTIVE_MS_KEYFRAMES && isChecked) {
          _warning('@-ms-keyframes should be @keyframes', _makeSpan(start));
        }
      // TODO(terry): End of workaround.

        /*  Key frames grammar:
         *
         *  @[browser]? keyframes [IDENT|STRING] '{' keyframes-blocks '}';
         *
         *  browser: [-webkit-, -moz-, -ms-, -o-]
         *
         *  keyframes-blocks:
         *    [keyframe-selectors '{' declarations '}']* ;
         *
         *  keyframe-selectors:
         *    ['from'|'to'|PERCENTAGE] [',' ['from'|'to'|PERCENTAGE] ]* ;
         */
        _next();

        var name;
        if (_peekIdentifier()) {
          name = identifier();
        }

        _eat(TokenKind.LBRACE);

        var keyframe = new KeyFrameDirective(tokId, name, _makeSpan(start));

        do {
          Expressions selectors = new Expressions(_makeSpan(start));

          do {
            var term = processTerm();

            // TODO(terry): Only allow from, to and PERCENTAGE ...

            selectors.add(term);
          } while (_maybeEat(TokenKind.COMMA));

          keyframe.add(new KeyFrameBlock(selectors, processDeclarations(),
              _makeSpan(start)));

        } while (!_maybeEat(TokenKind.RBRACE) && !isPrematureEndOfFile());

        return keyframe;

      case TokenKind.DIRECTIVE_FONTFACE:
        _next();
        return new FontFaceDirective(processDeclarations(), _makeSpan(start));

      case TokenKind.DIRECTIVE_STYLET:
        /* Stylet grammar:
         *
         *  @stylet IDENT '{'
         *    ruleset
         *  '}'
         */
        _next();

        var name;
        if (_peekIdentifier()) {
          name = identifier();
        }

        _eat(TokenKind.LBRACE);

        List<TreeNode> productions = [];

        start = _peekToken.span;
        while (!_maybeEat(TokenKind.END_OF_FILE)) {
          RuleSet ruleset = processRuleSet();
          if (ruleset == null) {
            break;
          }
          productions.add(ruleset);
        }

        _eat(TokenKind.RBRACE);

        return new StyletDirective(name, productions, _makeSpan(start));

      case TokenKind.DIRECTIVE_NAMESPACE:
        /* Namespace grammar:
         *
         * @namespace S* [namespace_prefix S*]? [STRING|URI] S* ';' S*
         * namespace_prefix : IDENT
         *
         */
        _next();

        var prefix;
        if (_peekIdentifier()) {
          prefix = identifier();
        }

        // The namespace URI can be either a quoted string url("uri_string")
        // are identical.
        String namespaceUri;
        if (_peekIdentifier()) {
          var func = processFunction(identifier());
          if (func is UriTerm) {
            namespaceUri = func.text;
          }
        } else {
          if (prefix != null && prefix.name == 'url') {
            var func = processFunction(prefix);
            if (func is UriTerm) {
              // @namespace url("");
              namespaceUri = func.text;
              prefix = null;
            }
          } else {
            namespaceUri = processQuotedString(false);
          }
        }

        return new NamespaceDirective(prefix != null ? prefix.name : '',
            namespaceUri, _makeSpan(start));

      case TokenKind.DIRECTIVE_MIXIN:
        return processMixin();

      case TokenKind.DIRECTIVE_INCLUDE:
        return processInclude( _makeSpan(start));

      case TokenKind.DIRECTIVE_CONTENT:
        // TODO(terry): TBD
        _warning("@content not implemented.", _makeSpan(start));
        return null;
    }
    return null;
  }

  /**
   * Parse the mixin beginning token offset [start]. Returns a [MixinDefinition]
   * node.
   *
   * Mixin grammar:
   *
   *  @mixin IDENT [(args,...)] '{'
   *    [ruleset | property | directive]*
   *  '}'
   */
  MixinDefinition processMixin() {
    _next();

    var name = identifier();

    List<VarDefinitionDirective> params = [];
    // Any parameters?
    if (_maybeEat(TokenKind.LPAREN)) {
      var mustHaveParam = false;
      var keepGoing = true;
      while (keepGoing) {
        var varDef = processVariableOrDirective(mixinParameter: true);
        if (varDef is VarDefinitionDirective || varDef is VarDefinition) {
          params.add(varDef);
        } else if (mustHaveParam) {
          _warning("Expecting parameter", _makeSpan(_peekToken.span));
          keepGoing = false;
        }
        if (_maybeEat(TokenKind.COMMA)) {
          mustHaveParam = true;
          continue;
        }
        keepGoing = !_maybeEat(TokenKind.RPAREN);
      }
    }

    _eat(TokenKind.LBRACE);

    List<TreeNode> productions = [];
    List<TreeNode> declarations = [];
    var mixinDirective;

    var start = _peekToken.span;
    while (!_maybeEat(TokenKind.END_OF_FILE)) {
      var directive = processDirective();
      if (directive != null) {
        productions.add(directive);
        continue;
      }

      var declGroup = processDeclarations(checkBrace: false);
      var decls = [];
      if (declGroup.declarations.any((decl) {
        return decl is Declaration &&
            decl is! IncludeMixinAtDeclaration;
      })) {
        var newDecls = [];
        productions.forEach((include) {
          // If declGroup has items that are declarations then we assume
          // this mixin is a declaration mixin not a top-level mixin.
          if (include is IncludeDirective) {
            newDecls.add(new IncludeMixinAtDeclaration(include,
                include.span));
          } else {
            _warning("Error mixing of top-level vs declarations mixins",
                _makeSpan(include.span));
          }
        });
        declGroup.declarations.insertAll(0, newDecls);
        productions = [];
      } else {
        // Declarations are just @includes make it a list of productions
        // not a declaration group (anything else is a ruleset).  Make it a
        // list of productions, not a declaration group.
        for (var decl in declGroup.declarations) {
          productions.add(decl is IncludeMixinAtDeclaration ?
              decl.include : decl);
        };
        declGroup.declarations.clear();
      }

      if (declGroup.declarations.isNotEmpty) {
        if (productions.isEmpty) {
          mixinDirective = new MixinDeclarationDirective(name.name, params,
              false, declGroup, _makeSpan(start));
          break;
        } else {
          for (var decl in declGroup.declarations) {
            productions.add(decl is IncludeMixinAtDeclaration ?
                decl.include : decl);
          }
        }
      } else {
        mixinDirective = new MixinRulesetDirective(name.name, params,
            false, productions, _makeSpan(start));
        break;
      }
    }

    if (productions.isNotEmpty) {
      mixinDirective = new MixinRulesetDirective(name.name, params,
          false, productions, _makeSpan(start));
    }

    _eat(TokenKind.RBRACE);

    return mixinDirective;
  }

  /**
   * Returns a VarDefinitionDirective or VarDefinition if a varaible otherwise
   * return the token id of a directive or -1 if neither.
   */
  processVariableOrDirective({bool mixinParameter: false}) {
    var start = _peekToken.span;

    var tokId = _peek();
    // Handle case for @ directive (where there's a whitespace between the @
    // sign and the directive name.  Technically, it's not valid grammar but
    // a number of CSS tests test for whitespace between @ and name.
    if (tokId == TokenKind.AT) {
      Token tok = _next();
      tokId = _peek();
      if (_peekIdentifier()) {
        // Is it a directive?
        var directive = _peekToken.text;
        var directiveLen = directive.length;
        tokId = TokenKind.matchDirectives(directive, 0, directiveLen);
        if (tokId == -1) {
          tokId = TokenKind.matchMarginDirectives(directive, 0, directiveLen);
        }
      }

      if (tokId == -1) {
        if (messages.options.lessSupport) {
          // Less compatibility:
          //    @name: value;      =>    var-name: value;       (VarDefinition)
          //    property: @name;   =>    property: var(name);   (VarUsage)
          var name;
          if (_peekIdentifier()) {
            name = identifier();
          }

          Expressions exprs;
          if (mixinParameter && _maybeEat(TokenKind.COLON)) {
            exprs = processExpr();
          } else if (!mixinParameter) {
            _eat(TokenKind.COLON);
            exprs = processExpr();
          }

          var span = _makeSpan(start);
          return new VarDefinitionDirective(
              new VarDefinition(name, exprs, span), span);
        } else if (isChecked) {
          _error('unexpected directive @$_peekToken', _peekToken.span);
        }
      }
    } else if (mixinParameter && _peekToken.kind == TokenKind.VAR_DEFINITION) {
      _next();
      var definedName;
      if (_peekIdentifier()) definedName = identifier();

      Expressions exprs;
      if (_maybeEat(TokenKind.COLON)) {
        exprs = processExpr();
      }

      return new VarDefinition(definedName, exprs, _makeSpan(start));
    }

    return tokId;
  }

  IncludeDirective processInclude(SourceSpan span, {bool eatSemiColon: true}) {
    /* Stylet grammar:
    *
     *  @include IDENT [(args,...)];
     */
    _next();

    var name;
    if (_peekIdentifier()) {
      name = identifier();
    }

    var params = [];

    // Any parameters?  Parameters can be multiple terms per argument e.g.,
    // 3px solid yellow, green is two parameters:
    //    1. 3px solid yellow
    //    2. green
    // the first has 3 terms and the second has 1 term.
    if (_maybeEat(TokenKind.LPAREN)) {
      var terms = [];
      var expr;
      var keepGoing = true;
      while (keepGoing && (expr = processTerm()) != null) {
        // VarUsage is returns as a list
        terms.add(expr is List ? expr[0] : expr);
        keepGoing = !_peekKind(TokenKind.RPAREN);
        if (keepGoing) {
          if (_maybeEat(TokenKind.COMMA)) {
            params.add(terms);
            terms = [];
          }
        }
      }
      params.add(terms);
      _maybeEat(TokenKind.RPAREN);
    }

    if (eatSemiColon) {
      _eat(TokenKind.SEMICOLON);
    }

    return new IncludeDirective(name.name, params, span);
  }

  RuleSet processRuleSet([SelectorGroup selectorGroup]) {
    if (selectorGroup == null) {
      selectorGroup = processSelectorGroup();
    }
    if (selectorGroup != null) {
      return new RuleSet(selectorGroup, processDeclarations(),
          selectorGroup.span);
    }
  }

  /**
   * Look ahead to see if what should be a declaration is really a selector.
   * If it's a selector than it's a nested selector.  This support's Less'
   * nested selector syntax (requires a look ahead). E.g.,
   *
   *    div {
   *      width : 20px;
   *      span {
   *        color: red;
   *      }
   *    }
   *
   * Two tag name selectors div and span equivalent to:
   *
   *    div {
   *      width: 20px;
   *    }
   *    div span {
   *      color: red;
   *    }
   *
   * Return [:null:] if no selector or [SelectorGroup] if a selector was parsed.
   */
  SelectorGroup _nestedSelector() {
    Messages oldMessages = messages;
    _createMessages();

    var markedData = _mark;

    // Look a head do we have a nested selector instead of a declaration?
    SelectorGroup selGroup = processSelectorGroup();

    var nestedSelector = selGroup != null && _peekKind(TokenKind.LBRACE) &&
        messages.messages.isEmpty;

    if (!nestedSelector) {
      // Not a selector so restore the world.
      _restore(markedData);
      messages = oldMessages;
      return null;
    } else {
      // Remember any messages from look ahead.
      oldMessages.mergeMessages(messages);
      messages = oldMessages;
      return selGroup;
    }
  }

  DeclarationGroup processDeclarations({bool checkBrace: true}) {
    var start = _peekToken.span;

    if (checkBrace) _eat(TokenKind.LBRACE);

    List decls = [];
    List dartStyles = [];             // List of latest styles exposed to Dart.

    do {
      var selectorGroup = _nestedSelector();
      while (selectorGroup != null) {
        // Nested selector so process as a ruleset.
        var ruleset = processRuleSet(selectorGroup);
        decls.add(ruleset);
        selectorGroup = _nestedSelector();
      }

      Declaration decl = processDeclaration(dartStyles);
      if (decl != null) {
        if (decl.hasDartStyle) {
          var newDartStyle = decl.dartStyle;

          // Replace or add latest Dart style.
          bool replaced = false;
          for (var i = 0; i < dartStyles.length; i++) {
            var dartStyle = dartStyles[i];
            if (dartStyle.isSame(newDartStyle)) {
              dartStyles[i] = newDartStyle;
              replaced = true;
              break;
            }
          }
          if (!replaced) {
            dartStyles.add(newDartStyle);
          }
        }
        decls.add(decl);
      }
    } while (_maybeEat(TokenKind.SEMICOLON));

    if (checkBrace) _eat(TokenKind.RBRACE);

    // Fixup declaration to only have dartStyle that are live for this set of
    // declarations.
    for (var decl in decls) {
      if (decl is Declaration) {
        if (decl.hasDartStyle && dartStyles.indexOf(decl.dartStyle) < 0) {
          // Dart style not live, ignore these styles in this Declarations.
          decl.dartStyle = null;
        }
      }
    }

    return new DeclarationGroup(decls, _makeSpan(start));
  }

  List<DeclarationGroup> processMarginsDeclarations() {
    List groups = [];

    var start = _peekToken.span;

    _eat(TokenKind.LBRACE);

    List<Declaration> decls = [];
    List dartStyles = [];             // List of latest styles exposed to Dart.

    do {
      switch (_peek()) {
        case TokenKind.MARGIN_DIRECTIVE_TOPLEFTCORNER:
        case TokenKind.MARGIN_DIRECTIVE_TOPLEFT:
        case TokenKind.MARGIN_DIRECTIVE_TOPCENTER:
        case TokenKind.MARGIN_DIRECTIVE_TOPRIGHT:
        case TokenKind.MARGIN_DIRECTIVE_TOPRIGHTCORNER:
        case TokenKind.MARGIN_DIRECTIVE_BOTTOMLEFTCORNER:
        case TokenKind.MARGIN_DIRECTIVE_BOTTOMLEFT:
        case TokenKind.MARGIN_DIRECTIVE_BOTTOMCENTER:
        case TokenKind.MARGIN_DIRECTIVE_BOTTOMRIGHT:
        case TokenKind.MARGIN_DIRECTIVE_BOTTOMRIGHTCORNER:
        case TokenKind.MARGIN_DIRECTIVE_LEFTTOP:
        case TokenKind.MARGIN_DIRECTIVE_LEFTMIDDLE:
        case TokenKind.MARGIN_DIRECTIVE_LEFTBOTTOM:
        case TokenKind.MARGIN_DIRECTIVE_RIGHTTOP:
        case TokenKind.MARGIN_DIRECTIVE_RIGHTMIDDLE:
        case TokenKind.MARGIN_DIRECTIVE_RIGHTBOTTOM:
          // Margin syms processed.
          //   margin :
          //      margin_sym S* '{' declaration [ ';' S* declaration? ]* '}' S*
          //
          //      margin_sym : @top-left-corner, @top-left, @bottom-left, etc.
          var marginSym = _peek();

          _next();

          var declGroup = processDeclarations();
          if (declGroup != null) {
            groups.add(new MarginGroup(marginSym, declGroup.declarations,
                _makeSpan(start)));
          }
          break;
        default:
          Declaration decl = processDeclaration(dartStyles);
          if (decl != null) {
            if (decl.hasDartStyle) {
              var newDartStyle = decl.dartStyle;

              // Replace or add latest Dart style.
              bool replaced = false;
              for (var i = 0; i < dartStyles.length; i++) {
                var dartStyle = dartStyles[i];
                if (dartStyle.isSame(newDartStyle)) {
                  dartStyles[i] = newDartStyle;
                  replaced = true;
                  break;
                }
              }
              if (!replaced) {
                dartStyles.add(newDartStyle);
              }
            }
            decls.add(decl);
          }
          _maybeEat(TokenKind.SEMICOLON);
          break;
      }
    } while (!_maybeEat(TokenKind.RBRACE) && !isPrematureEndOfFile());

    // Fixup declaration to only have dartStyle that are live for this set of
    // declarations.
    for (var decl in decls) {
      if (decl.hasDartStyle && dartStyles.indexOf(decl.dartStyle) < 0) {
        // Dart style not live, ignore these styles in this Declarations.
        decl.dartStyle = null;
      }
    }

    if (decls.length > 0) {
      groups.add(new DeclarationGroup(decls, _makeSpan(start)));
    }

    return groups;
  }

  SelectorGroup processSelectorGroup() {
    List<Selector> selectors = [];
    var start = _peekToken.span;

    do {
      Selector selector = processSelector();
      if (selector != null) {
        selectors.add(selector);
      }
    } while (_maybeEat(TokenKind.COMMA));

    if (selectors.length > 0) {
      return new SelectorGroup(selectors, _makeSpan(start));
    }
  }

  /**
   * Return list of selectors
   */
  Selector processSelector() {
    var simpleSequences = <SimpleSelectorSequence>[];
    var start = _peekToken.span;
    while (true) {
      // First item is never descendant make sure it's COMBINATOR_NONE.
      var selectorItem = simpleSelectorSequence(simpleSequences.length == 0);
      if (selectorItem != null) {
        simpleSequences.add(selectorItem);
      } else {
        break;
      }
    }

    if (simpleSequences.length > 0) {
      return new Selector(simpleSequences, _makeSpan(start));
    }
  }

  simpleSelectorSequence(bool forceCombinatorNone) {
    var start = _peekToken.span;
    var combinatorType = TokenKind.COMBINATOR_NONE;
    var thisOperator = false;

    switch (_peek()) {
      case TokenKind.PLUS:
        _eat(TokenKind.PLUS);
        combinatorType = TokenKind.COMBINATOR_PLUS;
        break;
      case TokenKind.GREATER:
        _eat(TokenKind.GREATER);
        combinatorType = TokenKind.COMBINATOR_GREATER;
        break;
      case TokenKind.TILDE:
        _eat(TokenKind.TILDE);
        combinatorType = TokenKind.COMBINATOR_TILDE;
        break;
      case TokenKind.AMPERSAND:
        _eat(TokenKind.AMPERSAND);
        thisOperator = true;
        break;
      }

    // Check if WHITESPACE existed between tokens if so we're descendent.
    if (combinatorType == TokenKind.COMBINATOR_NONE && !forceCombinatorNone) {
      if (this._previousToken != null &&
          this._previousToken.end != this._peekToken.start) {
        combinatorType = TokenKind.COMBINATOR_DESCENDANT;
      }
    }

    var span = _makeSpan(start);
    var simpleSel = thisOperator ?
        new ElementSelector(new ThisOperator(span), span) : simpleSelector();
    if (simpleSel == null &&
        (combinatorType == TokenKind.COMBINATOR_PLUS ||
        combinatorType == TokenKind.COMBINATOR_GREATER ||
        combinatorType == TokenKind.COMBINATOR_TILDE)) {
      // For "+ &", "~ &" or "> &" a selector sequence with no name is needed
      // so that the & will have a combinator too.  This is needed to
      // disambiguate selector expressions:
      //    .foo&:hover     combinator before & is NONE
      //    .foo &          combinator before & is DESCDENDANT
      //    .foo > &        combinator before & is GREATER
      simpleSel =  new ElementSelector(new Identifier("", span), span);
    }
    if (simpleSel != null) {
      return new SimpleSelectorSequence(simpleSel, span, combinatorType);
    }
  }

  /**
   * Simple selector grammar:
   *
   *    simple_selector_sequence
   *       : [ type_selector | universal ]
   *         [ HASH | class | attrib | pseudo | negation ]*
   *       | [ HASH | class | attrib | pseudo | negation ]+
   *    type_selector
   *       : [ namespace_prefix ]? element_name
   *    namespace_prefix
   *       : [ IDENT | '*' ]? '|'
   *    element_name
   *       : IDENT
   *    universal
   *       : [ namespace_prefix ]? '*'
   *    class
   *       : '.' IDENT
   */
  simpleSelector() {
    // TODO(terry): Natalie makes a good point parsing of namespace and element
    //              are essentially the same (asterisk or identifier) other
    //              than the error message for element.  Should consolidate the
    //              code.
    // TODO(terry): Need to handle attribute namespace too.
    var first;
    var start = _peekToken.span;
    switch (_peek()) {
      case TokenKind.ASTERISK:
        // Mark as universal namespace.
        var tok = _next();
        first = new Wildcard(_makeSpan(tok.span));
        break;
      case TokenKind.IDENTIFIER:
        first = identifier();
        break;
      default:
        // Expecting simple selector.
        // TODO(terry): Could be a synthesized token like value, etc.
        if (TokenKind.isKindIdentifier(_peek())) {
          first = identifier();
        } else if (_peekKind(TokenKind.SEMICOLON)) {
          // Can't be a selector if we found a semi-colon.
          return null;
        }
        break;
    }

    if (_maybeEat(TokenKind.NAMESPACE)) {
      var element;
      switch (_peek()) {
        case TokenKind.ASTERISK:
          // Mark as universal element
          var tok = _next();
          element = new Wildcard(_makeSpan(tok.span));
          break;
        case TokenKind.IDENTIFIER:
          element = identifier();
          break;
        default:
          _error('expected element name or universal(*), but found $_peekToken',
              _peekToken.span);
          break;
      }

      return new NamespaceSelector(first,
          new ElementSelector(element, element.span), _makeSpan(start));
    } else if (first != null) {
      return new ElementSelector(first, _makeSpan(start));
    } else {
      // Check for HASH | class | attrib | pseudo | negation
      return simpleSelectorTail();
    }
  }

  bool _anyWhiteSpaceBeforePeekToken(int kind) {
    if (_previousToken != null && _peekToken != null &&
        _previousToken.kind == kind) {
      // If end of previous token isn't same as the start of peek token then
      // there's something between these tokens probably whitespace.
      return _previousToken.end != _peekToken.start;
    }

    return false;
  }

  /**
   * type_selector | universal | HASH | class | attrib | pseudo
   */
  simpleSelectorTail() {
    // Check for HASH | class | attrib | pseudo | negation
    var start = _peekToken.span;
    switch (_peek()) {
      case TokenKind.HASH:
        _eat(TokenKind.HASH);

        var hasWhiteSpace = false;
        if (_anyWhiteSpaceBeforePeekToken(TokenKind.HASH)) {
          _warning("Not a valid ID selector expected #id", _makeSpan(start));
          hasWhiteSpace = true;
        }
        if (_peekIdentifier()) {
          var id = identifier();
          if (hasWhiteSpace) {
            // Generate bad selector id (normalized).
            id.name = " ${id.name}";
          }
          return new IdSelector(id, _makeSpan(start));
        }
        return null;
      case TokenKind.DOT:
        _eat(TokenKind.DOT);

        bool hasWhiteSpace = false;
        if (_anyWhiteSpaceBeforePeekToken(TokenKind.DOT)) {
          _warning("Not a valid class selector expected .className",
              _makeSpan(start));
          hasWhiteSpace = true;
        }
        var id = identifier();
        if (hasWhiteSpace) {
          // Generate bad selector class (normalized).
          id.name = " ${id.name}";
        }
        return new ClassSelector(id, _makeSpan(start));
      case TokenKind.COLON:
        // :pseudo-class ::pseudo-element
        return processPseudoSelector(start);
      case TokenKind.LBRACK:
        return processAttribute();
      case TokenKind.DOUBLE:
        _error('name must start with a alpha character, but found a number',
            _peekToken.span);
        _next();
        break;
    }
  }

  processPseudoSelector(FileSpan start) {
    // :pseudo-class ::pseudo-element
    // TODO(terry): '::' should be token.
    _eat(TokenKind.COLON);
    var pseudoElement = _maybeEat(TokenKind.COLON);

    // TODO(terry): If no identifier specified consider optimizing out the
    //              : or :: and making this a normal selector.  For now,
    //              create an empty pseudoName.
    var pseudoName;
    if (_peekIdentifier()) {
      pseudoName = identifier();
    } else {
      return null;
    }

    // Functional pseudo?

    if (_peekToken.kind == TokenKind.LPAREN) {

      if (!pseudoElement && pseudoName.name.toLowerCase() == 'not') {
        _eat(TokenKind.LPAREN);

        // Negation :   ':NOT(' S* negation_arg S* ')'
        var negArg = simpleSelector();

        _eat(TokenKind.RPAREN);
        return new NegationSelector(negArg, _makeSpan(start));
      } else {
        // Special parsing for expressions in pseudo functions.  Minus is used
        // as operator not identifier.
        // TODO(jmesserly): we need to flip this before we eat the "(" as the
        // next token will be fetched when we do that. I think we should try to
        // refactor so we don't need this boolean; it seems fragile.
        tokenizer.inSelectorExpression = true;
        _eat(TokenKind.LPAREN);

        // Handle function expression.
        var span = _makeSpan(start);
        var expr = processSelectorExpression();

        tokenizer.inSelectorExpression = false;

        // Used during selector look-a-head if not a SelectorExpression is
        // bad.
        if (expr is! SelectorExpression) {
          _errorExpected("CSS expression");
          return null;
        }

        _eat(TokenKind.RPAREN);
        return (pseudoElement) ?
            new PseudoElementFunctionSelector(pseudoName, expr, span) :
              new PseudoClassFunctionSelector(pseudoName, expr, span);
      }
    }

    // TODO(terry): Need to handle specific pseudo class/element name and
    // backward compatible names that are : as well as :: as well as
    // parameters.  Current, spec uses :: for pseudo-element and : for
    // pseudo-class.  However, CSS2.1 allows for : to specify old
    // pseudo-elements (:first-line, :first-letter, :before and :after) any
    // new pseudo-elements defined would require a ::.
    return pseudoElement ?
        new PseudoElementSelector(pseudoName, _makeSpan(start)) :
          new PseudoClassSelector(pseudoName, _makeSpan(start));
  }

  /**
   *  In CSS3, the expressions are identifiers, strings, or of the form "an+b".
   *
   *    : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
   *
   *    num               [0-9]+|[0-9]*\.[0-9]+
   *    PLUS              '+'
   *    DIMENSION         {num}{ident}
   *    NUMBER            {num}
   */
  processSelectorExpression() {
    var start = _peekToken.span;

    var expressions = [];

    Token termToken;
    var value;

    var keepParsing = true;
    while (keepParsing) {
      switch (_peek()) {
        case TokenKind.PLUS:
          start = _peekToken.span;
          termToken = _next();
          expressions.add(new OperatorPlus(_makeSpan(start)));
          break;
        case TokenKind.MINUS:
          start = _peekToken.span;
          termToken = _next();
          expressions.add(new OperatorMinus(_makeSpan(start)));
          break;
        case TokenKind.INTEGER:
          termToken = _next();
          value = int.parse(termToken.text);
          break;
        case TokenKind.DOUBLE:
          termToken = _next();
          value = double.parse(termToken.text);
          break;
        case TokenKind.SINGLE_QUOTE:
          value = processQuotedString(false);
          value = "'${_escapeString(value, single: true)}'";
          return new LiteralTerm(value, value, _makeSpan(start));
        case TokenKind.DOUBLE_QUOTE:
          value = processQuotedString(false);
          value = '"${_escapeString(value)}"';
          return new LiteralTerm(value, value, _makeSpan(start));
        case TokenKind.IDENTIFIER:
          value = identifier();   // Snarf up the ident we'll remap, maybe.
          break;
        default:
          keepParsing = false;
      }

      if (keepParsing && value != null) {
        var unitTerm;
        // Don't process the dimension if MINUS or PLUS is next.
        if (_peek() != TokenKind.MINUS && _peek() != TokenKind.PLUS) {
          unitTerm = processDimension(termToken, value, _makeSpan(start));
        }
        if (unitTerm == null) {
          unitTerm = new LiteralTerm(value, value.name, _makeSpan(start));
        }
        expressions.add(unitTerm);

        value = null;
      }
    }

    return new SelectorExpression(expressions, _makeSpan(start));
  }

  //  Attribute grammar:
  //
  //  attributes :
  //    '[' S* IDENT S* [ ATTRIB_MATCHES S* [ IDENT | STRING ] S* ]? ']'
  //
  //  ATTRIB_MATCHES :
  //    [ '=' | INCLUDES | DASHMATCH | PREFIXMATCH | SUFFIXMATCH | SUBSTRMATCH ]
  //
  //  INCLUDES:         '~='
  //
  //  DASHMATCH:        '|='
  //
  //  PREFIXMATCH:      '^='
  //
  //  SUFFIXMATCH:      '$='
  //
  //  SUBSTRMATCH:      '*='
  //
  //
  AttributeSelector processAttribute() {
    var start = _peekToken.span;

    if (_maybeEat(TokenKind.LBRACK)) {
      var attrName = identifier();

      int op;
      switch (_peek()) {
      case TokenKind.EQUALS:
      case TokenKind.INCLUDES:        // ~=
      case TokenKind.DASH_MATCH:      // |=
      case TokenKind.PREFIX_MATCH:    // ^=
      case TokenKind.SUFFIX_MATCH:    // $=
      case TokenKind.SUBSTRING_MATCH: // *=
        op = _peek();
        _next();
        break;
      default:
        op = TokenKind.NO_MATCH;
      }

      var value;
      if (op != TokenKind.NO_MATCH) {
        // Operator hit so we require a value too.
        if (_peekIdentifier()) {
          value = identifier();
        } else {
          value = processQuotedString(false);
        }

        if (value == null) {
          _error('expected attribute value string or ident', _peekToken.span);
        }
      }

      _eat(TokenKind.RBRACK);

      return new AttributeSelector(attrName, op, value, _makeSpan(start));
    }
  }

  //  Declaration grammar:
  //
  //  declaration:  property ':' expr prio?
  //
  //  property:  IDENT [or IE hacks]
  //  prio:      !important
  //  expr:      (see processExpr)
  //
  // Here are the ugly IE hacks we need to support:
  //   property: expr prio? \9; - IE8 and below property, /9 before semi-colon
  //   *IDENT                   - IE7 or below
  //   _IDENT                   - IE6 property (automatically a valid ident)
  //
  Declaration processDeclaration(List dartStyles) {
    Declaration decl;

    var start = _peekToken.span;

    // IE7 hack of * before property name if so the property is IE7 or below.
    var ie7 = _peekKind(TokenKind.ASTERISK);
    if (ie7) {
      _next();
    }

    // IDENT ':' expr '!important'?
    if (TokenKind.isIdentifier(_peekToken.kind)) {
      var propertyIdent = identifier();

      var ieFilterProperty = propertyIdent.name.toLowerCase() == 'filter';

      _eat(TokenKind.COLON);

      Expressions exprs = processExpr(ieFilterProperty);

      var dartComposite = _styleForDart(propertyIdent, exprs, dartStyles);

      // Handle !important (prio)
      var importantPriority = _maybeEat(TokenKind.IMPORTANT);

      decl = new Declaration(propertyIdent, exprs, dartComposite,
          _makeSpan(start), important: importantPriority, ie7: ie7);
    } else if (_peekToken.kind == TokenKind.VAR_DEFINITION) {
      _next();
      var definedName;
      if (_peekIdentifier()) definedName = identifier();

      _eat(TokenKind.COLON);

      Expressions exprs = processExpr();

      decl = new VarDefinition(definedName, exprs, _makeSpan(start));
    } else if (_peekToken.kind == TokenKind.DIRECTIVE_INCLUDE) {
      // @include mixinName in the declaration area.
      var span = _makeSpan(start);
      var include = processInclude(span, eatSemiColon: false);
      decl = new IncludeMixinAtDeclaration(include, span);
    } else if (_peekToken.kind == TokenKind.DIRECTIVE_EXTEND) {
      var simpleSequences = <TreeNode>[];

      _next();
      var span = _makeSpan(start);
      var selector = simpleSelector();
      if (selector == null) {
        _warning("@extends expecting simple selector name", span);
      } else {
        simpleSequences.add(selector);
      }
      if (_peekKind(TokenKind.COLON)) {
        var pseudoSelector = processPseudoSelector(_peekToken.span);
        if (pseudoSelector is PseudoElementSelector ||
            pseudoSelector is PseudoClassSelector) {
          simpleSequences.add(pseudoSelector);
        } else {
          _warning("not a valid selector", span);
        }
      }
      decl = new ExtendDeclaration(simpleSequences, span);
    }

    return decl;
  }

  /** List of styles exposed to the Dart UI framework. */
  static const int _fontPartFont= 0;
  static const int _fontPartVariant = 1;
  static const int _fontPartWeight = 2;
  static const int _fontPartSize = 3;
  static const int _fontPartFamily = 4;
  static const int _fontPartStyle = 5;
  static const int _marginPartMargin = 6;
  static const int _marginPartLeft = 7;
  static const int _marginPartTop = 8;
  static const int _marginPartRight = 9;
  static const int _marginPartBottom = 10;
  static const int _lineHeightPart = 11;
  static const int _borderPartBorder = 12;
  static const int _borderPartLeft = 13;
  static const int _borderPartTop = 14;
  static const int _borderPartRight = 15;
  static const int _borderPartBottom = 16;
  static const int _borderPartWidth = 17;
  static const int _borderPartLeftWidth = 18;
  static const int _borderPartTopWidth = 19;
  static const int _borderPartRightWidth = 20;
  static const int _borderPartBottomWidth = 21;
  static const int _heightPart = 22;
  static const int _widthPart = 23;
  static const int _paddingPartPadding = 24;
  static const int _paddingPartLeft = 25;
  static const int _paddingPartTop = 26;
  static const int _paddingPartRight = 27;
  static const int _paddingPartBottom = 28;

  static const Map<String, int> _stylesToDart = const {
    'font':                 _fontPartFont,
    'font-family':          _fontPartFamily,
    'font-size':            _fontPartSize,
    'font-style':           _fontPartStyle,
    'font-variant':         _fontPartVariant,
    'font-weight':          _fontPartWeight,
    'line-height':          _lineHeightPart,
    'margin':               _marginPartMargin,
    'margin-left':          _marginPartLeft,
    'margin-right':         _marginPartRight,
    'margin-top':           _marginPartTop,
    'margin-bottom':        _marginPartBottom,
    'border':               _borderPartBorder,
    'border-left':          _borderPartLeft,
    'border-right':         _borderPartRight,
    'border-top':           _borderPartTop,
    'border-bottom':        _borderPartBottom,
    'border-width':         _borderPartWidth,
    'border-left-width':    _borderPartLeftWidth,
    'border-top-width':     _borderPartTopWidth,
    'border-right-width':   _borderPartRightWidth,
    'border-bottom-width':  _borderPartBottomWidth,
    'height':               _heightPart,
    'width':                _widthPart,
    'padding':              _paddingPartPadding,
    'padding-left':         _paddingPartLeft,
    'padding-top':          _paddingPartTop,
    'padding-right':        _paddingPartRight,
    'padding-bottom':       _paddingPartBottom
  };

  static const Map<String, int> _nameToFontWeight = const {
    'bold' : FontWeight.bold,
    'normal' : FontWeight.normal
  };

  static int _findStyle(String styleName) => _stylesToDart[styleName];

  DartStyleExpression _styleForDart(Identifier property, Expressions exprs,
      List dartStyles) {
    var styleType = _findStyle(property.name.toLowerCase());
    if (styleType != null) {
      return buildDartStyleNode(styleType, exprs, dartStyles);
    }
  }

  FontExpression _mergeFontStyles(FontExpression fontExpr, List dartStyles) {
    // Merge all font styles for this class selector.
    for (var dartStyle in dartStyles) {
      if (dartStyle.isFont) {
        fontExpr = new FontExpression.merge(dartStyle, fontExpr);
      }
    }

    return fontExpr;
  }

  DartStyleExpression buildDartStyleNode(int styleType, Expressions exprs,
      List dartStyles) {

    switch (styleType) {
      /*
       * Properties in order:
       *
       *   font-style font-variant font-weight font-size/line-height font-family
       *
       * The font-size and font-family values are required. If other values are
       * missing; a default, if it exist, will be used.
       */
       case _fontPartFont:
         var processor = new ExpressionsProcessor(exprs);
         return _mergeFontStyles(processor.processFont(), dartStyles);
      case _fontPartFamily:
        var processor = new ExpressionsProcessor(exprs);

        try {
          return _mergeFontStyles(processor.processFontFamily(), dartStyles);
        } catch (fontException) {
          _error(fontException, _peekToken.span);
        }
        break;
      case _fontPartSize:
        var processor = new ExpressionsProcessor(exprs);
        return _mergeFontStyles(processor.processFontSize(), dartStyles);
      case _fontPartStyle:
        /* Possible style values:
         *   normal [default]
         *   italic
         *   oblique
         *   inherit
         */
        // TODO(terry): TBD
        break;
      case _fontPartVariant:
        /* Possible variant values:
         *   normal  [default]
         *   small-caps
         *   inherit
         */
        // TODO(terry): TBD
        break;
      case _fontPartWeight:
        /* Possible weight values:
         *   normal [default]
         *   bold
         *   bolder
         *   lighter
         *   100 - 900
         *   inherit
         */
        // TODO(terry): Only 'normal', 'bold', or values of 100-900 supoorted
        //              need to handle bolder, lighter, and inherit.  See
        //              https://github.com/dart-lang/csslib/issues/1
        var expr = exprs.expressions[0];
        if (expr is NumberTerm) {
          var fontExpr = new FontExpression(expr.span,
              weight: expr.value);
          return _mergeFontStyles(fontExpr, dartStyles);
        } else if (expr is LiteralTerm) {
          int weight = _nameToFontWeight[expr.value.toString()];
          if (weight != null) {
            var fontExpr = new FontExpression(expr.span, weight: weight);
            return _mergeFontStyles(fontExpr, dartStyles);
          }
        }
        break;
      case _lineHeightPart:
        num lineHeight;
        if (exprs.expressions.length == 1) {
          var expr = exprs.expressions[0];
          if (expr is UnitTerm) {
            UnitTerm unitTerm = expr;
            // TODO(terry): Need to handle other units and LiteralTerm normal
            //              See https://github.com/dart-lang/csslib/issues/2.
            if (unitTerm.unit == TokenKind.UNIT_LENGTH_PX ||
                   unitTerm.unit == TokenKind.UNIT_LENGTH_PT) {
              var fontExpr = new FontExpression(expr.span,
                  lineHeight: new LineHeight(expr.value, inPixels: true));
              return _mergeFontStyles(fontExpr, dartStyles);
            } else if (isChecked) {
              _warning("Unexpected unit for line-height", expr.span);
            }
          } else if (expr is NumberTerm) {
            var fontExpr = new FontExpression(expr.span,
                lineHeight: new LineHeight(expr.value, inPixels: false));
            return _mergeFontStyles(fontExpr, dartStyles);
          } else if (isChecked) {
            _warning("Unexpected value for line-height", expr.span);
          }
        }
        break;
      case _marginPartMargin:
        return new MarginExpression.boxEdge(exprs.span, processFourNums(exprs));
      case _borderPartBorder:
        for (var expr in exprs.expressions) {
          var v = marginValue(expr);
          if (v != null) {
            final box = new BoxEdge.uniform(v);
            return new BorderExpression.boxEdge(exprs.span, box);
          }
        }
        break;
      case _borderPartWidth:
        var v = marginValue(exprs.expressions[0]);
        if (v != null) {
          final box = new BoxEdge.uniform(v);
          return new BorderExpression.boxEdge(exprs.span, box);
        }
        break;
      case _paddingPartPadding:
        return new PaddingExpression.boxEdge(exprs.span,
            processFourNums(exprs));
      case _marginPartLeft:
      case _marginPartTop:
      case _marginPartRight:
      case _marginPartBottom:
      case _borderPartLeft:
      case _borderPartTop:
      case _borderPartRight:
      case _borderPartBottom:
      case _borderPartLeftWidth:
      case _borderPartTopWidth:
      case _borderPartRightWidth:
      case _borderPartBottomWidth:
      case _heightPart:
      case _widthPart:
      case _paddingPartLeft:
      case _paddingPartTop:
      case _paddingPartRight:
      case _paddingPartBottom:
        if (exprs.expressions.length > 0) {
          return processOneNumber(exprs, styleType);
        }
        break;
      default:
        // Don't handle it.
        return null;
    }
  }

  // TODO(terry): Look at handling width of thin, thick, etc. any none numbers
  //              to convert to a number.
  DartStyleExpression processOneNumber(Expressions exprs, int part) {
    var value = marginValue(exprs.expressions[0]);
    if (value != null) {
      switch (part) {
        case _marginPartLeft:
          return new MarginExpression(exprs.span, left: value);
        case _marginPartTop:
          return new MarginExpression(exprs.span, top: value);
        case _marginPartRight:
          return new MarginExpression(exprs.span, right: value);
        case _marginPartBottom:
          return new MarginExpression(exprs.span, bottom: value);
        case _borderPartLeft:
        case _borderPartLeftWidth:
          return new BorderExpression(exprs.span, left: value);
        case _borderPartTop:
        case _borderPartTopWidth:
          return new BorderExpression(exprs.span, top: value);
        case _borderPartRight:
        case _borderPartRightWidth:
          return new BorderExpression(exprs.span, right: value);
        case _borderPartBottom:
        case _borderPartBottomWidth:
          return new BorderExpression(exprs.span, bottom: value);
        case _heightPart:
          return new HeightExpression(exprs.span, value);
        case _widthPart:
          return new WidthExpression(exprs.span, value);
        case _paddingPartLeft:
          return new PaddingExpression(exprs.span, left: value);
        case _paddingPartTop:
          return new PaddingExpression(exprs.span, top: value);
        case _paddingPartRight:
          return new PaddingExpression(exprs.span, right: value);
        case _paddingPartBottom:
          return new PaddingExpression(exprs.span, bottom: value);
      }
    }
  }

  /**
   * Margins are of the format:
   *
   *   top,right,bottom,left      (4 parameters)
   *   top,right/left, bottom     (3 parameters)
   *   top/bottom,right/left      (2 parameters)
   *   top/right/bottom/left      (1 parameter)
   *
   * The values of the margins can be a unit or unitless or auto.
   */
  BoxEdge processFourNums(Expressions exprs) {
    num top;
    num right;
    num bottom;
    num left;

    int totalExprs = exprs.expressions.length;
    switch (totalExprs) {
      case 1:
        top = marginValue(exprs.expressions[0]);
        right = top;
        bottom = top;
        left = top;
        break;
      case 2:
        top = marginValue(exprs.expressions[0]);
        bottom = top;
        right = marginValue(exprs.expressions[1]);
        left = right;
       break;
      case 3:
        top = marginValue(exprs.expressions[0]);
        right = marginValue(exprs.expressions[1]);
        left = right;
        bottom = marginValue(exprs.expressions[2]);
        break;
      case 4:
        top = marginValue(exprs.expressions[0]);
        right = marginValue(exprs.expressions[1]);
        bottom = marginValue(exprs.expressions[2]);
        left = marginValue(exprs.expressions[3]);
        break;
      default:
        return null;
    }

    return new BoxEdge.clockwiseFromTop(top, right, bottom, left);
  }

  // TODO(terry): Need to handle auto.
  marginValue(var exprTerm) {
    if (exprTerm is UnitTerm || exprTerm is NumberTerm) {
      return exprTerm.value;
    }
  }

  //  Expression grammar:
  //
  //  expression:   term [ operator? term]*
  //
  //  operator:     '/' | ','
  //  term:         (see processTerm)
  //
  Expressions processExpr([bool ieFilter = false]) {
    var start = _peekToken.span;
    var expressions = new Expressions(_makeSpan(start));

    var keepGoing = true;
    var expr;
    while (keepGoing && (expr = processTerm(ieFilter)) != null) {
      var op;

      var opStart = _peekToken.span;

      switch (_peek()) {
      case TokenKind.SLASH:
        op = new OperatorSlash(_makeSpan(opStart));
        break;
      case TokenKind.COMMA:
        op = new OperatorComma(_makeSpan(opStart));
        break;
      case TokenKind.BACKSLASH:
        // Backslash outside of string; detected IE8 or older signaled by \9 at
        // end of an expression.
        var ie8Start = _peekToken.span;

        _next();
        if (_peekKind(TokenKind.INTEGER)) {
          var numToken = _next();
          var value = int.parse(numToken.text);
          if (value == 9) {
            op = new IE8Term(_makeSpan(ie8Start));
          } else if (isChecked) {
            _warning("\$value is not valid in an expression", _makeSpan(start));
          }
        }
        break;
      }

      if (expr != null) {
        if (expr is List) {
          expr.forEach((exprItem) {
            expressions.add(exprItem);
          });
        } else {
          expressions.add(expr);
        }
      } else {
        keepGoing = false;
      }

      if (op != null) {
        expressions.add(op);
        if (op is IE8Term) {
          keepGoing = false;
        } else {
          _next();
        }
      }
    }

    return expressions;
  }

  static const int MAX_UNICODE = 0x10FFFF;

  //  Term grammar:
  //
  //  term:
  //    unary_operator?
  //    [ term_value ]
  //    | STRING S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor
  //
  //  term_value:
  //    NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* |
  //    TIME S* | FREQ S* | function
  //
  //  NUMBER:       {num}
  //  PERCENTAGE:   {num}%
  //  LENGTH:       {num}['px' | 'cm' | 'mm' | 'in' | 'pt' | 'pc']
  //  EMS:          {num}'em'
  //  EXS:          {num}'ex'
  //  ANGLE:        {num}['deg' | 'rad' | 'grad']
  //  TIME:         {num}['ms' | 's']
  //  FREQ:         {num}['hz' | 'khz']
  //  function:     IDENT '(' expr ')'
  //
  processTerm([bool ieFilter = false]) {
    var start = _peekToken.span;
    Token t;                          // token for term's value
    var value;                        // value of term (numeric values)

    var unary = "";
    switch (_peek()) {
    case TokenKind.HASH:
      this._eat(TokenKind.HASH);
      if (!_anyWhiteSpaceBeforePeekToken(TokenKind.HASH)) {
        String hexText;
        if (_peekKind(TokenKind.INTEGER)) {
          String hexText1 = _peekToken.text;
          _next();
          if (_peekIdentifier()) {
            hexText = '$hexText1${identifier().name}';
          } else {
            hexText = hexText1;
          }
        } else if (_peekIdentifier()) {
          hexText = identifier().name;
        }
        if (hexText != null) {
          return _parseHex(hexText, _makeSpan(start));
        }
      }

      if (isChecked) {
        _warning("Expected hex number", _makeSpan(start));
      }
      // Construct the bad hex value with a #<space>number.
      return _parseHex(" ${processTerm().text}", _makeSpan(start));
    case TokenKind.INTEGER:
      t = _next();
      value = int.parse("${unary}${t.text}");
      break;
    case TokenKind.DOUBLE:
      t = _next();
      value = double.parse("${unary}${t.text}");
      break;
    case TokenKind.SINGLE_QUOTE:
      value = processQuotedString(false);
      value = "'${_escapeString(value, single: true)}'";
      return new LiteralTerm(value, value, _makeSpan(start));
    case TokenKind.DOUBLE_QUOTE:
      value = processQuotedString(false);
      value = '"${_escapeString(value)}"';
      return new LiteralTerm(value, value, _makeSpan(start));
    case TokenKind.LPAREN:
      _next();

      GroupTerm group = new GroupTerm(_makeSpan(start));

      var term;
      do {
        term = processTerm();
        if (term != null && term is LiteralTerm) {
          group.add(term);
        }
      } while (term != null && !_maybeEat(TokenKind.RPAREN) &&
          !isPrematureEndOfFile());

      return group;
    case TokenKind.LBRACK:
      _next();

      var term = processTerm();
      if (!(term is NumberTerm)) {
        _error('Expecting a positive number', _makeSpan(start));
      }

      _eat(TokenKind.RBRACK);

      return new ItemTerm(term.value, term.text, _makeSpan(start));
    case TokenKind.IDENTIFIER:
      var nameValue = identifier();   // Snarf up the ident we'll remap, maybe.

      if (!ieFilter && _maybeEat(TokenKind.LPAREN)) {
        // FUNCTION
        return processFunction(nameValue);
      } if (ieFilter) {
         if (_maybeEat(TokenKind.COLON) &&
           nameValue.name.toLowerCase() == 'progid') {
           // IE filter:progid:
           return processIEFilter(start);
         } else {
           // Handle filter:<name> where name is any filter e.g., alpha, chroma,
           // Wave, blur, etc.
           return processIEFilter(start);
         }
      }

      // TODO(terry): Need to have a list of known identifiers today only
      //              'from' is special.
      if (nameValue.name == 'from') {
        return new LiteralTerm(nameValue, nameValue.name, _makeSpan(start));
      }

      // What kind of identifier is it, named color?
      var colorEntry = TokenKind.matchColorName(nameValue.name);
      if (colorEntry == null) {
        if (isChecked) {
          var propName = nameValue.name;
          var errMsg = TokenKind.isPredefinedName(propName) ?
              "Improper use of property value ${propName}" :
              "Unknown property value ${propName}";
          _warning(errMsg, _makeSpan(start));
        }
        return new LiteralTerm(nameValue, nameValue.name, _makeSpan(start));
      }

      // Yes, process the color as an RGB value.
      var rgbColor =
          TokenKind.decimalToHex(TokenKind.colorValue(colorEntry), 6);
      return _parseHex(rgbColor, _makeSpan(start));
    case TokenKind.UNICODE_RANGE:
      var first;
      var second;
      var firstNumber;
      var secondNumber;
      _eat(TokenKind.UNICODE_RANGE, unicodeRange: true);
      if (_maybeEat(TokenKind.HEX_INTEGER, unicodeRange: true)) {
        first = _previousToken.text;
        firstNumber = int.parse('0x$first');
        if (firstNumber > MAX_UNICODE) {
          _error("unicode range must be less than 10FFFF", _makeSpan(start));
        }
        if (_maybeEat(TokenKind.MINUS, unicodeRange: true)) {
          if (_maybeEat(TokenKind.HEX_INTEGER, unicodeRange: true)) {
            second = _previousToken.text;
            secondNumber = int.parse('0x$second');
            if (secondNumber > MAX_UNICODE) {
              _error("unicode range must be less than 10FFFF",
                  _makeSpan(start));
            }
            if (firstNumber > secondNumber) {
              _error("unicode first range can not be greater than last",
                  _makeSpan(start));
            }
          }
        }
      } else if (_maybeEat(TokenKind.HEX_RANGE, unicodeRange: true)) {
        first = _previousToken.text;
      }

      return new UnicodeRangeTerm(first, second, _makeSpan(start));
    case TokenKind.AT:
      if (messages.options.lessSupport) {
        _next();

        var expr = processExpr();
        if (isChecked && expr.expressions.length > 1) {
          _error("only @name for Less syntax", _peekToken.span);
        }

        var param = expr.expressions[0];
        var varUsage = new VarUsage(param.text, [], _makeSpan(start));
        expr.expressions[0] = varUsage;
        return expr.expressions;
      }
      break;
    }

    return processDimension(t, value, _makeSpan(start));
  }

  /** Process all dimension units. */
  LiteralTerm processDimension(Token t, var value, SourceSpan span) {
    LiteralTerm term;
    var unitType = this._peek();

    switch (unitType) {
    case TokenKind.UNIT_EM:
      term = new EmTerm(value, t.text, span);
      _next();    // Skip the unit
      break;
    case TokenKind.UNIT_EX:
      term = new ExTerm(value, t.text, span);
      _next();    // Skip the unit
      break;
    case TokenKind.UNIT_LENGTH_PX:
    case TokenKind.UNIT_LENGTH_CM:
    case TokenKind.UNIT_LENGTH_MM:
    case TokenKind.UNIT_LENGTH_IN:
    case TokenKind.UNIT_LENGTH_PT:
    case TokenKind.UNIT_LENGTH_PC:
      term = new LengthTerm(value, t.text, span, unitType);
      _next();    // Skip the unit
      break;
    case TokenKind.UNIT_ANGLE_DEG:
    case TokenKind.UNIT_ANGLE_RAD:
    case TokenKind.UNIT_ANGLE_GRAD:
    case TokenKind.UNIT_ANGLE_TURN:
      term = new AngleTerm(value, t.text, span, unitType);
      _next();    // Skip the unit
      break;
    case TokenKind.UNIT_TIME_MS:
    case TokenKind.UNIT_TIME_S:
      term = new TimeTerm(value, t.text, span, unitType);
      _next();    // Skip the unit
      break;
    case TokenKind.UNIT_FREQ_HZ:
    case TokenKind.UNIT_FREQ_KHZ:
      term = new FreqTerm(value, t.text, span, unitType);
      _next();    // Skip the unit
      break;
    case TokenKind.PERCENT:
      term = new PercentageTerm(value, t.text, span);
      _next();    // Skip the %
      break;
    case TokenKind.UNIT_FRACTION:
      term = new FractionTerm(value, t.text, span);
      _next();     // Skip the unit
      break;
    case TokenKind.UNIT_RESOLUTION_DPI:
    case TokenKind.UNIT_RESOLUTION_DPCM:
    case TokenKind.UNIT_RESOLUTION_DPPX:
      term = new ResolutionTerm(value, t.text, span, unitType);
      _next();    // Skip the unit
      break;
    case TokenKind.UNIT_CH:
      term = new ChTerm(value, t.text, span, unitType);
      _next();    // Skip the unit
      break;
    case TokenKind.UNIT_REM:
      term = new RemTerm(value, t.text, span, unitType);
      _next();    // Skip the unit
      break;
    case TokenKind.UNIT_VIEWPORT_VW:
    case TokenKind.UNIT_VIEWPORT_VH:
    case TokenKind.UNIT_VIEWPORT_VMIN:
    case TokenKind.UNIT_VIEWPORT_VMAX:
      term = new ViewportTerm(value, t.text, span, unitType);
      _next();    // Skip the unit
      break;
    default:
      if (value != null && t != null) {
        term = (value is Identifier)
            ? new LiteralTerm(value, value.name, span)
            : new NumberTerm(value, t.text, span);
      }
      break;
    }

    return term;
  }

  String processQuotedString([bool urlString = false]) {
    var start = _peekToken.span;

    // URI term sucks up everything inside of quotes(' or ") or between parens
    var stopToken = urlString ? TokenKind.RPAREN : -1;

    // Note: disable skipping whitespace tokens inside a string.
    // TODO(jmesserly): the layering here feels wrong.
    var skipWhitespace = tokenizer._skipWhitespace;
    tokenizer._skipWhitespace = false;

    switch (_peek()) {
    case TokenKind.SINGLE_QUOTE:
      stopToken = TokenKind.SINGLE_QUOTE;
      _next(); // Skip the SINGLE_QUOTE.
      start = _peekToken.span;
      break;
    case TokenKind.DOUBLE_QUOTE:
      stopToken = TokenKind.DOUBLE_QUOTE;
      _next(); // Skip the DOUBLE_QUOTE.
      start = _peekToken.span;
      break;
    default:
      if (urlString) {
        if (_peek() == TokenKind.LPAREN) {
          _next();    // Skip the LPAREN.
          start = _peekToken.span;
        }
        stopToken = TokenKind.RPAREN;
      } else {
        _error('unexpected string', _makeSpan(start));
      }
      break;
    }

    // Gobble up everything until we hit our stop token.
    var stringValue = new StringBuffer();
    while (_peek() != stopToken && _peek() != TokenKind.END_OF_FILE) {
      stringValue.write(_next().text);
    }

    tokenizer._skipWhitespace = skipWhitespace;

    // All characters between quotes is the string.
    if (stopToken != TokenKind.RPAREN) {
      _next();    // Skip the SINGLE_QUOTE or DOUBLE_QUOTE;
    }

    return stringValue.toString();
  }

  // TODO(terry): Should probably understand IE's non-standard filter syntax to
  //              fully support calc, var(), etc.
  /**
   * IE's filter property breaks CSS value parsing.  IE's format can be:
   *
   *    filter: progid:DXImageTransform.MS.gradient(Type=0, Color='#9d8b83');
   *
   * We'll just parse everything after the 'progid:' look for the left paren
   * then parse to the right paren ignoring everything in between.
   */
  processIEFilter(FileSpan startAfterProgidColon) {
    var parens = 0;

    while (_peek() != TokenKind.END_OF_FILE) {
      switch (_peek()) {
        case TokenKind.LPAREN:
          _eat(TokenKind.LPAREN);
          parens++;
          break;
        case TokenKind.RPAREN:
          _eat(TokenKind.RPAREN);
          if (--parens == 0) {
            var tok = tokenizer.makeIEFilter(startAfterProgidColon.start.offset,
                _peekToken.start);
            return new LiteralTerm(tok.text, tok.text, tok.span);
          }
          break;
        default:
          _eat(_peek());
      }
    }
  }

  //  Function grammar:
  //
  //  function:     IDENT '(' expr ')'
  //
  processFunction(Identifier func) {
    var start = _peekToken.span;

    var name = func.name;

    switch (name) {
    case 'url':
      // URI term sucks up everything inside of quotes(' or ") or between parens
      var urlParam = processQuotedString(true);

      // TODO(terry): Better error messge and checking for mismatched quotes.
      if (_peek() == TokenKind.END_OF_FILE) {
        _error("problem parsing URI", _peekToken.span);
      }

      if (_peek() == TokenKind.RPAREN) {
        _next();
      }

      return new UriTerm(urlParam, _makeSpan(start));
    case 'calc':
      // TODO(terry): Implement expression handling...
      break;
    case 'var':
      // TODO(terry): Consider handling var in IE specific filter/progid.  This
      //              will require parsing entire IE specific syntax e.g.,
      //              param = value or progid:com_id, etc. for example:
      //
      //    var-blur: Blur(Add = 0, Direction = 225, Strength = 10);
      //    var-gradient: progid:DXImageTransform.Microsoft.gradient"
      //      (GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
      var expr = processExpr();
      if (!_maybeEat(TokenKind.RPAREN)) {
        _error("problem parsing var expected ), ", _peekToken.span);
      }
      if (isChecked &&
          expr.expressions.where((e) => e is OperatorComma).length > 1) {
        _error("too many parameters to var()", _peekToken.span);
      }

      var paramName = expr.expressions[0].text;

      // [0] - var name, [1] - OperatorComma, [2] - default value.
      var defaultValues = expr.expressions.length >= 3
          ? expr.expressions.sublist(2) : [];
      return new VarUsage(paramName, defaultValues, _makeSpan(start));
    default:
      var expr = processExpr();
      if (!_maybeEat(TokenKind.RPAREN)) {
        _error("problem parsing function expected ), ", _peekToken.span);
      }

      return new FunctionTerm(name, name, expr, _makeSpan(start));
    }

    return null;
  }

  Identifier identifier() {
    var tok = _next();

    if (!TokenKind.isIdentifier(tok.kind) &&
        !TokenKind.isKindIdentifier(tok.kind)) {
      if (isChecked) {
        _warning('expected identifier, but found $tok', tok.span);
      }
      return new Identifier("", _makeSpan(tok.span));
    }

    return new Identifier(tok.text, _makeSpan(tok.span));
  }

  // TODO(terry): Move this to base <= 36 and into shared code.
  static int _hexDigit(int c) {
    if (c >= 48/*0*/ && c <= 57/*9*/) {
      return c - 48;
    } else if (c >= 97/*a*/ && c <= 102/*f*/) {
      return c - 87;
    } else if (c >= 65/*A*/ && c <= 70/*F*/) {
      return c - 55;
    } else {
      return -1;
    }
  }

  HexColorTerm _parseHex(String hexText, SourceSpan span) {
    var hexValue = 0;

     for (var i = 0; i < hexText.length; i++) {
      var digit = _hexDigit(hexText.codeUnitAt(i));
      if (digit < 0) {
        _warning('Bad hex number', span);
        return new HexColorTerm(new BAD_HEX_VALUE(), hexText, span);
      }
      hexValue = (hexValue << 4) + digit;
    }

    // Make 3 character hex value #RRGGBB => #RGB iff:
    // high/low nibble of RR is the same, high/low nibble of GG is the same and
    // high/low nibble of BB is the same.
    if (hexText.length == 6 &&
        hexText[0] == hexText[1] &&
        hexText[2] == hexText[3] &&
        hexText[4] == hexText[5]) {
      hexText = '${hexText[0]}${hexText[2]}${hexText[4]}';
    } else if (hexText.length == 4 &&
        hexText[0] == hexText[1] &&
        hexText[2] == hexText[3]) {
      hexText = '${hexText[0]}${hexText[2]}';
    } else if (hexText.length == 2 && hexText[0] == hexText[1]) {
      hexText = '${hexText[0]}';
    }
    return new HexColorTerm(hexValue, hexText, span);
  }
}

class ExpressionsProcessor {
  final Expressions _exprs;
  int _index = 0;

  ExpressionsProcessor(this._exprs);

  // TODO(terry): Only handles ##px unit.
  FontExpression processFontSize() {
    /* font-size[/line-height]
     *
     * Possible size values:
     *   xx-small
     *   small
     *   medium [default]
     *   large
     *   x-large
     *   xx-large
     *   smaller
     *   larger
     *   ##length in px, pt, etc.
     *   ##%, percent of parent elem's font-size
     *   inherit
     */
    LengthTerm size;
    LineHeight lineHt;
    var nextIsLineHeight = false;
    for (; _index < _exprs.expressions.length; _index++) {
      var expr = _exprs.expressions[_index];
      if (size == null && expr is LengthTerm) {
        // font-size part.
        size = expr;
      } else if (size != null) {
        if (expr is OperatorSlash) {
          // LineHeight could follow?
          nextIsLineHeight = true;
        } else if (nextIsLineHeight && expr is LengthTerm) {
          assert(expr.unit == TokenKind.UNIT_LENGTH_PX);
          lineHt = new LineHeight(expr.value, inPixels: true);
          nextIsLineHeight = false;
          _index++;
          break;
        } else {
          break;
        }
      } else {
        break;
      }
    }

    return new FontExpression(_exprs.span, size: size, lineHeight: lineHt);
  }

  FontExpression processFontFamily() {
    var family = <String>[];

    /* Possible family values:
     * font-family: arial, Times new roman ,Lucida Sans Unicode,Courier;
     * font-family: "Times New Roman", arial, Lucida Sans Unicode, Courier;
     */
    var moreFamilies = false;

    for (; _index < _exprs.expressions.length; _index++) {
      Expression expr = _exprs.expressions[_index];
      if (expr is LiteralTerm) {
        if (family.length == 0 || moreFamilies) {
          // It's font-family now.
          family.add(expr.toString());
          moreFamilies = false;
        } else if (isChecked) {
          messages.warning('Only font-family can be a list', _exprs.span);
        }
      } else if (expr is OperatorComma && family.length > 0) {
        moreFamilies = true;
      } else {
        break;
      }
    }

    return new FontExpression(_exprs.span, family: family);
  }

  FontExpression processFont() {
    List<String> family;

    // Process all parts of the font expression.
    FontExpression fontSize;
    FontExpression fontFamily;
    for (; _index < _exprs.expressions.length; _index++) {
      var expr = _exprs.expressions[_index];
      // Order is font-size font-family
      if (fontSize == null) {
        fontSize = processFontSize();
      }
      if (fontFamily == null) {
        fontFamily = processFontFamily();
      }
      //TODO(terry): Handle font-weight, font-style, and font-variant. See
      //               https://github.com/dart-lang/csslib/issues/3
      //               https://github.com/dart-lang/csslib/issues/4
      //               https://github.com/dart-lang/csslib/issues/5
    }

    return new FontExpression(_exprs.span,
        size: fontSize.font.size,
        lineHeight: fontSize.font.lineHeight,
        family: fontFamily.font.family);
  }
}

/**
 * Escapes [text] for use in a CSS string.
 * [single] specifies single quote `'` vs double quote `"`.
 */
String _escapeString(String text, {bool single: false}) {
  StringBuffer result = null;

  for (int i = 0; i < text.length; i++) {
    var code = text.codeUnitAt(i);
    String replace = null;
    switch (code) {
      case 34/*'"'*/:  if (!single) replace = r'\"'; break;
      case 39/*"'"*/:  if (single) replace = r"\'"; break;
    }

    if (replace != null && result == null) {
      result = new StringBuffer(text.substring(0, i));
    }

    if (result != null) result.write(replace != null ? replace : text[i]);
  }

  return result == null ? text : result.toString();
}
