/*
 * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "CSSParser.h"

#include "CSSBorderImageValue.h"
#include "CSSCanvasValue.h"
#include "CSSCharsetRule.h"
#include "CSSCursorImageValue.h"
#include "CSSFontFaceRule.h"
#include "CSSFontFaceSrcValue.h"
#include "CSSGradientValue.h"
#include "CSSImageValue.h"
#include "CSSImportRule.h"
#include "CSSInheritedValue.h"
#include "CSSInitialValue.h"
#include "CSSLineBoxContainValue.h"
#include "CSSMediaRule.h"
#include "CSSMutableStyleDeclaration.h"
#include "CSSPageRule.h"
#include "CSSPrimitiveValue.h"
#include "CSSPrimitiveValueCache.h"
#include "CSSProperty.h"
#include "CSSPropertyNames.h"
#include "CSSPropertySourceData.h"
#include "CSSQuirkPrimitiveValue.h"
#include "CSSReflectValue.h"
#include "CSSRuleList.h"
#include "CSSSelector.h"
#include "CSSStyleRule.h"
#include "CSSStyleSheet.h"
#include "CSSTimingFunctionValue.h"
#include "CSSUnicodeRangeValue.h"
#include "CSSValueKeywords.h"
#include "CSSValueList.h"
#include "Counter.h"
#include "Document.h"
#include "FloatConversion.h"
#include "FontFamilyValue.h"
#include "FontValue.h"
#include "HTMLParserIdioms.h"
#include "HashTools.h"
#include "MediaList.h"
#include "MediaQueryExp.h"
#include "Page.h"
#include "Pair.h"
#include "Rect.h"
#include "RenderTheme.h"
#include "ShadowValue.h"
#include "WebKitCSSKeyframeRule.h"
#include "WebKitCSSKeyframesRule.h"
#include "WebKitCSSTransformValue.h"
#include <limits.h>
#include <wtf/HexNumber.h>
#include <wtf/dtoa.h>
#include <wtf/text/StringBuffer.h>

#if ENABLE(DASHBOARD_SUPPORT)
#include "DashboardRegion.h"
#endif

#define YYDEBUG 0

#if YYDEBUG > 0
extern int cssyydebug;
#endif

extern int cssyyparse(WebCore::CSSParser*);

using namespace std;
using namespace WTF;

namespace WebCore {

static const unsigned INVALID_NUM_PARSED_PROPERTIES = UINT_MAX;
static const double MAX_SCALE = 1000000;

static bool equal(const CSSParserString& a, const char* b)
{
    for (int i = 0; i < a.length; ++i) {
        if (!b[i])
            return false;
        if (a.characters[i] != b[i])
            return false;
    }
    return !b[a.length];
}

static bool equalIgnoringCase(const CSSParserString& a, const char* b)
{
    for (int i = 0; i < a.length; ++i) {
        if (!b[i])
            return false;
        ASSERT(!isASCIIUpper(b[i]));
        if (toASCIILower(a.characters[i]) != b[i])
            return false;
    }
    return !b[a.length];
}

static bool hasPrefix(const char* string, unsigned length, const char* prefix)
{
    for (unsigned i = 0; i < length; ++i) {
        if (!prefix[i])
            return true;
        if (string[i] != prefix[i])
            return false;
    }
    return false;
}

CSSParser::CSSParser(bool strictParsing)
    : m_strict(strictParsing)
    , m_important(false)
    , m_id(0)
    , m_styleSheet(0)
    , m_valueList(0)
    , m_parsedProperties(static_cast<CSSProperty**>(fastMalloc(32 * sizeof(CSSProperty*))))
    , m_numParsedProperties(0)
    , m_maxParsedProperties(32)
    , m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES)
    , m_inParseShorthand(0)
    , m_currentShorthand(0)
    , m_implicitShorthand(false)
    , m_hasFontFaceOnlyValues(false)
    , m_hadSyntacticallyValidCSSRule(false)
    , m_defaultNamespace(starAtom)
    , m_inStyleRuleOrDeclaration(false)
    , m_selectorListRange(0, 0)
    , m_ruleBodyRange(0, 0)
    , m_propertyRange(UINT_MAX, UINT_MAX)
    , m_ruleRangeMap(0)
    , m_currentRuleData(0)
    , m_data(0)
    , yy_start(1)
    , m_lineNumber(0)
    , m_lastSelectorLineNumber(0)
    , m_allowImportRules(true)
    , m_allowNamespaceDeclarations(true)
{
#if YYDEBUG > 0
    cssyydebug = 1;
#endif
    CSSPropertySourceData::init();
}

CSSParser::~CSSParser()
{
    clearProperties();
    fastFree(m_parsedProperties);

    delete m_valueList;

    fastFree(m_data);

    fastDeleteAllValues(m_floatingSelectors);
    deleteAllValues(m_floatingSelectorVectors);
    deleteAllValues(m_floatingValueLists);
    deleteAllValues(m_floatingFunctions);
}

void CSSParserString::lower()
{
    // FIXME: If we need Unicode lowercasing here, then we probably want the real kind
    // that can potentially change the length of the string rather than the character
    // by character kind. If we don't need Unicode lowercasing, it would be good to
    // simplify this function.

    if (charactersAreAllASCII(characters, length)) {
        // Fast case for all-ASCII.
        for (int i = 0; i < length; i++)
            characters[i] = toASCIILower(characters[i]);
    } else {
        for (int i = 0; i < length; i++)
            characters[i] = Unicode::toLower(characters[i]);
    }
}

void CSSParser::setupParser(const char* prefix, const String& string, const char* suffix)
{
    int length = string.length() + strlen(prefix) + strlen(suffix) + 2;

    fastFree(m_data);
    m_data = static_cast<UChar*>(fastMalloc(length * sizeof(UChar)));
    for (unsigned i = 0; i < strlen(prefix); i++)
        m_data[i] = prefix[i];

    memcpy(m_data + strlen(prefix), string.characters(), string.length() * sizeof(UChar));

    unsigned start = strlen(prefix) + string.length();
    unsigned end = start + strlen(suffix);
    for (unsigned i = start; i < end; i++)
        m_data[i] = suffix[i - start];

    m_data[length - 1] = 0;
    m_data[length - 2] = 0;

    yy_hold_char = 0;
    yyleng = 0;
    yytext = yy_c_buf_p = m_data;
    yy_hold_char = *yy_c_buf_p;
    resetRuleBodyMarks();
}

void CSSParser::parseSheet(CSSStyleSheet* sheet, const String& string, int startLineNumber, StyleRuleRangeMap* ruleRangeMap)
{
    setStyleSheet(sheet);
    m_defaultNamespace = starAtom; // Reset the default namespace.
    m_ruleRangeMap = ruleRangeMap;
    if (ruleRangeMap) {
        m_currentRuleData = CSSRuleSourceData::create();
        m_currentRuleData->styleSourceData = CSSStyleSourceData::create();
    }

    m_lineNumber = startLineNumber;
    setupParser("", string, "");
    cssyyparse(this);
    m_ruleRangeMap = 0;
    m_currentRuleData = 0;
    m_rule = 0;
}

PassRefPtr<CSSRule> CSSParser::parseRule(CSSStyleSheet* sheet, const String& string)
{
    setStyleSheet(sheet);
    m_allowNamespaceDeclarations = false;
    setupParser("@-webkit-rule{", string, "} ");
    cssyyparse(this);
    return m_rule.release();
}

PassRefPtr<CSSRule> CSSParser::parseKeyframeRule(CSSStyleSheet *sheet, const String &string)
{
    setStyleSheet(sheet);
    setupParser("@-webkit-keyframe-rule{ ", string, "} ");
    cssyyparse(this);
    return m_keyframe.release();
}

static inline bool isColorPropertyID(int propertyId)
{
    switch (propertyId) {
    case CSSPropertyColor:
    case CSSPropertyBackgroundColor:
    case CSSPropertyBorderBottomColor:
    case CSSPropertyBorderLeftColor:
    case CSSPropertyBorderRightColor:
    case CSSPropertyBorderTopColor:
    case CSSPropertyOutlineColor:
    case CSSPropertyTextLineThroughColor:
    case CSSPropertyTextOverlineColor:
    case CSSPropertyTextUnderlineColor:
    case CSSPropertyWebkitBorderAfterColor:
    case CSSPropertyWebkitBorderBeforeColor:
    case CSSPropertyWebkitBorderEndColor:
    case CSSPropertyWebkitBorderStartColor:
    case CSSPropertyWebkitColumnRuleColor:
    case CSSPropertyWebkitTextEmphasisColor:
    case CSSPropertyWebkitTextFillColor:
    case CSSPropertyWebkitTextStrokeColor:
        return true;
    default:
        return false;
    }
}

static bool parseColorValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, bool strict)
{
    if (!string.length())
        return false;
    if (!isColorPropertyID(propertyId))
        return false;
    CSSParserString cssString;
    cssString.characters = const_cast<UChar*>(string.characters());
    cssString.length = string.length();
    int valueID = cssValueKeywordID(cssString);
    bool validPrimitive = false;
    if (valueID == CSSValueWebkitText)
        validPrimitive = true;
    else if (valueID == CSSValueCurrentcolor)
        validPrimitive = true;
    else if ((valueID >= CSSValueAqua && valueID <= CSSValueWindowtext) || valueID == CSSValueMenu
             || (valueID >= CSSValueWebkitFocusRingColor && valueID < CSSValueWebkitText && !strict)) {
        validPrimitive = true;
    }

    CSSStyleSheet* stylesheet = static_cast<CSSStyleSheet*>(declaration->stylesheet());
    if (!stylesheet || !stylesheet->document())
        return false;
    if (validPrimitive) {
        CSSProperty property(propertyId, stylesheet->document()->cssPrimitiveValueCache()->createIdentifierValue(valueID), important);
        declaration->addParsedProperty(property);
        return true;
    }
    RGBA32 color;
    if (!CSSParser::parseColor(string, color, strict && string[0] != '#'))
        return false;
    CSSProperty property(propertyId, stylesheet->document()->cssPrimitiveValueCache()->createColorValue(color), important);
    declaration->addParsedProperty(property);
    return true;
}

static inline bool isSimpleLengthPropertyID(int propertyId, bool& acceptsNegativeNumbers)
{
    switch (propertyId) {
    case CSSPropertyFontSize:
    case CSSPropertyHeight:
    case CSSPropertyWidth:
    case CSSPropertyMinHeight:
    case CSSPropertyMinWidth:
    case CSSPropertyPaddingBottom:
    case CSSPropertyPaddingLeft:
    case CSSPropertyPaddingRight: 
    case CSSPropertyPaddingTop:
    case CSSPropertyWebkitLogicalWidth:
    case CSSPropertyWebkitLogicalHeight:
    case CSSPropertyWebkitMinLogicalWidth:
    case CSSPropertyWebkitMinLogicalHeight:
    case CSSPropertyWebkitPaddingAfter:
    case CSSPropertyWebkitPaddingBefore:
    case CSSPropertyWebkitPaddingEnd:
    case CSSPropertyWebkitPaddingStart:
        acceptsNegativeNumbers = false;
        return true;
    case CSSPropertyBottom:
    case CSSPropertyLeft:
    case CSSPropertyMarginBottom:
    case CSSPropertyMarginLeft: 
    case CSSPropertyMarginRight: 
    case CSSPropertyMarginTop:
    case CSSPropertyRight:
    case CSSPropertyTextIndent:
    case CSSPropertyTop:
    case CSSPropertyWebkitMarginAfter:
    case CSSPropertyWebkitMarginBefore:
    case CSSPropertyWebkitMarginEnd:
    case CSSPropertyWebkitMarginStart:
        acceptsNegativeNumbers = true;
        return true;
    default:
        return false;
    }
}

static bool parseSimpleLengthValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, bool strict)
{
    const UChar* characters = string.characters();
    unsigned length = string.length();
    if (!characters || !length)
        return false;
    bool acceptsNegativeNumbers;
    if (!isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
        return false;

    CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER;
    if (length > 2 && characters[length - 2] == 'p' && characters[length - 1] == 'x') {
        length -= 2;
        unit = CSSPrimitiveValue::CSS_PX;
    } else if (length > 1 && characters[length - 1] == '%') {
        length -= 1;
        unit = CSSPrimitiveValue::CSS_PERCENTAGE;
    }

    // We rely on charactersToDouble for validation as well. The function
    // will set "ok" to "false" if the entire passed-in character range does
    // not represent a double.
    bool ok;
    double number = charactersToDouble(characters, length, &ok);
    if (!ok)
        return false;
    if (unit == CSSPrimitiveValue::CSS_NUMBER) {
        if (number && strict)
            return false;
        unit = CSSPrimitiveValue::CSS_PX;
    }
    if (number < 0 && !acceptsNegativeNumbers)
        return false;

    CSSStyleSheet* stylesheet = static_cast<CSSStyleSheet*>(declaration->stylesheet());
    if (!stylesheet || !stylesheet->document())
        return false;
    CSSProperty property(propertyId, stylesheet->document()->cssPrimitiveValueCache()->createValue(number, unit), important);
    declaration->addParsedProperty(property);
    return true;
}

bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, bool strict)
{
    if (parseSimpleLengthValue(declaration, propertyId, string, important, strict))
        return true;
    if (parseColorValue(declaration, propertyId, string, important, strict))
        return true;
    CSSParser parser(strict);
    return parser.parseValue(declaration, propertyId, string, important);
}

bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important)
{
    ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet());
    setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet()));

    setupParser("@-webkit-value{", string, "} ");

    m_id = propertyId;
    m_important = important;

    cssyyparse(this);

    m_rule = 0;

    bool ok = false;
    if (m_hasFontFaceOnlyValues)
        deleteFontFaceOnlyValues();
    if (m_numParsedProperties) {
        ok = true;
        declaration->addParsedProperties(m_parsedProperties, m_numParsedProperties);
        clearProperties();
    }

    return ok;
}

// color will only be changed when string contains a valid css color, making it
// possible to set up a default color.
bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict)
{
    // First try creating a color specified by name, rgba(), rgb() or "#" syntax.
    if (parseColor(string, color, strict))
        return true;

    CSSParser parser(true);
    RefPtr<CSSMutableStyleDeclaration> dummyStyleDeclaration = CSSMutableStyleDeclaration::create();

    // Now try to create a color from rgba() syntax.
    if (!parser.parseColor(dummyStyleDeclaration.get(), string))
        return false;

    CSSValue* value = parser.m_parsedProperties[0]->value();
    if (value->cssValueType() != CSSValue::CSS_PRIMITIVE_VALUE)
        return false;

    CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
    if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_RGBCOLOR)
        return false;

    color = primitiveValue->getRGBA32Value();
    return true;
}

bool CSSParser::parseColor(CSSMutableStyleDeclaration* declaration, const String& string)
{
    ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet());
    setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet()));

    setupParser("@-webkit-decls{color:", string, "} ");
    cssyyparse(this);
    m_rule = 0;

    return (m_numParsedProperties && m_parsedProperties[0]->m_id == CSSPropertyColor);
}

bool CSSParser::parseSystemColor(RGBA32& color, const String& string, Document* document)
{
    if (!document || !document->page())
        return false;

    CSSParserString cssColor;
    cssColor.characters = const_cast<UChar*>(string.characters());
    cssColor.length = string.length();
    int id = cssValueKeywordID(cssColor);
    if (id <= 0)
        return false;

    color = document->page()->theme()->systemColor(id).rgb();
    return true;
}

void CSSParser::parseSelector(const String& string, Document* doc, CSSSelectorList& selectorList)
{
    RefPtr<CSSStyleSheet> dummyStyleSheet = CSSStyleSheet::create(doc);

    setStyleSheet(dummyStyleSheet.get());
    m_selectorListForParseSelector = &selectorList;

    setupParser("@-webkit-selector{", string, "}");

    cssyyparse(this);

    m_selectorListForParseSelector = 0;

    // The style sheet will be deleted right away, so it won't outlive the document.
    ASSERT(dummyStyleSheet->hasOneRef());
}

bool CSSParser::parseDeclaration(CSSMutableStyleDeclaration* declaration, const String& string, RefPtr<CSSStyleSourceData>* styleSourceData)
{
    // Length of the "@-webkit-decls{" prefix.
    static const unsigned prefixLength = 15;

    ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet());
    setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet()));
    if (styleSourceData) {
        m_currentRuleData = CSSRuleSourceData::create();
        m_currentRuleData->styleSourceData = CSSStyleSourceData::create();
        m_inStyleRuleOrDeclaration = true;
    }

    setupParser("@-webkit-decls{", string, "} ");
    cssyyparse(this);
    m_rule = 0;

    bool ok = false;
    if (m_hasFontFaceOnlyValues)
        deleteFontFaceOnlyValues();
    if (m_numParsedProperties) {
        ok = true;
        declaration->addParsedProperties(m_parsedProperties, m_numParsedProperties);
        clearProperties();
    }

    if (m_currentRuleData) {
        m_currentRuleData->styleSourceData->styleBodyRange.start = 0;
        m_currentRuleData->styleSourceData->styleBodyRange.end = string.length();
        for (Vector<CSSPropertySourceData>::iterator it = m_currentRuleData->styleSourceData->propertyData.begin(), endIt = m_currentRuleData->styleSourceData->propertyData.end(); it != endIt; ++it) {
            (*it).range.start -= prefixLength;
            (*it).range.end -= prefixLength;
        }
    }

    if (styleSourceData) {
        *styleSourceData = m_currentRuleData->styleSourceData.release();
        m_currentRuleData = 0;
        m_inStyleRuleOrDeclaration = false;
    }
    return ok;
}

bool CSSParser::parseMediaQuery(MediaList* queries, const String& string)
{
    if (string.isEmpty())
        return true;

    ASSERT(!m_mediaQuery);

    // can't use { because tokenizer state switches from mediaquery to initial state when it sees { token.
    // instead insert one " " (which is WHITESPACE in CSSGrammar.y)
    setupParser("@-webkit-mediaquery ", string, "} ");
    cssyyparse(this);

    bool ok = false;
    if (m_mediaQuery) {
        ok = true;
        queries->appendMediaQuery(m_mediaQuery.release());
    }

    return ok;
}


void CSSParser::addProperty(int propId, PassRefPtr<CSSValue> value, bool important)
{
    OwnPtr<CSSProperty> prop(new CSSProperty(propId, value, important, m_currentShorthand, m_implicitShorthand));
    if (m_numParsedProperties >= m_maxParsedProperties) {
        m_maxParsedProperties += 32;
        if (m_maxParsedProperties > UINT_MAX / sizeof(CSSProperty*))
            return;
        m_parsedProperties = static_cast<CSSProperty**>(fastRealloc(m_parsedProperties,
            m_maxParsedProperties * sizeof(CSSProperty*)));
    }
    m_parsedProperties[m_numParsedProperties++] = prop.leakPtr();
}

void CSSParser::rollbackLastProperties(int num)
{
    ASSERT(num >= 0);
    ASSERT(m_numParsedProperties >= static_cast<unsigned>(num));

    for (int i = 0; i < num; ++i)
        delete m_parsedProperties[--m_numParsedProperties];
}

void CSSParser::clearProperties()
{
    for (unsigned i = 0; i < m_numParsedProperties; i++)
        delete m_parsedProperties[i];
    m_numParsedProperties = 0;
    m_numParsedPropertiesBeforeMarginBox = INVALID_NUM_PARSED_PROPERTIES;
    m_hasFontFaceOnlyValues = false;
}
    
void CSSParser::setStyleSheet(CSSStyleSheet* styleSheet)
{
    m_styleSheet = styleSheet;
    m_primitiveValueCache = document() ? document()->cssPrimitiveValueCache() : CSSPrimitiveValueCache::create();
}

Document* CSSParser::document() const
{
    StyleBase* root = m_styleSheet;
    while (root && root->parent())
        root = root->parent();
    if (!root)
        return 0;
    if (!root->isCSSStyleSheet())
        return 0;
    return static_cast<CSSStyleSheet*>(root)->document();
}

bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, bool strict)
{
    bool b = false;
    switch (value->unit) {
    case CSSPrimitiveValue::CSS_NUMBER:
        b = (unitflags & FNumber);
        if (!b && ((unitflags & (FLength | FAngle | FTime)) && (value->fValue == 0 || !strict))) {
            value->unit = (unitflags & FLength) ? CSSPrimitiveValue::CSS_PX :
                          ((unitflags & FAngle) ? CSSPrimitiveValue::CSS_DEG : CSSPrimitiveValue::CSS_MS);
            b = true;
        }
        if (!b && (unitflags & FInteger) && value->isInt)
            b = true;
        break;
    case CSSPrimitiveValue::CSS_PERCENTAGE:
        b = (unitflags & FPercent);
        break;
    case CSSParserValue::Q_EMS:
    case CSSPrimitiveValue::CSS_EMS:
    case CSSPrimitiveValue::CSS_REMS:
    case CSSPrimitiveValue::CSS_EXS:
    case CSSPrimitiveValue::CSS_PX:
    case CSSPrimitiveValue::CSS_CM:
    case CSSPrimitiveValue::CSS_MM:
    case CSSPrimitiveValue::CSS_IN:
    case CSSPrimitiveValue::CSS_PT:
    case CSSPrimitiveValue::CSS_PC:
        b = (unitflags & FLength);
        break;
    case CSSPrimitiveValue::CSS_MS:
    case CSSPrimitiveValue::CSS_S:
        b = (unitflags & FTime);
        break;
    case CSSPrimitiveValue::CSS_DEG:
    case CSSPrimitiveValue::CSS_RAD:
    case CSSPrimitiveValue::CSS_GRAD:
    case CSSPrimitiveValue::CSS_TURN:
        b = (unitflags & FAngle);
        break;
    case CSSPrimitiveValue::CSS_HZ:
    case CSSPrimitiveValue::CSS_KHZ:
    case CSSPrimitiveValue::CSS_DIMENSION:
    default:
        break;
    }
    if (b && unitflags & FNonNeg && value->fValue < 0)
        b = false;
    return b;
}

static int unitFromString(CSSParserValue* value)
{
    if (value->unit != CSSPrimitiveValue::CSS_IDENT || value->id)
        return 0;

    if (equal(value->string, "em"))
        return CSSPrimitiveValue::CSS_EMS;
    if (equal(value->string, "rem"))
        return CSSPrimitiveValue::CSS_REMS;
    if (equal(value->string, "ex"))
        return CSSPrimitiveValue::CSS_EXS;
    if (equal(value->string, "px"))
        return CSSPrimitiveValue::CSS_PX;
    if (equal(value->string, "cm"))
        return CSSPrimitiveValue::CSS_CM;
    if (equal(value->string, "mm"))
        return CSSPrimitiveValue::CSS_MM;
    if (equal(value->string, "in"))
        return CSSPrimitiveValue::CSS_IN;
    if (equal(value->string, "pt"))
        return CSSPrimitiveValue::CSS_PT;
    if (equal(value->string, "pc"))
        return CSSPrimitiveValue::CSS_PC;
    if (equal(value->string, "deg"))
        return CSSPrimitiveValue::CSS_DEG;
    if (equal(value->string, "rad"))
        return CSSPrimitiveValue::CSS_RAD;
    if (equal(value->string, "grad"))
        return CSSPrimitiveValue::CSS_GRAD;
    if (equal(value->string, "turn"))
        return CSSPrimitiveValue::CSS_TURN;
    if (equal(value->string, "ms"))
        return CSSPrimitiveValue::CSS_MS;
    if (equal(value->string, "s"))
        return CSSPrimitiveValue::CSS_S;
    if (equal(value->string, "Hz"))
        return CSSPrimitiveValue::CSS_HZ;
    if (equal(value->string, "kHz"))
        return CSSPrimitiveValue::CSS_KHZ;

    return 0;
}

void CSSParser::checkForOrphanedUnits()
{
    if (m_strict || inShorthand())
        return;

    // The purpose of this code is to implement the WinIE quirk that allows unit types to be separated from their numeric values
    // by whitespace, so e.g., width: 20 px instead of width:20px.  This is invalid CSS, so we don't do this in strict mode.
    CSSParserValue* numericVal = 0;
    unsigned size = m_valueList->size();
    for (unsigned i = 0; i < size; i++) {
        CSSParserValue* value = m_valueList->valueAt(i);

        if (numericVal) {
            // Change the unit type of the numeric val to match.
            int unit = unitFromString(value);
            if (unit) {
                numericVal->unit = unit;
                numericVal = 0;

                // Now delete the bogus unit value.
                m_valueList->deleteValueAt(i);
                i--; // We're safe even though |i| is unsigned, since we only hit this code if we had a previous numeric value (so |i| is always > 0 here).
                size--;
                continue;
            }
        }

        numericVal = (value->unit == CSSPrimitiveValue::CSS_NUMBER) ? value : 0;
    }
}

bool CSSParser::parseValue(int propId, bool important)
{
    if (!m_valueList)
        return false;

    CSSParserValue* value = m_valueList->current();

    if (!value)
        return false;

    int id = value->id;

    // In quirks mode, we will look for units that have been incorrectly separated from the number they belong to
    // by a space.  We go ahead and associate the unit with the number even though it is invalid CSS.
    checkForOrphanedUnits();

    int num = inShorthand() ? 1 : m_valueList->size();

    if (id == CSSValueInherit) {
        if (num != 1)
            return false;
        addProperty(propId, CSSInheritedValue::create(), important);
        return true;
    }
    else if (id == CSSValueInitial) {
        if (num != 1)
            return false;
        addProperty(propId, CSSInitialValue::createExplicit(), important);
        return true;
    }

    bool validPrimitive = false;
    RefPtr<CSSValue> parsedValue;

    switch (static_cast<CSSPropertyID>(propId)) {
        /* The comment to the left defines all valid value of this properties as defined
         * in CSS 2, Appendix F. Property index
         */

        /* All the CSS properties are not supported by the renderer at the moment.
         * Note that all the CSS2 Aural properties are only checked, if CSS_AURAL is defined
         * (see parseAuralValues). As we don't support them at all this seems reasonable.
         */

    case CSSPropertySize:                 // <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ]
        return parseSize(propId, important);

    case CSSPropertyQuotes:               // [<string> <string>]+ | none | inherit
        if (id)
            validPrimitive = true;
        else
            return parseQuotes(propId, important);
        break;
    case CSSPropertyUnicodeBidi: // normal | embed | bidi-override | isolate | inherit
        if (id == CSSValueNormal
            || id == CSSValueEmbed
            || id == CSSValueBidiOverride
            || id == CSSValueWebkitIsolate)
            validPrimitive = true;
        break;

    case CSSPropertyPosition:             // static | relative | absolute | fixed | inherit
        if (id == CSSValueStatic ||
             id == CSSValueRelative ||
             id == CSSValueAbsolute ||
             id == CSSValueFixed)
            validPrimitive = true;
        break;

    case CSSPropertyPageBreakAfter:     // auto | always | avoid | left | right | inherit
    case CSSPropertyPageBreakBefore:
    case CSSPropertyWebkitColumnBreakAfter:
    case CSSPropertyWebkitColumnBreakBefore:
        if (id == CSSValueAuto ||
             id == CSSValueAlways ||
             id == CSSValueAvoid ||
             id == CSSValueLeft ||
             id == CSSValueRight)
            validPrimitive = true;
        break;

    case CSSPropertyPageBreakInside:    // avoid | auto | inherit
    case CSSPropertyWebkitColumnBreakInside:
        if (id == CSSValueAuto || id == CSSValueAvoid)
            validPrimitive = true;
        break;

    case CSSPropertyEmptyCells:          // show | hide | inherit
        if (id == CSSValueShow ||
             id == CSSValueHide)
            validPrimitive = true;
        break;

    case CSSPropertyContent:              // [ <string> | <uri> | <counter> | attr(X) | open-quote |
        // close-quote | no-open-quote | no-close-quote ]+ | inherit
        return parseContent(propId, important);

    case CSSPropertyWhiteSpace:          // normal | pre | nowrap | inherit
        if (id == CSSValueNormal ||
            id == CSSValuePre ||
            id == CSSValuePreWrap ||
            id == CSSValuePreLine ||
            id == CSSValueNowrap)
            validPrimitive = true;
        break;

    case CSSPropertyClip:                 // <shape> | auto | inherit
        if (id == CSSValueAuto)
            validPrimitive = true;
        else if (value->unit == CSSParserValue::Function)
            return parseShape(propId, important);
        break;

    /* Start of supported CSS properties with validation. This is needed for parseShorthand to work
     * correctly and allows optimization in WebCore::applyRule(..)
     */
    case CSSPropertyCaptionSide:         // top | bottom | left | right | inherit
        if (id == CSSValueLeft || id == CSSValueRight ||
            id == CSSValueTop || id == CSSValueBottom)
            validPrimitive = true;
        break;

    case CSSPropertyBorderCollapse:      // collapse | separate | inherit
        if (id == CSSValueCollapse || id == CSSValueSeparate)
            validPrimitive = true;
        break;

    case CSSPropertyVisibility:           // visible | hidden | collapse | inherit
        if (id == CSSValueVisible || id == CSSValueHidden || id == CSSValueCollapse)
            validPrimitive = true;
        break;

    case CSSPropertyOverflow: {
        ShorthandScope scope(this, propId);
        if (num != 1 || !parseValue(CSSPropertyOverflowX, important))
            return false;
        CSSValue* value = m_parsedProperties[m_numParsedProperties - 1]->value();
        addProperty(CSSPropertyOverflowY, value, important);
        return true;
    }
    case CSSPropertyOverflowX:
    case CSSPropertyOverflowY:           // visible | hidden | scroll | auto | marquee | overlay | inherit
        if (id == CSSValueVisible || id == CSSValueHidden || id == CSSValueScroll || id == CSSValueAuto ||
            id == CSSValueOverlay || id == CSSValueWebkitMarquee)
            validPrimitive = true;
        break;

    case CSSPropertyListStylePosition:  // inside | outside | inherit
        if (id == CSSValueInside || id == CSSValueOutside)
            validPrimitive = true;
        break;

    case CSSPropertyListStyleType:
        // See section CSS_PROP_LIST_STYLE_TYPE of file CSSValueKeywords.in
        // for the list of supported list-style-types.
        if ((id >= CSSValueDisc && id <= CSSValueKatakanaIroha) || id == CSSValueNone)
            validPrimitive = true;
        break;

    case CSSPropertyDisplay:
        // inline | block | list-item | run-in | inline-block | table |
        // inline-table | table-row-group | table-header-group | table-footer-group | table-row |
        // table-column-group | table-column | table-cell | table-caption | box | inline-box | none | inherit
