     throw new Meteor.Error 'messageParent.noChild',
       "Missing child message #{child} to reparent"
   if parent?
-    pmsg = Messages.findOne parent
-    unless pmsg?
-      ## This can happen in client simulation when parent isn't in
-      ## subscription.
-      return if @isSimulation
-      throw new Meteor.Error 'messageParent.noParent',
-        "Missing parent message #{parent} to reparent"
+    ## On server, can give a parent message instead of an ID, to save query.
+    if parent._id?
+      pmsg = parent
+      parent = pmsg._id
+    else
+      pmsg = Messages.findOne parent
+      unless pmsg?
+        ## This can happen in client simulation when parent isn't in
+        ## subscription.
+        return if Meteor.isClient
+        throw new Meteor.Error 'messageParent.noParent',
+          "Missing parent message #{parent} to reparent"
     group = pmsg.group
     root = pmsg.root ? parent
   else

      oldParent = null
  return if parent == oldParent == null  ## no-op, root case
  if parent?
    if position?
      Messages.update parent,
        $push: children:
          $each: [child]
          $position: position
    else
      Messages.update parent,
        $push: children: child
  if root != cmsg.root
    Messages.update child,
      $set: root: root

  notifyMessageUpdate message if Meteor.isServer  ## client in simulation
  diffid

_messageAddChild = (child, parent, position = null) ->
  if position?
    Messages.update parent,
      $push: children:
        $each: [child]
        $position: position
  else
    Messages.update parent,
      $push: children: child

_messageParent = (child, parent, position = null, oldParent = true, importing = false) ->
  ## oldParent is an internal option for server only; true means "search for/
  ## deal with old parent", while null means we assert there is no old parent.
