decide whether to compact the newest change into the old last; return new change list. assumes changes is safe to mutate.\
  note: newtext MUST be the result of applying change to changes, and is only passed to save doing the computation again.

def update_changes(changes,newtext,change):
  "decide whether to compact the newest change into the old last; return new change list. assumes changes is safe to mutate.\
  note: newtext MUST be the result of applying change to changes, and is only passed to save doing the computation again."
  # the criteria for a new version are:
  # 1. mode change (modes are adding to end, deleting from end, internal edits)
  # 2. length changed by more than 256 chars (why power of 2? why not)
  # 3. time delta > COMPACTION_TIME_THRESH
  if not changes: return [change] # todo(awinter): needs test case
  if change.utc-changes[-1].utc>COMPACTION_TIME_THRESH:
    changes.append(change)
    return changes
  base=reduce(apply_change,changes[:-1],'')
  final=apply_change(base,changes[-1])
  prev_mode=detect_change_mode(base,changes[-1])
  cur_mode=detect_change_mode(final,change)
  if prev_mode==cur_mode and abs(len(newtext)-len(final)<COMPACTION_LEN_THRESH):
    changes[-1]=mkchange(base,newtext,change.version,change.utc)
  else: changes.append(change)
  return changes