public void DataAndValue ()
		{
			string val = "\t\t\r\n ";
			whitespace = doc2.CreateSignificantWhitespace (val);
			Assert.AreEqual (val, whitespace.Data, "#DataValue.1");
			Assert.AreEqual (val, whitespace.Value, "#DataValue.2");
			whitespace.Value = val + "\t";
			Assert.AreEqual (val + "\t", whitespace.Data, "#DataValue.3");
		}
		public void DataAndValue ()
		{
			string val = "\t\t\r\n ";
			whitespace = doc2.CreateSignificantWhitespace (val);
			AssertEquals ("#DataValue.1", val, whitespace.Data);
			AssertEquals ("#DataValue.2", val, whitespace.Value);
			whitespace.Value = val + "\t";
			AssertEquals ("#DataValue.3", val + "\t", whitespace.Data);
		}
		public void GetReady ()
		{
			document = new XmlDocument ();
			document.LoadXml ("<root><foo></foo></root>");
			XmlElement element = document.CreateElement ("foo");
			whitespace = document.CreateSignificantWhitespace ("\r\n");
			element.AppendChild (whitespace);

			doc2 = new XmlDocument ();
		}
		public void XmlSignificantWhitespaceBadConstructor ()
		{
			try {
				broken = document.CreateSignificantWhitespace ("black");				

			} catch (ArgumentException) {
				return;

			} catch (Exception) {
				Fail ("Incorrect Exception thrown.");
			}
		}
Esempio n. 5
0
        // LoadNodeDirect does not use creator functions on XmlDocument. It is used loading nodes that are children of entity nodes,
        // because we do not want to let users extend these (if we would allow this, XmlDataDocument would have a problem, because
        // they do not know that those nodes should not be mapped). It can be also used for an optimized load path when if the
        // XmlDocument is not extended if XmlDocumentType and XmlDeclaration handling is added.
        private XmlNode LoadNodeDirect()
        {
            XmlReader r      = _reader;
            XmlNode   parent = null;

            do
            {
                XmlNode node = null;
                switch (r.NodeType)
                {
                case XmlNodeType.Element:
                    bool       fEmptyElement = _reader.IsEmptyElement;
                    XmlElement element       = new XmlElement(_reader.Prefix, _reader.LocalName, _reader.NamespaceURI, _doc);
                    element.IsEmpty = fEmptyElement;

                    if (_reader.MoveToFirstAttribute())
                    {
                        XmlAttributeCollection attributes = element.Attributes;
                        do
                        {
                            XmlAttribute attr = LoadAttributeNodeDirect();
                            attributes.Append(attr);     // special case for load
                        } while (r.MoveToNextAttribute());
                    }

                    // recursively load all children.
                    if (!fEmptyElement)
                    {
                        parent.AppendChildForLoad(element, _doc);
                        parent = element;
                        continue;
                    }
                    else
                    {
                        node = element;
                        break;
                    }

                case XmlNodeType.EndElement:
                    Debug.Assert(parent.NodeType == XmlNodeType.Element);
                    if (parent.ParentNode == null)
                    {
                        return(parent);
                    }
                    parent = parent.ParentNode;
                    continue;

                case XmlNodeType.EntityReference:
                    node = LoadEntityReferenceNode(true);
                    break;

                case XmlNodeType.EndEntity:
                    continue;

                case XmlNodeType.Attribute:
                    node = LoadAttributeNodeDirect();
                    break;

                case XmlNodeType.SignificantWhitespace:
                    node = new XmlSignificantWhitespace(_reader.Value, _doc);
                    break;

                case XmlNodeType.Whitespace:
                    if (_preserveWhitespace)
                    {
                        node = new XmlWhitespace(_reader.Value, _doc);
                    }
                    else
                    {
                        continue;
                    }
                    break;

                case XmlNodeType.Text:
                    node = new XmlText(_reader.Value, _doc);
                    break;

                case XmlNodeType.CDATA:
                    node = new XmlCDataSection(_reader.Value, _doc);
                    break;

                case XmlNodeType.ProcessingInstruction:
                    node = new XmlProcessingInstruction(_reader.Name, _reader.Value, _doc);
                    break;

                case XmlNodeType.Comment:
                    node = new XmlComment(_reader.Value, _doc);
                    break;

                default:
                    throw UnexpectedNodeType(_reader.NodeType);
                }

                Debug.Assert(node != null);
                if (parent != null)
                {
                    parent.AppendChildForLoad(node, _doc);
                }
                else
                {
                    return(node);
                }
            }while (r.Read());

            return(null);
        }
