Наследование: SyntaxTreeNode
        static SyntaxTreeNode CreateNode(BBTag[] allowedTags, bool allowText)
        {
            switch (PexChoose.ValueFromRange("type", allowText ? 0 : 1, 2))
            {
                case 0:
                    var text = PexChoose.Value<string>("text");
                    PexAssume.IsTrue(!String.IsNullOrEmpty(text));
                    return new TextNode(text);
                case 1:
                    var tag = allowedTags[PexChoose.ValueFromRange("tag", 0, allowedTags.Length)];
                    var node = new TagNode(tag);

                    AddSubnodes(allowedTags, node);

                    if (tag.Attributes != null)
                    {
                        var selectedIds = new List<string>();
                        foreach (var attr in tag.Attributes)
                        {
                            if (!selectedIds.Contains(attr.ID) && PexChoose.Value<bool>("include"))
                            {
                                var val = PexChoose.Value<string>("val");
                                PexAssume.IsTrue(val != null);
                                PexAssume.IsTrue(val.IndexOfAny("[] ".ToCharArray()) == -1);
                                node.AttributeValues[attr] = val;
                                selectedIds.Add(attr.ID);
                            }
                        }
                    }
                    return node;
                default:
                    PexAssume.Fail();
                    return null;
            }
        }
        protected internal virtual SyntaxTreeNode Visit(TagNode node)
        {
            if (node == null) return null;

            var modifiedSubNodes = GetModifiedSubNodes(node);

            if (modifiedSubNodes == null)
                return node; //unmodified
            else
                return node.SetSubNodes(modifiedSubNodes); //subnodes were modified
        }
 protected internal override SyntaxTreeNode Visit(TagNode node)
 {
     var baseResult = base.Visit(node);
     return baseResult.SetSubNodes(baseResult.SubNodes.Concat(new[] { new TextNode("z") }));
 }
 protected internal override SyntaxTreeNode Visit(TagNode node)
 {
     var baseResult = base.Visit(node);
     if (!PexChoose.Value<bool>("x")) return baseResult;
     return baseResult.SetSubNodes(baseResult.SubNodes.ToList());
 }
        TagNode ParseTagStart(string input, ref int pos)
        {
            var end = pos;

            if (!ParseChar(input, ref end, '[')) return null;

            var tagName = ParseName(input, ref end);
            if (tagName == null) return null;

            var tag = Tags.SingleOrDefault(t => t.Name.Equals(tagName, StringComparison.OrdinalIgnoreCase));
            if (tag == null && ErrorOrReturn("UnknownTag", tagName)) return null;

            var result = new TagNode(tag);

            var defaultAttrValue = ParseAttributeValue(input, ref end, tag.GreedyAttributeProcessing);
            if (defaultAttrValue != null)
            {
                var attr = tag.FindAttribute("");
                if (attr == null && ErrorOrReturn("UnknownAttribute", tag.Name, "\"Default Attribute\"")) return null;
                result.AttributeValues.Add(attr, defaultAttrValue);
            }

            while (true)
            {
                ParseWhitespace(input, ref end);
                var attrName = ParseName(input, ref end);
                if (attrName == null) break;

                var attrVal = ParseAttributeValue(input, ref end);
                if (attrVal == null && ErrorOrReturn("")) return null;

                if (tag.Attributes == null && ErrorOrReturn("UnknownTag", tag.Name)) return null;
                var attr = tag.FindAttribute(attrName);
                if (attr == null && ErrorOrReturn("UnknownTag", tag.Name, attrName)) return null;

                if (result.AttributeValues.ContainsKey(attr) && ErrorOrReturn("DuplicateAttribute", tagName, attrName)) return null;
                result.AttributeValues.Add(attr, attrVal);
            }
            if (!ParseChar(input, ref end, ']') && ErrorOrReturn("TagNotClosed", tagName)) return null;

            ParseWhitespace(input, ref end);

            pos = end;
            return result;
        }