#if ENABLE(WCSS)
        if ((id >= CSSValueInline && id <= CSSValueWapMarquee) || id == CSSValueNone)
#else
        if ((id >= CSSValueInline && id <= CSSValueWebkitInlineBox) || id == CSSValueNone)
#endif
            validPrimitive = true;
        break;

    case CSSPropertyDirection:            // ltr | rtl | inherit
        if (id == CSSValueLtr || id == CSSValueRtl)
            validPrimitive = true;
        break;

    case CSSPropertyTextTransform:       // capitalize | uppercase | lowercase | none | inherit
        if ((id >= CSSValueCapitalize && id <= CSSValueLowercase) || id == CSSValueNone)
            validPrimitive = true;
        break;

    case CSSPropertyFloat:                // left | right | none | inherit + center for buggy CSS
        if (id == CSSValueLeft || id == CSSValueRight ||
             id == CSSValueNone || id == CSSValueCenter)
            validPrimitive = true;
        break;

    case CSSPropertyClear:                // none | left | right | both | inherit
        if (id == CSSValueNone || id == CSSValueLeft ||
             id == CSSValueRight|| id == CSSValueBoth)
            validPrimitive = true;
        break;

    case CSSPropertyTextAlign:
        // left | right | center | justify | webkit_left | webkit_right | webkit_center | webkit_match_parent |
        // start | end | <string> | inherit
        if ((id >= CSSValueWebkitAuto && id <= CSSValueWebkitMatchParent) || id == CSSValueStart || id == CSSValueEnd
             || value->unit == CSSPrimitiveValue::CSS_STRING)
            validPrimitive = true;
        break;

    case CSSPropertyOutlineStyle:        // (<border-style> except hidden) | auto | inherit
        if (id == CSSValueAuto || id == CSSValueNone || (id >= CSSValueInset && id <= CSSValueDouble))
            validPrimitive = true;
        break;

    case CSSPropertyBorderTopStyle:     //// <border-style> | inherit
    case CSSPropertyBorderRightStyle:   //   Defined as:    none | hidden | dotted | dashed |
    case CSSPropertyBorderBottomStyle:  //   solid | double | groove | ridge | inset | outset
    case CSSPropertyBorderLeftStyle:
    case CSSPropertyWebkitBorderStartStyle:
    case CSSPropertyWebkitBorderEndStyle:
    case CSSPropertyWebkitBorderBeforeStyle:
    case CSSPropertyWebkitBorderAfterStyle:
    case CSSPropertyWebkitColumnRuleStyle:
        if (id >= CSSValueNone && id <= CSSValueDouble)
            validPrimitive = true;
        break;

    case CSSPropertyFontWeight:  // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit
        return parseFontWeight(important);

    case CSSPropertyBorderSpacing: {
        const int properties[2] = { CSSPropertyWebkitBorderHorizontalSpacing,
                                    CSSPropertyWebkitBorderVerticalSpacing };
        if (num == 1) {
            ShorthandScope scope(this, CSSPropertyBorderSpacing);
            if (!parseValue(properties[0], important))
                return false;
            CSSValue* value = m_parsedProperties[m_numParsedProperties-1]->value();
            addProperty(properties[1], value, important);
            return true;
        }
        else if (num == 2) {
            ShorthandScope scope(this, CSSPropertyBorderSpacing);
            if (!parseValue(properties[0], important) || !parseValue(properties[1], important))
                return false;
            return true;
        }
        return false;
    }
    case CSSPropertyWebkitBorderHorizontalSpacing:
    case CSSPropertyWebkitBorderVerticalSpacing:
        validPrimitive = validUnit(value, FLength | FNonNeg, m_strict);
        break;
    case CSSPropertyOutlineColor:        // <color> | invert | inherit
        // Outline color has "invert" as additional keyword.
        // Also, we want to allow the special focus color even in strict parsing mode.
        if (id == CSSValueInvert || id == CSSValueWebkitFocusRingColor) {
            validPrimitive = true;
            break;
        }
        /* nobreak */
    case CSSPropertyBackgroundColor: // <color> | inherit
    case CSSPropertyBorderTopColor: // <color> | inherit
    case CSSPropertyBorderRightColor:
    case CSSPropertyBorderBottomColor:
    case CSSPropertyBorderLeftColor:
    case CSSPropertyWebkitBorderStartColor:
    case CSSPropertyWebkitBorderEndColor:
    case CSSPropertyWebkitBorderBeforeColor:
    case CSSPropertyWebkitBorderAfterColor:
    case CSSPropertyColor: // <color> | inherit
    case CSSPropertyTextLineThroughColor: // CSS3 text decoration colors
    case CSSPropertyTextUnderlineColor:
    case CSSPropertyTextOverlineColor:
    case CSSPropertyWebkitColumnRuleColor:
    case CSSPropertyWebkitTextEmphasisColor:
    case CSSPropertyWebkitTextFillColor:
    case CSSPropertyWebkitTextStrokeColor:
        if (id == CSSValueWebkitText)
            validPrimitive = true; // Always allow this, even when strict parsing is on,
                                    // since we use this in our UA sheets.
        else if (id == CSSValueCurrentcolor)
            validPrimitive = true;
        else if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu ||
             (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && !m_strict)) {
            validPrimitive = true;
        } else {
            parsedValue = parseColor();
            if (parsedValue)
                m_valueList->next();
        }
        break;

    case CSSPropertyCursor: {
        // [<uri>,]*  [ auto | crosshair | default | pointer | progress | move | e-resize | ne-resize |
        // nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | ew-resize |
        // ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | text | wait | help |
        // vertical-text | cell | context-menu | alias | copy | no-drop | not-allowed | -webkit-zoom-in
        // -webkit-zoom-out | all-scroll | -webkit-grab | -webkit-grabbing ] ] | inherit
        RefPtr<CSSValueList> list;
        while (value && value->unit == CSSPrimitiveValue::CSS_URI) {
            if (!list)
                list = CSSValueList::createCommaSeparated();
            String uri = value->string;
            Vector<int> coords;
            value = m_valueList->next();
            while (value && value->unit == CSSPrimitiveValue::CSS_NUMBER) {
                coords.append(int(value->fValue));
                value = m_valueList->next();
            }
            IntPoint hotSpot(-1, -1);
            int nrcoords = coords.size();
            if (nrcoords > 0 && nrcoords != 2)
                return false;
            if (nrcoords == 2)
                hotSpot = IntPoint(coords[0], coords[1]);

            if (!uri.isNull() && m_styleSheet) {
                // FIXME: The completeURL call should be done when using the CSSCursorImageValue,
                // not when creating it.
                list->append(CSSCursorImageValue::create(m_styleSheet->completeURL(uri), hotSpot));
            }

            if ((m_strict && !value) || (value && !(value->unit == CSSParserValue::Operator && value->iValue == ',')))
                return false;
            value = m_valueList->next(); // comma
        }
        if (list) {
            if (!value) { // no value after url list (MSIE 5 compatibility)
                if (list->length() != 1)
                    return false;
            } else if (!m_strict && value->id == CSSValueHand) // MSIE 5 compatibility :/
                list->append(primitiveValueCache()->createIdentifierValue(CSSValuePointer));
            else if (value && ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone))
                list->append(primitiveValueCache()->createIdentifierValue(value->id));
            m_valueList->next();
            parsedValue = list.release();
            break;
        }
        id = value->id;
        if (!m_strict && value->id == CSSValueHand) { // MSIE 5 compatibility :/
            id = CSSValuePointer;
            validPrimitive = true;
        } else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone)
            validPrimitive = true;
        break;
    }

    case CSSPropertyBackgroundAttachment:
    case CSSPropertyBackgroundClip:
    case CSSPropertyWebkitBackgroundClip:
    case CSSPropertyWebkitBackgroundComposite:
    case CSSPropertyBackgroundImage:
    case CSSPropertyBackgroundOrigin:
    case CSSPropertyWebkitBackgroundOrigin:
    case CSSPropertyBackgroundPosition:
    case CSSPropertyBackgroundPositionX:
    case CSSPropertyBackgroundPositionY:
    case CSSPropertyBackgroundSize:
    case CSSPropertyWebkitBackgroundSize:
    case CSSPropertyBackgroundRepeat:
    case CSSPropertyBackgroundRepeatX:
    case CSSPropertyBackgroundRepeatY:
    case CSSPropertyWebkitMaskAttachment:
    case CSSPropertyWebkitMaskClip:
    case CSSPropertyWebkitMaskComposite:
    case CSSPropertyWebkitMaskImage:
    case CSSPropertyWebkitMaskOrigin:
    case CSSPropertyWebkitMaskPosition:
    case CSSPropertyWebkitMaskPositionX:
    case CSSPropertyWebkitMaskPositionY:
    case CSSPropertyWebkitMaskSize:
    case CSSPropertyWebkitMaskRepeat:
    case CSSPropertyWebkitMaskRepeatX:
    case CSSPropertyWebkitMaskRepeatY: {
        RefPtr<CSSValue> val1;
        RefPtr<CSSValue> val2;
        int propId1, propId2;
        bool result = false;
        if (parseFillProperty(propId, propId1, propId2, val1, val2)) {
            OwnPtr<ShorthandScope> shorthandScope;
            if (propId == CSSPropertyBackgroundPosition ||
                propId == CSSPropertyBackgroundRepeat ||
                propId == CSSPropertyWebkitMaskPosition ||
                propId == CSSPropertyWebkitMaskRepeat) {
                shorthandScope.set(new ShorthandScope(this, propId));
            }
            addProperty(propId1, val1.release(), important);
            if (val2)
                addProperty(propId2, val2.release(), important);
            result = true;
        }
        m_implicitShorthand = false;
        return result;
    }
    case CSSPropertyListStyleImage:     // <uri> | none | inherit
        if (id == CSSValueNone) {
            parsedValue = CSSImageValue::create();
            m_valueList->next();
        } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
            if (m_styleSheet) {
                // FIXME: The completeURL call should be done when using the CSSImageValue,
                // not when creating it.
                parsedValue = CSSImageValue::create(m_styleSheet->completeURL(value->string));
                m_valueList->next();
            }
        } else if (isGeneratedImageValue(value)) {
            if (parseGeneratedImage(parsedValue))
                m_valueList->next();
            else
                return false;
        }
        break;

    case CSSPropertyWebkitTextStrokeWidth:
    case CSSPropertyOutlineWidth:        // <border-width> | inherit
    case CSSPropertyBorderTopWidth:     //// <border-width> | inherit
    case CSSPropertyBorderRightWidth:   //   Which is defined as
    case CSSPropertyBorderBottomWidth:  //   thin | medium | thick | <length>
    case CSSPropertyBorderLeftWidth:
    case CSSPropertyWebkitBorderStartWidth:
    case CSSPropertyWebkitBorderEndWidth:
    case CSSPropertyWebkitBorderBeforeWidth:
    case CSSPropertyWebkitBorderAfterWidth:
    case CSSPropertyWebkitColumnRuleWidth:
        if (id == CSSValueThin || id == CSSValueMedium || id == CSSValueThick)
            validPrimitive = true;
        else
            validPrimitive = validUnit(value, FLength | FNonNeg, m_strict);
        break;

    case CSSPropertyLetterSpacing:       // normal | <length> | inherit
    case CSSPropertyWordSpacing:         // normal | <length> | inherit
        if (id == CSSValueNormal)
            validPrimitive = true;
        else
            validPrimitive = validUnit(value, FLength, m_strict);
        break;

    case CSSPropertyWordBreak:          // normal | break-all | break-word (this is a custom extension)
        if (id == CSSValueNormal || id == CSSValueBreakAll || id == CSSValueBreakWord)
            validPrimitive = true;
        break;

    case CSSPropertyWordWrap:           // normal | break-word
        if (id == CSSValueNormal || id == CSSValueBreakWord)
            validPrimitive = true;
        break;
    case CSSPropertySpeak:           // none | normal | spell-out | digits | literal-punctuation | no-punctuation | inherit
        if (id == CSSValueNone || id == CSSValueNormal || id == CSSValueSpellOut || id == CSSValueDigits 
            || id == CSSValueLiteralPunctuation || id == CSSValueNoPunctuation)
            validPrimitive = true;
        break;
            
    case CSSPropertyTextIndent:          // <length> | <percentage> | inherit
        validPrimitive = (!id && validUnit(value, FLength | FPercent, m_strict));
        break;

    case CSSPropertyPaddingTop:          //// <padding-width> | inherit
    case CSSPropertyPaddingRight:        //   Which is defined as
    case CSSPropertyPaddingBottom:       //   <length> | <percentage>
    case CSSPropertyPaddingLeft:         ////
    case CSSPropertyWebkitPaddingStart:
    case CSSPropertyWebkitPaddingEnd:
    case CSSPropertyWebkitPaddingBefore:
    case CSSPropertyWebkitPaddingAfter:
        validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg, m_strict));
        break;

    case CSSPropertyMaxHeight:           // <length> | <percentage> | none | inherit
    case CSSPropertyMaxWidth:            // <length> | <percentage> | none | inherit
    case CSSPropertyWebkitMaxLogicalWidth:
    case CSSPropertyWebkitMaxLogicalHeight:
        if (id == CSSValueNone || id == CSSValueIntrinsic || id == CSSValueMinIntrinsic) {
            validPrimitive = true;
            break;
        }
        /* nobreak */
    case CSSPropertyMinHeight:           // <length> | <percentage> | inherit
    case CSSPropertyMinWidth:            // <length> | <percentage> | inherit
    case CSSPropertyWebkitMinLogicalWidth:
    case CSSPropertyWebkitMinLogicalHeight:
        if (id == CSSValueIntrinsic || id == CSSValueMinIntrinsic)
            validPrimitive = true;
        else
            validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg, m_strict));
        break;

    case CSSPropertyFontSize:
        // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
        if (id >= CSSValueXxSmall && id <= CSSValueLarger)
            validPrimitive = true;
        else
            validPrimitive = (validUnit(value, FLength | FPercent | FNonNeg, m_strict));
        break;

    case CSSPropertyFontStyle:           // normal | italic | oblique | inherit
        return parseFontStyle(important);

    case CSSPropertyFontVariant:         // normal | small-caps | inherit
        return parseFontVariant(important);

    case CSSPropertyVerticalAlign:
        // baseline | sub | super | top | text-top | middle | bottom | text-bottom |
        // <percentage> | <length> | inherit

        if (id >= CSSValueBaseline && id <= CSSValueWebkitBaselineMiddle)
            validPrimitive = true;
        else
            validPrimitive = (!id && validUnit(value, FLength | FPercent, m_strict));
        break;

    case CSSPropertyHeight:               // <length> | <percentage> | auto | inherit
    case CSSPropertyWidth:                // <length> | <percentage> | auto | inherit
    case CSSPropertyWebkitLogicalWidth:  
    case CSSPropertyWebkitLogicalHeight:
        if (id == CSSValueAuto || id == CSSValueIntrinsic || id == CSSValueMinIntrinsic)
            validPrimitive = true;
        else
            // ### handle multilength case where we allow relative units
            validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg, m_strict));
        break;

    case CSSPropertyBottom:               // <length> | <percentage> | auto | inherit
    case CSSPropertyLeft:                 // <length> | <percentage> | auto | inherit
    case CSSPropertyRight:                // <length> | <percentage> | auto | inherit
    case CSSPropertyTop:                  // <length> | <percentage> | auto | inherit
    case CSSPropertyMarginTop:           //// <margin-width> | inherit
    case CSSPropertyMarginRight:         //   Which is defined as
    case CSSPropertyMarginBottom:        //   <length> | <percentage> | auto | inherit
    case CSSPropertyMarginLeft:          ////
    case CSSPropertyWebkitMarginStart:
    case CSSPropertyWebkitMarginEnd:
    case CSSPropertyWebkitMarginBefore:
    case CSSPropertyWebkitMarginAfter:
        if (id == CSSValueAuto)
            validPrimitive = true;
        else
            validPrimitive = (!id && validUnit(value, FLength | FPercent, m_strict));
        break;

    case CSSPropertyZIndex:              // auto | <integer> | inherit
        if (id == CSSValueAuto) {
            validPrimitive = true;
            break;
        }
        /* nobreak */
    case CSSPropertyOrphans:              // <integer> | inherit
    case CSSPropertyWidows:               // <integer> | inherit
        // ### not supported later on
        validPrimitive = (!id && validUnit(value, FInteger, false));
        break;

    case CSSPropertyLineHeight:          // normal | <number> | <length> | <percentage> | inherit
        if (id == CSSValueNormal)
            validPrimitive = true;
        else
            validPrimitive = (!id && validUnit(value, FNumber | FLength | FPercent | FNonNeg, m_strict));
        break;
    case CSSPropertyCounterIncrement:    // [ <identifier> <integer>? ]+ | none | inherit
        if (id != CSSValueNone)
            return parseCounter(propId, 1, important);
        validPrimitive = true;
        break;
     case CSSPropertyCounterReset:        // [ <identifier> <integer>? ]+ | none | inherit
        if (id != CSSValueNone)
            return parseCounter(propId, 0, important);
        validPrimitive = true;
        break;
    case CSSPropertyFontFamily:
        // [[ <family-name> | <generic-family> ],]* [<family-name> | <generic-family>] | inherit
    {
        parsedValue = parseFontFamily();
        break;
    }

    case CSSPropertyTextDecoration:
    case CSSPropertyWebkitTextDecorationsInEffect:
        // none | [ underline || overline || line-through || blink ] | inherit
        if (id == CSSValueNone) {
            validPrimitive = true;
        } else {
            RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
            bool isValid = true;
            while (isValid && value) {
                switch (value->id) {
                case CSSValueBlink:
                    break;
                case CSSValueUnderline:
                case CSSValueOverline:
                case CSSValueLineThrough:
                    list->append(primitiveValueCache()->createIdentifierValue(value->id));
                    break;
                default:
                    isValid = false;
                }
                value = m_valueList->next();
            }
            if (list->length() && isValid) {
                parsedValue = list.release();
                m_valueList->next();
            }
        }
        break;

    case CSSPropertyZoom:          // normal | reset | document | <number> | <percentage> | inherit
        if (id == CSSValueNormal || id == CSSValueReset || id == CSSValueDocument)
            validPrimitive = true;
        else
            validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg, true));
        break;

    case CSSPropertyTableLayout:         // auto | fixed | inherit
        if (id == CSSValueAuto || id == CSSValueFixed)
            validPrimitive = true;
        break;

    case CSSPropertySrc:  // Only used within @font-face, so cannot use inherit | initial or be !important.  This is a list of urls or local references.
        return parseFontFaceSrc();

    case CSSPropertyUnicodeRange:
        return parseFontFaceUnicodeRange();

    /* CSS3 properties */
    case CSSPropertyWebkitAppearance:
        if ((id >= CSSValueCheckbox && id <= CSSValueTextarea) || id == CSSValueNone)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitBorderImage:
    case CSSPropertyWebkitMaskBoxImage:
        if (id == CSSValueNone)
            validPrimitive = true;
        else {
            RefPtr<CSSValue> result;
            if (parseBorderImage(propId, important, result)) {
                addProperty(propId, result, important);
                return true;
            }
        }
        break;
    case CSSPropertyBorderTopRightRadius:
    case CSSPropertyBorderTopLeftRadius:
    case CSSPropertyBorderBottomLeftRadius:
    case CSSPropertyBorderBottomRightRadius: {
        if (num != 1 && num != 2)
            return false;
        validPrimitive = validUnit(value, FLength | FPercent, m_strict);
        if (!validPrimitive)
            return false;
        RefPtr<CSSPrimitiveValue> parsedValue1 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
        RefPtr<CSSPrimitiveValue> parsedValue2;
        if (num == 2) {
            value = m_valueList->next();
            validPrimitive = validUnit(value, FLength | FPercent, m_strict);
            if (!validPrimitive)
                return false;
            parsedValue2 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
        } else
            parsedValue2 = parsedValue1;

        RefPtr<Pair> pair = Pair::create(parsedValue1.release(), parsedValue2.release());
        RefPtr<CSSPrimitiveValue> val = primitiveValueCache()->createValue(pair.release());
        addProperty(propId, val.release(), important);
        return true;
    }
    case CSSPropertyBorderRadius:
    case CSSPropertyWebkitBorderRadius:
        return parseBorderRadius(propId, important);
    case CSSPropertyOutlineOffset:
        validPrimitive = validUnit(value, FLength | FPercent, m_strict);
        break;
    case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3
    case CSSPropertyBoxShadow:
    case CSSPropertyWebkitBoxShadow:
        if (id == CSSValueNone)
            validPrimitive = true;
        else
            return parseShadow(propId, important);
        break;
    case CSSPropertyWebkitBoxReflect:
        if (id == CSSValueNone)
            validPrimitive = true;
        else
            return parseReflect(propId, important);
        break;
    case CSSPropertyOpacity:
        validPrimitive = validUnit(value, FNumber, m_strict);
        break;
    case CSSPropertyWebkitBoxAlign:
        if (id == CSSValueStretch || id == CSSValueStart || id == CSSValueEnd ||
            id == CSSValueCenter || id == CSSValueBaseline)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitBoxDirection:
        if (id == CSSValueNormal || id == CSSValueReverse)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitBoxLines:
        if (id == CSSValueSingle || id == CSSValueMultiple)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitBoxOrient:
        if (id == CSSValueHorizontal || id == CSSValueVertical ||
            id == CSSValueInlineAxis || id == CSSValueBlockAxis)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitBoxPack:
        if (id == CSSValueStart || id == CSSValueEnd ||
            id == CSSValueCenter || id == CSSValueJustify)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitBoxFlex:
        validPrimitive = validUnit(value, FNumber, m_strict);
        break;
    case CSSPropertyWebkitBoxFlexGroup:
    case CSSPropertyWebkitBoxOrdinalGroup:
        validPrimitive = validUnit(value, FInteger | FNonNeg, true);
        break;
    case CSSPropertyBoxSizing:
        validPrimitive = id == CSSValueBorderBox || id == CSSValueContentBox;
        break;
    case CSSPropertyWebkitColorCorrection:
        validPrimitive = id == CSSValueSrgb || id == CSSValueDefault;
        break;
    case CSSPropertyWebkitMarquee: {
        const int properties[5] = { CSSPropertyWebkitMarqueeDirection, CSSPropertyWebkitMarqueeIncrement,
                                    CSSPropertyWebkitMarqueeRepetition,
                                    CSSPropertyWebkitMarqueeStyle, CSSPropertyWebkitMarqueeSpeed };
        return parseShorthand(propId, properties, 5, important);
    }
    case CSSPropertyWebkitMarqueeDirection:
        if (id == CSSValueForwards || id == CSSValueBackwards || id == CSSValueAhead ||
            id == CSSValueReverse || id == CSSValueLeft || id == CSSValueRight || id == CSSValueDown ||
            id == CSSValueUp || id == CSSValueAuto)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitMarqueeIncrement:
        if (id == CSSValueSmall || id == CSSValueLarge || id == CSSValueMedium)
            validPrimitive = true;
        else
            validPrimitive = validUnit(value, FLength | FPercent, m_strict);
        break;
    case CSSPropertyWebkitMarqueeStyle:
        if (id == CSSValueNone || id == CSSValueSlide || id == CSSValueScroll || id == CSSValueAlternate)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitMarqueeRepetition:
        if (id == CSSValueInfinite)
            validPrimitive = true;
        else
            validPrimitive = validUnit(value, FInteger | FNonNeg, m_strict);
        break;
    case CSSPropertyWebkitMarqueeSpeed:
        if (id == CSSValueNormal || id == CSSValueSlow || id == CSSValueFast)
            validPrimitive = true;
        else
            validPrimitive = validUnit(value, FTime | FInteger | FNonNeg, m_strict);
        break;
#if ENABLE(WCSS)
    case CSSPropertyWapMarqueeDir:
        if (id == CSSValueLtr || id == CSSValueRtl)
            validPrimitive = true;
        break;
    case CSSPropertyWapMarqueeStyle:
        if (id == CSSValueNone || id == CSSValueSlide || id == CSSValueScroll || id == CSSValueAlternate)
            validPrimitive = true;
        break;
    case CSSPropertyWapMarqueeLoop:
        if (id == CSSValueInfinite)
            validPrimitive = true;
        else
            validPrimitive = validUnit(value, FInteger | FNonNeg, m_strict);
        break;
    case CSSPropertyWapMarqueeSpeed:
        if (id == CSSValueNormal || id == CSSValueSlow || id == CSSValueFast)
            validPrimitive = true;
        else
            validPrimitive = validUnit(value, FTime | FInteger | FNonNeg, m_strict);
        break;
