protected virtual bool ParseArguments(ItemFactory itemFactory, ITextProvider text, TokenStream tokens)
        {
            if (tokens.CurrentToken.IsFunctionTerminator())
            {
                // There could be functions without arguments (like "filter: mask();")
                return(false);
            }

            while (!tokens.CurrentToken.IsFunctionTerminator())
            {
                ParseItem fa = CreateArgumentObject(this, itemFactory, Arguments.Count);

                if (fa.Parse(itemFactory, text, tokens))
                {
                    fa.Context = GetArgumentContext(Arguments.Count);
                    Children.Add(fa);
                    Arguments.Add(fa);
                }
                else
                {
                    // Don't know what this is
                    Children.AddUnknownAndAdvance(itemFactory, text, tokens, ParseErrorType.UnexpectedToken);
                }
            }

            FunctionArgument lastArgument = (Arguments.Count > 0) ? Arguments[Arguments.Count - 1] as FunctionArgument : null;

            if (lastArgument != null && lastArgument.Comma != null && lastArgument == Children[Children.Count - 1])
            {
                Children.AddParseError(ParseErrorType.FunctionArgumentMissing);
            }

            return(true);
        }
        /// <summary>
        /// This helps the ColorParser class to figure out the values of each color argument.
        /// If the output argumentValue is float.NaN then the argument can still be valid, but
        /// its actualy value cannot be determined.
        /// </summary>
        internal virtual bool GetColorArgumentValue(int argumentIndex, bool looseParsing, out float argumentValue)
        {
            argumentValue = 0;

            FunctionArgument colorArgument = (argumentIndex >= 0 && argumentIndex < Arguments.Count)
                ? Arguments[argumentIndex] as FunctionArgument
                : null;

            // Make sure the argument has the right number of children

            if (colorArgument == null ||
                colorArgument.ArgumentItems.Count == 0 ||
                (!looseParsing && colorArgument.ArgumentItems.Count != 1))
            {
                return(false);
            }

            ParseItem colorNumber = colorArgument.ArgumentItems[0];
            UnitType  unitType    = PropertyValueHelpers.GetUnitType(colorNumber);

            if (argumentIndex > 3)
            {
                // No color function has more than four arguments
                return(false);
            }
            else if (argumentIndex == 3)
            {
                // It's the alpha value
                if (ColorFunction == ColorFunctionType.Rgba || ColorFunction == ColorFunctionType.Hsla)
                {
                    if (PropertyValueHelpers.IsValidNumber(colorNumber))
                    {
                        if (float.TryParse(colorNumber.Text, NumberStyles.Number, NumberFormatInfo.InvariantInfo, out argumentValue))
                        {
                            return(true);
                        }
                    }
                }
            }
            else if (ColorFunction == ColorFunctionType.Rgb || ColorFunction == ColorFunctionType.Rgba)
            {
                // Red, Green, and Blue are always a <percentage> or <integer>

                if (unitType == UnitType.Percentage)
                {
                    if (float.TryParse(colorNumber.Text.TrimEnd('%'), NumberStyles.Number, NumberFormatInfo.InvariantInfo, out argumentValue))
                    {
                        argumentValue /= 100.0f;
                        return(true);
                    }
                }
                else if (PropertyValueHelpers.IsValidInteger(colorNumber))
                {
                    if (int.TryParse(colorNumber.Text, out int intValue))
                    {
                        argumentValue = intValue / 255.0f;
                        return(true);
                    }
                }
            }
            else if (argumentIndex == 0)
            {
                // Hue is always a <number>

                if (PropertyValueHelpers.IsValidNumber(colorNumber))
                {
                    if (float.TryParse(colorNumber.Text, NumberStyles.Number, NumberFormatInfo.InvariantInfo, out argumentValue))
                    {
                        argumentValue /= 360.0f;
                        return(true);
                    }
                }
            }
            else
            {
                // Saturation and Lightness are always a percentage

                if (unitType == UnitType.Percentage)
                {
                    if (float.TryParse(colorNumber.Text.TrimEnd('%'), NumberStyles.Number, NumberFormatInfo.InvariantInfo, out argumentValue))
                    {
                        argumentValue /= 100.0f;
                        return(true);
                    }
                }
            }

            return(false);
        }