/// <summary>
        /// Which nodes are allowed in XML at this point?
        /// </summary>
        public string[] AtThisPosAllowedTags(XmlCursorPos cursorPosToCheck, bool allowPcDATA, bool allowComments)
        {
            // To avoid accidentally returning some changes, first clone the CursorPos
            var cursorPos = cursorPosToCheck.Clone();

#if ThinkLogging
            _thinkLog = new StringBuilder();
#endif

            var testPattern = this.GetAllTestPattern(cursorPos);

            // Write elements of valid test patterns into the result
            var result = new List <string>();
            foreach (var muster in testPattern)
            {
                if (muster.Success)
                {
                    if (muster.ElementName == null)
                    {
                        result.Add(""); // the existing element may be deleted
                    }
                    else
                    {
                        switch (muster.ElementName.ToLower())
                        {
                        case "#pcdata":
                            if (allowPcDATA)
                            {
                                result.Add(muster.ElementName);                  // This element may be inserted
                            }
                            break;

                        case "#comment":
                            if (allowComments)
                            {
                                result.Add(muster.ElementName);                    // This element may be inserted
                            }
                            break;

                        default:
                            result.Add(muster.ElementName);     // This element may be inserted
                            break;
                        }
                    }
                }
#if ThinkLogging
                _thinkLog.Append(muster.Summary + "\r\n");
#endif
            }

            return(result.ToArray());
        }
        /// <summary>
        /// Replaces the root node of the editor with the content of the clipboard
        /// </summary>
        private async Task <bool> ActionReplaceRootNodeByClipboardContent(SetUndoSnapshotOptions setUnDoSnapshot)
        {
            if (!ActionsAllowed)
            {
                return(false);
            }

            try
            {
                var text = await this.nativePlatform.Clipboard.GetText();

                using (var reader = new XmlTextReader(text, XmlNodeType.Element, null))
                {
                    reader.MoveToContent(); // Move to the cd element node.

                    // Create a new root node from the clipboard, from which we can then steal the children
                    var pasteNode = this.editorState.RootNode.OwnerDocument.ReadNode(reader);

                    if (pasteNode.Name != this.editorState.RootNode.Name)
                    {
                        // The node in the clipboard and the current root node do not have the same name
                        return(false); // not allowed
                    }

                    if (setUnDoSnapshot == SetUndoSnapshotOptions.Yes)
                    {
                        this.editorState.UndoHandler.SetSnapshot("replace root node by clipboard content", this.editorState.CursorRaw);
                    }

                    // Delete all children + attributes of the previous root node
                    this.editorState.RootNode.RemoveAll();

                    // Copy all attributes of the clipboard root node to the correct root node
                    while (pasteNode.Attributes.Count > 0)
                    {
                        var attrib = pasteNode.Attributes.Remove(pasteNode.Attributes[0]); // Remove from clipboard root node
                        this.editorState.RootNode.Attributes.Append(attrib);               // put to the right root node
                    }

                    var startPos = new XmlCursorPos();
                    startPos.SetPos(this.editorState.RootNode, XmlCursorPositions.CursorInsideTheEmptyNode);
                    XmlCursorPos endPos;

                    // Now insert all children of the virtual root node one after the other at the CursorPos
                    endPos = startPos.Clone(); // Before inserting start- and endPos are equal
                    while (pasteNode.ChildNodes.Count > 0)
                    {
                        var child = pasteNode.RemoveChild(pasteNode.FirstChild);
                        this.editorState.RootNode.AppendChild(child);
                    }
                    await this.editorState.CursorRaw.SetPositions(this.editorState.RootNode, XmlCursorPositions.CursorOnNodeStartTag, 0, throwChangedEventWhenValuesChanged : false);

                    await this.editorState.FireContentChangedEvent(needToSetFocusOnEditorWhenLost : false, forceFullRepaint : false);

                    return(true);
                }
            }
            catch (Exception e)
            {
                this.nativePlatform.LogError($"ActionReplaceRootNodeByClipboardContent: error for insert text 'text': {e.Message}");
                return(false);
            }
        }