#endif
    case CSSPropertyWebkitUserDrag: // auto | none | element
        if (id == CSSValueAuto || id == CSSValueNone || id == CSSValueElement)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitUserModify: // read-only | read-write
        if (id == CSSValueReadOnly || id == CSSValueReadWrite || id == CSSValueReadWritePlaintextOnly)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitUserSelect: // auto | none | text
        if (id == CSSValueAuto || id == CSSValueNone || id == CSSValueText)
            validPrimitive = true;
        break;
    case CSSPropertyTextOverflow: // clip | ellipsis
        if (id == CSSValueClip || id == CSSValueEllipsis)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitTransform:
        if (id == CSSValueNone)
            validPrimitive = true;
        else {
            PassRefPtr<CSSValue> val = parseTransform();
            if (val) {
                addProperty(propId, val, important);
                return true;
            }
            return false;
        }
        break;
    case CSSPropertyWebkitTransformOrigin:
    case CSSPropertyWebkitTransformOriginX:
    case CSSPropertyWebkitTransformOriginY:
    case CSSPropertyWebkitTransformOriginZ: {
        RefPtr<CSSValue> val1;
        RefPtr<CSSValue> val2;
        RefPtr<CSSValue> val3;
        int propId1, propId2, propId3;
        if (parseTransformOrigin(propId, propId1, propId2, propId3, val1, val2, val3)) {
            addProperty(propId1, val1.release(), important);
            if (val2)
                addProperty(propId2, val2.release(), important);
            if (val3)
                addProperty(propId3, val3.release(), important);
            return true;
        }
        return false;
    }
    case CSSPropertyWebkitTransformStyle:
        if (value->id == CSSValueFlat || value->id == CSSValuePreserve3d)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitBackfaceVisibility:
        if (value->id == CSSValueVisible || value->id == CSSValueHidden)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitPerspective:
        if (id == CSSValueNone)
            validPrimitive = true;
        else {
            // Accepting valueless numbers is a quirk of the -webkit prefixed version of the property.
            if (validUnit(value, FNumber | FLength | FNonNeg, m_strict)) {
                RefPtr<CSSValue> val = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
                if (val) {
                    addProperty(propId, val.release(), important);
                    return true;
                }
                return false;
            }
        }
        break;
    case CSSPropertyWebkitPerspectiveOrigin:
    case CSSPropertyWebkitPerspectiveOriginX:
    case CSSPropertyWebkitPerspectiveOriginY: {
        RefPtr<CSSValue> val1;
        RefPtr<CSSValue> val2;
        int propId1, propId2;
        if (parsePerspectiveOrigin(propId, propId1, propId2, val1, val2)) {
            addProperty(propId1, val1.release(), important);
            if (val2)
                addProperty(propId2, val2.release(), important);
            return true;
        }
        return false;
    }
    case CSSPropertyWebkitAnimationDelay:
    case CSSPropertyWebkitAnimationDirection:
    case CSSPropertyWebkitAnimationDuration:
    case CSSPropertyWebkitAnimationFillMode:
    case CSSPropertyWebkitAnimationName:
    case CSSPropertyWebkitAnimationPlayState:
    case CSSPropertyWebkitAnimationIterationCount:
    case CSSPropertyWebkitAnimationTimingFunction:
    case CSSPropertyWebkitTransitionDelay:
    case CSSPropertyWebkitTransitionDuration:
    case CSSPropertyWebkitTransitionTimingFunction:
    case CSSPropertyWebkitTransitionProperty: {
        RefPtr<CSSValue> val;
        if (parseAnimationProperty(propId, val)) {
            addProperty(propId, val.release(), important);
            return true;
        }
        return false;
    }
    case CSSPropertyWebkitMarginCollapse: {
        const int properties[2] = { CSSPropertyWebkitMarginBeforeCollapse,
            CSSPropertyWebkitMarginAfterCollapse };
        if (num == 1) {
            ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
            if (!parseValue(properties[0], important))
                return false;
            CSSValue* value = m_parsedProperties[m_numParsedProperties-1]->value();
            addProperty(properties[1], value, important);
            return true;
        }
        else if (num == 2) {
            ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
            if (!parseValue(properties[0], important) || !parseValue(properties[1], important))
                return false;
            return true;
        }
        return false;
    }
    case CSSPropertyWebkitMarginBeforeCollapse:
    case CSSPropertyWebkitMarginAfterCollapse:
    case CSSPropertyWebkitMarginTopCollapse:
    case CSSPropertyWebkitMarginBottomCollapse:
        if (id == CSSValueCollapse || id == CSSValueSeparate || id == CSSValueDiscard)
            validPrimitive = true;
        break;
    case CSSPropertyTextLineThroughMode:
    case CSSPropertyTextOverlineMode:
    case CSSPropertyTextUnderlineMode:
        if (id == CSSValueContinuous || id == CSSValueSkipWhiteSpace)
            validPrimitive = true;
        break;
    case CSSPropertyTextLineThroughStyle:
    case CSSPropertyTextOverlineStyle:
    case CSSPropertyTextUnderlineStyle:
        if (id == CSSValueNone || id == CSSValueSolid || id == CSSValueDouble ||
            id == CSSValueDashed || id == CSSValueDotDash || id == CSSValueDotDotDash ||
            id == CSSValueWave)
            validPrimitive = true;
        break;
    case CSSPropertyTextRendering: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision
        if (id == CSSValueAuto || id == CSSValueOptimizespeed || id == CSSValueOptimizelegibility
            || id == CSSValueGeometricprecision)
            validPrimitive = true;
        break;
    case CSSPropertyTextLineThroughWidth:
    case CSSPropertyTextOverlineWidth:
    case CSSPropertyTextUnderlineWidth:
        if (id == CSSValueAuto || id == CSSValueNormal || id == CSSValueThin ||
            id == CSSValueMedium || id == CSSValueThick)
            validPrimitive = true;
        else
            validPrimitive = !id && validUnit(value, FNumber | FLength | FPercent, m_strict);
        break;
    case CSSPropertyResize: // none | both | horizontal | vertical | auto
        if (id == CSSValueNone || id == CSSValueBoth || id == CSSValueHorizontal || id == CSSValueVertical || id == CSSValueAuto)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitColumnCount:
        if (id == CSSValueAuto)
            validPrimitive = true;
        else
            validPrimitive = !id && validUnit(value, FInteger | FNonNeg, false);
        break;
    case CSSPropertyWebkitColumnGap:         // normal | <length>
        if (id == CSSValueNormal)
            validPrimitive = true;
        else
            validPrimitive = validUnit(value, FLength | FNonNeg, m_strict);
        break;
    case CSSPropertyWebkitColumnSpan:        // all | 1
        if (id == CSSValueAll)
            validPrimitive = true;
        else
            validPrimitive = validUnit(value, FNumber | FNonNeg, m_strict) && value->fValue == 1;
        break;
    case CSSPropertyWebkitColumnWidth:         // auto | <length>
        if (id == CSSValueAuto)
            validPrimitive = true;
        else // Always parse this property in strict mode, since it would be ambiguous otherwise when used in the 'columns' shorthand property.
            validPrimitive = validUnit(value, FLength, true);
        break;
    case CSSPropertyPointerEvents:
        // none | visiblePainted | visibleFill | visibleStroke | visible |
        // painted | fill | stroke | auto | all | inherit
        if (id == CSSValueVisible || id == CSSValueNone || id == CSSValueAll || id == CSSValueAuto ||
            (id >= CSSValueVisiblepainted && id <= CSSValueStroke))
            validPrimitive = true;
        break;

    // End of CSS3 properties

    // Apple specific properties.  These will never be standardized and are purely to
    // support custom WebKit-based Apple applications.
    case CSSPropertyWebkitLineClamp:
        // When specifying number of lines, don't allow 0 as a valid value
        // When specifying either type of unit, require non-negative integers
        validPrimitive = (!id && (value->unit == CSSPrimitiveValue::CSS_PERCENTAGE || value->fValue) && validUnit(value, FInteger | FPercent | FNonNeg, false));
        break;
    case CSSPropertyWebkitTextSizeAdjust:
        if (id == CSSValueAuto || id == CSSValueNone)
            validPrimitive = true;
        break;
    case CSSPropertyWebkitRtlOrdering:
        if (id == CSSValueLogical || id == CSSValueVisual)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitFontSizeDelta:           // <length>
        validPrimitive = validUnit(value, FLength, m_strict);
        break;

    case CSSPropertyWebkitNbspMode:     // normal | space
        if (id == CSSValueNormal || id == CSSValueSpace)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitLineBreak:   // normal | after-white-space
        if (id == CSSValueNormal || id == CSSValueAfterWhiteSpace)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitMatchNearestMailBlockquoteColor:   // normal | match
        if (id == CSSValueNormal || id == CSSValueMatch)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitHighlight:
        if (id == CSSValueNone || value->unit == CSSPrimitiveValue::CSS_STRING)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitHyphens:
        if (id == CSSValueNone || id == CSSValueManual || id == CSSValueAuto)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitHyphenateCharacter:
        if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitHyphenateLimitBefore:
    case CSSPropertyWebkitHyphenateLimitAfter:
        if (id == CSSValueAuto || validUnit(value, FInteger | FNonNeg, true))
            validPrimitive = true;
        break;

    case CSSPropertyWebkitLocale:
        if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitBorderFit:
        if (id == CSSValueBorder || id == CSSValueLines)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitTextSecurity:
        // disc | circle | square | none | inherit
        if (id == CSSValueDisc || id == CSSValueCircle || id == CSSValueSquare|| id == CSSValueNone)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitFontSmoothing:
        if (id == CSSValueAuto || id == CSSValueNone
            || id == CSSValueAntialiased || id == CSSValueSubpixelAntialiased)
            validPrimitive = true;
        break;

#if ENABLE(DASHBOARD_SUPPORT)
    case CSSPropertyWebkitDashboardRegion: // <dashboard-region> | <dashboard-region>
        if (value->unit == CSSParserValue::Function || id == CSSValueNone)
            return parseDashboardRegions(propId, important);
        break;
#endif
    // End Apple-specific properties

        /* shorthand properties */
    case CSSPropertyBackground: {
        // Position must come before color in this array because a plain old "0" is a legal color
        // in quirks mode but it's usually the X coordinate of a position.
        // FIXME: Add CSSPropertyBackgroundSize to the shorthand.
        const int properties[] = { CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat,
                                   CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition, CSSPropertyBackgroundOrigin,
                                   CSSPropertyBackgroundClip, CSSPropertyBackgroundColor };
        return parseFillShorthand(propId, properties, 7, important);
    }
    case CSSPropertyWebkitMask: {
        const int properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskRepeat,
                                   CSSPropertyWebkitMaskAttachment, CSSPropertyWebkitMaskPosition,
                                   CSSPropertyWebkitMaskOrigin, CSSPropertyWebkitMaskClip };
        return parseFillShorthand(propId, properties, 6, important);
    }
    case CSSPropertyBorder:
        // [ 'border-width' || 'border-style' || <color> ] | inherit
    {
        const int properties[3] = { CSSPropertyBorderWidth, CSSPropertyBorderStyle,
                                    CSSPropertyBorderColor };
        return parseShorthand(propId, properties, 3, important);
    }
    case CSSPropertyBorderTop:
        // [ 'border-top-width' || 'border-style' || <color> ] | inherit
    {
        const int properties[3] = { CSSPropertyBorderTopWidth, CSSPropertyBorderTopStyle,
                                    CSSPropertyBorderTopColor};
        return parseShorthand(propId, properties, 3, important);
    }
    case CSSPropertyBorderRight:
        // [ 'border-right-width' || 'border-style' || <color> ] | inherit
    {
        const int properties[3] = { CSSPropertyBorderRightWidth, CSSPropertyBorderRightStyle,
                                    CSSPropertyBorderRightColor };
        return parseShorthand(propId, properties, 3, important);
    }
    case CSSPropertyBorderBottom:
        // [ 'border-bottom-width' || 'border-style' || <color> ] | inherit
    {
        const int properties[3] = { CSSPropertyBorderBottomWidth, CSSPropertyBorderBottomStyle,
                                    CSSPropertyBorderBottomColor };
        return parseShorthand(propId, properties, 3, important);
    }
    case CSSPropertyBorderLeft:
        // [ 'border-left-width' || 'border-style' || <color> ] | inherit
    {
        const int properties[3] = { CSSPropertyBorderLeftWidth, CSSPropertyBorderLeftStyle,
                                    CSSPropertyBorderLeftColor };
        return parseShorthand(propId, properties, 3, important);
    }
    case CSSPropertyWebkitBorderStart:
    {
        const int properties[3] = { CSSPropertyWebkitBorderStartWidth, CSSPropertyWebkitBorderStartStyle,
            CSSPropertyWebkitBorderStartColor };
        return parseShorthand(propId, properties, 3, important);
    }
    case CSSPropertyWebkitBorderEnd:
    {
        const int properties[3] = { CSSPropertyWebkitBorderEndWidth, CSSPropertyWebkitBorderEndStyle,
            CSSPropertyWebkitBorderEndColor };
        return parseShorthand(propId, properties, 3, important);
    }
    case CSSPropertyWebkitBorderBefore:
    {
        const int properties[3] = { CSSPropertyWebkitBorderBeforeWidth, CSSPropertyWebkitBorderBeforeStyle,
            CSSPropertyWebkitBorderBeforeColor };
        return parseShorthand(propId, properties, 3, important);
    }
    case CSSPropertyWebkitBorderAfter:
    {
        const int properties[3] = { CSSPropertyWebkitBorderAfterWidth, CSSPropertyWebkitBorderAfterStyle,
            CSSPropertyWebkitBorderAfterColor };
        return parseShorthand(propId, properties, 3, important);
    }
    case CSSPropertyOutline:
        // [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit
    {
        const int properties[3] = { CSSPropertyOutlineWidth, CSSPropertyOutlineStyle,
                                    CSSPropertyOutlineColor };
        return parseShorthand(propId, properties, 3, important);
    }
    case CSSPropertyBorderColor:
        // <color>{1,4} | inherit
    {
        const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor,
                                    CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor };
        return parse4Values(propId, properties, important);
    }
    case CSSPropertyBorderWidth:
        // <border-width>{1,4} | inherit
    {
        const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth,
                                    CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth };
        return parse4Values(propId, properties, important);
    }
    case CSSPropertyBorderStyle:
        // <border-style>{1,4} | inherit
    {
        const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle,
                                    CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle };
        return parse4Values(propId, properties, important);
    }
    case CSSPropertyMargin:
        // <margin-width>{1,4} | inherit
    {
        const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight,
                                    CSSPropertyMarginBottom, CSSPropertyMarginLeft };
        return parse4Values(propId, properties, important);
    }
    case CSSPropertyPadding:
        // <padding-width>{1,4} | inherit
    {
        const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight,
                                    CSSPropertyPaddingBottom, CSSPropertyPaddingLeft };
        return parse4Values(propId, properties, important);
    }
    case CSSPropertyFont:
        // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]?
        // 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit
        if (id >= CSSValueCaption && id <= CSSValueStatusBar)
            validPrimitive = true;
        else
            return parseFont(important);
        break;
    case CSSPropertyListStyle:
    {
        const int properties[3] = { CSSPropertyListStyleType, CSSPropertyListStylePosition,
                                    CSSPropertyListStyleImage };
        return parseShorthand(propId, properties, 3, important);
    }
    case CSSPropertyWebkitColumns: {
        const int properties[2] = { CSSPropertyWebkitColumnWidth, CSSPropertyWebkitColumnCount };
        return parseShorthand(propId, properties, 2, important);
    }
    case CSSPropertyWebkitColumnRule: {
        const int properties[3] = { CSSPropertyWebkitColumnRuleWidth, CSSPropertyWebkitColumnRuleStyle,
                                    CSSPropertyWebkitColumnRuleColor };
        return parseShorthand(propId, properties, 3, important);
    }
    case CSSPropertyWebkitTextStroke: {
        const int properties[2] = { CSSPropertyWebkitTextStrokeWidth, CSSPropertyWebkitTextStrokeColor };
        return parseShorthand(propId, properties, 2, important);
    }
    case CSSPropertyWebkitAnimation:
        return parseAnimationShorthand(important);
    case CSSPropertyWebkitTransition:
        return parseTransitionShorthand(important);
    case CSSPropertyInvalid:
        return false;
    case CSSPropertyPage:
        return parsePage(propId, important);
    case CSSPropertyFontStretch:
    case CSSPropertyTextLineThrough:
    case CSSPropertyTextOverline:
    case CSSPropertyTextUnderline:
        return false;
#if ENABLE(WCSS)
    case CSSPropertyWapInputFormat:
        validPrimitive = true;
        break;
    case CSSPropertyWapInputRequired:
        parsedValue = parseWCSSInputProperty();
        break;
#endif

    // CSS Text Layout Module Level 3: Vertical writing support
    case CSSPropertyWebkitWritingMode:
        if (id >= CSSValueHorizontalTb && id <= CSSValueHorizontalBt)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitTextCombine:
        if (id == CSSValueNone || id == CSSValueHorizontal)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitTextEmphasis: {
        const int properties[] = { CSSPropertyWebkitTextEmphasisStyle, CSSPropertyWebkitTextEmphasisColor };
        return parseShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
    }

    case CSSPropertyWebkitTextEmphasisPosition:
        if (id == CSSValueOver || id == CSSValueUnder)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitTextEmphasisStyle:
        return parseTextEmphasisStyle(important);

    case CSSPropertyWebkitTextOrientation:
        // FIXME: For now just support upright and vertical-right.
        if (id == CSSValueVerticalRight || id == CSSValueUpright)
            validPrimitive = true;
        break;

    case CSSPropertyWebkitLineBoxContain:
        if (id == CSSValueNone)
            validPrimitive = true;
        else
            return parseLineBoxContain(important);
        break;

#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
    case CSSPropertyWebkitTapHighlightColor:
        parsedValue = parseColor();
        if (parsedValue)
            m_valueList->next();
        break;
#endif

#if ENABLE(SVG)
    default:
        return parseSVGValue(propId, important);
#endif
    }

    if (validPrimitive) {
        if (id != 0)
            parsedValue = primitiveValueCache()->createIdentifierValue(id);
        else if (value->unit == CSSPrimitiveValue::CSS_STRING)
            parsedValue = primitiveValueCache()->createValue(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
        else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
            parsedValue = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
        else if (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_REMS)
            parsedValue = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
        else if (value->unit >= CSSParserValue::Q_EMS)
            parsedValue = CSSQuirkPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_EMS);
        m_valueList->next();
    }
    if (parsedValue) {
        if (!m_valueList->current() || inShorthand()) {
            addProperty(propId, parsedValue.release(), important);
            return true;
        }
    }
    return false;
}

#if ENABLE(WCSS)
PassRefPtr<CSSValue> CSSParser::parseWCSSInputProperty()
{
    RefPtr<CSSValue> parsedValue = 0;
    CSSParserValue* value = m_valueList->current();
    String inputProperty;
    if (value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT)
        inputProperty = String(value->string);

    if (!inputProperty.isEmpty())
       parsedValue = primitiveValueCache()->createValue(inputProperty, CSSPrimitiveValue::CSS_STRING);

    while (m_valueList->next()) {
    // pass all other values, if any. If we don't do this,
    // the parser will think that it's not done and won't process this property
    }

    return parsedValue;
}
#endif

void CSSParser::addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval)
{
    if (lval) {
        if (lval->isValueList())
            static_cast<CSSValueList*>(lval.get())->append(rval);
        else {
            PassRefPtr<CSSValue> oldlVal(lval.release());
            PassRefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
            list->append(oldlVal);
            list->append(rval);
            lval = list;
        }
    }
    else
        lval = rval;
}

static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtr<CSSValue>& cssValue, CSSPrimitiveValueCache* primitiveValueCache)
{
    if (parserValue->id == CSSValueBorderBox || parserValue->id == CSSValuePaddingBox
        || parserValue->id == CSSValueContentBox || parserValue->id == CSSValueWebkitText) {
        cssValue = primitiveValueCache->createIdentifierValue(parserValue->id);
        return true;
    }
    return false;
}

const int cMaxFillProperties = 9;

bool CSSParser::parseFillShorthand(int propId, const int* properties, int numProperties, bool important)
{
    ASSERT(numProperties <= cMaxFillProperties);
    if (numProperties > cMaxFillProperties)
        return false;

    ShorthandScope scope(this, propId);

    bool parsedProperty[cMaxFillProperties] = { false };
    RefPtr<CSSValue> values[cMaxFillProperties];
    RefPtr<CSSValue> clipValue;
    RefPtr<CSSValue> positionYValue;
    RefPtr<CSSValue> repeatYValue;
    bool foundClip = false;
    int i;

    while (m_valueList->current()) {
        CSSParserValue* val = m_valueList->current();
        if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
            // We hit the end.  Fill in all remaining values with the initial value.
            m_valueList->next();
            for (i = 0; i < numProperties; ++i) {
                if (properties[i] == CSSPropertyBackgroundColor && parsedProperty[i])
                    // Color is not allowed except as the last item in a list for backgrounds.
                    // Reject the entire property.
                    return false;

                if (!parsedProperty[i] && properties[i] != CSSPropertyBackgroundColor) {
                    addFillValue(values[i], CSSInitialValue::createImplicit());
                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
                        addFillValue(positionYValue, CSSInitialValue::createImplicit());
                    if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
                        addFillValue(repeatYValue, CSSInitialValue::createImplicit());
                    if ((properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) && !parsedProperty[i]) {
                        // If background-origin wasn't present, then reset background-clip also.
                        addFillValue(clipValue, CSSInitialValue::createImplicit());
                    }                    
                }
                parsedProperty[i] = false;
            }
            if (!m_valueList->current())
                break;
        }

        bool found = false;
        for (i = 0; !found && i < numProperties; ++i) {
            if (!parsedProperty[i]) {
                RefPtr<CSSValue> val1;
                RefPtr<CSSValue> val2;
                int propId1, propId2;
                CSSParserValue* parserValue = m_valueList->current();
                if (parseFillProperty(properties[i], propId1, propId2, val1, val2)) {
                    parsedProperty[i] = found = true;
                    addFillValue(values[i], val1.release());
                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
                        addFillValue(positionYValue, val2.release());
                    if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
                        addFillValue(repeatYValue, val2.release());
                    if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
                        // Reparse the value as a clip, and see if we succeed.
                        if (parseBackgroundClip(parserValue, val1, primitiveValueCache()))
                            addFillValue(clipValue, val1.release()); // The property parsed successfully.
                        else
                            addFillValue(clipValue, CSSInitialValue::createImplicit()); // Some value was used for origin that is not supported by clip. Just reset clip instead.
                    }
                    if (properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) {
                        // Update clipValue
                        addFillValue(clipValue, val1.release());
                        foundClip = true;
                    }
                }
            }
        }

        // if we didn't find at least one match, this is an
        // invalid shorthand and we have to ignore it
        if (!found)
            return false;
    }

    // Fill in any remaining properties with the initial value.
    for (i = 0; i < numProperties; ++i) {
        if (!parsedProperty[i]) {
            addFillValue(values[i], CSSInitialValue::createImplicit());
            if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
                addFillValue(positionYValue, CSSInitialValue::createImplicit());
            if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
                addFillValue(repeatYValue, CSSInitialValue::createImplicit());
            if ((properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) && !parsedProperty[i]) {
                // If background-origin wasn't present, then reset background-clip also.
                addFillValue(clipValue, CSSInitialValue::createImplicit());
            }
        }
    }

    // Now add all of the properties we found.
    for (i = 0; i < numProperties; i++) {
        if (properties[i] == CSSPropertyBackgroundPosition) {
            addProperty(CSSPropertyBackgroundPositionX, values[i].release(), important);
            // it's OK to call positionYValue.release() since we only see CSSPropertyBackgroundPosition once
            addProperty(CSSPropertyBackgroundPositionY, positionYValue.release(), important);
        } else if (properties[i] == CSSPropertyWebkitMaskPosition) {
            addProperty(CSSPropertyWebkitMaskPositionX, values[i].release(), important);
            // it's OK to call positionYValue.release() since we only see CSSPropertyWebkitMaskPosition once
            addProperty(CSSPropertyWebkitMaskPositionY, positionYValue.release(), important);
        } else if (properties[i] == CSSPropertyBackgroundRepeat) {
            addProperty(CSSPropertyBackgroundRepeatX, values[i].release(), important);
            // it's OK to call repeatYValue.release() since we only see CSSPropertyBackgroundPosition once
            addProperty(CSSPropertyBackgroundRepeatY, repeatYValue.release(), important);
        } else if (properties[i] == CSSPropertyWebkitMaskRepeat) {
            addProperty(CSSPropertyWebkitMaskRepeatX, values[i].release(), important);
            // it's OK to call repeatYValue.release() since we only see CSSPropertyBackgroundPosition once
            addProperty(CSSPropertyWebkitMaskRepeatY, repeatYValue.release(), important);
        } else if ((properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) && !foundClip)
            // Value is already set while updating origin
            continue;
        else
            addProperty(properties[i], values[i].release(), important);

        // Add in clip values when we hit the corresponding origin property.
        if (properties[i] == CSSPropertyBackgroundOrigin && !foundClip)
            addProperty(CSSPropertyBackgroundClip, clipValue.release(), important);
        else if (properties[i] == CSSPropertyWebkitMaskOrigin && !foundClip)
            addProperty(CSSPropertyWebkitMaskClip, clipValue.release(), important);
    }

    return true;
}

void CSSParser::addAnimationValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval)
{
    if (lval) {
        if (lval->isValueList())
            static_cast<CSSValueList*>(lval.get())->append(rval);
        else {
            PassRefPtr<CSSValue> oldVal(lval.release());
            PassRefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
            list->append(oldVal);
            list->append(rval);
            lval = list;
        }
    }
    else
        lval = rval;
}

bool CSSParser::parseAnimationShorthand(bool important)
{
    const int properties[] = {  CSSPropertyWebkitAnimationName,
                                CSSPropertyWebkitAnimationDuration,
                                CSSPropertyWebkitAnimationTimingFunction,
                                CSSPropertyWebkitAnimationDelay,
                                CSSPropertyWebkitAnimationIterationCount,
                                CSSPropertyWebkitAnimationDirection,
                                CSSPropertyWebkitAnimationFillMode };
    const int numProperties = WTF_ARRAY_LENGTH(properties);

    ShorthandScope scope(this, CSSPropertyWebkitAnimation);

    bool parsedProperty[numProperties] = { false }; // compiler will repeat false as necessary
    RefPtr<CSSValue> values[numProperties];

    int i;
    while (m_valueList->current()) {
        CSSParserValue* val = m_valueList->current();
        if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
            // We hit the end.  Fill in all remaining values with the initial value.
            m_valueList->next();
            for (i = 0; i < numProperties; ++i) {
                if (!parsedProperty[i])
                    addAnimationValue(values[i], CSSInitialValue::createImplicit());
                parsedProperty[i] = false;
            }
            if (!m_valueList->current())
                break;
        }

        bool found = false;
        for (i = 0; !found && i < numProperties; ++i) {
            if (!parsedProperty[i]) {
                RefPtr<CSSValue> val;
                if (parseAnimationProperty(properties[i], val)) {
                    parsedProperty[i] = found = true;
                    addAnimationValue(values[i], val.release());
                }
            }
        }

        // if we didn't find at least one match, this is an
        // invalid shorthand and we have to ignore it
        if (!found)
            return false;
    }

    // Fill in any remaining properties with the initial value.
    for (i = 0; i < numProperties; ++i) {
        if (!parsedProperty[i])
            addAnimationValue(values[i], CSSInitialValue::createImplicit());
    }

    // Now add all of the properties we found.
    for (i = 0; i < numProperties; i++)
        addProperty(properties[i], values[i].release(), important);

    return true;
}

bool CSSParser::parseTransitionShorthand(bool important)
{
    const int properties[] = { CSSPropertyWebkitTransitionProperty,
                               CSSPropertyWebkitTransitionDuration,
                               CSSPropertyWebkitTransitionTimingFunction,
                               CSSPropertyWebkitTransitionDelay };
    const int numProperties = WTF_ARRAY_LENGTH(properties);

    ShorthandScope scope(this, CSSPropertyWebkitTransition);

    bool parsedProperty[numProperties] = { false }; // compiler will repeat false as necessary
    RefPtr<CSSValue> values[numProperties];

    int i;
    while (m_valueList->current()) {
        CSSParserValue* val = m_valueList->current();
        if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
            // We hit the end.  Fill in all remaining values with the initial value.
            m_valueList->next();
            for (i = 0; i < numProperties; ++i) {
                if (!parsedProperty[i])
                    addAnimationValue(values[i], CSSInitialValue::createImplicit());
                parsedProperty[i] = false;
            }
            if (!m_valueList->current())
                break;
        }

        bool found = false;
        for (i = 0; !found && i < numProperties; ++i) {
            if (!parsedProperty[i]) {
                RefPtr<CSSValue> val;
                if (parseAnimationProperty(properties[i], val)) {
                    parsedProperty[i] = found = true;
                    addAnimationValue(values[i], val.release());
                }
            }
        }

        // if we didn't find at least one match, this is an
        // invalid shorthand and we have to ignore it
        if (!found)
            return false;
    }

    // Fill in any remaining properties with the initial value.
    for (i = 0; i < numProperties; ++i) {
        if (!parsedProperty[i])
            addAnimationValue(values[i], CSSInitialValue::createImplicit());
    }

    // Now add all of the properties we found.
    for (i = 0; i < numProperties; i++)
        addProperty(properties[i], values[i].release(), important);

    return true;
}