Esempio n. 6
0
        // LoadNodeDirect does not use creator functions on XmlDocument. It is used loading nodes that are children of entity nodes, 
        // because we do not want to let users extend these (if we would allow this, XmlDataDocument would have a problem, because 
        // they do not know that those nodes should not be mapped). It can be also used for an optimized load path when if the 
        // XmlDocument is not extended if XmlDocumentType and XmlDeclaration handling is added.
        private XmlNode LoadNodeDirect()
        {
            XmlReader r = _reader;
            XmlNode parent = null;
            do
            {
                XmlNode node = null;
                switch (r.NodeType)
                {
                    case XmlNodeType.Element:
                        bool fEmptyElement = _reader.IsEmptyElement;
                        XmlElement element = new XmlElement(_reader.Prefix, _reader.LocalName, _reader.NamespaceURI, _doc);
                        element.IsEmpty = fEmptyElement;

                        if (_reader.MoveToFirstAttribute())
                        {
                            XmlAttributeCollection attributes = element.Attributes;
                            do
                            {
                                XmlAttribute attr = LoadAttributeNodeDirect();
                                attributes.Append(attr); // special case for load
                            } while (r.MoveToNextAttribute());
                        }

                        // recursively load all children.
                        if (!fEmptyElement)
                        {
                            parent.AppendChildForLoad(element, _doc);
                            parent = element;
                            continue;
                        }
                        else
                        {
                            node = element;
                            break;
                        }

                    case XmlNodeType.EndElement:
                        Debug.Assert(parent.NodeType == XmlNodeType.Element);
                        if (parent.ParentNode == null)
                        {
                            return parent;
                        }
                        parent = parent.ParentNode;
                        continue;

                    case XmlNodeType.EntityReference:
                        node = LoadEntityReferenceNode(true);
                        break;

                    case XmlNodeType.EndEntity:
                        continue;

                    case XmlNodeType.Attribute:
                        node = LoadAttributeNodeDirect();
                        break;

                    case XmlNodeType.SignificantWhitespace:
                        node = new XmlSignificantWhitespace(_reader.Value, _doc);
                        break;

                    case XmlNodeType.Whitespace:
                        if (_preserveWhitespace)
                        {
                            node = new XmlWhitespace(_reader.Value, _doc);
                        }
                        else
                        {
                            continue;
                        }
                        break;

                    case XmlNodeType.Text:
                        node = new XmlText(_reader.Value, _doc);
                        break;

                    case XmlNodeType.CDATA:
                        node = new XmlCDataSection(_reader.Value, _doc);
                        break;

                    case XmlNodeType.ProcessingInstruction:
                        node = new XmlProcessingInstruction(_reader.Name, _reader.Value, _doc);
                        break;

                    case XmlNodeType.Comment:
                        node = new XmlComment(_reader.Value, _doc);
                        break;

                    default:
                        throw UnexpectedNodeType(_reader.NodeType);
                }

                Debug.Assert(node != null);
                if (parent != null)
                {
                    parent.AppendChildForLoad(node, _doc);
                }
                else
                {
                    return node;
                }
            }
            while (r.Read());

            return null;
        }
