private ICollection<Tag> Tags(Tokenizer.Tokenizer tokenizer)
{
// This function needs some refactoring.
List<Tag> tags = new List<Tag>();
while (tokenizer.Peek().GetType() != typeof (ClosingBrace))
{
Tag tag = new Tag {Key = Text(tokenizer)};
Equals(tokenizer);
AbstractToken startToken = ValueStart(tokenizer);
List<AbstractToken> tokens = new List<AbstractToken>();
bool keepProcessing = true;
int balance = 1;
while (keepProcessing)
{
Type nextTokenType = tokenizer.Peek().GetType();
if (nextTokenType == typeof (OpeningBrace))
{
balance++;
}
if ( (startToken.GetType() == typeof(OpeningBrace) && nextTokenType == typeof (ClosingBrace)))
{
if (balance == 1)
{
keepProcessing = false;
ValueStop(tokenizer);
}
}
if (nextTokenType == typeof(ClosingBrace))
{
if (balance > 1)
{
balance--;
}
}
// Double quotes are much more difficult to handle then the braces. The problem is that there is no distinction between
// start and stop quotes. This means we need to look forward to see what is behind the quote to see if it is a quote @ the end
// or the start of a new quote.
if (nextTokenType == typeof (ValueQuote))
{
AbstractToken quote = tokenizer.NextToken();
Type nextType = tokenizer.Peek().GetType();
if ((nextType == typeof(ClosingBrace) && balance == 1) ||
nextType == typeof(Comma))
{
// end of line found.
keepProcessing = false;
}
else
{
tokens.Add(quote);
continue;
}
}
if (keepProcessing)
{
tokens.Add(tokenizer.NextToken());
}
}
tag.Value = tokens.Aggregate("", (s, token) => s + token.RawValue);
Comma(tokenizer, true);
NewLine(tokenizer, true);
tags.Add(tag);
}
return tags;
}