bool CSSParser::parseShorthand(int propId, const int *properties, int numProperties, bool important)
{
    // We try to match as many properties as possible
    // We set up an array of booleans to mark which property has been found,
    // and we try to search for properties until it makes no longer any sense.
    ShorthandScope scope(this, propId);

    bool found = false;
    bool fnd[6]; // Trust me ;)
    for (int i = 0; i < numProperties; i++)
        fnd[i] = false;

    while (m_valueList->current()) {
        found = false;
        for (int propIndex = 0; !found && propIndex < numProperties; ++propIndex) {
            if (!fnd[propIndex]) {
                if (parseValue(properties[propIndex], important))
                    fnd[propIndex] = found = true;
            }
        }

        // if we didn't find at least one match, this is an
        // invalid shorthand and we have to ignore it
        if (!found)
            return false;
    }

    // Fill in any remaining properties with the initial value.
    m_implicitShorthand = true;
    for (int i = 0; i < numProperties; ++i) {
        if (!fnd[i])
            addProperty(properties[i], CSSInitialValue::createImplicit(), important);
    }
    m_implicitShorthand = false;

    return true;
}

bool CSSParser::parse4Values(int propId, const int *properties,  bool important)
{
    /* From the CSS 2 specs, 8.3
     * If there is only one value, it applies to all sides. If there are two values, the top and
     * bottom margins are set to the first value and the right and left margins are set to the second.
     * If there are three values, the top is set to the first value, the left and right are set to the
     * second, and the bottom is set to the third. If there are four values, they apply to the top,
     * right, bottom, and left, respectively.
     */

    int num = inShorthand() ? 1 : m_valueList->size();

    ShorthandScope scope(this, propId);

    // the order is top, right, bottom, left
    switch (num) {
        case 1: {
            if (!parseValue(properties[0], important))
                return false;
            CSSValue *value = m_parsedProperties[m_numParsedProperties-1]->value();
            m_implicitShorthand = true;
            addProperty(properties[1], value, important);
            addProperty(properties[2], value, important);
            addProperty(properties[3], value, important);
            m_implicitShorthand = false;
            break;
        }
        case 2: {
            if (!parseValue(properties[0], important) || !parseValue(properties[1], important))
                return false;
            CSSValue *value = m_parsedProperties[m_numParsedProperties-2]->value();
            m_implicitShorthand = true;
            addProperty(properties[2], value, important);
            value = m_parsedProperties[m_numParsedProperties-2]->value();
            addProperty(properties[3], value, important);
            m_implicitShorthand = false;
            break;
        }
        case 3: {
            if (!parseValue(properties[0], important) || !parseValue(properties[1], important) || !parseValue(properties[2], important))
                return false;
            CSSValue *value = m_parsedProperties[m_numParsedProperties-2]->value();
            m_implicitShorthand = true;
            addProperty(properties[3], value, important);
            m_implicitShorthand = false;
            break;
        }
        case 4: {
            if (!parseValue(properties[0], important) || !parseValue(properties[1], important) ||
                !parseValue(properties[2], important) || !parseValue(properties[3], important))
                return false;
            break;
        }
        default: {
            return false;
        }
    }

    return true;
}

// auto | <identifier>
bool CSSParser::parsePage(int propId, bool important)
{
    ASSERT(propId == CSSPropertyPage);

    if (m_valueList->size() != 1)
        return false;

    CSSParserValue* value = m_valueList->current();
    if (!value)
        return false;

    if (value->id == CSSValueAuto) {
        addProperty(propId, primitiveValueCache()->createIdentifierValue(value->id), important);
        return true;
    } else if (value->id == 0 && value->unit == CSSPrimitiveValue::CSS_IDENT) {
        addProperty(propId, primitiveValueCache()->createValue(value->string, CSSPrimitiveValue::CSS_STRING), important);
        return true;
    }
    return false;
}

// <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ]
bool CSSParser::parseSize(int propId, bool important)
{
    ASSERT(propId == CSSPropertySize);

    if (m_valueList->size() > 2)
        return false;

    CSSParserValue* value = m_valueList->current();
    if (!value)
        return false;

    RefPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();

    // First parameter.
    SizeParameterType paramType = parseSizeParameter(parsedValues.get(), value, None);
    if (paramType == None)
        return false;

    // Second parameter, if any.
    value = m_valueList->next();
    if (value) {
        paramType = parseSizeParameter(parsedValues.get(), value, paramType);
        if (paramType == None)
            return false;
    }

    addProperty(propId, parsedValues.release(), important);
    return true;
}

CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedValues, CSSParserValue* value, SizeParameterType prevParamType)
{
    switch (value->id) {
    case CSSValueAuto:
        if (prevParamType == None) {
            parsedValues->append(primitiveValueCache()->createIdentifierValue(value->id));
            return Auto;
        }
        return None;
    case CSSValueLandscape:
    case CSSValuePortrait:
        if (prevParamType == None || prevParamType == PageSize) {
            parsedValues->append(primitiveValueCache()->createIdentifierValue(value->id));
            return Orientation;
        }
        return None;
    case CSSValueA3:
    case CSSValueA4:
    case CSSValueA5:
    case CSSValueB4:
    case CSSValueB5:
    case CSSValueLedger:
    case CSSValueLegal:
    case CSSValueLetter:
        if (prevParamType == None || prevParamType == Orientation) {
            // Normalize to Page Size then Orientation order by prepending.
            // This is not specified by the CSS3 Paged Media specification, but for simpler processing later (CSSStyleSelector::applyPageSizeProperty).
            parsedValues->prepend(primitiveValueCache()->createIdentifierValue(value->id));
            return PageSize;
        }
        return None;
    case 0:
        if (validUnit(value, FLength | FNonNeg, m_strict) && (prevParamType == None || prevParamType == Length)) {
            parsedValues->append(primitiveValueCache()->createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)));
            return Length;
        }
        return None;
    default:
        return None;
    }
}

// [ <string> <string> ]+ | inherit | none
// inherit and none are handled in parseValue.
bool CSSParser::parseQuotes(int propId, bool important)
{
    RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
    while (CSSParserValue* val = m_valueList->current()) {
        RefPtr<CSSValue> parsedValue;
        if (val->unit == CSSPrimitiveValue::CSS_STRING)
            parsedValue = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING);
        else
            break;
        values->append(parsedValue.release());
        m_valueList->next();
    }
    if (values->length()) {
        addProperty(propId, values.release(), important);
        m_valueList->next();
        return true;
    }
    return false;
}

// [ <string> | <uri> | <counter> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
// in CSS 2.1 this got somewhat reduced:
// [ <string> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
bool CSSParser::parseContent(int propId, bool important)
{
    RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated();

    while (CSSParserValue* val = m_valueList->current()) {
        RefPtr<CSSValue> parsedValue;
        if (val->unit == CSSPrimitiveValue::CSS_URI && m_styleSheet) {
            // url
            // FIXME: The completeURL call should be done when using the CSSImageValue,
            // not when creating it.
            parsedValue = CSSImageValue::create(m_styleSheet->completeURL(val->string));
        } else if (val->unit == CSSParserValue::Function) {
            // attr(X) | counter(X [,Y]) | counters(X, Y, [,Z]) | -webkit-gradient(...)
            CSSParserValueList* args = val->function->args.get();
            if (!args)
                return false;
            if (equalIgnoringCase(val->function->name, "attr(")) {
                parsedValue = parseAttr(args);
                if (!parsedValue)
                    return false;
            } else if (equalIgnoringCase(val->function->name, "counter(")) {
                parsedValue = parseCounterContent(args, false);
                if (!parsedValue)
                    return false;
            } else if (equalIgnoringCase(val->function->name, "counters(")) {
                parsedValue = parseCounterContent(args, true);
                if (!parsedValue)
                    return false;
            } else if (isGeneratedImageValue(val)) {
                if (!parseGeneratedImage(parsedValue))
                    return false;
            } else
                return false;
        } else if (val->unit == CSSPrimitiveValue::CSS_IDENT) {
            // open-quote
            // close-quote
            // no-open-quote
            // no-close-quote
            // inherit
            // FIXME: These are not yet implemented (http://bugs.webkit.org/show_bug.cgi?id=6503).
            // none
            // normal
            switch (val->id) {
            case CSSValueOpenQuote:
            case CSSValueCloseQuote:
            case CSSValueNoOpenQuote:
            case CSSValueNoCloseQuote:
            case CSSValueNone:
            case CSSValueNormal:
                parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
            }
        } else if (val->unit == CSSPrimitiveValue::CSS_STRING) {
            parsedValue = primitiveValueCache()->createValue(val->string, CSSPrimitiveValue::CSS_STRING);
        }
        if (!parsedValue)
            break;
        values->append(parsedValue.release());
        m_valueList->next();
    }

    if (values->length()) {
        addProperty(propId, values.release(), important);
        m_valueList->next();
        return true;
    }

    return false;
}

PassRefPtr<CSSValue> CSSParser::parseAttr(CSSParserValueList* args)
{
    if (args->size() != 1)
        return 0;

    CSSParserValue* a = args->current();

    if (a->unit != CSSPrimitiveValue::CSS_IDENT)
        return 0;

    String attrName = a->string;
    // CSS allows identifiers with "-" at the start, like "-webkit-mask-image".
    // But HTML attribute names can't have those characters, and we should not
    // even parse them inside attr().
    if (attrName[0] == '-')
        return 0;

    if (document() && document()->isHTMLDocument())
        attrName = attrName.lower();

    return primitiveValueCache()->createValue(attrName, CSSPrimitiveValue::CSS_ATTR);
}

PassRefPtr<CSSValue> CSSParser::parseBackgroundColor()
{
    int id = m_valueList->current()->id;
    if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor ||
        (id >= CSSValueGrey && id < CSSValueWebkitText && !m_strict))
       return primitiveValueCache()->createIdentifierValue(id);
    return parseColor();
}

bool CSSParser::parseFillImage(RefPtr<CSSValue>& value)
{
    if (m_valueList->current()->id == CSSValueNone) {
        value = CSSImageValue::create();
        return true;
    }
    if (m_valueList->current()->unit == CSSPrimitiveValue::CSS_URI) {
        // FIXME: The completeURL call should be done when using the CSSImageValue,
        // not when creating it.
        if (m_styleSheet)
            value = CSSImageValue::create(m_styleSheet->completeURL(m_valueList->current()->string));
        return true;
    }

    if (isGeneratedImageValue(m_valueList->current()))
        return parseGeneratedImage(value);

    return false;
}

PassRefPtr<CSSValue> CSSParser::parseFillPositionX(CSSParserValueList* valueList)
{
    int id = valueList->current()->id;
    if (id == CSSValueLeft || id == CSSValueRight || id == CSSValueCenter) {
        int percent = 0;
        if (id == CSSValueRight)
            percent = 100;
        else if (id == CSSValueCenter)
            percent = 50;
        return primitiveValueCache()->createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
    }
    if (validUnit(valueList->current(), FPercent | FLength, m_strict))
        return primitiveValueCache()->createValue(valueList->current()->fValue,
                                                  (CSSPrimitiveValue::UnitTypes)valueList->current()->unit);
    return 0;
}

PassRefPtr<CSSValue> CSSParser::parseFillPositionY(CSSParserValueList* valueList)
{
    int id = valueList->current()->id;
    if (id == CSSValueTop || id == CSSValueBottom || id == CSSValueCenter) {
        int percent = 0;
        if (id == CSSValueBottom)
            percent = 100;
        else if (id == CSSValueCenter)
            percent = 50;
        return primitiveValueCache()->createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
    }
    if (validUnit(valueList->current(), FPercent | FLength, m_strict))
        return primitiveValueCache()->createValue(valueList->current()->fValue,
                                                  (CSSPrimitiveValue::UnitTypes)valueList->current()->unit);
    return 0;
}

PassRefPtr<CSSValue> CSSParser::parseFillPositionComponent(CSSParserValueList* valueList, unsigned& cumulativeFlags, FillPositionFlag& individualFlag)
{
    int id = valueList->current()->id;
    if (id == CSSValueLeft || id == CSSValueTop || id == CSSValueRight || id == CSSValueBottom || id == CSSValueCenter) {
        int percent = 0;
        if (id == CSSValueLeft || id == CSSValueRight) {
            if (cumulativeFlags & XFillPosition)
                return 0;
            cumulativeFlags |= XFillPosition;
            individualFlag = XFillPosition;
            if (id == CSSValueRight)
                percent = 100;
        }
        else if (id == CSSValueTop || id == CSSValueBottom) {
            if (cumulativeFlags & YFillPosition)
                return 0;
            cumulativeFlags |= YFillPosition;
            individualFlag = YFillPosition;
            if (id == CSSValueBottom)
                percent = 100;
        } else if (id == CSSValueCenter) {
            // Center is ambiguous, so we're not sure which position we've found yet, an x or a y.
            percent = 50;
            cumulativeFlags |= AmbiguousFillPosition;
            individualFlag = AmbiguousFillPosition;
        }
        return primitiveValueCache()->createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
    }
    if (validUnit(valueList->current(), FPercent | FLength, m_strict)) {
        if (!cumulativeFlags) {
            cumulativeFlags |= XFillPosition;
            individualFlag = XFillPosition;
        } else if (cumulativeFlags & (XFillPosition | AmbiguousFillPosition)) {
            cumulativeFlags |= YFillPosition;
            individualFlag = YFillPosition;
        } else
            return 0;
        return primitiveValueCache()->createValue(valueList->current()->fValue,
                                                  (CSSPrimitiveValue::UnitTypes)valueList->current()->unit);
    }
    return 0;
}

void CSSParser::parseFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2)
{
    CSSParserValue* value = valueList->current();

    // Parse the first value.  We're just making sure that it is one of the valid keywords or a percentage/length.
    unsigned cumulativeFlags = 0;
    FillPositionFlag value1Flag = InvalidFillPosition;
    FillPositionFlag value2Flag = InvalidFillPosition;
    value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag);
    if (!value1)
        return;

    // It only takes one value for background-position to be correctly parsed if it was specified in a shorthand (since we
    // can assume that any other values belong to the rest of the shorthand).  If we're not parsing a shorthand, though, the
    // value was explicitly specified for our property.
    value = valueList->next();

    // First check for the comma.  If so, we are finished parsing this value or value pair.
    if (value && value->unit == CSSParserValue::Operator && value->iValue == ',')
        value = 0;

    if (value) {
        value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag);
        if (value2)
            valueList->next();
        else {
            if (!inShorthand()) {
                value1.clear();
                return;
            }
        }
    }

    if (!value2)
        // Only one value was specified.  If that value was not a keyword, then it sets the x position, and the y position
        // is simply 50%.  This is our default.
        // For keywords, the keyword was either an x-keyword (left/right), a y-keyword (top/bottom), or an ambiguous keyword (center).
        // For left/right/center, the default of 50% in the y is still correct.
        value2 = primitiveValueCache()->createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE);

    if (value1Flag == YFillPosition || value2Flag == XFillPosition)
        value1.swap(value2);
}

void CSSParser::parseFillRepeat(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2)
{
    CSSParserValue* value = m_valueList->current();

    int id = m_valueList->current()->id;
    if (id == CSSValueRepeatX) {
        m_implicitShorthand = true;
        value1 = primitiveValueCache()->createIdentifierValue(CSSValueRepeat);
        value2 = primitiveValueCache()->createIdentifierValue(CSSValueNoRepeat);
        m_valueList->next();
        return;
    }
    if (id == CSSValueRepeatY) {
        m_implicitShorthand = true;
        value1 = primitiveValueCache()->createIdentifierValue(CSSValueNoRepeat);
        value2 = primitiveValueCache()->createIdentifierValue(CSSValueRepeat);
        m_valueList->next();
        return;
    }
    if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)
        value1 = primitiveValueCache()->createIdentifierValue(id);
    else {
        value1 = 0;
        return;
    }

    value = m_valueList->next();

    // First check for the comma.  If so, we are finished parsing this value or value pair.
    if (value && value->unit == CSSParserValue::Operator && value->iValue == ',')
        value = 0;

    if (value)
        id = m_valueList->current()->id;

    if (value && (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)) {
        value2 = primitiveValueCache()->createIdentifierValue(id);
        m_valueList->next();
    } else {
        // If only one value was specified, value2 is the same as value1.
        m_implicitShorthand = true;
        value2 = primitiveValueCache()->createIdentifierValue(static_cast<CSSPrimitiveValue*>(value1.get())->getIdent());
    }
}

PassRefPtr<CSSValue> CSSParser::parseFillSize(int propId, bool& allowComma)
{
    allowComma = true;
    CSSParserValue* value = m_valueList->current();

    if (value->id == CSSValueContain || value->id == CSSValueCover)
        return primitiveValueCache()->createIdentifierValue(value->id);

    RefPtr<CSSPrimitiveValue> parsedValue1;

    if (value->id == CSSValueAuto)
        parsedValue1 = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_UNKNOWN);
    else {
        if (!validUnit(value, FLength | FPercent, m_strict))
            return 0;
        parsedValue1 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
    }

    CSSPropertyID property = static_cast<CSSPropertyID>(propId);
    RefPtr<CSSPrimitiveValue> parsedValue2;
    if ((value = m_valueList->next())) {
        if (value->id == CSSValueAuto)
            parsedValue2 = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_UNKNOWN);
        else if (value->unit == CSSParserValue::Operator && value->iValue == ',')
            allowComma = false;
        else {
            if (!validUnit(value, FLength | FPercent, m_strict))
                return 0;
            parsedValue2 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
        }
    }
    if (!parsedValue2) {
        if (property == CSSPropertyWebkitBackgroundSize || property == CSSPropertyWebkitMaskSize)
            parsedValue2 = parsedValue1;
        else
            parsedValue2 = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_UNKNOWN);
    }

    return primitiveValueCache()->createValue(Pair::create(parsedValue1.release(), parsedValue2.release()));
}

bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
                                  RefPtr<CSSValue>& retValue1, RefPtr<CSSValue>& retValue2)
{
    RefPtr<CSSValueList> values;
    RefPtr<CSSValueList> values2;
    CSSParserValue* val;
    RefPtr<CSSValue> value;
    RefPtr<CSSValue> value2;

    bool allowComma = false;

    retValue1 = retValue2 = 0;
    propId1 = propId;
    propId2 = propId;
    if (propId == CSSPropertyBackgroundPosition) {
        propId1 = CSSPropertyBackgroundPositionX;
        propId2 = CSSPropertyBackgroundPositionY;
    } else if (propId == CSSPropertyWebkitMaskPosition) {
        propId1 = CSSPropertyWebkitMaskPositionX;
        propId2 = CSSPropertyWebkitMaskPositionY;
    } else if (propId == CSSPropertyBackgroundRepeat) {
        propId1 = CSSPropertyBackgroundRepeatX;
        propId2 = CSSPropertyBackgroundRepeatY;
    } else if (propId == CSSPropertyWebkitMaskRepeat) {
        propId1 = CSSPropertyWebkitMaskRepeatX;
        propId2 = CSSPropertyWebkitMaskRepeatY;
    }

    while ((val = m_valueList->current())) {
        RefPtr<CSSValue> currValue;
        RefPtr<CSSValue> currValue2;

        if (allowComma) {
            if (val->unit != CSSParserValue::Operator || val->iValue != ',')
                return false;
            m_valueList->next();
            allowComma = false;
        } else {
            allowComma = true;
            switch (propId) {
                case CSSPropertyBackgroundColor:
                    currValue = parseBackgroundColor();
                    if (currValue)
                        m_valueList->next();
                    break;
                case CSSPropertyBackgroundAttachment:
                case CSSPropertyWebkitMaskAttachment:
                    if (val->id == CSSValueScroll || val->id == CSSValueFixed || val->id == CSSValueLocal) {
                        currValue = primitiveValueCache()->createIdentifierValue(val->id);
                        m_valueList->next();
                    }
                    break;
                case CSSPropertyBackgroundImage:
                case CSSPropertyWebkitMaskImage:
                    if (parseFillImage(currValue))
                        m_valueList->next();
                    break;
                case CSSPropertyWebkitBackgroundClip:
                case CSSPropertyWebkitBackgroundOrigin:
                case CSSPropertyWebkitMaskClip:
                case CSSPropertyWebkitMaskOrigin:
                    // The first three values here are deprecated and do not apply to the version of the property that has
                    // the -webkit- prefix removed.
                    if (val->id == CSSValueBorder || val->id == CSSValuePadding || val->id == CSSValueContent ||
                        val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox ||
                        ((propId == CSSPropertyWebkitBackgroundClip || propId == CSSPropertyWebkitMaskClip) &&
                         (val->id == CSSValueText || val->id == CSSValueWebkitText))) {
                        currValue = primitiveValueCache()->createIdentifierValue(val->id);
                        m_valueList->next();
                    }
                    break;
                case CSSPropertyBackgroundClip:
                    if (parseBackgroundClip(val, currValue, primitiveValueCache()))
                        m_valueList->next();
                    break;
                case CSSPropertyBackgroundOrigin:
                    if (val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox) {
                        currValue = primitiveValueCache()->createIdentifierValue(val->id);
                        m_valueList->next();
                    }
                    break;
                case CSSPropertyBackgroundPosition:
                case CSSPropertyWebkitMaskPosition:
                    parseFillPosition(m_valueList, currValue, currValue2);
                    // parseFillPosition advances the m_valueList pointer
                    break;
                case CSSPropertyBackgroundPositionX:
                case CSSPropertyWebkitMaskPositionX: {
                    currValue = parseFillPositionX(m_valueList);
                    if (currValue)
                        m_valueList->next();
                    break;
                }
                case CSSPropertyBackgroundPositionY:
                case CSSPropertyWebkitMaskPositionY: {
                    currValue = parseFillPositionY(m_valueList);
                    if (currValue)
                        m_valueList->next();
                    break;
                }
                case CSSPropertyWebkitBackgroundComposite:
                case CSSPropertyWebkitMaskComposite:
                    if ((val->id >= CSSValueClear && val->id <= CSSValuePlusLighter) || val->id == CSSValueHighlight) {
                        currValue = primitiveValueCache()->createIdentifierValue(val->id);
                        m_valueList->next();
                    }
                    break;
                case CSSPropertyBackgroundRepeat:
                case CSSPropertyWebkitMaskRepeat:
                    parseFillRepeat(currValue, currValue2);
                    // parseFillRepeat advances the m_valueList pointer
                    break;
                case CSSPropertyBackgroundSize:
                case CSSPropertyWebkitBackgroundSize:
                case CSSPropertyWebkitMaskSize: {
                    currValue = parseFillSize(propId, allowComma);
                    if (currValue)
                        m_valueList->next();
                    break;
                }
            }
            if (!currValue)
                return false;

            if (value && !values) {
                values = CSSValueList::createCommaSeparated();
                values->append(value.release());
            }

            if (value2 && !values2) {
                values2 = CSSValueList::createCommaSeparated();
                values2->append(value2.release());
            }

            if (values)
                values->append(currValue.release());
            else
                value = currValue.release();
            if (currValue2) {
                if (values2)
                    values2->append(currValue2.release());
                else
                    value2 = currValue2.release();
            }
        }

        // When parsing any fill shorthand property, we let it handle building up the lists for all
        // properties.
        if (inShorthand())
            break;
    }

    if (values && values->length()) {
        retValue1 = values.release();
        if (values2 && values2->length())
            retValue2 = values2.release();
        return true;
    }
    if (value) {
        retValue1 = value.release();
        retValue2 = value2.release();
        return true;
    }
    return false;
}

PassRefPtr<CSSValue> CSSParser::parseAnimationDelay()
{
    CSSParserValue* value = m_valueList->current();
    if (validUnit(value, FTime, m_strict))
        return primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
    return 0;
}

PassRefPtr<CSSValue> CSSParser::parseAnimationDirection()
{
    CSSParserValue* value = m_valueList->current();
    if (value->id == CSSValueNormal || value->id == CSSValueAlternate)
        return primitiveValueCache()->createIdentifierValue(value->id);
    return 0;
}

PassRefPtr<CSSValue> CSSParser::parseAnimationDuration()
{
    CSSParserValue* value = m_valueList->current();
    if (validUnit(value, FTime | FNonNeg, m_strict))
        return primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
    return 0;
}

PassRefPtr<CSSValue> CSSParser::parseAnimationFillMode()
{
    CSSParserValue* value = m_valueList->current();
    if (value->id == CSSValueNone || value->id == CSSValueForwards || value->id == CSSValueBackwards || value->id == CSSValueBoth)
        return primitiveValueCache()->createIdentifierValue(value->id);
    return 0;
}

PassRefPtr<CSSValue> CSSParser::parseAnimationIterationCount()
{
    CSSParserValue* value = m_valueList->current();
    if (value->id == CSSValueInfinite)
        return primitiveValueCache()->createIdentifierValue(value->id);
    if (validUnit(value, FInteger | FNonNeg, m_strict))
        return primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
    return 0;
}

PassRefPtr<CSSValue> CSSParser::parseAnimationName()
{
    CSSParserValue* value = m_valueList->current();
    if (value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT) {
        if (value->id == CSSValueNone || (value->unit == CSSPrimitiveValue::CSS_STRING && equalIgnoringCase(value->string, "none"))) {
            return primitiveValueCache()->createIdentifierValue(CSSValueNone);
        } else {
            return primitiveValueCache()->createValue(value->string, CSSPrimitiveValue::CSS_STRING);
        }
    }
    return 0;
}

PassRefPtr<CSSValue> CSSParser::parseAnimationPlayState()
{
    CSSParserValue* value = m_valueList->current();
    if (value->id == CSSValueRunning || value->id == CSSValuePaused)
        return primitiveValueCache()->createIdentifierValue(value->id);
    return 0;
}

PassRefPtr<CSSValue> CSSParser::parseAnimationProperty()
{
    CSSParserValue* value = m_valueList->current();
    if (value->unit != CSSPrimitiveValue::CSS_IDENT)
        return 0;
    int result = cssPropertyID(value->string);
    if (result)
        return primitiveValueCache()->createIdentifierValue(result);
    if (equalIgnoringCase(value->string, "all"))
        return primitiveValueCache()->createIdentifierValue(CSSValueAll);
    if (equalIgnoringCase(value->string, "none"))
        return primitiveValueCache()->createIdentifierValue(CSSValueNone);
    return 0;
}

bool CSSParser::parseTransformOriginShorthand(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2, RefPtr<CSSValue>& value3)
{
    parseFillPosition(m_valueList, value1, value2);

    // now get z
    if (m_valueList->current()) {
        if (validUnit(m_valueList->current(), FLength, m_strict)) {
            value3 = primitiveValueCache()->createValue(m_valueList->current()->fValue,
                                             (CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit);
            m_valueList->next();
            return true;
        }
        return false;
    }
    return true;
}

bool CSSParser::parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result)
{
    CSSParserValue* v = args->current();
    if (!validUnit(v, FNumber, m_strict))
        return false;
    result = v->fValue;
    if (result < 0 || result > 1.0)
        return false;
    v = args->next();
    if (!v)
        // The last number in the function has no comma after it, so we're done.
        return true;
    if (v->unit != CSSParserValue::Operator && v->iValue != ',')
        return false;
    v = args->next();
    return true;
}