Esempio n. 7
0
        private XmlNode LoadNodeDirect()
        {
            XmlNode   node2;
            XmlReader reader     = this.reader;
            XmlNode   parentNode = null;

Label_0009:
            node2 = null;
            switch (reader.NodeType)
            {
            case XmlNodeType.Element:
            {
                bool       isEmptyElement = this.reader.IsEmptyElement;
                XmlElement newChild       = new XmlElement(this.reader.Prefix, this.reader.LocalName, this.reader.NamespaceURI, this.doc)
                {
                    IsEmpty = isEmptyElement
                };
                if (this.reader.MoveToFirstAttribute())
                {
                    XmlAttributeCollection attributes = newChild.Attributes;
                    do
                    {
                        XmlAttribute attribute = this.LoadAttributeNodeDirect();
                        attributes.Append(attribute);
                    }while (reader.MoveToNextAttribute());
                }
                if (!isEmptyElement)
                {
                    parentNode.AppendChildForLoad(newChild, this.doc);
                    parentNode = newChild;
                    goto Label_01FC;
                }
                node2 = newChild;
                break;
            }

            case XmlNodeType.Attribute:
                node2 = this.LoadAttributeNodeDirect();
                break;

            case XmlNodeType.Text:
                node2 = new XmlText(this.reader.Value, this.doc);
                break;

            case XmlNodeType.CDATA:
                node2 = new XmlCDataSection(this.reader.Value, this.doc);
                break;

            case XmlNodeType.EntityReference:
                node2 = this.LoadEntityReferenceNode(true);
                break;

            case XmlNodeType.ProcessingInstruction:
                node2 = new XmlProcessingInstruction(this.reader.Name, this.reader.Value, this.doc);
                break;

            case XmlNodeType.Comment:
                node2 = new XmlComment(this.reader.Value, this.doc);
                break;

            case XmlNodeType.Whitespace:
                if (!this.preserveWhitespace)
                {
                    goto Label_01FC;
                }
                node2 = new XmlWhitespace(this.reader.Value, this.doc);
                break;

            case XmlNodeType.SignificantWhitespace:
                node2 = new XmlSignificantWhitespace(this.reader.Value, this.doc);
                break;

            case XmlNodeType.EndElement:
                if (parentNode.ParentNode != null)
                {
                    parentNode = parentNode.ParentNode;
                    goto Label_01FC;
                }
                return(parentNode);

            case XmlNodeType.EndEntity:
                goto Label_01FC;

            default:
                throw UnexpectedNodeType(this.reader.NodeType);
            }
            if (parentNode != null)
            {
                parentNode.AppendChildForLoad(node2, this.doc);
            }
            else
            {
                return(node2);
            }
Label_01FC:
            if (reader.Read())
            {
                goto Label_0009;
            }
            return(null);
        }
Esempio n. 8
0
        private XmlNode LoadEntityChildren() {
            XmlNode node = null;

            // We do not use creator functions on XmlDocument, b/c we do not want to let users extend the nodes that are children of entity nodes (also, if we do
            // this, XmlDataDocument will have a problem, b/c they do not know that those nodes should not be mapped).
            switch (reader.NodeType) {
                case XmlNodeType.EndElement:
                case XmlNodeType.EndEntity:
                    break;

                case XmlNodeType.Element: {
                    bool fEmptyElement = reader.IsEmptyElement;

                    XmlElement element = new XmlElement( reader.Prefix, reader.LocalName, reader.NamespaceURI, this.doc );
                    element.IsEmpty = fEmptyElement;

                    while(reader.MoveToNextAttribute()) {
                        XmlAttribute attr = (XmlAttribute) LoadEntityChildren();
                        element.Attributes.Append( attr );
                    }

                    // recursively load all children.
                    if (! fEmptyElement)
                        LoadEntityChildren( element );

                    node = element;
                    break;
                }

                case XmlNodeType.Attribute:
                    if (reader.IsDefault) {
                        XmlUnspecifiedAttribute attr = new XmlUnspecifiedAttribute( reader.Prefix, reader.LocalName, reader.NamespaceURI, this.doc );
                        LoadEntityAttributeChildren( attr );
                        attr.SetSpecified( false );
                        node = attr;
                    }
                    else {
                        XmlAttribute attr = new XmlAttribute( reader.Prefix, reader.LocalName, reader.NamespaceURI, this.doc );
                        LoadEntityAttributeChildren( attr );
                        node = attr;
                    }
                    break;

                case XmlNodeType.SignificantWhitespace:
                    node = new XmlSignificantWhitespace( reader.Value, this.doc );
                    break;

                case XmlNodeType.Whitespace:
                    if ( preserveWhitespace )
                        node = new XmlWhitespace( reader.Value, this.doc );
                    else {
                        // if preserveWhitespace is false skip all subsequent WS nodes and position on the first non-WS node
                        do {
                            if (! reader.Read() )
                                return null;
                        } while (reader.NodeType == XmlNodeType.Whitespace);
                        node = LoadEntityChildren();   // Skip WS node if preserveWhitespace is false
                    }
                    break;

                case XmlNodeType.Text:
                    node = new XmlText( reader.Value, this.doc );
                    break;

                case XmlNodeType.CDATA:
                    node = new XmlCDataSection( reader.Value, this.doc );
                    break;

                case XmlNodeType.EntityReference:{
                    XmlEntityReference eref = new XmlEntityReference( reader.Name, this.doc );
                    if ( reader.CanResolveEntity ) {
                        reader.ResolveEntity();
                        LoadEntityChildren( eref );
                        //what if eref doesn't have children at all? should we just put a Empty String text here?
                        if ( eref.ChildNodes.Count == 0 )
                            eref.AppendChild( new XmlText("") );
                    }
                    node = eref;
                    break;
                }

                case XmlNodeType.ProcessingInstruction:
                    node = new XmlProcessingInstruction( reader.Name, reader.Value, this.doc );
                    break;

                case XmlNodeType.Comment:
                    node = new XmlComment( reader.Value, this.doc );
                    break;

                default:
                    throw new InvalidOperationException(string.Format(Res.GetString(Res.Xdom_Load_NodeType),reader.NodeType.ToString()));
            }

            return node;
        }
		// Methods
		public override XmlNode CloneNode (bool deep)
		{
			XmlNode n = new XmlSignificantWhitespace (Data, OwnerDocument);
			return n;
		}
