public XmlTreeNode GetTreeNode(XmlDocument owner, XmlTreeNode target, XmlTreeView view)
        {
            XmlTreeNode node = view.CreateTreeNode();

            if (this.img == -1 && this.xml != null){
                Regex regex = new Regex(@"[:_.\w]+\s*=\s*(""[^""]*"")|('[^']*')\s*");
                Match m = regex.Match(xml);
                string trimmed = xml.Trim();
                if (m.Success && m.Index == 0 && m.Length == xml.Length) {
                    nodeType = (int)XmlNodeType.Attribute;
                    img = (int)NodeImage.Attribute - 1;
                } else if (trimmed.StartsWith("<?")) {
                    nodeType = (int)XmlNodeType.ProcessingInstruction;
                    img = (int)NodeImage.PI - 1;
                } else if (trimmed.StartsWith("<!--")) {
                    nodeType = (int)XmlNodeType.Comment;
                    img = (int)NodeImage.Comment - 1;
                } else if (trimmed.StartsWith("<![CDATA[")) {
                    nodeType = (int)XmlNodeType.CDATA;
                    img = (int)NodeImage.CData - 1;
                } else if (trimmed.StartsWith("<")) {
                    nodeType = (int)XmlNodeType.Element;
                    img = (int)NodeImage.Element - 1;
                } else {
                    nodeType = (int)XmlNodeType.Text;
                    img = (int)NodeImage.Text - 1;
                }
            }

            XmlNode xn = null;
            XmlNode context = (target != null) ? target.Node : owner;

            if (this.nodeType == (int)XmlNodeType.Attribute) {
                int i = this.xml.IndexOf('=');
                if (i > 0) {
                    string name = this.xml.Substring(0, i).Trim();
                    XmlName qname = XmlHelpers.ParseName(context, name, XmlNodeType.Attribute);
                    xn = owner.CreateAttribute(qname.Prefix, qname.LocalName, qname.NamespaceUri);
                    string s = this.xml.Substring(i + 1).Trim();
                    if (s.Length > 2) {
                        char quote = s[0];
                        s = s.Substring(1, s.Length - 2); // strip off quotes
                        // un-escape quotes in the value.
                        xn.Value = s.Replace(quote == '\'' ? "&apos;" : "&quot;", quote.ToString());
                    }
                }

            } else {
                XmlNamespaceManager nsmgr = XmlHelpers.GetNamespaceScope(context);
                XmlParserContext pcontext = new XmlParserContext(owner.NameTable, nsmgr, null, XmlSpace.None);
                XmlTextReader r = null;
                if (this.xml != null) {
                    r = new XmlTextReader(this.xml, XmlNodeType.Element, pcontext);
                } else {
                    r = new XmlTextReader(this.stm, XmlNodeType.Element, pcontext);
                }
                r.WhitespaceHandling = WhitespaceHandling.Significant;

                // TODO: add multi-select support, so we can insert multiple nodes also.
                // And find valid nodes (for example, don't attempt to insert Xml declaration
                // if target node is not at the top of the document, etc).
                // For now we just favor XML elements over other node types.
                ArrayList list = new ArrayList();
                while (true){
                    XmlNode rn = owner.ReadNode(r);
                    if (rn == null)
                        break;
                    if (rn is XmlElement){
                        xn = rn;
                        NormalizeNamespaces((XmlElement)rn, nsmgr);
                    }
                    list.Add(rn);
                }
                if (xn == null && list.Count>0)
                    xn = list[0] as XmlNode;
            }
            node.Node = xn;

            if (!(xn is XmlAttribute)) {
                view.Invalidate();
                if (xn is XmlElement){
                    if (node.Nodes.Count <= 1){
                        this.img = ((int)NodeImage.Leaf -1);
                    }
                }
            }
            return node;
        }
 /// <summary>
 /// Insert a new element as a sibling or child of current node. This command can create
 /// new XmlTreeNodes and new XmlNodes to go with it, or it can 
 /// </summary>
 public InsertNode(XmlTreeView view)
 {
     this.view = view;
     this.newNode = view.CreateTreeNode();
     this.doc = view.Model.Document;
     this.position = InsertPosition.Child;
 }
        /// <summary>
        /// Move or copy a node from one place to another place in the tree.
        /// </summary>
        /// <param name="view">The MyTreeView that we are inserting into</param>
        /// <param name="source">The node that we are moving.  This node may not be in the tree
        /// and that is ok, so it might be a node that is being cut&paste from another process
        /// for example</param>
        /// <param name="target">The existing node that establishes where in the tree we want
        /// to move the source node to</param>
        /// <param name="where">The position relative to the target node (before or after)</param>
        /// <param name="copy">Whether we are moving or copying the source node</param>
        public MoveNode(XmlTreeView view, XmlTreeNode source, XmlTreeNode target, InsertPosition where, bool copy)
        {
            XmlNode sn = source.Node;
            XmlNode dn = target.Node;

            this.copy = copy;
            TreeView tv = view.TreeView;
            XmlDocument doc = view.Model.Document;
            this.view = view;
            this.sourcePosition = source.Index;

            view.Model.BeginUpdate();
            try {
                if (copy) {
                    this.wasExpanded = source.IsExpanded;
                    XmlTreeNode newSource = view.CreateTreeNode();
                    if (sn != null) {
                        sn = sn.CloneNode(true);
                        newSource.Node = sn;
                    }
                    source = newSource;
                }

                this.sourceParent = new TreeParent(tv, doc, source);
                this.tp = new TreeParent(tv, doc, target);

                // normalize destination based on source node type.
                // for example, if source is an attribute, then it can only be
                // inserted amongst attributes of another node.
                if (tp.IsRoot && where != InsertPosition.Child) {
                    if (sn is XmlAttribute)
                        throw new Exception(SR.RootLevelAttributes);
                    if (sn is XmlText || sn is XmlCDataSection)
                        throw new Exception(SR.RootLevelText);
                    if (sn is XmlElement && sn.OwnerDocument.DocumentElement != null && sn.OwnerDocument.DocumentElement != sn)
                        throw new Exception(SR.RootLevelElements);
                    if (dn is XmlDeclaration && where == InsertPosition.Before)
                        throw new Exception(SR.RootLevelBeforeXmlDecl);
                }
                if (where != InsertPosition.Child) {
                    if (sn is XmlAttribute) {
                        if (!(dn is XmlAttribute)) {
                            if (tp.AttributeCount != 0) {
                                // move target to valid location for attributes.
                                target = tp.GetChild(tp.AttributeCount - 1);
                                where = InsertPosition.After;
                            } else {
                                // append the attribute.
                                where = InsertPosition.Child;
                                target = (XmlTreeNode)target.Parent;
                            }

                        }
                    } else if (dn is XmlAttribute) {
                        if (!(sn is XmlAttribute)) {
                            int skip = tp.AttributeCount;
                            if (tp.Count > skip) {
                                // Move non-attribute down to beginning of child elements.
                                target = tp.GetChild(skip);
                                where = InsertPosition.Before;
                            } else {
                                // append the node.
                                where = InsertPosition.Child;
                                target = (XmlTreeNode)target.Parent;
                            }
                        }
                    }
                }
                this.source = source;
                this.target = target;
                this.where = where;
                this.tp = new TreeParent(tv, doc, target);

                if (where == InsertPosition.Child) {
                    this.tp.SetParent(target);
                }
            } finally {
                view.Model.EndUpdate();
            }
        }