PassRefPtr<CSSValue> CSSParser::parseAnimationTimingFunction()
{
    CSSParserValue* value = m_valueList->current();
    if (value->id == CSSValueEase || value->id == CSSValueLinear || value->id == CSSValueEaseIn || value->id == CSSValueEaseOut
        || value->id == CSSValueEaseInOut || value->id == CSSValueStepStart || value->id == CSSValueStepEnd)
        return primitiveValueCache()->createIdentifierValue(value->id);

    // We must be a function.
    if (value->unit != CSSParserValue::Function)
        return 0;

    CSSParserValueList* args = value->function->args.get();

    if (equalIgnoringCase(value->function->name, "steps(")) {
        // For steps, 1 or 2 params must be specified (comma-separated)
        if (!args || (args->size() != 1 && args->size() != 3))
            return 0;

        // There are two values.
        int numSteps;
        bool stepAtStart = false;

        CSSParserValue* v = args->current();
        if (!validUnit(v, FInteger, m_strict))
            return 0;
        numSteps = (int) min(v->fValue, (double)INT_MAX);
        if (numSteps < 1)
            return 0;
        v = args->next();

        if (v) {
            // There is a comma so we need to parse the second value
            if (v->unit != CSSParserValue::Operator && v->iValue != ',')
                return 0;
            v = args->next();
            if (v->id != CSSValueStart && v->id != CSSValueEnd)
                return 0;
            stepAtStart = v->id == CSSValueStart;
        }

        return CSSStepsTimingFunctionValue::create(numSteps, stepAtStart);
    }
    
    if (equalIgnoringCase(value->function->name, "cubic-bezier(")) {
        // For cubic bezier, 4 values must be specified.
        if (!args || args->size() != 7)
            return 0;

        // There are two points specified.  The values must be between 0 and 1.
        double x1, y1, x2, y2;

        if (!parseCubicBezierTimingFunctionValue(args, x1))
            return 0;
        if (!parseCubicBezierTimingFunctionValue(args, y1))
            return 0;
        if (!parseCubicBezierTimingFunctionValue(args, x2))
            return 0;
        if (!parseCubicBezierTimingFunctionValue(args, y2))
            return 0;

        return CSSCubicBezierTimingFunctionValue::create(x1, y1, x2, y2);
    }
    
    return 0;
}

bool CSSParser::parseAnimationProperty(int propId, RefPtr<CSSValue>& result)
{
    RefPtr<CSSValueList> values;
    CSSParserValue* val;
    RefPtr<CSSValue> value;
    bool allowComma = false;

    result = 0;

    while ((val = m_valueList->current())) {
        RefPtr<CSSValue> currValue;
        if (allowComma) {
            if (val->unit != CSSParserValue::Operator || val->iValue != ',')
                return false;
            m_valueList->next();
            allowComma = false;
        }
        else {
            switch (propId) {
                case CSSPropertyWebkitAnimationDelay:
                case CSSPropertyWebkitTransitionDelay:
                    currValue = parseAnimationDelay();
                    if (currValue)
                        m_valueList->next();
                    break;
                case CSSPropertyWebkitAnimationDirection:
                    currValue = parseAnimationDirection();
                    if (currValue)
                        m_valueList->next();
                    break;
                case CSSPropertyWebkitAnimationDuration:
                case CSSPropertyWebkitTransitionDuration:
                    currValue = parseAnimationDuration();
                    if (currValue)
                        m_valueList->next();
                    break;
                case CSSPropertyWebkitAnimationFillMode:
                    currValue = parseAnimationFillMode();
                    if (currValue)
                        m_valueList->next();
                    break;
                case CSSPropertyWebkitAnimationIterationCount:
                    currValue = parseAnimationIterationCount();
                    if (currValue)
                        m_valueList->next();
                    break;
                case CSSPropertyWebkitAnimationName:
                    currValue = parseAnimationName();
                    if (currValue)
                        m_valueList->next();
                    break;
                case CSSPropertyWebkitAnimationPlayState:
                    currValue = parseAnimationPlayState();
                    if (currValue)
                        m_valueList->next();
                    break;
                case CSSPropertyWebkitTransitionProperty:
                    currValue = parseAnimationProperty();
                    if (currValue)
                        m_valueList->next();
                    break;
                case CSSPropertyWebkitAnimationTimingFunction:
                case CSSPropertyWebkitTransitionTimingFunction:
                    currValue = parseAnimationTimingFunction();
                    if (currValue)
                        m_valueList->next();
                    break;
            }

            if (!currValue)
                return false;

            if (value && !values) {
                values = CSSValueList::createCommaSeparated();
                values->append(value.release());
            }

            if (values)
                values->append(currValue.release());
            else
                value = currValue.release();

            allowComma = true;
        }

        // When parsing the 'transition' shorthand property, we let it handle building up the lists for all
        // properties.
        if (inShorthand())
            break;
    }

    if (values && values->length()) {
        result = values.release();
        return true;
    }
    if (value) {
        result = value.release();
        return true;
    }
    return false;
}



#if ENABLE(DASHBOARD_SUPPORT)

#define DASHBOARD_REGION_NUM_PARAMETERS  6
#define DASHBOARD_REGION_SHORT_NUM_PARAMETERS  2

static CSSParserValue* skipCommaInDashboardRegion(CSSParserValueList *args)
{
    if (args->size() == (DASHBOARD_REGION_NUM_PARAMETERS*2-1) ||
         args->size() == (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1)) {
        CSSParserValue* current = args->current();
        if (current->unit == CSSParserValue::Operator && current->iValue == ',')
            return args->next();
    }
    return args->current();
}

bool CSSParser::parseDashboardRegions(int propId, bool important)
{
    bool valid = true;

    CSSParserValue* value = m_valueList->current();

    if (value->id == CSSValueNone) {
        if (m_valueList->next())
            return false;
        addProperty(propId, primitiveValueCache()->createIdentifierValue(value->id), important);
        return valid;
    }

    RefPtr<DashboardRegion> firstRegion = DashboardRegion::create();
    DashboardRegion* region = 0;

    while (value) {
        if (region == 0) {
            region = firstRegion.get();
        } else {
            RefPtr<DashboardRegion> nextRegion = DashboardRegion::create();
            region->m_next = nextRegion;
            region = nextRegion.get();
        }

        if (value->unit != CSSParserValue::Function) {
            valid = false;
            break;
        }

        // Commas count as values, so allow:
        // dashboard-region(label, type, t, r, b, l) or dashboard-region(label type t r b l)
        // dashboard-region(label, type, t, r, b, l) or dashboard-region(label type t r b l)
        // also allow
        // dashboard-region(label, type) or dashboard-region(label type)
        // dashboard-region(label, type) or dashboard-region(label type)
        CSSParserValueList* args = value->function->args.get();
        if (!equalIgnoringCase(value->function->name, "dashboard-region(") || !args) {
            valid = false;
            break;
        }

        int numArgs = args->size();
        if ((numArgs != DASHBOARD_REGION_NUM_PARAMETERS && numArgs != (DASHBOARD_REGION_NUM_PARAMETERS*2-1)) &&
            (numArgs != DASHBOARD_REGION_SHORT_NUM_PARAMETERS && numArgs != (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1))) {
            valid = false;
            break;
        }

        // First arg is a label.
        CSSParserValue* arg = args->current();
        if (arg->unit != CSSPrimitiveValue::CSS_IDENT) {
            valid = false;
            break;
        }

        region->m_label = arg->string;

        // Second arg is a type.
        arg = args->next();
        arg = skipCommaInDashboardRegion(args);
        if (arg->unit != CSSPrimitiveValue::CSS_IDENT) {
            valid = false;
            break;
        }

        if (equalIgnoringCase(arg->string, "circle"))
            region->m_isCircle = true;
        else if (equalIgnoringCase(arg->string, "rectangle"))
            region->m_isRectangle = true;
        else {
            valid = false;
            break;
        }

        region->m_geometryType = arg->string;

        if (numArgs == DASHBOARD_REGION_SHORT_NUM_PARAMETERS || numArgs == (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1)) {
            // This originally used CSSValueInvalid by accident. It might be more logical to use something else.
            RefPtr<CSSPrimitiveValue> amount = primitiveValueCache()->createIdentifierValue(CSSValueInvalid);

            region->setTop(amount);
            region->setRight(amount);
            region->setBottom(amount);
            region->setLeft(amount);
        } else {
            // Next four arguments must be offset numbers
            int i;
            for (i = 0; i < 4; i++) {
                arg = args->next();
                arg = skipCommaInDashboardRegion(args);

                valid = arg->id == CSSValueAuto || validUnit(arg, FLength, m_strict);
                if (!valid)
                    break;

                RefPtr<CSSPrimitiveValue> amount = arg->id == CSSValueAuto ?
                    primitiveValueCache()->createIdentifierValue(CSSValueAuto) :
                    primitiveValueCache()->createValue(arg->fValue, (CSSPrimitiveValue::UnitTypes) arg->unit);

                if (i == 0)
                    region->setTop(amount);
                else if (i == 1)
                    region->setRight(amount);
                else if (i == 2)
                    region->setBottom(amount);
                else
                    region->setLeft(amount);
            }
        }

        if (args->next())
            return false;

        value = m_valueList->next();
    }

    if (valid)
        addProperty(propId, primitiveValueCache()->createValue(firstRegion.release()), important);

    return valid;
}

#endif /* ENABLE(DASHBOARD_SUPPORT) */

PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bool counters)
{
    unsigned numArgs = args->size();
    if (counters && numArgs != 3 && numArgs != 5)
        return 0;
    if (!counters && numArgs != 1 && numArgs != 3)
        return 0;

    CSSParserValue* i = args->current();
    if (i->unit != CSSPrimitiveValue::CSS_IDENT)
        return 0;
    RefPtr<CSSPrimitiveValue> identifier = primitiveValueCache()->createValue(i->string, CSSPrimitiveValue::CSS_STRING);

    RefPtr<CSSPrimitiveValue> separator;
    if (!counters)
        separator = primitiveValueCache()->createValue(String(), CSSPrimitiveValue::CSS_STRING);
    else {
        i = args->next();
        if (i->unit != CSSParserValue::Operator || i->iValue != ',')
            return 0;

        i = args->next();
        if (i->unit != CSSPrimitiveValue::CSS_STRING)
            return 0;

        separator = primitiveValueCache()->createValue(i->string, (CSSPrimitiveValue::UnitTypes) i->unit);
    }

    RefPtr<CSSPrimitiveValue> listStyle;
    i = args->next();
    if (!i) // Make the list style default decimal
        listStyle = primitiveValueCache()->createValue(CSSValueDecimal - CSSValueDisc, CSSPrimitiveValue::CSS_NUMBER);
    else {
        if (i->unit != CSSParserValue::Operator || i->iValue != ',')
            return 0;

        i = args->next();
        if (i->unit != CSSPrimitiveValue::CSS_IDENT)
            return 0;

        short ls = 0;
        if (i->id == CSSValueNone)
            ls = CSSValueKatakanaIroha - CSSValueDisc + 1;
        else if (i->id >= CSSValueDisc && i->id <= CSSValueKatakanaIroha)
            ls = i->id - CSSValueDisc;
        else
            return 0;

        listStyle = primitiveValueCache()->createValue(ls, (CSSPrimitiveValue::UnitTypes) i->unit);
    }

    return primitiveValueCache()->createValue(Counter::create(identifier.release(), listStyle.release(), separator.release()));
}

bool CSSParser::parseShape(int propId, bool important)
{
    CSSParserValue* value = m_valueList->current();
    CSSParserValueList* args = value->function->args.get();

    if (!equalIgnoringCase(value->function->name, "rect(") || !args)
        return false;

    // rect(t, r, b, l) || rect(t r b l)
    if (args->size() != 4 && args->size() != 7)
        return false;
    RefPtr<Rect> rect = Rect::create();
    bool valid = true;
    int i = 0;
    CSSParserValue* a = args->current();
    while (a) {
        valid = a->id == CSSValueAuto || validUnit(a, FLength, m_strict);
        if (!valid)
            break;
        RefPtr<CSSPrimitiveValue> length = a->id == CSSValueAuto ?
            primitiveValueCache()->createIdentifierValue(CSSValueAuto) :
            primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
        if (i == 0)
            rect->setTop(length);
        else if (i == 1)
            rect->setRight(length);
        else if (i == 2)
            rect->setBottom(length);
        else
            rect->setLeft(length);
        a = args->next();
        if (a && args->size() == 7) {
            if (a->unit == CSSParserValue::Operator && a->iValue == ',') {
                a = args->next();
            } else {
                valid = false;
                break;
            }
        }
        i++;
    }
    if (valid) {
        addProperty(propId, primitiveValueCache()->createValue(rect.release()), important);
        m_valueList->next();
        return true;
    }
    return false;
}

// [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family'
bool CSSParser::parseFont(bool important)
{
    bool valid = true;
    CSSParserValue *value = m_valueList->current();
    RefPtr<FontValue> font = FontValue::create();
    // optional font-style, font-variant and font-weight
    while (value) {
        int id = value->id;
        if (id) {
            if (id == CSSValueNormal) {
                // do nothing, it's the inital value for all three
            } else if (id == CSSValueItalic || id == CSSValueOblique) {
                if (font->style)
                    return false;
                font->style = primitiveValueCache()->createIdentifierValue(id);
            } else if (id == CSSValueSmallCaps) {
                if (font->variant)
                    return false;
                font->variant = primitiveValueCache()->createIdentifierValue(id);
            } else if (id >= CSSValueBold && id <= CSSValueLighter) {
                if (font->weight)
                    return false;
                font->weight = primitiveValueCache()->createIdentifierValue(id);
            } else {
                valid = false;
            }
        } else if (!font->weight && validUnit(value, FInteger | FNonNeg, true)) {
            int weight = (int)value->fValue;
            int val = 0;
            if (weight == 100)
                val = CSSValue100;
            else if (weight == 200)
                val = CSSValue200;
            else if (weight == 300)
                val = CSSValue300;
            else if (weight == 400)
                val = CSSValue400;
            else if (weight == 500)
                val = CSSValue500;
            else if (weight == 600)
                val = CSSValue600;
            else if (weight == 700)
                val = CSSValue700;
            else if (weight == 800)
                val = CSSValue800;
            else if (weight == 900)
                val = CSSValue900;

            if (val)
                font->weight = primitiveValueCache()->createIdentifierValue(val);
            else
                valid = false;
        } else {
            valid = false;
        }
        if (!valid)
            break;
        value = m_valueList->next();
    }
    if (!value)
        return false;

    // set undefined values to default
    if (!font->style)
        font->style = primitiveValueCache()->createIdentifierValue(CSSValueNormal);
    if (!font->variant)
        font->variant = primitiveValueCache()->createIdentifierValue(CSSValueNormal);
    if (!font->weight)
        font->weight = primitiveValueCache()->createIdentifierValue(CSSValueNormal);

    // now a font size _must_ come
    // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
    if (value->id >= CSSValueXxSmall && value->id <= CSSValueLarger)
        font->size = primitiveValueCache()->createIdentifierValue(value->id);
    else if (validUnit(value, FLength | FPercent | FNonNeg, m_strict))
        font->size = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
    value = m_valueList->next();
    if (!font->size || !value)
        return false;

    if (value->unit == CSSParserValue::Operator && value->iValue == '/') {
        // line-height
        value = m_valueList->next();
        if (!value)
            return false;
        if (value->id == CSSValueNormal) {
            // default value, nothing to do
        } else if (validUnit(value, FNumber | FLength | FPercent | FNonNeg, m_strict))
            font->lineHeight = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
        else
            return false;
        value = m_valueList->next();
        if (!value)
            return false;
    }

    if (!font->lineHeight)
        font->lineHeight = primitiveValueCache()->createIdentifierValue(CSSValueNormal);

    // font family must come now
    font->family = parseFontFamily();

    if (m_valueList->current() || !font->family)
        return false;

    addProperty(CSSPropertyFont, font.release(), important);
    return true;
}

PassRefPtr<CSSValueList> CSSParser::parseFontFamily()
{
    RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
    CSSParserValue* value = m_valueList->current();

    FontFamilyValue* currFamily = 0;
    while (value) {
        CSSParserValue* nextValue = m_valueList->next();
        bool nextValBreaksFont = !nextValue ||
                                 (nextValue->unit == CSSParserValue::Operator && nextValue->iValue == ',');
        bool nextValIsFontName = nextValue &&
            ((nextValue->id >= CSSValueSerif && nextValue->id <= CSSValueWebkitBody) ||
            (nextValue->unit == CSSPrimitiveValue::CSS_STRING || nextValue->unit == CSSPrimitiveValue::CSS_IDENT));

        if (value->id >= CSSValueSerif && value->id <= CSSValueWebkitBody) {
            if (currFamily)
                currFamily->appendSpaceSeparated(value->string.characters, value->string.length);
            else if (nextValBreaksFont || !nextValIsFontName)
                list->append(primitiveValueCache()->createIdentifierValue(value->id));
            else {
                RefPtr<FontFamilyValue> newFamily = FontFamilyValue::create(value->string);
                currFamily = newFamily.get();
                list->append(newFamily.release());
            }
        } else if (value->unit == CSSPrimitiveValue::CSS_STRING) {
            // Strings never share in a family name.
            currFamily = 0;
            list->append(FontFamilyValue::create(value->string));
        } else if (value->unit == CSSPrimitiveValue::CSS_IDENT) {
            if (currFamily)
                currFamily->appendSpaceSeparated(value->string.characters, value->string.length);
            else if (nextValBreaksFont || !nextValIsFontName)
                list->append(FontFamilyValue::create(value->string));
            else {
                RefPtr<FontFamilyValue> newFamily = FontFamilyValue::create(value->string);
                currFamily = newFamily.get();
                list->append(newFamily.release());
            }
        } else {
            break;
        }

        if (!nextValue)
            break;

        if (nextValBreaksFont) {
            value = m_valueList->next();
            currFamily = 0;
        }
        else if (nextValIsFontName)
            value = nextValue;
        else
            break;
    }
    if (!list->length())
        list = 0;
    return list.release();
}

bool CSSParser::parseFontStyle(bool important)
{
    RefPtr<CSSValueList> values;
    if (m_valueList->size() > 1)
        values = CSSValueList::createCommaSeparated();
    CSSParserValue* val;
    bool expectComma = false;
    while ((val = m_valueList->current())) {
        RefPtr<CSSPrimitiveValue> parsedValue;
        if (!expectComma) {
            expectComma = true;
            if (val->id == CSSValueNormal || val->id == CSSValueItalic || val->id == CSSValueOblique)
                parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
            else if (val->id == CSSValueAll && !values) {
                // 'all' is only allowed in @font-face and with no other values. Make a value list to
                // indicate that we are in the @font-face case.
                values = CSSValueList::createCommaSeparated();
                parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
            }
        } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
            expectComma = false;
            m_valueList->next();
            continue;
        }

        if (!parsedValue)
            return false;

        m_valueList->next();

        if (values)
            values->append(parsedValue.release());
        else {
            addProperty(CSSPropertyFontStyle, parsedValue.release(), important);
            return true;
        }
    }

    if (values && values->length()) {
        m_hasFontFaceOnlyValues = true;
        addProperty(CSSPropertyFontStyle, values.release(), important);
        return true;
    }

    return false;
}

bool CSSParser::parseFontVariant(bool important)
{
    RefPtr<CSSValueList> values;
    if (m_valueList->size() > 1)
        values = CSSValueList::createCommaSeparated();
    CSSParserValue* val;
    bool expectComma = false;
    while ((val = m_valueList->current())) {
        RefPtr<CSSPrimitiveValue> parsedValue;
        if (!expectComma) {
            expectComma = true;
            if (val->id == CSSValueNormal || val->id == CSSValueSmallCaps)
                parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
            else if (val->id == CSSValueAll && !values) {
                // 'all' is only allowed in @font-face and with no other values. Make a value list to
                // indicate that we are in the @font-face case.
                values = CSSValueList::createCommaSeparated();
                parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
            }
        } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
            expectComma = false;
            m_valueList->next();
            continue;
        }

        if (!parsedValue)
            return false;

        m_valueList->next();

        if (values)
            values->append(parsedValue.release());
        else {
            addProperty(CSSPropertyFontVariant, parsedValue.release(), important);
            return true;
        }
    }

    if (values && values->length()) {
        m_hasFontFaceOnlyValues = true;
        addProperty(CSSPropertyFontVariant, values.release(), important);
        return true;
    }

    return false;
}

bool CSSParser::parseFontWeight(bool important)
{
    RefPtr<CSSValueList> values;
    if (m_valueList->size() > 1)
        values = CSSValueList::createCommaSeparated();
    CSSParserValue* val;
    bool expectComma = false;
    while ((val = m_valueList->current())) {
        RefPtr<CSSPrimitiveValue> parsedValue;
        if (!expectComma) {
            expectComma = true;
            if (val->unit == CSSPrimitiveValue::CSS_IDENT) {
                if (val->id >= CSSValueNormal && val->id <= CSSValue900)
                    parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
                else if (val->id == CSSValueAll && !values) {
                    // 'all' is only allowed in @font-face and with no other values. Make a value list to
                    // indicate that we are in the @font-face case.
                    values = CSSValueList::createCommaSeparated();
                    parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
                }
            } else if (validUnit(val, FInteger | FNonNeg, false)) {
                int weight = static_cast<int>(val->fValue);
                if (!(weight % 100) && weight >= 100 && weight <= 900)
                    parsedValue = primitiveValueCache()->createIdentifierValue(CSSValue100 + weight / 100 - 1);
            }
        } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
            expectComma = false;
            m_valueList->next();
            continue;
        }

        if (!parsedValue)
            return false;

        m_valueList->next();

        if (values)
            values->append(parsedValue.release());
        else {
            addProperty(CSSPropertyFontWeight, parsedValue.release(), important);
            return true;
        }
    }

    if (values && values->length()) {
        m_hasFontFaceOnlyValues = true;
        addProperty(CSSPropertyFontWeight, values.release(), important);
        return true;
    }

    return false;
}

static bool isValidFormatFunction(CSSParserValue* val)
{
    CSSParserValueList* args = val->function->args.get();
    return equalIgnoringCase(val->function->name, "format(") && (args->current()->unit == CSSPrimitiveValue::CSS_STRING || args->current()->unit == CSSPrimitiveValue::CSS_IDENT);
}

bool CSSParser::parseFontFaceSrc()
{
    RefPtr<CSSValueList> values(CSSValueList::createCommaSeparated());
    CSSParserValue* val;
    bool expectComma = false;
    bool allowFormat = false;
    bool failed = false;
    RefPtr<CSSFontFaceSrcValue> uriValue;
    while ((val = m_valueList->current())) {
        RefPtr<CSSFontFaceSrcValue> parsedValue;
        if (val->unit == CSSPrimitiveValue::CSS_URI && !expectComma && m_styleSheet) {
            // FIXME: The completeURL call should be done when using the CSSFontFaceSrcValue,
            // not when creating it.
            parsedValue = CSSFontFaceSrcValue::create(m_styleSheet->completeURL(val->string));
            uriValue = parsedValue;
            allowFormat = true;
            expectComma = true;
        } else if (val->unit == CSSParserValue::Function) {
            // There are two allowed functions: local() and format().
            CSSParserValueList* args = val->function->args.get();
            if (args && args->size() == 1) {
                if (equalIgnoringCase(val->function->name, "local(") && !expectComma && (args->current()->unit == CSSPrimitiveValue::CSS_STRING || args->current()->unit == CSSPrimitiveValue::CSS_IDENT)) {
                    expectComma = true;
                    allowFormat = false;
                    CSSParserValue* a = args->current();
                    uriValue.clear();
                    parsedValue = CSSFontFaceSrcValue::createLocal(a->string);
                } else if (allowFormat && uriValue && isValidFormatFunction(val)) {
                    expectComma = true;
                    allowFormat = false;
                    uriValue->setFormat(args->current()->string);
                    uriValue.clear();
                    m_valueList->next();
                    continue;
                }
            }
        } else if (val->unit == CSSParserValue::Operator && val->iValue == ',' && expectComma) {
            expectComma = false;
            allowFormat = false;
            uriValue.clear();
            m_valueList->next();
            continue;
        }

        if (parsedValue)
            values->append(parsedValue.release());
        else {
            failed = true;
            break;
        }
        m_valueList->next();
    }

    if (values->length() && !failed) {
        addProperty(CSSPropertySrc, values.release(), m_important);
        m_valueList->next();
        return true;
    }

    return false;
}

bool CSSParser::parseFontFaceUnicodeRange()
{
    RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
    bool failed = false;
    bool operatorExpected = false;
    for (; m_valueList->current(); m_valueList->next(), operatorExpected = !operatorExpected) {
        if (operatorExpected) {
            if (m_valueList->current()->unit == CSSParserValue::Operator && m_valueList->current()->iValue == ',')
                continue;
            failed = true;
            break;
        }
        if (m_valueList->current()->unit != CSSPrimitiveValue::CSS_UNICODE_RANGE) {
            failed = true;
            break;
        }

        String rangeString = m_valueList->current()->string;
        UChar32 from = 0;
        UChar32 to = 0;
        unsigned length = rangeString.length();

        if (length < 3) {
            failed = true;
            break;
        }

        unsigned i = 2;
        while (i < length) {
            UChar c = rangeString[i];
            if (c == '-' || c == '?')
                break;
            from *= 16;
            if (c >= '0' && c <= '9')
                from += c - '0';
            else if (c >= 'A' && c <= 'F')
                from += 10 + c - 'A';
            else if (c >= 'a' && c <= 'f')
                from += 10 + c - 'a';
            else {
                failed = true;
                break;
            }
            i++;
        }
        if (failed)
            break;

        if (i == length)
            to = from;
        else if (rangeString[i] == '?') {
            unsigned span = 1;
            while (i < length && rangeString[i] == '?') {
                span *= 16;
                from *= 16;
                i++;
            }
            if (i < length)
                failed = true;
            to = from + span - 1;
        } else {
            if (length < i + 2) {
                failed = true;
                break;
            }
            i++;
            while (i < length) {
                UChar c = rangeString[i];
                to *= 16;
                if (c >= '0' && c <= '9')
                    to += c - '0';
                else if (c >= 'A' && c <= 'F')
                    to += 10 + c - 'A';
                else if (c >= 'a' && c <= 'f')
                    to += 10 + c - 'a';
                else {
                    failed = true;
                    break;
                }
                i++;
            }
            if (failed)
                break;
        }
        if (from <= to)
            values->append(CSSUnicodeRangeValue::create(from, to));
    }
    if (failed || !values->length())
        return false;
    addProperty(CSSPropertyUnicodeRange, values.release(), m_important);
    return true;
}

// Returns the number of characters which form a valid double
// and are terminated by the given terminator character
static int checkForValidDouble(const UChar* string, const UChar* end, const char terminator)
{
    int length = end - string;
    if (length < 1)
        return 0;

    bool decimalMarkSeen = false;
    int processedLength = 0;

    for (int i = 0; i < length; ++i) {
        if (string[i] == terminator) {
            processedLength = i;
            break;
        }
        if (!isASCIIDigit(string[i])) {
            if (!decimalMarkSeen && string[i] == '.')
                decimalMarkSeen = true;
            else
                return 0;
        }
    }

    if (decimalMarkSeen && processedLength == 1)
        return 0;

    return processedLength;
}

// Returns the number of characters consumed for parsing a valid double
// terminated by the given terminator character
static int parseDouble(const UChar* string, const UChar* end, const char terminator, double& value)
{
    int length = checkForValidDouble(string, end, terminator);
    if (!length)
        return 0;

    int position = 0;
    double localValue = 0;

    // The consumed characters here are guaranteed to be
    // ASCII digits with or without a decimal mark
    for (; position < length; ++position) {
        if (string[position] == '.')
            break;
        localValue = localValue * 10 + string[position] - '0';
    }

    if (++position == length) {
        value = localValue;
        return length;
    }

    double fraction = 0;
    double scale = 1;

    while (position < length && scale < MAX_SCALE) {
        fraction = fraction * 10 + string[position++] - '0';
        scale *= 10;
    }

    value = localValue + fraction / scale;
    return length;
}