Esempio n. 10
0
        private XmlNode LoadEntityChildren()
        {
            XmlNode node = null;

            // We do not use creator functions on XmlDocument, b/c we do not want to let users extend the nodes that are children of entity nodes (also, if we do
            // this, XmlDataDocument will have a problem, b/c they do not know that those nodes should not be mapped).
            switch (reader.NodeType)
            {
            case XmlNodeType.EndElement:
            case XmlNodeType.EndEntity:
                break;

            case XmlNodeType.Element: {
                bool fEmptyElement = reader.IsEmptyElement;

                XmlElement element = new XmlElement(reader.Prefix, reader.LocalName, reader.NamespaceURI, this.doc);
                element.IsEmpty = fEmptyElement;

                while (reader.MoveToNextAttribute())
                {
                    XmlAttribute attr = (XmlAttribute)LoadEntityChildren();
                    element.Attributes.Append(attr);
                }

                // recursively load all children.
                if (!fEmptyElement)
                {
                    LoadEntityChildren(element);
                }

                node = element;
                break;
            }

            case XmlNodeType.Attribute:
                if (reader.IsDefault)
                {
                    XmlUnspecifiedAttribute attr = new XmlUnspecifiedAttribute(reader.Prefix, reader.LocalName, reader.NamespaceURI, this.doc);
                    LoadEntityAttributeChildren(attr);
                    attr.SetSpecified(false);
                    node = attr;
                }
                else
                {
                    XmlAttribute attr = new XmlAttribute(reader.Prefix, reader.LocalName, reader.NamespaceURI, this.doc);
                    LoadEntityAttributeChildren(attr);
                    node = attr;
                }
                break;

            case XmlNodeType.SignificantWhitespace:
                node = new XmlSignificantWhitespace(reader.Value, this.doc);
                break;

            case XmlNodeType.Whitespace:
                if (preserveWhitespace)
                {
                    node = new XmlWhitespace(reader.Value, this.doc);
                }
                else
                {
                    // if preserveWhitespace is false skip all subsequent WS nodes and position on the first non-WS node
                    do
                    {
                        if (!reader.Read())
                        {
                            return(null);
                        }
                    } while (reader.NodeType == XmlNodeType.Whitespace);
                    node = LoadEntityChildren();       // Skip WS node if preserveWhitespace is false
                }
                break;

            case XmlNodeType.Text:
                node = new XmlText(reader.Value, this.doc);
                break;

            case XmlNodeType.CDATA:
                node = new XmlCDataSection(reader.Value, this.doc);
                break;

            case XmlNodeType.EntityReference: {
                XmlEntityReference eref = new XmlEntityReference(reader.Name, this.doc);
                if (reader.CanResolveEntity)
                {
                    reader.ResolveEntity();
                    LoadEntityChildren(eref);
                    //what if eref doesn't have children at all? should we just put a Empty String text here?
                    if (eref.ChildNodes.Count == 0)
                    {
                        eref.AppendChild(new XmlText(""));
                    }
                }
                node = eref;
                break;
            }

            case XmlNodeType.ProcessingInstruction:
                node = new XmlProcessingInstruction(reader.Name, reader.Value, this.doc);
                break;

            case XmlNodeType.Comment:
                node = new XmlComment(reader.Value, this.doc);
                break;

            default:
                throw new InvalidOperationException(string.Format(Res.GetString(Res.Xdom_Load_NodeType), reader.NodeType.ToString()));
            }

            return(node);
        }
		public void InnerAndOuterXml ()
		{
			whitespace = doc2.CreateSignificantWhitespace ("\r\n\t ");
			AssertEquals (String.Empty, whitespace.InnerXml);
			AssertEquals ("\r\n\t ", whitespace.OuterXml);
		}
