/// <summary>
        /// Inserts the specified text at the current cursor position, if possible
        /// </summary>
        private async Task InsertText(XmlCursor cursor, string text, XmlRules xmlRules)
        {
            XmlCursorPos insertPos;

            // If something is selected, then delete it first, because it will be replaced by the new text
            XmlCursor deleteArea = cursor.Clone();
            await deleteArea.OptimizeSelection();

            var deleteResult = await XmlCursorSelectionHelper.DeleteSelection(deleteArea);

            if (deleteResult.Success)
            {
                insertPos = deleteResult.NewCursorPosAfterDelete;
            }
            else
            {
                insertPos = cursor.StartPos.Clone();
            }

            // insert the specified text at the cursor position
            var replacementNode = InsertAtCursorPosHelper.InsertText(insertPos, text, xmlRules).ReplaceNode;

            if (replacementNode != null)
            {
                // Text could not be inserted because a node input was converted from text input.
                // Example: In the AIML template, * is pressed, and a <star> is inserted there instead
                InsertAtCursorPosHelper.InsertXmlNode(insertPos, replacementNode, xmlRules, false);
            }

            // then the cursor is only one line behind the inserted text
            await cursor.SetPositions(insertPos.ActualNode, insertPos.PosOnNode, insertPos.PosInTextNode, throwChangedEventWhenValuesChanged : false);
        }
        /// <summary>
        /// FInserts the specified node at the current cursor position, if possible
        /// </summary>
        private async Task XMLNodeEinfuegen(XmlCursor cursor, XmlNode node, XmlRules xmlRules, bool setNewCursorPosBehindNewInsertedNode)
        {
            // If something is selected, then delete it first, because it will be replaced by the new text
            XmlCursor deleteArea = cursor.Clone();
            await deleteArea.OptimizeSelection();

            var deleteResult = await XmlCursorSelectionHelper.DeleteSelection(deleteArea);

            if (deleteResult.Success)
            {
                await cursor.SetPositions(deleteResult.NewCursorPosAfterDelete.ActualNode, deleteResult.NewCursorPosAfterDelete.PosOnNode, deleteResult.NewCursorPosAfterDelete.PosInTextNode, throwChangedEventWhenValuesChanged : false);
            }

            // insert the specified node at the cursor position
            if (InsertAtCursorPosHelper.InsertXmlNode(cursor.StartPos, node, xmlRules, setNewCursorPosBehindNewInsertedNode))
            {
                // then the cursor is only one line behind the inserted
                cursor.EndPos.SetPos(cursor.StartPos.ActualNode, cursor.StartPos.PosOnNode, cursor.StartPos.PosInTextNode);
            }
        }
        public virtual async Task <bool> ActionPasteFromClipboard(SetUndoSnapshotOptions setUnDoSnapshot)
        {
            if (!ActionsAllowed)
            {
                return(false);                 // If no actions are allowed at all, cancel
            }
            string text = string.Empty;

            try
            {
                if (await this.nativePlatform.Clipboard.ContainsText()) // if text is in the clipboard
                {
                    XmlCursorPos startPos;
                    XmlCursorPos endPos;

                    if (this.editorState.IsRootNodeSelected) // The root node is selected and should therefore be replaced by the clipboard content
                    {
                        return(await ActionReplaceRootNodeByClipboardContent(setUnDoSnapshot));
                    }
                    else // something other than the root node should be replaced
                    {
                        // First delete any selection
                        if (this.editorState.IsSomethingSelected) // Something is selected
                        {
                            if (await ActionDelete(SetUndoSnapshotOptions.nein))
                            {
                                startPos = this.editorState.CursorRaw.StartPos;
                            }
                            else // Failed to delete the selection
                            {
                                return(false);
                            }
                        }
                        else // nothing selected
                        {
                            startPos = this.editorState.CursorOptimized.StartPos;
                        }
                    }

                    if (setUnDoSnapshot == SetUndoSnapshotOptions.Yes)
                    {
                        this.editorState.UndoHandler.SetSnapshot("insert", this.editorState.CursorRaw);
                    }

                    // Wrap the text with an enclosing virtual tag
                    text = await this.nativePlatform.Clipboard.GetText();

                    // clean white-spaces
                    text = text.Replace("\r\n", " ");
                    text = text.Replace("\n\r", " ");
                    text = text.Replace("\r", " ");
                    text = text.Replace("\n", " ");
                    text = text.Replace("\t", " ");

                    string content = String.Format("<paste>{0}</paste>", text);

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

                        // Creating the Virtual Paste Node
                        var pasteNode = this.editorState.RootNode.OwnerDocument.ReadNode(reader);

                        // Now insert all Children of the virtual Paste-Node one after the other at the CursorPos
                        endPos = startPos.Clone(); // Before inserting start- and endPos are equal
                        foreach (XmlNode node in pasteNode.ChildNodes)
                        {
                            if (node is XmlText) // Insert a text
                            {
                                var pasteResult = InsertAtCursorPosHelper.InsertText(endPos, node.Clone().Value, this.xmlRules);
                                if (pasteResult.ReplaceNode != null)
                                {
                                    // Text could not be inserted because a node input was converted from text input.
                                    // Example: In the AIML template, * is pressed, and a <star> is inserted there instead
                                    InsertAtCursorPosHelper.InsertXmlNode(endPos, pasteResult.ReplaceNode.Clone(), this.xmlRules, true);
                                }
                            }
                            else //  Insert a Node
                            {
                                InsertAtCursorPosHelper.InsertXmlNode(endPos, node.Clone(), this.xmlRules, true);
                            }
                        }

                        switch (this.editorState.CursorRaw.EndPos.PosOnNode)
                        {
                        case XmlCursorPositions.CursorInsideTextNode:
                        case XmlCursorPositions.CursorInFrontOfNode:
                            // The end of the insert is a text or before the node
                            await this.editorState.CursorRaw.SetPositions(endPos.ActualNode, endPos.PosOnNode, endPos.PosInTextNode, throwChangedEventWhenValuesChanged : false);

                            break;

                        default:
                            // End of the insert is behind the last inserted node
                            await this.editorState.CursorRaw.SetPositions(endPos.ActualNode, XmlCursorPositions.CursorBehindTheNode, textPosInBothNodes : 0, throwChangedEventWhenValuesChanged : false);

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

                        return(true);
                    }
                }
                else //  No text on the clipboard
                {
                    return(false);
                }
            }
            catch (Exception e)
            {
                this.nativePlatform.LogError(
                    String.Format("AktionPasteFromClipboard:Error for insert text '{0}':{1}", text, e.Message));
                return(false);
            }
        }