public IEnumerator <TheaterBlock> GetEnumerator()
        {
            Stack <TheaterBlock> stack = new Stack <TheaterBlock>();

            for (int i = Root.Count - 1; i >= 0; --i)
            {
                stack.Push(Root[i]);
            }

            while (stack.Count > 0)
            {
                TheaterBlock block = stack.Pop();
                yield return(block);

                if (block.IsContainer)
                {
                    for (int i = block.Childs.Count - 1; i >= 0; --i)
                    {
                        stack.Push(block.Childs[i]);
                    }
                }
            }
        }
        public void ValidateToken()
        {
            int level = 0;

            for (var iter = GetEnumerator(); iter.MoveNext();)
            {
                TheaterBlock block = iter.Current;
                if (block.IsContainer)
                {
                    switch (level)
                    {
                    case 0:
                        if (block.Key.CompareTo("theater") != 0)
                        {
                            throw new Exception("Syntax error(" + block.Line + "): First collection must be \"theater\".");
                        }
                        break;

                    case 1:
                        bool contain = false;
                        foreach (string cat in CATEGORIS)
                        {
                            if (block.Key.CompareTo(cat) == 0)
                            {
                                contain = true;
                                break;
                            }
                        }

                        if (!contain)
                        {
                            StringBuilder builder = new StringBuilder("Syntax error(");
                            builder.Append(block.Line);
                            builder.Append("): Second collection must be one of the next.\n");
                            foreach (string cat in CATEGORIS)
                            {
                                builder.Append(cat);
                                builder.Append(", ");
                            }
                            builder.Remove(builder.Length - 2, 2);
                            throw new Exception(builder.ToString());
                        }
                        break;

                    default:
                        break;
                    }
                    level++;
                }
                else
                {
                    switch (block.Key)
                    {
                    case "#base":
                        if (level > 0)
                        {
                            throw new Exception("Syntax error(" + block.Line + "): \"#base\" must be top of file.");
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
        }
        public void Tokenize(string theater)
        {
            int currentLine = 1;

            theater = theater.Trim();
            Stack <List <TheaterBlock> > stack = new Stack <List <TheaterBlock> >();

            stack.Push(Root);

            string        key                = null;
            StringBuilder builder            = new StringBuilder();
            bool          buildingIdentifier = false;
            bool          isComment          = false;

            while (!string.IsNullOrEmpty(theater))
            {
                char c = theater[0];
                theater = theater.Substring(1);
                switch (c)
                {
                case '/':
                    if (theater[0] == '/')
                    {
                        isComment = true;
                        theater   = theater.Substring(1);
                    }
                    break;

                case '\"':
                    if (isComment)
                    {
                        break;
                    }
                    if (buildingIdentifier == false)
                    {
                        buildingIdentifier = true;
                    }
                    else
                    {
                        buildingIdentifier = false;
                        if (key == null)
                        {
                            key = builder.ToString();
                        }
                        else
                        {
                            string       value = builder.ToString();
                            TheaterBlock blk   = new TheaterBlock(key, value, stack.Count - 1);
                            blk.Line = currentLine;
                            stack.Peek().Add(blk);
                            key = null;
                        }
                        builder.Clear();
                    }
                    break;

                case '{':
                    if (isComment)
                    {
                        break;
                    }
                    if (buildingIdentifier)
                    {
                        throw new Exception("Invalid syntax(" + currentLine + "): Cannot use brace as identifier.");
                    }
                    if (key == null)
                    {
                        throw new Exception("Invalid syntax(" + currentLine + "): No identifier for this collection found.");
                    }
                    TheaterBlock block = new TheaterBlock(key, new List <TheaterBlock>(), stack.Count - 1);
                    block.Line = currentLine;
                    key        = null;
                    stack.Peek().Add(block);
                    stack.Push(block.Childs);
                    break;

                case '}':
                    if (isComment)
                    {
                        break;
                    }
                    if (buildingIdentifier)
                    {
                        throw new Exception("Invalid syntax(" + currentLine + "): Cannot use brace as identifier.");
                    }
                    stack.Pop();
                    break;

                case ' ':
                    if (isComment)
                    {
                        break;
                    }
                    if (buildingIdentifier)
                    {
                        builder.Append(c);
                        break;
                    }
                    break;

                case '\t':
                    if (isComment)
                    {
                        break;
                    }
                    if (buildingIdentifier)
                    {
                        throw new Exception("Invalid syntax(" + currentLine + "): Cannot use tab character as identifier.");
                    }
                    break;

                case '\n':
                    isComment = false;
                    currentLine++;
                    if (buildingIdentifier)
                    {
                        throw new Exception("Invalid syntax(" + currentLine + "): Cannot use new line character as identifier.");
                    }
                    break;

                default:
                    if (isComment)
                    {
                        break;
                    }
                    if (buildingIdentifier)
                    {
                        builder.Append(c);
                        break;
                    }
                    break;
                }
            }

            if (stack.Count != 1)
            {
                throw new Exception("Invalid syntax(" + currentLine + "): Number of braces does not match.");
            }
        }