static bool parseColorIntOrPercentage(const UChar*& string, const UChar* end, const char terminator, CSSPrimitiveValue::UnitTypes& expect, int& value)
{
    const UChar* current = string;
    double localValue = 0;
    bool negative = false;
    while (current != end && isHTMLSpace(*current))
        current++;
    if (current != end && *current == '-') {
        negative = true;
        current++;
    }
    if (current == end || !isASCIIDigit(*current))
        return false;
    while (current != end && isASCIIDigit(*current)) {
        double newValue = localValue * 10 + *current++ - '0';
        if (newValue >= 255) {
            // Clamp values at 255.
            localValue = 255;
            while (current != end && isASCIIDigit(*current))
                ++current;
            break;
        }
        localValue = newValue;
    }

    if (current == end)
        return false;

    if (expect == CSSPrimitiveValue::CSS_NUMBER && (*current == '.' || *current == '%'))
        return false;

    if (*current == '.') {
        // We already parsed the integral part, try to parse
        // the fraction part of the percentage value.
        double percentage = 0;
        int numCharactersParsed = parseDouble(current, end, '%', percentage);
        if (!numCharactersParsed)
            return false;
        current += numCharactersParsed;
        if (*current != '%')
            return false;
        localValue += percentage;
    }

    if (expect == CSSPrimitiveValue::CSS_PERCENTAGE && *current != '%')
        return false;

    if (*current == '%') {
        expect = CSSPrimitiveValue::CSS_PERCENTAGE;
        localValue = localValue / 100.0 * 256.0;
        // Clamp values at 255 for percentages over 100%
        if (localValue > 255)
            localValue = 255;
        current++;
    } else
        expect = CSSPrimitiveValue::CSS_NUMBER;

    while (current != end && isHTMLSpace(*current))
        current++;
    if (current == end || *current++ != terminator)
        return false;
    // Clamp negative values at zero.
    value = negative ? 0 : static_cast<int>(localValue);
    string = current;
    return true;
}

static inline bool isTenthAlpha(const UChar* string, const int length)
{
    // "0.X"
    if (length == 3 && string[0] == '0' && string[1] == '.' && isASCIIDigit(string[2]))
        return true;

    // ".X"
    if (length == 2 && string[0] == '.' && isASCIIDigit(string[1]))
        return true;

    return false;
}

static inline bool parseAlphaValue(const UChar*& string, const UChar* end, const char terminator, int& value)
{
    while (string != end && isHTMLSpace(*string))
        string++;

    bool negative = false;

    if (string != end && *string == '-') {
        negative = true;
        string++;
    }

    value = 0;

    int length = end - string;
    if (length < 2)
        return false;

    if (string[length - 1] != terminator)
        return false;

    if (string[0] != '0' && string[0] != '1' && string[0] != '.') {
        if (checkForValidDouble(string, end, terminator)) {
            value = negative ? 0 : 255;
            string = end;
            return true;
        }
        return false;
    }

    if (length == 2 && string[0] != '.') {
        value = !negative && string[0] == '1' ? 255 : 0;
        string = end;
        return true;
    }

    if (isTenthAlpha(string, length - 1)) {
        static const int tenthAlphaValues[] = { 0, 25, 51, 76, 102, 127, 153, 179, 204, 230 };
        value = negative ? 0 : tenthAlphaValues[string[length - 2] - '0'];
        string = end;
        return true;
    }

    double alpha = 0;
    if (!parseDouble(string, end, terminator, alpha))
        return false;
    value = negative ? 0 : static_cast<int>(alpha * nextafter(256.0, 0.0));
    string = end;
    return true;
}

static inline bool mightBeRGBA(const UChar* characters, unsigned length)
{
    if (length < 5)
        return false;
    return characters[4] == '('
        && (characters[0] | 0x20) == 'r'
        && (characters[1] | 0x20) == 'g'
        && (characters[2] | 0x20) == 'b'
        && (characters[3] | 0x20) == 'a';
}

static inline bool mightBeRGB(const UChar* characters, unsigned length)
{
    if (length < 4)
        return false;
    return characters[3] == '('
        && (characters[0] | 0x20) == 'r'
        && (characters[1] | 0x20) == 'g'
        && (characters[2] | 0x20) == 'b';
}

bool CSSParser::parseColor(const String &name, RGBA32& rgb, bool strict)
{
    const UChar* characters = name.characters();
    unsigned length = name.length();
    CSSPrimitiveValue::UnitTypes expect = CSSPrimitiveValue::CSS_UNKNOWN;

    if (!strict && length >= 3) {
        if (name[0] == '#') {
            if (Color::parseHexColor(characters + 1, length - 1, rgb))
                return true;
        } else {
            if (Color::parseHexColor(characters, length, rgb))
                return true;
        }
    }

    // Try rgba() syntax.
    if (mightBeRGBA(characters, length)) {
        const UChar* current = characters + 5;
        const UChar* end = characters + length;
        int red;
        int green;
        int blue;
        int alpha;

        if (!parseColorIntOrPercentage(current, end, ',', expect, red))
            return false;
        if (!parseColorIntOrPercentage(current, end, ',', expect, green))
            return false;
        if (!parseColorIntOrPercentage(current, end, ',', expect, blue))
            return false;
        if (!parseAlphaValue(current, end, ')', alpha))
            return false;
        if (current != end)
            return false;
        rgb = makeRGBA(red, green, blue, alpha);
        return true;
    }

    // Try rgb() syntax.
    if (mightBeRGB(characters, length)) {
        const UChar* current = characters + 4;
        const UChar* end = characters + length;
        int red;
        int green;
        int blue;
        if (!parseColorIntOrPercentage(current, end, ',', expect, red))
            return false;
        if (!parseColorIntOrPercentage(current, end, ',', expect, green))
            return false;
        if (!parseColorIntOrPercentage(current, end, ')', expect, blue))
            return false;
        if (current != end)
            return false;
        rgb = makeRGB(red, green, blue);
        return true;
    }

    // Try named colors.
    Color tc;
    tc.setNamedColor(name);
    if (tc.isValid()) {
        rgb = tc.rgb();
        return true;
    }
    return false;
}

static inline int colorIntFromValue(CSSParserValue* v)
{
    if (v->fValue <= 0.0)
        return 0;

    if (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE) {
        if (v->fValue >= 100.0)
            return 255;
        return static_cast<int>(v->fValue * 256.0 / 100.0);
    }

    if (v->fValue >= 255.0)
        return 255;

    return static_cast<int>(v->fValue);
}

bool CSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, bool parseAlpha)
{
    CSSParserValueList* args = value->function->args.get();
    CSSParserValue* v = args->current();
    Units unitType = FUnknown;
    // Get the first value and its type
    if (validUnit(v, FInteger, true))
        unitType = FInteger;
    else if (validUnit(v, FPercent, true))
        unitType = FPercent;
    else
        return false;
    colorArray[0] = colorIntFromValue(v);
    for (int i = 1; i < 3; i++) {
        v = args->next();
        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
            return false;
        v = args->next();
        if (!validUnit(v, unitType, true))
            return false;
        colorArray[i] = colorIntFromValue(v);
    }
    if (parseAlpha) {
        v = args->next();
        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
            return false;
        v = args->next();
        if (!validUnit(v, FNumber, true))
            return false;
        // Convert the floating pointer number of alpha to an integer in the range [0, 256),
        // with an equal distribution across all 256 values.
        colorArray[3] = static_cast<int>(max(0.0, min(1.0, v->fValue)) * nextafter(256.0, 0.0));
    }
    return true;
}

// The CSS3 specification defines the format of a HSL color as
// hsl(<number>, <percent>, <percent>)
// and with alpha, the format is
// hsla(<number>, <percent>, <percent>, <number>)
// The first value, HUE, is in an angle with a value between 0 and 360
bool CSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bool parseAlpha)
{
    CSSParserValueList* args = value->function->args.get();
    CSSParserValue* v = args->current();
    // Get the first value
    if (!validUnit(v, FNumber, true))
        return false;
    // normalize the Hue value and change it to be between 0 and 1.0
    colorArray[0] = (((static_cast<int>(v->fValue) % 360) + 360) % 360) / 360.0;
    for (int i = 1; i < 3; i++) {
        v = args->next();
        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
            return false;
        v = args->next();
        if (!validUnit(v, FPercent, true))
            return false;
        colorArray[i] = max(0.0, min(100.0, v->fValue)) / 100.0; // needs to be value between 0 and 1.0
    }
    if (parseAlpha) {
        v = args->next();
        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
            return false;
        v = args->next();
        if (!validUnit(v, FNumber, true))
            return false;
        colorArray[3] = max(0.0, min(1.0, v->fValue));
    }
    return true;
}

PassRefPtr<CSSPrimitiveValue> CSSParser::parseColor(CSSParserValue* value)
{
    RGBA32 c = Color::transparent;
    if (!parseColorFromValue(value ? value : m_valueList->current(), c))
        return 0;
    return primitiveValueCache()->createColorValue(c);
}

bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c)
{
    if (!m_strict && value->unit == CSSPrimitiveValue::CSS_NUMBER &&
        value->fValue >= 0. && value->fValue < 1000000.) {
        String str = String::format("%06d", (int)(value->fValue+.5));
        if (!CSSParser::parseColor(str, c, m_strict))
            return false;
    } else if (value->unit == CSSPrimitiveValue::CSS_PARSER_HEXCOLOR ||
                value->unit == CSSPrimitiveValue::CSS_IDENT ||
                (!m_strict && value->unit == CSSPrimitiveValue::CSS_DIMENSION)) {
        if (!CSSParser::parseColor(value->string, c, m_strict && value->unit == CSSPrimitiveValue::CSS_IDENT))
            return false;
    } else if (value->unit == CSSParserValue::Function &&
                value->function->args != 0 &&
                value->function->args->size() == 5 /* rgb + two commas */ &&
                equalIgnoringCase(value->function->name, "rgb(")) {
        int colorValues[3];
        if (!parseColorParameters(value, colorValues, false))
            return false;
        c = makeRGB(colorValues[0], colorValues[1], colorValues[2]);
    } else {
        if (value->unit == CSSParserValue::Function &&
                value->function->args != 0 &&
                value->function->args->size() == 7 /* rgba + three commas */ &&
                equalIgnoringCase(value->function->name, "rgba(")) {
            int colorValues[4];
            if (!parseColorParameters(value, colorValues, true))
                return false;
            c = makeRGBA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
        } else if (value->unit == CSSParserValue::Function &&
                    value->function->args != 0 &&
                    value->function->args->size() == 5 /* hsl + two commas */ &&
                    equalIgnoringCase(value->function->name, "hsl(")) {
            double colorValues[3];
            if (!parseHSLParameters(value, colorValues, false))
                return false;
            c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], 1.0);
        } else if (value->unit == CSSParserValue::Function &&
                    value->function->args != 0 &&
                    value->function->args->size() == 7 /* hsla + three commas */ &&
                    equalIgnoringCase(value->function->name, "hsla(")) {
            double colorValues[4];
            if (!parseHSLParameters(value, colorValues, true))
                return false;
            c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
        } else
            return false;
    }

    return true;
}

// This class tracks parsing state for shadow values.  If it goes out of scope (e.g., due to an early return)
// without the allowBreak bit being set, then it will clean up all of the objects and destroy them.
struct ShadowParseContext {
    ShadowParseContext(CSSPropertyID prop, CSSPrimitiveValueCache* primitiveValueCache)
        : property(prop)
        , m_primitiveValueCache(primitiveValueCache)
        , allowX(true)
        , allowY(false)
        , allowBlur(false)
        , allowSpread(false)
        , allowColor(true)
        , allowStyle(prop == CSSPropertyWebkitBoxShadow || prop == CSSPropertyBoxShadow)
        , allowBreak(true)
    {
    }

    bool allowLength() { return allowX || allowY || allowBlur || allowSpread; }

    void commitValue()
    {
        // Handle the ,, case gracefully by doing nothing.
        if (x || y || blur || spread || color || style) {
            if (!values)
                values = CSSValueList::createCommaSeparated();

            // Construct the current shadow value and add it to the list.
            values->append(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
        }

        // Now reset for the next shadow value.
        x = 0;
        y = 0;
        blur = 0;
        spread = 0;
        style = 0;
        color = 0;

        allowX = true;
        allowColor = true;
        allowBreak = true;
        allowY = false;
        allowBlur = false;
        allowSpread = false;
        allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
    }

    void commitLength(CSSParserValue* v)
    {
        RefPtr<CSSPrimitiveValue> val = m_primitiveValueCache->createValue(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);

        if (allowX) {
            x = val.release();
            allowX = false;
            allowY = true;
            allowColor = false;
            allowStyle = false;
            allowBreak = false;
        } else if (allowY) {
            y = val.release();
            allowY = false;
            allowBlur = true;
            allowColor = true;
            allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
            allowBreak = true;
        } else if (allowBlur) {
            blur = val.release();
            allowBlur = false;
            allowSpread = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
        } else if (allowSpread) {
            spread = val.release();
            allowSpread = false;
        }
    }

    void commitColor(PassRefPtr<CSSPrimitiveValue> val)
    {
        color = val;
        allowColor = false;
        if (allowX) {
            allowStyle = false;
            allowBreak = false;
        } else {
            allowBlur = false;
            allowSpread = false;
            allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
        }
    }

    void commitStyle(CSSParserValue* v)
    {
        style = m_primitiveValueCache->createIdentifierValue(v->id);
        allowStyle = false;
        if (allowX)
            allowBreak = false;
        else {
            allowBlur = false;
            allowSpread = false;
            allowColor = false;
        }
    }

    CSSPropertyID property;
    CSSPrimitiveValueCache* m_primitiveValueCache;

    RefPtr<CSSValueList> values;
    RefPtr<CSSPrimitiveValue> x;
    RefPtr<CSSPrimitiveValue> y;
    RefPtr<CSSPrimitiveValue> blur;
    RefPtr<CSSPrimitiveValue> spread;
    RefPtr<CSSPrimitiveValue> style;
    RefPtr<CSSPrimitiveValue> color;

    bool allowX;
    bool allowY;
    bool allowBlur;
    bool allowSpread;
    bool allowColor;
    bool allowStyle; // inset or not.
    bool allowBreak;
};

bool CSSParser::parseShadow(int propId, bool important)
{
    ShadowParseContext context(static_cast<CSSPropertyID>(propId), primitiveValueCache());
    CSSParserValue* val;
    while ((val = m_valueList->current())) {
        // Check for a comma break first.
        if (val->unit == CSSParserValue::Operator) {
            if (val->iValue != ',' || !context.allowBreak)
                // Other operators aren't legal or we aren't done with the current shadow
                // value.  Treat as invalid.
                return false;
#if ENABLE(SVG)
            // -webkit-svg-shadow does not support multiple values.
            if (static_cast<CSSPropertyID>(propId) == CSSPropertyWebkitSvgShadow)
                return false;
#endif
            // The value is good.  Commit it.
            context.commitValue();
        } else if (validUnit(val, FLength, true)) {
            // We required a length and didn't get one. Invalid.
            if (!context.allowLength())
                return false;

            // A length is allowed here.  Construct the value and add it.
            context.commitLength(val);
        } else if (val->id == CSSValueInset) {
            if (!context.allowStyle)
                return false;

            context.commitStyle(val);
        } else {
            // The only other type of value that's ok is a color value.
            RefPtr<CSSPrimitiveValue> parsedColor;
            bool isColor = ((val->id >= CSSValueAqua && val->id <= CSSValueWindowtext) || val->id == CSSValueMenu ||
                            (val->id >= CSSValueWebkitFocusRingColor && val->id <= CSSValueWebkitText && !m_strict));
            if (isColor) {
                if (!context.allowColor)
                    return false;
                parsedColor = primitiveValueCache()->createIdentifierValue(val->id);
            }

            if (!parsedColor)
                // It's not built-in. Try to parse it as a color.
                parsedColor = parseColor(val);

            if (!parsedColor || !context.allowColor)
                return false; // This value is not a color or length and is invalid or
                              // it is a color, but a color isn't allowed at this point.

            context.commitColor(parsedColor.release());
        }

        m_valueList->next();
    }

    if (context.allowBreak) {
        context.commitValue();
        if (context.values->length()) {
            addProperty(propId, context.values.release(), important);
            m_valueList->next();
            return true;
        }
    }

    return false;
}

bool CSSParser::parseReflect(int propId, bool important)
{
    // box-reflect: <direction> <offset> <mask>

    // Direction comes first.
    CSSParserValue* val = m_valueList->current();
    CSSReflectionDirection direction;
    switch (val->id) {
        case CSSValueAbove:
            direction = ReflectionAbove;
            break;
        case CSSValueBelow:
            direction = ReflectionBelow;
            break;
        case CSSValueLeft:
            direction = ReflectionLeft;
            break;
        case CSSValueRight:
            direction = ReflectionRight;
            break;
        default:
            return false;
    }

    // The offset comes next.
    val = m_valueList->next();
    RefPtr<CSSPrimitiveValue> offset;
    if (!val)
        offset = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_PX);
    else {
        if (!validUnit(val, FLength | FPercent, m_strict))
            return false;
        offset = primitiveValueCache()->createValue(val->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(val->unit));
    }

    // Now for the mask.
    RefPtr<CSSValue> mask;
    val = m_valueList->next();
    if (val) {
        if (!parseBorderImage(propId, important, mask))
            return false;
    }

    RefPtr<CSSReflectValue> reflectValue = CSSReflectValue::create(direction, offset.release(), mask.release());
    addProperty(propId, reflectValue.release(), important);
    m_valueList->next();
    return true;
}

struct BorderImageParseContext {
    BorderImageParseContext(CSSPrimitiveValueCache* primitiveValueCache)
    : m_primitiveValueCache(primitiveValueCache)
    , m_allowBreak(false)
    , m_allowNumber(false)
    , m_allowSlash(false)
    , m_allowWidth(false)
    , m_allowRule(false)
    , m_borderTop(0)
    , m_borderRight(0)
    , m_borderBottom(0)
    , m_borderLeft(0)
    , m_horizontalRule(0)
    , m_verticalRule(0)
    {}

    bool allowBreak() const { return m_allowBreak; }
    bool allowNumber() const { return m_allowNumber; }
    bool allowSlash() const { return m_allowSlash; }
    bool allowWidth() const { return m_allowWidth; }
    bool allowRule() const { return m_allowRule; }

    void commitImage(PassRefPtr<CSSValue> image) { m_image = image; m_allowNumber = true; }
    void commitNumber(CSSParserValue* v)
    {
        PassRefPtr<CSSPrimitiveValue> val = m_primitiveValueCache->createValue(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
        if (!m_top)
            m_top = val;
        else if (!m_right)
            m_right = val;
        else if (!m_bottom)
            m_bottom = val;
        else {
            ASSERT(!m_left);
            m_left = val;
        }

        m_allowBreak = m_allowSlash = m_allowRule = true;
        m_allowNumber = !m_left;
    }
    void commitSlash() { m_allowBreak = m_allowSlash = m_allowNumber = false; m_allowWidth = true; }
    void commitWidth(CSSParserValue* val)
    {
        if (!m_borderTop)
            m_borderTop = val;
        else if (!m_borderRight)
            m_borderRight = val;
        else if (!m_borderBottom)
            m_borderBottom = val;
        else {
            ASSERT(!m_borderLeft);
            m_borderLeft = val;
        }

        m_allowBreak = m_allowRule = true;
        m_allowWidth = !m_borderLeft;
    }
    void commitRule(int keyword)
    {
        if (!m_horizontalRule)
            m_horizontalRule = keyword;
        else if (!m_verticalRule)
            m_verticalRule = keyword;
        m_allowRule = !m_verticalRule;
    }
    PassRefPtr<CSSValue> commitBorderImage(CSSParser* p, bool important)
    {
        // We need to clone and repeat values for any omissions.
        if (!m_right) {
            m_right = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
            m_bottom = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
            m_left = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
        }
        if (!m_bottom) {
            m_bottom = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
            m_left = m_primitiveValueCache->createValue(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
        }
        if (!m_left)
             m_left = m_primitiveValueCache->createValue(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());

        // Now build a rect value to hold all four of our primitive values.
        RefPtr<Rect> rect = Rect::create();
        rect->setTop(m_top);
        rect->setRight(m_right);
        rect->setBottom(m_bottom);
        rect->setLeft(m_left);

        // Fill in STRETCH as the default if it wasn't specified.
        if (!m_horizontalRule)
            m_horizontalRule = CSSValueStretch;

        // The vertical rule should match the horizontal rule if unspecified.
        if (!m_verticalRule)
            m_verticalRule = m_horizontalRule;

        // Now we have to deal with the border widths.  The best way to deal with these is to actually put these values into a value
        // list and then make our parsing machinery do the parsing.
        if (m_borderTop) {
            CSSParserValueList newList;
            newList.addValue(*m_borderTop);
            if (m_borderRight)
                newList.addValue(*m_borderRight);
            if (m_borderBottom)
                newList.addValue(*m_borderBottom);
            if (m_borderLeft)
                newList.addValue(*m_borderLeft);
            CSSParserValueList* oldList = p->m_valueList;
            p->m_valueList = &newList;
            p->parseValue(CSSPropertyBorderWidth, important);
            p->m_valueList = oldList;
        }

        // Make our new border image value now.
        return CSSBorderImageValue::create(m_image, rect.release(), m_horizontalRule, m_verticalRule);
    }
    
    CSSPrimitiveValueCache* m_primitiveValueCache;

    bool m_allowBreak;
    bool m_allowNumber;
    bool m_allowSlash;
    bool m_allowWidth;
    bool m_allowRule;

    RefPtr<CSSValue> m_image;

    RefPtr<CSSPrimitiveValue> m_top;
    RefPtr<CSSPrimitiveValue> m_right;
    RefPtr<CSSPrimitiveValue> m_bottom;
    RefPtr<CSSPrimitiveValue> m_left;

    CSSParserValue* m_borderTop;
    CSSParserValue* m_borderRight;
    CSSParserValue* m_borderBottom;
    CSSParserValue* m_borderLeft;

    int m_horizontalRule;
    int m_verticalRule;
};

bool CSSParser::parseBorderImage(int propId, bool important, RefPtr<CSSValue>& result)
{
    // Look for an image initially.  If the first value is not a URI, then we're done.
    BorderImageParseContext context(primitiveValueCache());
    CSSParserValue* val = m_valueList->current();
    if (val->unit == CSSPrimitiveValue::CSS_URI && m_styleSheet) {
        // FIXME: The completeURL call should be done when using the CSSImageValue,
        // not when creating it.
        context.commitImage(CSSImageValue::create(m_styleSheet->completeURL(val->string)));
    } else if (isGeneratedImageValue(val)) {
        RefPtr<CSSValue> value;
        if (parseGeneratedImage(value))
            context.commitImage(value);
        else
            return false;
    } else
        return false;

    while ((val = m_valueList->next())) {
        if (context.allowNumber() && validUnit(val, FInteger | FNonNeg | FPercent, true)) {
            context.commitNumber(val);
        } else if (propId == CSSPropertyWebkitBorderImage && context.allowSlash() && val->unit == CSSParserValue::Operator && val->iValue == '/') {
            context.commitSlash();
        } else if (context.allowWidth() &&
            (val->id == CSSValueThin || val->id == CSSValueMedium || val->id == CSSValueThick || validUnit(val, FLength, m_strict))) {
            context.commitWidth(val);
        } else if (context.allowRule() &&
            (val->id == CSSValueStretch || val->id == CSSValueRound || val->id == CSSValueRepeat)) {
            context.commitRule(val->id);
        } else {
            // Something invalid was encountered.
            return false;
        }
    }

    if (context.allowNumber() && propId != CSSPropertyWebkitBorderImage) {
        // Allow the slices to be omitted for images that don't fit to a border.  We just set the slices to be 0.
        context.m_top = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_NUMBER);
        context.m_allowBreak = true;
    }

    if (context.allowBreak()) {
        // Need to fully commit as a single value.
        result = context.commitBorderImage(this, important);
        return true;
    }

    return false;
}

static void completeBorderRadii(RefPtr<CSSPrimitiveValue> radii[4])
{
    if (radii[3])
        return;
    if (!radii[2]) {
        if (!radii[1])
            radii[1] = radii[0];
        radii[2] = radii[0];
    }
    radii[3] = radii[1];
}

bool CSSParser::parseBorderRadius(int propId, bool important)
{
    unsigned num = m_valueList->size();
    if (num > 9)
        return false;

    ShorthandScope scope(this, propId);
    RefPtr<CSSPrimitiveValue> radii[2][4];

    unsigned indexAfterSlash = 0;
    for (unsigned i = 0; i < num; ++i) {
        CSSParserValue* value = m_valueList->valueAt(i);
        if (value->unit == CSSParserValue::Operator) {
            if (value->iValue != '/')
                return false;

            if (!i || indexAfterSlash || i + 1 == num || num > i + 5)
                return false;

            indexAfterSlash = i + 1;
            completeBorderRadii(radii[0]);
            continue;
        }

        if (i - indexAfterSlash >= 4)
            return false;

        if (!validUnit(value, FLength | FPercent, m_strict))
            return false;

        RefPtr<CSSPrimitiveValue> radius = primitiveValueCache()->createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit));

        if (!indexAfterSlash) {
            radii[0][i] = radius;

            // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to border-radius: l1 / l2;
            if (num == 2 && propId == CSSPropertyWebkitBorderRadius) {
                indexAfterSlash = 1;
                completeBorderRadii(radii[0]);
            }
        } else
            radii[1][i - indexAfterSlash] = radius.release();
    }

    if (!indexAfterSlash) {
        completeBorderRadii(radii[0]);
        for (unsigned i = 0; i < 4; ++i)
            radii[1][i] = radii[0][i];
    } else
        completeBorderRadii(radii[1]);

    m_implicitShorthand = true;
    addProperty(CSSPropertyBorderTopLeftRadius, primitiveValueCache()->createValue(Pair::create(radii[0][0].release(), radii[1][0].release())), important);
    addProperty(CSSPropertyBorderTopRightRadius, primitiveValueCache()->createValue(Pair::create(radii[0][1].release(), radii[1][1].release())), important);
    addProperty(CSSPropertyBorderBottomRightRadius, primitiveValueCache()->createValue(Pair::create(radii[0][2].release(), radii[1][2].release())), important);
    addProperty(CSSPropertyBorderBottomLeftRadius, primitiveValueCache()->createValue(Pair::create(radii[0][3].release(), radii[1][3].release())), important);
    m_implicitShorthand = false;
    return true;
}

bool CSSParser::parseCounter(int propId, int defaultValue, bool important)
{
    enum { ID, VAL } state = ID;

    RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
    RefPtr<CSSPrimitiveValue> counterName;

    while (true) {
        CSSParserValue* val = m_valueList->current();
        switch (state) {
            case ID:
                if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) {
                    counterName = primitiveValueCache()->createValue(val->string, CSSPrimitiveValue::CSS_STRING);
                    state = VAL;
                    m_valueList->next();
                    continue;
                }
                break;
            case VAL: {
                int i = defaultValue;
                if (val && val->unit == CSSPrimitiveValue::CSS_NUMBER) {
                    i = clampToInteger(val->fValue);
                    m_valueList->next();
                }

                list->append(primitiveValueCache()->createValue(Pair::create(counterName.release(),
                    primitiveValueCache()->createValue(i, CSSPrimitiveValue::CSS_NUMBER))));
                state = ID;
                continue;
            }
        }
        break;
    }

    if (list->length() > 0) {
        addProperty(propId, list.release(), important);
        return true;
    }

    return false;
}

// This should go away once we drop support for -webkit-gradient
static PassRefPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue* a, bool horizontal, CSSPrimitiveValueCache* primitiveValueCache)
{
    RefPtr<CSSPrimitiveValue> result;
    if (a->unit == CSSPrimitiveValue::CSS_IDENT) {
        if ((equalIgnoringCase(a->string, "left") && horizontal) || 
            (equalIgnoringCase(a->string, "top") && !horizontal))
            result = primitiveValueCache->createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE);
        else if ((equalIgnoringCase(a->string, "right") && horizontal) ||
                 (equalIgnoringCase(a->string, "bottom") && !horizontal))
            result = primitiveValueCache->createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE);
        else if (equalIgnoringCase(a->string, "center"))
            result = primitiveValueCache->createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE);
    } else if (a->unit == CSSPrimitiveValue::CSS_NUMBER || a->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
        result = primitiveValueCache->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit);
    return result;
}

