function paste (tx, args) {
  const sel = tx.selection
  if (!sel || sel.isNull()) {
    throw new Error('Can not paste without selection.')
  }
  if (sel.isCustomSelection()) {
    throw new Error('Paste not implemented for custom selection.')
  }
  args = args || {}
  args.text = args.text || ''
  let pasteDoc = args.doc
  // TODO: is there a better way to detect that this paste is happening within a container?
  const inContainer = Boolean(sel.containerPath)
  // first delete the current selection
  if (!sel.isCollapsed()) {
    tx.deleteSelection()
  }
  // snippet is plain-text only
  if (!pasteDoc) {
    // in a PropertyEditor paste the text
    if (!inContainer) {
      tx.insertText(args.text)
      return
    // in a ContainerEditor interpret line-breaks
    // and create a document with multiple paragraphs
    } else {
      pasteDoc = _convertPlainTextToDocument(tx, args)
    }
  }
  // pasting into a TextProperty
  const snippet = pasteDoc.get(SNIPPET_ID)
  let L = snippet.getLength()
  if (L === 0) return
  const first = snippet.getNodeAt(0)
  // paste into a TextProperty
  if (!inContainer) {
    // if there is only one node it better be a text node
    // otherwise we can't do
    if (L === 1) {
      if (first.isText()) {
        _pasteAnnotatedText(tx, pasteDoc)
      }
    } else {
      pasteDoc = _convertIntoAnnotatedText(tx, pasteDoc)
      _pasteAnnotatedText(tx, pasteDoc)
    }
  } else {
    if (first.isText()) {
      _pasteAnnotatedText(tx, pasteDoc)
      // now we remove the first node from the snippet,
      // so that we can call _pasteDocument for the remaining
      // content
      snippet.removeAt(0)
      L--
    }
    // if still nodes left paste the remaining document
    if (L > 0) {
      _pasteDocument(tx, pasteDoc)
    }
  }
  return args
}
Pastes clipboard content at the current selection

  @param {Object} args object with `selection` and `doc` for Substance content or
  `text` for external HTML content
  @return {Object} with updated `selection`