Esempio n. 12
0
        // Used by the ReadNode method for recursively building a DOM subtree.
        internal XmlNode ReadNodeInternal(XmlReader r)
        {
            switch (r.NodeType)
            {
            case XmlNodeType.Attribute:
            {
                // create the attribute
                XmlAttribute att = CreateAttribute
                                       (r.Prefix, r.LocalName, r.NamespaceURI);

                // read and append the children
                ReadChildren(r, att);

                // return the attribute
                return(att);
            }
            // Not reached.

            case XmlNodeType.CDATA:
            {
                // create the character data section
                XmlCDataSection cdata = CreateCDataSection(r.Value);

                // advance the reader to the next node
                r.Read();

                // return the character data section
                return(cdata);
            }
            // Not reached.

            case XmlNodeType.Comment:
            {
                // create the comment
                XmlComment comment = CreateComment(r.Value);

                // advance the reader to the next node
                r.Read();

                // return the comment
                return(comment);
            }
            // Not reached.

            case XmlNodeType.DocumentType:
            {
                // create the document type
                XmlDocumentType doctype = CreateDocumentType
                                              (r.Name, r["PUBLIC"], r["SYSTEM"], r.Value);

                // advance the reader to the next node
                r.Read();

                // return the document type
                return(doctype);
            }
            // Not reached.

            case XmlNodeType.Element:
            {
                // create the element
                XmlElement elem = CreateElement
                                      (r.Prefix, r.LocalName, r.NamespaceURI);
                bool isEmptyElement = r.IsEmptyElement;

                // read the attributes
                while (r.MoveToNextAttribute())
                {
                    XmlAttribute att = (XmlAttribute)ReadNodeInternal(r);
                    elem.SetAttributeNode(att);
                }
                r.MoveToElement();

                // return now if there are no children
                if (isEmptyElement)
                {
                    // advance the reader to the next node
                    r.Read();

                    // return the empty element
                    return(elem);
                }

                elem.IsEmpty = isEmptyElement;

                // read and append the children
                ReadChildren(r, elem);

                // return the element
                return(elem);
            }
            // Not reached.

            case XmlNodeType.DocumentFragment:
            case XmlNodeType.EndElement:
            case XmlNodeType.EndEntity:
            case XmlNodeType.Entity:
            case XmlNodeType.Notation:
            {
                // TODO

                // advance the reader to the next node
                r.Read();

                // nothing to return
                return(null);
            }
            // Not reached.

            case XmlNodeType.EntityReference:
            {
                // create the entity reference
                XmlEntityReference er = CreateEntityReference(r.Name);

                // advance the reader to the next node
                r.Read();

                // return the entity reference
                return(er);
            }
            // Not reached.

            case XmlNodeType.ProcessingInstruction:
            {
                // create the processing instruction
                XmlProcessingInstruction pi = CreateProcessingInstruction
                                                  (r.Name, r.Value);

                // advance the reader to the next node
                r.Read();

                // return the processing instruction
                return(pi);
            }
            // Not reached.

            case XmlNodeType.SignificantWhitespace:
            {
                // create the significant whitespace
                XmlSignificantWhitespace sws = CreateSignificantWhitespace
                                                   (r.Value);

                // advance the reader to the next node
                r.Read();

                // return the significant whitespace
                return(sws);
            }
            // Not reached.

            case XmlNodeType.Text:
            {
                // create the text
                XmlText text = CreateTextNode(r.Value);

                // advance the reader to the next node
                r.Read();

                // return the text
                return(text);
            }
            // Not reached.

            case XmlNodeType.Whitespace:
            {
                // if whitespace preservation is off, skip whitespace
                if (!preserveWhitespace)
                {
                    while (r.Read())
                    {
                        if (r.NodeType != XmlNodeType.Whitespace)
                        {
                            return(null);
                        }
                    }
                    return(null);
                }

                // create the whitespace
                XmlWhitespace ws = CreateWhitespace(r.Value);

                // advance the reader to the next node
                r.Read();

                // return the whitespace
                return(ws);
            }
            // Not reached.

            case XmlNodeType.XmlDeclaration:
            {
                // set up the defaults
                String e = String.Empty;
                String s = String.Empty;

                // read the version
                r.MoveToNextAttribute();

                // read the optional attributes
                if (r.MoveToNextAttribute())
                {
                    if (r.Name == "encoding")
                    {
                        e = r.Value;
                        if (r.MoveToNextAttribute())
                        {
                            s = r.Value;
                        }
                    }
                    else
                    {
                        s = r.Value;
                    }
                }

                // create the xml declaration
                XmlDeclaration xml = CreateXmlDeclaration("1.0", e, s);

                // advance the reader to the next node
                r.Read();

                // return the xml declaration
                return(xml);
            }
            // Not reached.

            default:
            {
                throw new InvalidOperationException(/* TODO */);
            }
                // Not reached.
            }
        }