static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CSSGradientColorStop& stop)
{
    if (a->unit != CSSParserValue::Function)
        return false;

    if (!equalIgnoringCase(a->function->name, "from(") &&
        !equalIgnoringCase(a->function->name, "to(") &&
        !equalIgnoringCase(a->function->name, "color-stop("))
        return false;

    CSSParserValueList* args = a->function->args.get();
    if (!args)
        return false;

    if (equalIgnoringCase(a->function->name, "from(") || 
        equalIgnoringCase(a->function->name, "to(")) {
        // The "from" and "to" stops expect 1 argument.
        if (args->size() != 1)
            return false;

        if (equalIgnoringCase(a->function->name, "from("))
            stop.m_position = p->primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_NUMBER);
        else
            stop.m_position = p->primitiveValueCache()->createValue(1, CSSPrimitiveValue::CSS_NUMBER);

        int id = args->current()->id;
        if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
            stop.m_color = p->primitiveValueCache()->createIdentifierValue(id);
        else
            stop.m_color = p->parseColor(args->current());
        if (!stop.m_color)
            return false;
    }

    // The "color-stop" function expects 3 arguments.
    if (equalIgnoringCase(a->function->name, "color-stop(")) {
        if (args->size() != 3)
            return false;

        CSSParserValue* stopArg = args->current();
        if (stopArg->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
            stop.m_position = p->primitiveValueCache()->createValue(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER);
        else if (stopArg->unit == CSSPrimitiveValue::CSS_NUMBER)
            stop.m_position = p->primitiveValueCache()->createValue(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER);
        else
            return false;

        stopArg = args->next();
        if (stopArg->unit != CSSParserValue::Operator || stopArg->iValue != ',')
            return false;

        stopArg = args->next();
        int id = stopArg->id;
        if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
            stop.m_color = p->primitiveValueCache()->createIdentifierValue(id);
        else
            stop.m_color = p->parseColor(stopArg);
        if (!stop.m_color)
            return false;
    }

    return true;
}

bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
{
    // Walk the arguments.
    CSSParserValueList* args = m_valueList->current()->function->args.get();
    if (!args || args->size() == 0)
        return false;

    // The first argument is the gradient type.  It is an identifier.
    CSSGradientType gradientType;
    CSSParserValue* a = args->current();
    if (!a || a->unit != CSSPrimitiveValue::CSS_IDENT)
        return false;
    if (equalIgnoringCase(a->string, "linear"))
        gradientType = CSSLinearGradient;
    else if (equalIgnoringCase(a->string, "radial"))
        gradientType = CSSRadialGradient;
    else
        return false;

    RefPtr<CSSGradientValue> result;
    switch (gradientType) {
        case CSSLinearGradient:
            result = CSSLinearGradientValue::create(NonRepeating, true);
            break;
        case CSSRadialGradient:
            result = CSSRadialGradientValue::create(NonRepeating, true);
            break;
    }

    // Comma.
    a = args->next();
    if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',')
        return false;

    // Next comes the starting point for the gradient as an x y pair.  There is no
    // comma between the x and the y values.
    // First X.  It can be left, right, number or percent.
    a = args->next();
    if (!a)
        return false;
    RefPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true, primitiveValueCache());
    if (!point)
        return false;
    result->setFirstX(point.release());

    // First Y.  It can be top, bottom, number or percent.
    a = args->next();
    if (!a)
        return false;
    point = parseDeprecatedGradientPoint(a, false, primitiveValueCache());
    if (!point)
        return false;
    result->setFirstY(point.release());

    // Comma after the first point.
    a = args->next();
    if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',')
        return false;

    // For radial gradients only, we now expect a numeric radius.
    if (gradientType == CSSRadialGradient) {
        a = args->next();
        if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
            return false;
        static_cast<CSSRadialGradientValue*>(result.get())->setFirstRadius(primitiveValueCache()->createValue(a->fValue, CSSPrimitiveValue::CSS_NUMBER));

        // Comma after the first radius.
        a = args->next();
        if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',')
            return false;
    }

    // Next is the ending point for the gradient as an x, y pair.
    // Second X.  It can be left, right, number or percent.
    a = args->next();
    if (!a)
        return false;
    point = parseDeprecatedGradientPoint(a, true, primitiveValueCache());
    if (!point)
        return false;
    result->setSecondX(point.release());

    // Second Y.  It can be top, bottom, number or percent.
    a = args->next();
    if (!a)
        return false;
    point = parseDeprecatedGradientPoint(a, false, primitiveValueCache());
    if (!point)
        return false;
    result->setSecondY(point.release());

    // For radial gradients only, we now expect the second radius.
    if (gradientType == CSSRadialGradient) {
        // Comma after the second point.
        a = args->next();
        if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',')
            return false;

        a = args->next();
        if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
            return false;
        static_cast<CSSRadialGradientValue*>(result.get())->setSecondRadius(primitiveValueCache()->createValue(a->fValue, CSSPrimitiveValue::CSS_NUMBER));
    }

    // We now will accept any number of stops (0 or more).
    a = args->next();
    while (a) {
        // Look for the comma before the next stop.
        if (a->unit != CSSParserValue::Operator || a->iValue != ',')
            return false;

        // Now examine the stop itself.
        a = args->next();
        if (!a)
            return false;

        // The function name needs to be one of "from", "to", or "color-stop."
        CSSGradientColorStop stop;
        if (!parseDeprecatedGradientColorStop(this, a, stop))
            return false;
        result->addStop(stop);

        // Advance
        a = args->next();
    }

    gradient = result.release();
    return true;
}

static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal, CSSPrimitiveValueCache* primitiveValueCache)
{
    if (a->unit != CSSPrimitiveValue::CSS_IDENT)
        return 0;

    switch (a->id) {
        case CSSValueLeft:
        case CSSValueRight:
            isHorizontal = true;
            break;
        case CSSValueTop:
        case CSSValueBottom:
            isHorizontal = false;
            break;
        default:
            return 0;
    }
    return primitiveValueCache->createIdentifierValue(a->id);
}

static PassRefPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(CSSParser* p, CSSParserValue* value)
{
    int id = value->id;
    if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
        return p->primitiveValueCache()->createIdentifierValue(id);

    return p->parseColor(value);
}

bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
{
    RefPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating);
    
    // Walk the arguments.
    CSSParserValueList* args = m_valueList->current()->function->args.get();
    if (!args || !args->size())
        return false;

    CSSParserValue* a = args->current();
    if (!a)
        return false;

    bool expectComma = false;
    // Look for angle.
    if (validUnit(a, FAngle, true)) {
        result->setAngle(primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit));
        
        a = args->next();
        expectComma = true;
    } else {
        // Look one or two optional keywords that indicate a side or corner.
        RefPtr<CSSPrimitiveValue> startX, startY;
        
        RefPtr<CSSPrimitiveValue> location;
        bool isHorizontal = false;
        if ((location = valueFromSideKeyword(a, isHorizontal, primitiveValueCache()))) {
            if (isHorizontal)
                startX = location;
            else
                startY = location;
            
            a = args->next();
            if (a) {
                if ((location = valueFromSideKeyword(a, isHorizontal, primitiveValueCache()))) {
                    if (isHorizontal) {
                        if (startX)
                            return false;
                        startX = location;
                    } else {
                        if (startY)
                            return false;
                        startY = location;
                    }

                    a = args->next();
                }
            }

            expectComma = true;
        }
        
        if (!startX && !startY)
            startY = primitiveValueCache()->createIdentifierValue(CSSValueTop);
            
        result->setFirstX(startX.release());
        result->setFirstY(startY.release());
    }

    if (!parseGradientColorStops(args, result.get(), expectComma))
        return false;

    Vector<CSSGradientColorStop>& stops = result->stops();
    if (stops.isEmpty())
        return false;

    gradient = result.release();
    return true;
}

bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
{
    RefPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating);
    
    // Walk the arguments.
    CSSParserValueList* args = m_valueList->current()->function->args.get();
    if (!args || !args->size())
        return false;

    CSSParserValue* a = args->current();
    if (!a)
        return false;

    bool expectComma = false;

    // Optional background-position
    RefPtr<CSSValue> centerX;
    RefPtr<CSSValue> centerY;
    // parseFillPosition advances the args next pointer.
    parseFillPosition(args, centerX, centerY);
    a = args->current();
    if (!a)
        return false;
    
    if (centerX || centerY) {
        // Comma
        if (a->unit != CSSParserValue::Operator || a->iValue != ',')
            return false;

        a = args->next();
        if (!a)
            return false;
    }
    
    ASSERT(!centerX || centerX->isPrimitiveValue());
    ASSERT(!centerY || centerY->isPrimitiveValue());

    result->setFirstX(static_cast<CSSPrimitiveValue*>(centerX.get()));
    result->setSecondX(static_cast<CSSPrimitiveValue*>(centerX.get()));
    // CSS3 radial gradients always share the same start and end point.
    result->setFirstY(static_cast<CSSPrimitiveValue*>(centerY.get()));
    result->setSecondY(static_cast<CSSPrimitiveValue*>(centerY.get()));
    
    RefPtr<CSSPrimitiveValue> shapeValue;
    RefPtr<CSSPrimitiveValue> sizeValue;

    // Optional shape and/or size in any order.
    for (int i = 0; i < 2; ++i) {
        if (a->unit != CSSPrimitiveValue::CSS_IDENT)
            break;
    
        bool foundValue = false;
        switch (a->id) {
        case CSSValueCircle:
        case CSSValueEllipse:
            shapeValue = primitiveValueCache()->createIdentifierValue(a->id);
            foundValue = true;
            break;
        case CSSValueClosestSide:
        case CSSValueClosestCorner:
        case CSSValueFarthestSide:
        case CSSValueFarthestCorner:
        case CSSValueContain:
        case CSSValueCover:
            sizeValue = primitiveValueCache()->createIdentifierValue(a->id);
            foundValue = true;
            break;
        }

        if (foundValue) {
            a = args->next();
            if (!a)
                return false;

            expectComma = true;
        }
    }
    
    result->setShape(shapeValue);
    result->setSizingBehavior(sizeValue);
    
    // Or, two lengths or percentages
    RefPtr<CSSPrimitiveValue> horizontalSize;
    RefPtr<CSSPrimitiveValue> verticalSize;

    if (!shapeValue && !sizeValue) {
        if (validUnit(a, FLength | FPercent, m_strict)) {
            horizontalSize = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
            a = args->next();
            if (!a)
                return false;

            expectComma = true;
        }

        if (validUnit(a, FLength | FPercent, m_strict)) {
            verticalSize = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);

            a = args->next();
            if (!a)
                return false;
            expectComma = true;
        }
    }

    // Must have neither or both.
    if (!horizontalSize != !verticalSize)
        return false;
    
    result->setEndHorizontalSize(horizontalSize);
    result->setEndVerticalSize(verticalSize);

    if (!parseGradientColorStops(args, result.get(), expectComma))
        return false;

    gradient = result.release();
    return true;
}

bool CSSParser::parseGradientColorStops(CSSParserValueList* valueList, CSSGradientValue* gradient, bool expectComma)
{
    CSSParserValue* a = valueList->current();

    // Now look for color stops.
    while (a) {
        // Look for the comma before the next stop.
        if (expectComma) {
            if (a->unit != CSSParserValue::Operator || a->iValue != ',')
                return false;

            a = valueList->next();
            if (!a)
                return false;
        }

        // <color-stop> = <color> [ <percentage> | <length> ]?
        CSSGradientColorStop stop;
        stop.m_color = parseGradientColorOrKeyword(this, a);
        if (!stop.m_color)
            return false;

        a = valueList->next();
        if (a) {
            if (validUnit(a, FLength | FPercent, m_strict)) {
                stop.m_position = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit);
                a = valueList->next();
            }
        }
        
        gradient->addStop(stop);
        expectComma = true;
    }

    // Must have 2 or more stops to be valid.
    return gradient->stops().size() > 1;
}

bool CSSParser::isGeneratedImageValue(CSSParserValue* val) const
{
    if (val->unit != CSSParserValue::Function)
        return false;

    return equalIgnoringCase(val->function->name, "-webkit-gradient(")
        || equalIgnoringCase(val->function->name, "-webkit-linear-gradient(")
        || equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient(")
        || equalIgnoringCase(val->function->name, "-webkit-radial-gradient(")
        || equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient(")
        || equalIgnoringCase(val->function->name, "-webkit-canvas(");
}

bool CSSParser::parseGeneratedImage(RefPtr<CSSValue>& value)
{
    CSSParserValue* val = m_valueList->current();

    if (val->unit != CSSParserValue::Function)
        return false;

    if (equalIgnoringCase(val->function->name, "-webkit-gradient("))
        return parseDeprecatedGradient(value);

    if (equalIgnoringCase(val->function->name, "-webkit-linear-gradient("))
        return parseLinearGradient(value, NonRepeating);

    if (equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient("))
        return parseLinearGradient(value, Repeating);

    if (equalIgnoringCase(val->function->name, "-webkit-radial-gradient("))
        return parseRadialGradient(value, NonRepeating);

    if (equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient("))
        return parseRadialGradient(value, Repeating);

    if (equalIgnoringCase(val->function->name, "-webkit-canvas("))
        return parseCanvas(value);

    return false;
}

bool CSSParser::parseCanvas(RefPtr<CSSValue>& canvas)
{
    RefPtr<CSSCanvasValue> result = CSSCanvasValue::create();

    // Walk the arguments.
    CSSParserValueList* args = m_valueList->current()->function->args.get();
    if (!args || args->size() != 1)
        return false;

    // The first argument is the canvas name.  It is an identifier.
    CSSParserValue* a = args->current();
    if (!a || a->unit != CSSPrimitiveValue::CSS_IDENT)
        return false;
    result->setName(a->string);
    canvas = result;
    return true;
}

class TransformOperationInfo {
public:
    TransformOperationInfo(const CSSParserString& name)
    : m_type(WebKitCSSTransformValue::UnknownTransformOperation)
    , m_argCount(1)
    , m_allowSingleArgument(false)
    , m_unit(CSSParser::FUnknown)
    {
        if (equalIgnoringCase(name, "scale(") || equalIgnoringCase(name, "scalex(") || equalIgnoringCase(name, "scaley(") || equalIgnoringCase(name, "scalez(")) {
            m_unit = CSSParser::FNumber;
            if (equalIgnoringCase(name, "scale("))
                m_type = WebKitCSSTransformValue::ScaleTransformOperation;
            else if (equalIgnoringCase(name, "scalex("))
                m_type = WebKitCSSTransformValue::ScaleXTransformOperation;
            else if (equalIgnoringCase(name, "scaley("))
                m_type = WebKitCSSTransformValue::ScaleYTransformOperation;
            else
                m_type = WebKitCSSTransformValue::ScaleZTransformOperation;
        } else if (equalIgnoringCase(name, "scale3d(")) {
            m_type = WebKitCSSTransformValue::Scale3DTransformOperation;
            m_argCount = 5;
            m_unit = CSSParser::FNumber;
        } else if (equalIgnoringCase(name, "rotate(")) {
            m_type = WebKitCSSTransformValue::RotateTransformOperation;
            m_unit = CSSParser::FAngle;
        } else if (equalIgnoringCase(name, "rotatex(") ||
                   equalIgnoringCase(name, "rotatey(") ||
                   equalIgnoringCase(name, "rotatez(")) {
            m_unit = CSSParser::FAngle;
            if (equalIgnoringCase(name, "rotatex("))
                m_type = WebKitCSSTransformValue::RotateXTransformOperation;
            else if (equalIgnoringCase(name, "rotatey("))
                m_type = WebKitCSSTransformValue::RotateYTransformOperation;
            else
                m_type = WebKitCSSTransformValue::RotateZTransformOperation;
        } else if (equalIgnoringCase(name, "rotate3d(")) {
            m_type = WebKitCSSTransformValue::Rotate3DTransformOperation;
            m_argCount = 7;
            m_unit = CSSParser::FNumber;
        } else if (equalIgnoringCase(name, "skew(") || equalIgnoringCase(name, "skewx(") || equalIgnoringCase(name, "skewy(")) {
            m_unit = CSSParser::FAngle;
            if (equalIgnoringCase(name, "skew("))
                m_type = WebKitCSSTransformValue::SkewTransformOperation;
            else if (equalIgnoringCase(name, "skewx("))
                m_type = WebKitCSSTransformValue::SkewXTransformOperation;
            else
                m_type = WebKitCSSTransformValue::SkewYTransformOperation;
        } else if (equalIgnoringCase(name, "translate(") || equalIgnoringCase(name, "translatex(") || equalIgnoringCase(name, "translatey(") || equalIgnoringCase(name, "translatez(")) {
            m_unit = CSSParser::FLength | CSSParser::FPercent;
            if (equalIgnoringCase(name, "translate("))
                m_type = WebKitCSSTransformValue::TranslateTransformOperation;
            else if (equalIgnoringCase(name, "translatex("))
                m_type = WebKitCSSTransformValue::TranslateXTransformOperation;
            else if (equalIgnoringCase(name, "translatey("))
                m_type = WebKitCSSTransformValue::TranslateYTransformOperation;
            else
                m_type = WebKitCSSTransformValue::TranslateZTransformOperation;
        } else if (equalIgnoringCase(name, "translate3d(")) {
            m_type = WebKitCSSTransformValue::Translate3DTransformOperation;
            m_argCount = 5;
            m_unit = CSSParser::FLength | CSSParser::FPercent;
        } else if (equalIgnoringCase(name, "matrix(")) {
            m_type = WebKitCSSTransformValue::MatrixTransformOperation;
            m_argCount = 11;
            m_unit = CSSParser::FNumber;
        } else if (equalIgnoringCase(name, "matrix3d(")) {
            m_type = WebKitCSSTransformValue::Matrix3DTransformOperation;
            m_argCount = 31;
            m_unit = CSSParser::FNumber;
        } else if (equalIgnoringCase(name, "perspective(")) {
            m_type = WebKitCSSTransformValue::PerspectiveTransformOperation;
            m_unit = CSSParser::FNumber;
        }

        if (equalIgnoringCase(name, "scale(") || equalIgnoringCase(name, "skew(") || equalIgnoringCase(name, "translate(")) {
            m_allowSingleArgument = true;
            m_argCount = 3;
        }
    }

    WebKitCSSTransformValue::TransformOperationType type() const { return m_type; }
    unsigned argCount() const { return m_argCount; }
    CSSParser::Units unit() const { return m_unit; }

    bool unknown() const { return m_type == WebKitCSSTransformValue::UnknownTransformOperation; }
    bool hasCorrectArgCount(unsigned argCount) { return m_argCount == argCount || (m_allowSingleArgument && argCount == 1); }

private:
    WebKitCSSTransformValue::TransformOperationType m_type;
    unsigned m_argCount;
    bool m_allowSingleArgument;
    CSSParser::Units m_unit;
};

PassRefPtr<CSSValueList> CSSParser::parseTransform()
{
    if (!m_valueList)
        return 0;

    // The transform is a list of functional primitives that specify transform operations.
    // We collect a list of WebKitCSSTransformValues, where each value specifies a single operation.
    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
        if (value->unit != CSSParserValue::Function || !value->function)
            return 0;

        // Every primitive requires at least one argument.
        CSSParserValueList* args = value->function->args.get();
        if (!args)
            return 0;

        // See if the specified primitive is one we understand.
        TransformOperationInfo info(value->function->name);
        if (info.unknown())
            return 0;

        if (!info.hasCorrectArgCount(args->size()))
            return 0;

        // Create the new WebKitCSSTransformValue for this operation and add it to our list.
        RefPtr<WebKitCSSTransformValue> transformValue = WebKitCSSTransformValue::create(info.type());
        list->append(transformValue);

        // Snag our values.
        CSSParserValue* a = args->current();
        unsigned argNumber = 0;
        while (a) {
            CSSParser::Units unit = info.unit();

            if (info.type() == WebKitCSSTransformValue::Rotate3DTransformOperation && argNumber == 3) {
                // 4th param of rotate3d() is an angle rather than a bare number, validate it as such
                if (!validUnit(a, FAngle, true))
                    return 0;
            } else if (info.type() == WebKitCSSTransformValue::Translate3DTransformOperation && argNumber == 2) {
                // 3rd param of translate3d() cannot be a percentage
                if (!validUnit(a, FLength, true))
                    return 0;
            } else if (info.type() == WebKitCSSTransformValue::TranslateZTransformOperation && argNumber == 0) {
                // 1st param of translateZ() cannot be a percentage
                if (!validUnit(a, FLength, true))
                    return 0;
            } else if (info.type() == WebKitCSSTransformValue::PerspectiveTransformOperation && argNumber == 0) {
                // 1st param of perspective() must be a non-negative number (deprecated) or length.
                if (!validUnit(a, FNumber | FLength | FNonNeg, true))
                    return 0;
            } else if (!validUnit(a, unit, true))
                return 0;

            // Add the value to the current transform operation.
            transformValue->append(primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit));

            a = args->next();
            if (!a)
                break;
            if (a->unit != CSSParserValue::Operator || a->iValue != ',')
                return 0;
            a = args->next();

            argNumber++;
        }
    }

    return list.release();
}

bool CSSParser::parseTransformOrigin(int propId, int& propId1, int& propId2, int& propId3, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2, RefPtr<CSSValue>& value3)
{
    propId1 = propId;
    propId2 = propId;
    propId3 = propId;
    if (propId == CSSPropertyWebkitTransformOrigin) {
        propId1 = CSSPropertyWebkitTransformOriginX;
        propId2 = CSSPropertyWebkitTransformOriginY;
        propId3 = CSSPropertyWebkitTransformOriginZ;
    }

    switch (propId) {
        case CSSPropertyWebkitTransformOrigin:
            if (!parseTransformOriginShorthand(value, value2, value3))
                return false;
            // parseTransformOriginShorthand advances the m_valueList pointer
            break;
        case CSSPropertyWebkitTransformOriginX: {
            value = parseFillPositionX(m_valueList);
            if (value)
                m_valueList->next();
            break;
        }
        case CSSPropertyWebkitTransformOriginY: {
            value = parseFillPositionY(m_valueList);
            if (value)
                m_valueList->next();
            break;
        }
        case CSSPropertyWebkitTransformOriginZ: {
            if (validUnit(m_valueList->current(), FLength, m_strict))
                value = primitiveValueCache()->createValue(m_valueList->current()->fValue, (CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit);
            if (value)
                m_valueList->next();
            break;
        }
    }

    return value;
}

bool CSSParser::parsePerspectiveOrigin(int propId, int& propId1, int& propId2, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2)
{
    propId1 = propId;
    propId2 = propId;
    if (propId == CSSPropertyWebkitPerspectiveOrigin) {
        propId1 = CSSPropertyWebkitPerspectiveOriginX;
        propId2 = CSSPropertyWebkitPerspectiveOriginY;
    }

    switch (propId) {
        case CSSPropertyWebkitPerspectiveOrigin:
            parseFillPosition(m_valueList, value, value2);
            break;
        case CSSPropertyWebkitPerspectiveOriginX: {
            value = parseFillPositionX(m_valueList);
            if (value)
                m_valueList->next();
            break;
        }
        case CSSPropertyWebkitPerspectiveOriginY: {
            value = parseFillPositionY(m_valueList);
            if (value)
                m_valueList->next();
            break;
        }
    }

    return value;
}

bool CSSParser::parseTextEmphasisStyle(bool important)
{
    unsigned valueListSize = m_valueList->size();

    RefPtr<CSSPrimitiveValue> fill;
    RefPtr<CSSPrimitiveValue> shape;

    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
        if (value->unit == CSSPrimitiveValue::CSS_STRING) {
            if (fill || shape || (valueListSize != 1 && !inShorthand()))
                return false;
            addProperty(CSSPropertyWebkitTextEmphasisStyle, primitiveValueCache()->createValue(value->string, CSSPrimitiveValue::CSS_STRING), important);
            m_valueList->next();
            return true;
        }

        if (value->id == CSSValueNone) {
            if (fill || shape || (valueListSize != 1 && !inShorthand()))
                return false;
            addProperty(CSSPropertyWebkitTextEmphasisStyle, primitiveValueCache()->createIdentifierValue(CSSValueNone), important);
            m_valueList->next();
            return true;
        }

        if (value->id == CSSValueOpen || value->id == CSSValueFilled) {
            if (fill)
                return false;
            fill = primitiveValueCache()->createIdentifierValue(value->id);
        } else if (value->id == CSSValueDot || value->id == CSSValueCircle || value->id == CSSValueDoubleCircle || value->id == CSSValueTriangle || value->id == CSSValueSesame) {
            if (shape)
                return false;
            shape = primitiveValueCache()->createIdentifierValue(value->id);
        } else if (!inShorthand())
            return false;
        else
            break;
    }

    if (fill && shape) {
        RefPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
        parsedValues->append(fill.release());
        parsedValues->append(shape.release());
        addProperty(CSSPropertyWebkitTextEmphasisStyle, parsedValues.release(), important);
        return true;
    }
    if (fill) {
        addProperty(CSSPropertyWebkitTextEmphasisStyle, fill.release(), important);
        return true;
    }
    if (shape) {
        addProperty(CSSPropertyWebkitTextEmphasisStyle, shape.release(), important);
        return true;
    }

    return false;
}

bool CSSParser::parseLineBoxContain(bool important)
{
    LineBoxContain lineBoxContain = LineBoxContainNone;

    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
        if (value->id == CSSValueBlock) {
            if (lineBoxContain & LineBoxContainBlock)
                return false;
            lineBoxContain |= LineBoxContainBlock;
        } else if (value->id == CSSValueInline) {
            if (lineBoxContain & LineBoxContainInline)
                return false;
            lineBoxContain |= LineBoxContainInline;
        } else if (value->id == CSSValueFont) {
            if (lineBoxContain & LineBoxContainFont)
                return false;
            lineBoxContain |= LineBoxContainFont;
        } else if (value->id == CSSValueGlyphs) {
            if (lineBoxContain & LineBoxContainGlyphs)
                return false;
            lineBoxContain |= LineBoxContainGlyphs;
        } else if (value->id == CSSValueReplaced) {
            if (lineBoxContain & LineBoxContainReplaced)
                return false;
            lineBoxContain |= LineBoxContainReplaced;
        } else if (value->id == CSSValueInlineBox) {
            if (lineBoxContain & LineBoxContainInlineBox)
                return false;
            lineBoxContain |= LineBoxContainInlineBox;
        } else
            return false;
    }
    
    if (!lineBoxContain)
        return false;

    addProperty(CSSPropertyWebkitLineBoxContain, CSSLineBoxContainValue::create(lineBoxContain), important);
    return true;
}

static inline int yyerror(const char*) { return 1; }

#define END_TOKEN 0

#include "CSSGrammar.h"

int CSSParser::lex(void* yylvalWithoutType)
{
    YYSTYPE* yylval = static_cast<YYSTYPE*>(yylvalWithoutType);
    int length;

    lex();

    UChar* t = text(&length);

    switch (token()) {
    case WHITESPACE:
    case SGML_CD:
    case INCLUDES:
    case DASHMATCH:
        break;

    case URI:
    case STRING:
    case IDENT:
    case NTH:
    case HEX:
    case IDSEL:
    case DIMEN:
    case UNICODERANGE:
    case FUNCTION:
    case ANYFUNCTION:
    case NOTFUNCTION:
    case CALCFUNCTION:
    case MINFUNCTION:
    case MAXFUNCTION:
        yylval->string.characters = t;
        yylval->string.length = length;
        break;

    case IMPORT_SYM:
    case PAGE_SYM:
    case MEDIA_SYM:
    case FONT_FACE_SYM:
    case CHARSET_SYM:
    case NAMESPACE_SYM:
    case WEBKIT_KEYFRAMES_SYM:

    case IMPORTANT_SYM:
        break;

    case QEMS:
        length--;
    case GRADS:
    case TURNS:
        length--;
    case DEGS:
    case RADS:
    case KHERTZ:
    case REMS:
        length--;
    case MSECS:
    case HERTZ:
    case EMS:
    case EXS:
    case PXS:
    case CMS:
    case MMS:
    case INS:
    case PTS:
    case PCS:
        length--;
    case SECS:
    case PERCENTAGE:
        length--;
    case FLOATTOKEN:
    case INTEGER:
        yylval->number = charactersToDouble(t, length);
        break;

    default:
        break;
    }

    return token();
}

void CSSParser::recheckAtKeyword(const UChar* str, int len)
{
    String ruleName(str, len);
    if (equalIgnoringCase(ruleName, "@import"))
        yyTok = IMPORT_SYM;
    else if (equalIgnoringCase(ruleName, "@page"))
        yyTok = PAGE_SYM;
    else if (equalIgnoringCase(ruleName, "@media"))
        yyTok = MEDIA_SYM;
    else if (equalIgnoringCase(ruleName, "@font-face"))
        yyTok = FONT_FACE_SYM;
    else if (equalIgnoringCase(ruleName, "@charset"))
        yyTok = CHARSET_SYM;
    else if (equalIgnoringCase(ruleName, "@namespace"))
        yyTok = NAMESPACE_SYM;
    else if (equalIgnoringCase(ruleName, "@-webkit-keyframes"))
        yyTok = WEBKIT_KEYFRAMES_SYM;
    else if (equalIgnoringCase(ruleName, "@-webkit-mediaquery"))
        yyTok = WEBKIT_MEDIAQUERY_SYM;
}

UChar* CSSParser::text(int *length)
{
    UChar* start = yytext;
    int l = yyleng;
    switch (yyTok) {
    case STRING:
        l--;
        /* nobreak */
    case HEX:
    case IDSEL:
        start++;
        l--;
        break;
    case URI:
        // "url("{w}{string}{w}")"
        // "url("{w}{url}{w}")"
        // strip "url(" and ")"
        start += 4;
        l -= 5;
        // strip {w}
        while (l && isHTMLSpace(*start)) {
            ++start;
            --l;
        }
        while (l && isHTMLSpace(start[l - 1]))
            --l;
        if (l && (*start == '"' || *start == '\'')) {
            ASSERT(l >= 2 && start[l - 1] == *start);
            ++start;
            l -= 2;
        }
        break;
    default:
        break;
    }

    // process escapes
    UChar* out = start;
    UChar* escape = 0;

    bool sawEscape = false;

    for (int i = 0; i < l; i++) {
        UChar* current = start + i;
        if (escape == current - 1) {
            if (isASCIIHexDigit(*current))
                continue;
            if (yyTok == STRING &&
                 (*current == '\n' || *current == '\r' || *current == '\f')) {
                // ### handle \r\n case
                if (*current != '\r')
                    escape = 0;
                continue;
            }
            // in all other cases copy the char to output
            // ###
            *out++ = *current;
            escape = 0;
            continue;
        }
        if (escape == current - 2 && yyTok == STRING &&
             *(current-1) == '\r' && *current == '\n') {
            escape = 0;
            continue;
        }
        if (escape > current - 7 && isASCIIHexDigit(*current))
            continue;
        if (escape) {
            // add escaped char
            unsigned uc = 0;
            escape++;
            while (escape < current) {
                uc *= 16;
                uc += toASCIIHexValue(*escape);
                escape++;
            }
            // can't handle chars outside ucs2
            if (uc > 0xffff)
                uc = 0xfffd;
            *out++ = uc;
            escape = 0;
            if (isHTMLSpace(*current))
                continue;
        }
        if (!escape && *current == '\\') {
            escape = current;
            sawEscape = true;
            continue;
        }
        *out++ = *current;
    }
    if (escape) {
        // add escaped char
        unsigned uc = 0;
        escape++;
        while (escape < start+l) {
            uc *= 16;
            uc += toASCIIHexValue(*escape);
            escape++;
        }
        // can't handle chars outside ucs2
        if (uc > 0xffff)
            uc = 0xfffd;
        *out++ = uc;
    }

    *length = out - start;

    // If we have an unrecognized @-keyword, and if we handled any escapes at all, then
    // we should attempt to adjust yyTok to the correct type.
    if (yyTok == ATKEYWORD && sawEscape)
        recheckAtKeyword(start, *length);

    return start;
}

void CSSParser::countLines()
{
    for (UChar* current = yytext; current < yytext + yyleng; ++current) {
        if (*current == '\n')
            ++m_lineNumber;
    }
}

CSSParserSelector* CSSParser::createFloatingSelector()
{
    CSSParserSelector* selector = new CSSParserSelector;
    m_floatingSelectors.add(selector);
    return selector;
}

PassOwnPtr<CSSParserSelector> CSSParser::sinkFloatingSelector(CSSParserSelector* selector)
{
    if (selector) {
        ASSERT(m_floatingSelectors.contains(selector));
        m_floatingSelectors.remove(selector);
    }
    return adoptPtr(selector);
}

Vector<OwnPtr<CSSParserSelector> >* CSSParser::createFloatingSelectorVector()
{
    Vector<OwnPtr<CSSParserSelector> >* selectorVector = new Vector<OwnPtr<CSSParserSelector> >;
    m_floatingSelectorVectors.add(selectorVector);
    return selectorVector;
}

PassOwnPtr<Vector<OwnPtr<CSSParserSelector> > > CSSParser::sinkFloatingSelectorVector(Vector<OwnPtr<CSSParserSelector> >* selectorVector)
{
    if (selectorVector) {
        ASSERT(m_floatingSelectorVectors.contains(selectorVector));
        m_floatingSelectorVectors.remove(selectorVector);
    }
    return adoptPtr(selectorVector);
}

CSSParserValueList* CSSParser::createFloatingValueList()
{
    CSSParserValueList* list = new CSSParserValueList;
    m_floatingValueLists.add(list);
    return list;
}

CSSParserValueList* CSSParser::sinkFloatingValueList(CSSParserValueList* list)
{
    if (list) {
        ASSERT(m_floatingValueLists.contains(list));
        m_floatingValueLists.remove(list);
    }
    return list;
}

CSSParserFunction* CSSParser::createFloatingFunction()
{
    CSSParserFunction* function = new CSSParserFunction;
    m_floatingFunctions.add(function);
    return function;
}

CSSParserFunction* CSSParser::sinkFloatingFunction(CSSParserFunction* function)
{
    if (function) {
        ASSERT(m_floatingFunctions.contains(function));
        m_floatingFunctions.remove(function);
    }
    return function;
}

CSSParserValue& CSSParser::sinkFloatingValue(CSSParserValue& value)
{
    if (value.unit == CSSParserValue::Function) {
        ASSERT(m_floatingFunctions.contains(value.function));
        m_floatingFunctions.remove(value.function);
    }
    return value;
}

MediaQueryExp* CSSParser::createFloatingMediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* values)
{
    m_floatingMediaQueryExp = MediaQueryExp::create(mediaFeature, values);
    return m_floatingMediaQueryExp.get();
}

PassOwnPtr<MediaQueryExp> CSSParser::sinkFloatingMediaQueryExp(MediaQueryExp* expression)
{
    ASSERT_UNUSED(expression, expression == m_floatingMediaQueryExp);
    return m_floatingMediaQueryExp.release();
}

Vector<OwnPtr<MediaQueryExp> >* CSSParser::createFloatingMediaQueryExpList()
{
    m_floatingMediaQueryExpList = adoptPtr(new Vector<OwnPtr<MediaQueryExp> >);
    return m_floatingMediaQueryExpList.get();
}

PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > CSSParser::sinkFloatingMediaQueryExpList(Vector<OwnPtr<MediaQueryExp> >* list)
{
    ASSERT_UNUSED(list, list == m_floatingMediaQueryExpList);
    return m_floatingMediaQueryExpList.release();
}

MediaQuery* CSSParser::createFloatingMediaQuery(MediaQuery::Restrictor restrictor, const String& mediaType, PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > expressions)
{
    m_floatingMediaQuery = adoptPtr(new MediaQuery(restrictor, mediaType, expressions));
    return m_floatingMediaQuery.get();
}

MediaQuery* CSSParser::createFloatingMediaQuery(PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > expressions)
{
    return createFloatingMediaQuery(MediaQuery::None, "all", expressions);
}

PassOwnPtr<MediaQuery> CSSParser::sinkFloatingMediaQuery(MediaQuery* query)
{
    ASSERT_UNUSED(query, query == m_floatingMediaQuery);
    return m_floatingMediaQuery.release();
}

MediaList* CSSParser::createMediaList()
{
    RefPtr<MediaList> list = MediaList::create();
    MediaList* result = list.get();
    m_parsedStyleObjects.append(list.release());
    return result;
}

CSSRule* CSSParser::createCharsetRule(const CSSParserString& charset)
{
    if (!m_styleSheet)
        return 0;
    RefPtr<CSSCharsetRule> rule = CSSCharsetRule::create(m_styleSheet, charset);
    CSSCharsetRule* result = rule.get();
    m_parsedStyleObjects.append(rule.release());
    return result;
}

CSSRule* CSSParser::createImportRule(const CSSParserString& url, MediaList* media)
{
    if (!media || !m_styleSheet || !m_allowImportRules)
        return 0;
    RefPtr<CSSImportRule> rule = CSSImportRule::create(m_styleSheet, url, media);
    CSSImportRule* result = rule.get();
    m_parsedStyleObjects.append(rule.release());
    return result;
}

CSSRule* CSSParser::createMediaRule(MediaList* media, CSSRuleList* rules)
{
    if (!media || !rules || !m_styleSheet)
        return 0;
    m_allowImportRules = m_allowNamespaceDeclarations = false;
    RefPtr<CSSMediaRule> rule = CSSMediaRule::create(m_styleSheet, media, rules);
    CSSMediaRule* result = rule.get();
    m_parsedStyleObjects.append(rule.release());
    return result;
}

CSSRuleList* CSSParser::createRuleList()
{
    RefPtr<CSSRuleList> list = CSSRuleList::create();
    CSSRuleList* listPtr = list.get();

    m_parsedRuleLists.append(list.release());
    return listPtr;
}

WebKitCSSKeyframesRule* CSSParser::createKeyframesRule()
{
    m_allowImportRules = m_allowNamespaceDeclarations = false;
    RefPtr<WebKitCSSKeyframesRule> rule = WebKitCSSKeyframesRule::create(m_styleSheet);
    WebKitCSSKeyframesRule* rulePtr = rule.get();
    m_parsedStyleObjects.append(rule.release());
    return rulePtr;
}

CSSRule* CSSParser::createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors)
{
    CSSStyleRule* result = 0;
    markRuleBodyEnd();
    if (selectors) {
        m_allowImportRules = m_allowNamespaceDeclarations = false;
        RefPtr<CSSStyleRule> rule = CSSStyleRule::create(m_styleSheet, m_lastSelectorLineNumber);
        rule->adoptSelectorVector(*selectors);
        if (m_hasFontFaceOnlyValues)
            deleteFontFaceOnlyValues();
        rule->setDeclaration(CSSMutableStyleDeclaration::create(rule.get(), m_parsedProperties, m_numParsedProperties));
        result = rule.get();
        m_parsedStyleObjects.append(rule.release());
        if (m_ruleRangeMap) {
            ASSERT(m_currentRuleData);
            m_currentRuleData->styleSourceData->styleBodyRange = m_ruleBodyRange;
            m_currentRuleData->selectorListRange = m_selectorListRange;
            m_ruleRangeMap->set(result, m_currentRuleData.release());
            m_currentRuleData = CSSRuleSourceData::create();
            m_currentRuleData->styleSourceData = CSSStyleSourceData::create();
            m_inStyleRuleOrDeclaration = false;
        }
    }
    resetSelectorListMarks();
    resetRuleBodyMarks();
    clearProperties();
    return result;
}

CSSRule* CSSParser::createFontFaceRule()
{
    m_allowImportRules = m_allowNamespaceDeclarations = false;
    for (unsigned i = 0; i < m_numParsedProperties; ++i) {
        CSSProperty* property = m_parsedProperties[i];
        int id = property->id();
        if ((id == CSSPropertyFontWeight || id == CSSPropertyFontStyle || id == CSSPropertyFontVariant) && property->value()->isPrimitiveValue()) {
            RefPtr<CSSValue> value = property->m_value.release();
            property->m_value = CSSValueList::createCommaSeparated();
            static_cast<CSSValueList*>(property->value())->append(value.release());
        } else if (id == CSSPropertyFontFamily && (!property->value()->isValueList() || static_cast<CSSValueList*>(property->value())->length() != 1)) {
            // Unlike font-family property, font-family descriptor in @font-face rule 
            // has to be a value list with exactly one family name. It cannot have a
            // have 'initial' value and cannot 'inherit' from parent.
            // See http://dev.w3.org/csswg/css3-fonts/#font-family-desc
            clearProperties();
            return 0;
        }
    }
    RefPtr<CSSFontFaceRule> rule = CSSFontFaceRule::create(m_styleSheet);
    rule->setDeclaration(CSSMutableStyleDeclaration::create(rule.get(), m_parsedProperties, m_numParsedProperties));
    clearProperties();
    CSSFontFaceRule* result = rule.get();
    m_parsedStyleObjects.append(rule.release());
    return result;
}

void CSSParser::addNamespace(const AtomicString& prefix, const AtomicString& uri)
{
    if (!m_styleSheet || !m_allowNamespaceDeclarations)
        return;
    m_allowImportRules = false;
    m_styleSheet->addNamespace(this, prefix, uri);
}

void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector* specifiers)
{
    AtomicString determinedNamespace = namespacePrefix != nullAtom && m_styleSheet ? m_styleSheet->determineNamespace(namespacePrefix) : m_defaultNamespace;
    QualifiedName tag = QualifiedName(namespacePrefix, elementName, determinedNamespace);
    if (!specifiers->isUnknownPseudoElement()) {
        specifiers->setTag(tag);
        return;
    }

    specifiers->setRelation(CSSSelector::ShadowDescendant);
    if (CSSParserSelector* history = specifiers->tagHistory()) {
        history->setTag(tag);
        return;
    }

    // No need to create an extra element name selector if we are matching any element
    // in any namespace.
    if (elementName == starAtom && m_defaultNamespace == starAtom)
        return;

    CSSParserSelector* elementNameSelector = new CSSParserSelector;
    elementNameSelector->setTag(tag);
    specifiers->setTagHistory(elementNameSelector);
}


