docs: def coercer(self, dataSets):
          """
          Coerce all of the repetitions and sort them into creations, edits and
          deletions.
  
          @rtype: L{ListChanges}
          @return: An object describing all of the creations, modifications, and
              deletions represented by C{dataSets}.
          """
          # Xxx - This does a slightly complex (hey, it's like 20 lines, how
          # complex could it really be?) thing to figure out which elements are
          # newly created, which elements were edited, and which elements no
          # longer exist.  It might be simpler if the client kept track of this
          # and passed a three-tuple of lists (or whatever - some separate data
          # structures) to the server, so everything would be all figured out
          # already.  This would require the client
          # (Mantissa.LiveForm.RepeatableForm) to be more aware of what events
          # the user is triggering in the browser so that it could keep state for
          # adds/deletes/edits separately from DOM and widget objects.  This
          # would remove the need for RepeatedLiveFormWrapper.
          def makeSetter(identifier, values):
              def setter(defaultObject):
                  self._idsToObjects[identifier] = defaultObject
                  self._lastValues[identifier] = values
              return setter
  
          created = self._coerceAll(self._extractCreations(dataSets))
          edited = self._coerceAll(self._extractEdits(dataSets))
  
          coerceDeferred = gatherResults([created, edited])
          def cbCoerced((created, edited)):
              receivedIdentifiers = set()
  
              createObjects = []
              for (identifier, dataSet) in created:
                  receivedIdentifiers.add(identifier)
                  createObjects.append(
                      CreateObject(dataSet, makeSetter(identifier, dataSet)))
  
              editObjects = []
              for (identifier, dataSet) in edited:
                  receivedIdentifiers.add(identifier)
                  lastValues = self._lastValues[identifier]
                  if dataSet != lastValues:
                      modelObject = self._objectFromID(identifier)
                      editObjects.append(EditObject(modelObject, dataSet))
                      self._lastValues[identifier] = dataSet
  
              deleted = []
              for identifier in set(self._idsToObjects) - receivedIdentifiers:
                  existing = self._objectFromID(identifier)
                  if existing is not self._NO_OBJECT_MARKER:
                      deleted.append(existing)
                  self._idsToObjects.pop(identifier)
  
              return ListChanges(createObjects, editObjects, deleted)
  
          coerceDeferred.addCallback(cbCoerced)
          return coerceDeferred