Esempio n. 13
0
        // Methods
        public override XmlNode CloneNode(bool deep)
        {
            XmlNode n = new XmlSignificantWhitespace(Data, OwnerDocument);

            return(n);
        }
        private XmlNode LoadNodeDirect()
        {
            XmlNode node2;
            XmlReader reader = this.reader;
            XmlNode parentNode = null;
        Label_0009:
            node2 = null;
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                {
                    bool isEmptyElement = this.reader.IsEmptyElement;
                    XmlElement newChild = new XmlElement(this.reader.Prefix, this.reader.LocalName, this.reader.NamespaceURI, this.doc) {
                        IsEmpty = isEmptyElement
                    };
                    if (this.reader.MoveToFirstAttribute())
                    {
                        XmlAttributeCollection attributes = newChild.Attributes;
                        do
                        {
                            XmlAttribute attribute = this.LoadAttributeNodeDirect();
                            attributes.Append(attribute);
                        }
                        while (reader.MoveToNextAttribute());
                    }
                    if (!isEmptyElement)
                    {
                        parentNode.AppendChildForLoad(newChild, this.doc);
                        parentNode = newChild;
                        goto Label_01FC;
                    }
                    node2 = newChild;
                    break;
                }
                case XmlNodeType.Attribute:
                    node2 = this.LoadAttributeNodeDirect();
                    break;

                case XmlNodeType.Text:
                    node2 = new XmlText(this.reader.Value, this.doc);
                    break;

                case XmlNodeType.CDATA:
                    node2 = new XmlCDataSection(this.reader.Value, this.doc);
                    break;

                case XmlNodeType.EntityReference:
                    node2 = this.LoadEntityReferenceNode(true);
                    break;

                case XmlNodeType.ProcessingInstruction:
                    node2 = new XmlProcessingInstruction(this.reader.Name, this.reader.Value, this.doc);
                    break;

                case XmlNodeType.Comment:
                    node2 = new XmlComment(this.reader.Value, this.doc);
                    break;

                case XmlNodeType.Whitespace:
                    if (!this.preserveWhitespace)
                    {
                        goto Label_01FC;
                    }
                    node2 = new XmlWhitespace(this.reader.Value, this.doc);
                    break;

                case XmlNodeType.SignificantWhitespace:
                    node2 = new XmlSignificantWhitespace(this.reader.Value, this.doc);
                    break;

                case XmlNodeType.EndElement:
                    if (parentNode.ParentNode != null)
                    {
                        parentNode = parentNode.ParentNode;
                        goto Label_01FC;
                    }
                    return parentNode;

                case XmlNodeType.EndEntity:
                    goto Label_01FC;

                default:
                    throw UnexpectedNodeType(this.reader.NodeType);
            }
            if (parentNode != null)
            {
                parentNode.AppendChildForLoad(node2, this.doc);
            }
            else
            {
                return node2;
            }
        Label_01FC:
            if (reader.Read())
            {
                goto Label_0009;
            }
            return null;
        }