function applyPatch(doc, patch, backendState = undefined) {
  if (doc[OBJECT_ID] !== '_root') {
    throw new TypeError('The first argument to Frontend.applyPatch must be the document root')
  }
  const state = copyObject(doc[STATE])

  if (doc[OPTIONS].backend) {
    if (!backendState) {
      throw new RangeError('applyPatch must be called with the updated backend state')
    }
    state.backendState = backendState
    return applyPatchToDoc(doc, patch, state, true)
  }

  let baseDoc

  if (state.requests.length > 0) {
    baseDoc = state.requests[0].before
    if (patch.actor === getActorId(doc)) {
      if (state.requests[0].seq !== patch.seq) {
        throw new RangeError(`Mismatched sequence number: patch ${patch.seq} does not match next request ${state.requests[0].seq}`)
      }
      state.requests = state.requests.slice(1)
    } else {
      state.requests = state.requests.slice()
    }
  } else {
    baseDoc = doc
    state.requests = []
  }

  let newDoc = applyPatchToDoc(baseDoc, patch, state, true)
  if (state.requests.length === 0) {
    return newDoc
  } else {
    state.requests[0] = copyObject(state.requests[0])
    state.requests[0].before = newDoc
    return updateRootObject(doc, {}, state)
  }
}
Applies `patch` to the document root object `doc`. This patch must come
from the backend; it may be the result of a local change or a remote change.
If it is the result of a local change, the `seq` field from the change
request should be included in the patch, so that we can match them up here.