CSSRule* CSSParser::createPageRule(PassOwnPtr<CSSParserSelector> pageSelector)
{
    // FIXME: Margin at-rules are ignored.
    m_allowImportRules = m_allowNamespaceDeclarations = false;
    CSSPageRule* pageRule = 0;
    if (pageSelector) {
        RefPtr<CSSPageRule> rule = CSSPageRule::create(m_styleSheet, m_lastSelectorLineNumber);
        Vector<OwnPtr<CSSParserSelector> > selectorVector;
        selectorVector.append(pageSelector);
        rule->adoptSelectorVector(selectorVector);
        rule->setDeclaration(CSSMutableStyleDeclaration::create(rule.get(), m_parsedProperties, m_numParsedProperties));
        pageRule = rule.get();
        m_parsedStyleObjects.append(rule.release());
    }
    clearProperties();
    return pageRule;
}

CSSRule* CSSParser::createMarginAtRule(CSSSelector::MarginBoxType /* marginBox */)
{
    // FIXME: Implement margin at-rule here, using:
    //        - marginBox: margin box
    //        - m_parsedProperties: properties at [m_numParsedPropertiesBeforeMarginBox, m_numParsedProperties) are for this at-rule.
    // Don't forget to also update the action for page symbol in CSSGrammar.y such that margin at-rule data is cleared if page_selector is invalid.

    endDeclarationsForMarginBox();
    return 0; // until this method is implemented.
}

void CSSParser::startDeclarationsForMarginBox()
{
    m_numParsedPropertiesBeforeMarginBox = m_numParsedProperties;
}

void CSSParser::endDeclarationsForMarginBox()
{
    ASSERT(m_numParsedPropertiesBeforeMarginBox != INVALID_NUM_PARSED_PROPERTIES);
    rollbackLastProperties(m_numParsedProperties - m_numParsedPropertiesBeforeMarginBox);
    m_numParsedPropertiesBeforeMarginBox = INVALID_NUM_PARSED_PROPERTIES;
}

void CSSParser::deleteFontFaceOnlyValues()
{
    ASSERT(m_hasFontFaceOnlyValues);
    int deletedProperties = 0;

    for (unsigned i = 0; i < m_numParsedProperties; ++i) {
        CSSProperty* property = m_parsedProperties[i];
        int id = property->id();
        if ((id == CSSPropertyFontWeight || id == CSSPropertyFontStyle || id == CSSPropertyFontVariant) && property->value()->isValueList()) {
            delete property;
            deletedProperties++;
        } else if (deletedProperties)
            m_parsedProperties[i - deletedProperties] = m_parsedProperties[i];
    }

    m_numParsedProperties -= deletedProperties;
}

WebKitCSSKeyframeRule* CSSParser::createKeyframeRule(CSSParserValueList* keys)
{
    // Create a key string from the passed keys
    String keyString;
    for (unsigned i = 0; i < keys->size(); ++i) {
        float key = (float) keys->valueAt(i)->fValue;
        if (i != 0)
            keyString += ",";
        keyString += String::number(key);
        keyString += "%";
    }

    RefPtr<WebKitCSSKeyframeRule> keyframe = WebKitCSSKeyframeRule::create(m_styleSheet);
    keyframe->setKeyText(keyString);
    keyframe->setDeclaration(CSSMutableStyleDeclaration::create(0, m_parsedProperties, m_numParsedProperties));

    clearProperties();

    WebKitCSSKeyframeRule* keyframePtr = keyframe.get();
    m_parsedStyleObjects.append(keyframe.release());
    return keyframePtr;
}

void CSSParser::invalidBlockHit()
{
    if (m_styleSheet && !m_hadSyntacticallyValidCSSRule)
        m_styleSheet->setHasSyntacticallyValidCSSHeader(false);
}

void CSSParser::updateLastSelectorLineAndPosition()
{
    m_lastSelectorLineNumber = m_lineNumber;
    markRuleBodyStart();
}

void CSSParser::markSelectorListStart()
{
    m_selectorListRange.start = yytext - m_data;
}

void CSSParser::markSelectorListEnd()
{
    if (!m_currentRuleData)
        return;
    UChar* listEnd = yytext;
    while (listEnd > m_data + 1) {
        if (isHTMLSpace(*(listEnd - 1)))
            --listEnd;
        else
            break;
    }
    m_selectorListRange.end = listEnd - m_data;
}

void CSSParser::markRuleBodyStart()
{
    unsigned offset = yytext - m_data;
    if (*yytext == '{')
        ++offset; // Skip the rule body opening brace.
    if (offset > m_ruleBodyRange.start)
        m_ruleBodyRange.start = offset;
    m_inStyleRuleOrDeclaration = true;
}

void CSSParser::markRuleBodyEnd()
{
    unsigned offset = yytext - m_data;
    if (offset > m_ruleBodyRange.end)
        m_ruleBodyRange.end = offset;
}

void CSSParser::markPropertyStart()
{
    if (!m_inStyleRuleOrDeclaration)
        return;
    m_propertyRange.start = yytext - m_data;
}

void CSSParser::markPropertyEnd(bool isImportantFound, bool isPropertyParsed)
{
    if (!m_inStyleRuleOrDeclaration)
        return;
    unsigned offset = yytext - m_data;
    if (*yytext == ';') // Include semicolon into the property text.
        ++offset;
    m_propertyRange.end = offset;
    if (m_propertyRange.start != UINT_MAX && m_currentRuleData) {
        // This stuff is only executed when the style data retrieval is requested by client.
        const unsigned start = m_propertyRange.start;
        const unsigned end = m_propertyRange.end;
        ASSERT(start < end);
        String propertyString = String(m_data + start, end - start).stripWhiteSpace();
        if (propertyString.endsWith(";", true))
            propertyString = propertyString.left(propertyString.length() - 1);
        Vector<String> propertyComponents;
        size_t colonIndex = propertyString.find(":");
        ASSERT(colonIndex != notFound);

        String name = propertyString.left(colonIndex).stripWhiteSpace();
        String value = propertyString.substring(colonIndex + 1, propertyString.length()).stripWhiteSpace();
        // The property range is relative to the declaration start offset.
        m_currentRuleData->styleSourceData->propertyData.append(
            CSSPropertySourceData(name, value, isImportantFound, isPropertyParsed, SourceRange(start - m_ruleBodyRange.start, end - m_ruleBodyRange.start)));
    }
    resetPropertyMarks();
}

static int cssPropertyID(const UChar* propertyName, unsigned length)
{
    if (!length)
        return 0;
    if (length > maxCSSPropertyNameLength)
        return 0;

    char buffer[maxCSSPropertyNameLength + 1 + 1]; // 1 to turn "apple"/"khtml" into "webkit", 1 for null character

    for (unsigned i = 0; i != length; ++i) {
        UChar c = propertyName[i];
        if (c == 0 || c >= 0x7F)
            return 0; // illegal character
        buffer[i] = toASCIILower(c);
    }
    buffer[length] = '\0';

    const char* name = buffer;
    if (buffer[0] == '-') {
        // If the prefix is -apple- or -khtml-, change it to -webkit-.
        // This makes the string one character longer.
        if (hasPrefix(buffer, length, "-apple-") || hasPrefix(buffer, length, "-khtml-")) {
            memmove(buffer + 7, buffer + 6, length + 1 - 6);
            memcpy(buffer, "-webkit", 7);
            ++length;
        }

        if (hasPrefix(buffer, length, "-webkit")) {
            if (!strcmp(buffer, "-webkit-box-sizing")) {
                // -webkit-box-sizing worked in Safari 4 and earlier.
                const char* const boxSizing = "box-sizing";
                name = boxSizing;
                length = strlen(boxSizing);
            } else if (!strcmp(buffer, "-webkit-opacity")) {
                // Honor -webkit-opacity as a synonym for opacity.
                // This was the only syntax that worked in Safari 1.1, and may be in use on some websites and widgets.
                const char* const opacity = "opacity";
                name = opacity;
                length = strlen(opacity);
#if PLATFORM(IOS)
            } else if (!strcmp(buffer, "-webkit-hyphenate-locale")) {
                // Worked in iOS 4.2.
                const char* const webkitLocale = "-webkit-locale";
                name = webkitLocale;
                length = strlen(webkitLocale);
#endif
            } else if (hasPrefix(buffer + 7, length - 7, "-border-")) {
                // -webkit-border-*-*-radius worked in Safari 4 and earlier. -webkit-border-radius syntax
                // differs from border-radius, so it is remains as a distinct property.
                if (!strcmp(buffer + 15, "top-left-radius")
                        || !strcmp(buffer + 15, "top-right-radius")
                        || !strcmp(buffer + 15, "bottom-right-radius")
                        || !strcmp(buffer + 15, "bottom-left-radius")) {
                    name = buffer + 8;
                    length -= 8;
                }
            }
        }
    }

    const Property* hashTableEntry = findProperty(name, length);
    return hashTableEntry ? hashTableEntry->id : 0;
}

int cssPropertyID(const String& string)
{
    return cssPropertyID(string.characters(), string.length());
}

int cssPropertyID(const CSSParserString& string)
{
    return cssPropertyID(string.characters, string.length);
}

int cssValueKeywordID(const CSSParserString& string)
{
    unsigned length = string.length;
    if (!length)
        return 0;
    if (length > maxCSSValueKeywordLength)
        return 0;

    char buffer[maxCSSValueKeywordLength + 1 + 1]; // 1 to turn "apple"/"khtml" into "webkit", 1 for null character

    for (unsigned i = 0; i != length; ++i) {
        UChar c = string.characters[i];
        if (c == 0 || c >= 0x7F)
            return 0; // illegal character
        buffer[i] = WTF::toASCIILower(c);
    }
    buffer[length] = '\0';

    if (buffer[0] == '-') {
        // If the prefix is -apple- or -khtml-, change it to -webkit-.
        // This makes the string one character longer.
        if (hasPrefix(buffer, length, "-apple-") || hasPrefix(buffer, length, "-khtml-")) {
            memmove(buffer + 7, buffer + 6, length + 1 - 6);
            memcpy(buffer, "-webkit", 7);
            ++length;
        }
    }

    const Value* hashTableEntry = findValue(buffer, length);
    return hashTableEntry ? hashTableEntry->id : 0;
}

// "ident" from the CSS tokenizer, minus backslash-escape sequences
static bool isCSSTokenizerIdentifier(const String& string)
{
    const UChar* p = string.characters();
    const UChar* end = p + string.length();

    // -?
    if (p != end && p[0] == '-')
        ++p;

    // {nmstart}
    if (p == end || !(p[0] == '_' || p[0] >= 128 || isASCIIAlpha(p[0])))
        return false;
    ++p;

    // {nmchar}*
    for (; p != end; ++p) {
        if (!(p[0] == '_' || p[0] == '-' || p[0] >= 128 || isASCIIAlphanumeric(p[0])))
            return false;
    }

    return true;
}

// "url" from the CSS tokenizer, minus backslash-escape sequences
static bool isCSSTokenizerURL(const String& string)
{
    const UChar* p = string.characters();
    const UChar* end = p + string.length();

    for (; p != end; ++p) {
        UChar c = p[0];
        switch (c) {
            case '!':
            case '#':
            case '$':
            case '%':
            case '&':
                break;
            default:
                if (c < '*')
                    return false;
                if (c <= '~')
                    break;
                if (c < 128)
                    return false;
        }
    }

    return true;
}

// We use single quotes for now because markup.cpp uses double quotes.
String quoteCSSString(const String& string)
{
    // For efficiency, we first pre-calculate the length of the quoted string, then we build the actual one.
    // Please see below for the actual logic.
    unsigned quotedStringSize = 2; // Two quotes surrounding the entire string.
    bool afterEscape = false;
    for (unsigned i = 0; i < string.length(); ++i) {
        UChar ch = string[i];
        if (ch == '\\' || ch == '\'') {
            quotedStringSize += 2;
            afterEscape = false;
        } else if (ch < 0x20 || ch == 0x7F) {
            quotedStringSize += 2 + (ch >= 0x10);
            afterEscape = true;
        } else {
            quotedStringSize += 1 + (afterEscape && (isASCIIHexDigit(ch) || ch == ' '));
            afterEscape = false;
        }
    }

    StringBuffer buffer(quotedStringSize);
    unsigned index = 0;
    buffer[index++] = '\'';
    afterEscape = false;
    for (unsigned i = 0; i < string.length(); ++i) {
        UChar ch = string[i];
        if (ch == '\\' || ch == '\'') {
            buffer[index++] = '\\';
            buffer[index++] = ch;
            afterEscape = false;
        } else if (ch < 0x20 || ch == 0x7F) { // Control characters.
            buffer[index++] = '\\';
            placeByteAsHexCompressIfPossible(ch, buffer, index, Lowercase);
            afterEscape = true;
        } else {
            // Space character may be required to separate backslash-escape sequence and normal characters.
            if (afterEscape && (isASCIIHexDigit(ch) || ch == ' '))
                buffer[index++] = ' ';
            buffer[index++] = ch;
            afterEscape = false;
        }
    }
    buffer[index++] = '\'';

    ASSERT(quotedStringSize == index);
    return String::adopt(buffer);
}

String quoteCSSStringIfNeeded(const String& string)
{
    return isCSSTokenizerIdentifier(string) ? string : quoteCSSString(string);
}

String quoteCSSURLIfNeeded(const String& string)
{
    return isCSSTokenizerURL(string) ? string : quoteCSSString(string);
}

bool isValidNthToken(const CSSParserString& token)
{
    // The tokenizer checks for the construct of an+b.
    // nth can also accept "odd" or "even" but should not accept any other token.
    return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even");
}

#define YY_DECL int CSSParser::lex()
#define yyconst const
typedef int yy_state_type;
typedef unsigned YY_CHAR;
// The following line makes sure we treat non-Latin-1 Unicode characters correctly.
#define YY_SC_TO_UI(c) (c > 0xff ? 0xff : c)
#define YY_DO_BEFORE_ACTION \
        yytext = yy_bp; \
        yyleng = (int) (yy_cp - yy_bp); \
        yy_hold_char = *yy_cp; \
        *yy_cp = 0; \
        yy_c_buf_p = yy_cp;
#define YY_BREAK break;
#define ECHO
#define YY_RULE_SETUP
#define INITIAL 0
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
#define yyterminate() yyTok = END_TOKEN; return yyTok
#define YY_FATAL_ERROR(a)
// The following line is needed to build the tokenizer with a condition stack.
// The macro is used in the tokenizer grammar with lines containing
// BEGIN(mediaqueries) and BEGIN(initial). yy_start acts as index to
// tokenizer transition table, and 'mediaqueries' and 'initial' are
// offset multipliers that specify which transitions are active
// in the tokenizer during in each condition (tokenizer state).
#define BEGIN yy_start = 1 + 2 *

#include "tokenizer.cpp"

}
