static void
inf_text_default_delete_operation_apply(InfAdoptedOperation* operation,
                                        InfAdoptedUser* by,
                                        InfBuffer* buffer)
{
  InfTextDefaultDeleteOperationPrivate* priv;

  g_assert(INF_TEXT_IS_DEFAULT_DELETE_OPERATION(operation));
  g_assert(INF_TEXT_IS_BUFFER(buffer));

  priv = INF_TEXT_DEFAULT_DELETE_OPERATION_PRIVATE(operation);

#ifdef DELETE_OPERATION_CHECK_TEXT_MATCH
  g_assert(
    inf_text_default_delete_operation_text_match(
      INF_TEXT_DEFAULT_DELETE_OPERATION(operation),
      INF_TEXT_BUFFER(buffer)
    )
  );
#endif /* DELETE_OPERATION_CHECK_TEXT_MATCH */

  inf_text_buffer_erase_text(
    INF_TEXT_BUFFER(buffer),
    priv->position,
    inf_text_chunk_get_length(priv->chunk),
    INF_USER(by)
  );
}
static void
inf_text_default_delete_operation_get_property(GObject* object,
                                               guint prop_id,
                                               GValue* value,
                                               GParamSpec* pspec)
{
  InfTextDefaultDeleteOperation* operation;
  InfTextDefaultDeleteOperationPrivate* priv;

  operation = INF_TEXT_DEFAULT_DELETE_OPERATION(object);
  priv = INF_TEXT_DEFAULT_DELETE_OPERATION_PRIVATE(operation);

  switch(prop_id)
  {
  case PROP_POSITION:
    g_value_set_uint(value, priv->position);
    break;
  case PROP_CHUNK:
    g_value_set_boxed(value, priv->chunk);
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    break;
  }
}
static void
inf_text_default_delete_operation_init(GTypeInstance* instance,
                                       gpointer g_class)
{
  InfTextDefaultDeleteOperation* operation;
  InfTextDefaultDeleteOperationPrivate* priv;

  operation = INF_TEXT_DEFAULT_DELETE_OPERATION(instance);
  priv = INF_TEXT_DEFAULT_DELETE_OPERATION_PRIVATE(operation);

  priv->position = 0;
  priv->chunk = NULL;
}
static void
inf_text_default_delete_operation_finalize(GObject* object)
{
  InfTextDefaultDeleteOperation* operation;
  InfTextDefaultDeleteOperationPrivate* priv;

  operation = INF_TEXT_DEFAULT_DELETE_OPERATION(object);
  priv = INF_TEXT_DEFAULT_DELETE_OPERATION_PRIVATE(operation);

  inf_text_chunk_free(priv->chunk);

  G_OBJECT_CLASS(parent_class)->finalize(object);
}
static InfTextDeleteOperation*
inf_text_remote_delete_operation_transform_overlap(
  InfTextDeleteOperation* operation,
  InfTextDeleteOperation* other,
  guint position,
  guint begin,
  guint other_begin,
  guint length)
{
  InfTextRemoteDeleteOperationPrivate* priv;
  InfTextChunk* chunk;
  GObject* result;
  InfTextRemoteDeleteOperationPrivate* result_priv;


  /* It is actually possible that two remote delete operations are
   * transformed against each other (actually the parts of a splitted
   * remote delete operation). However, they must not overlap. */
  g_assert(INF_TEXT_IS_DEFAULT_DELETE_OPERATION(other));

  priv = INF_TEXT_REMOTE_DELETE_OPERATION_PRIVATE(operation);

  chunk = inf_text_chunk_substring(
    inf_text_default_delete_operation_get_chunk(
      INF_TEXT_DEFAULT_DELETE_OPERATION(other)
    ),
    other_begin,
    length
  );

  result = g_object_new(
    INF_TEXT_TYPE_REMOTE_DELETE_OPERATION,
    "position", position,
    "length", priv->length - length,
    NULL
  );

  result_priv = INF_TEXT_REMOTE_DELETE_OPERATION_PRIVATE(result);

  result_priv->recon = inf_text_remote_delete_operation_recon_feed(
    priv->recon,
    begin,
    chunk
  );

  inf_text_chunk_free(chunk);

  result_priv->recon_offset = priv->recon_offset;
  return INF_TEXT_DELETE_OPERATION(result);
}
/**
 * inf_text_default_delete_operation_new:
 * @position: The position at which to delete text.
 * @chunk: The text to delete.
 *
 * Creates a new delete operation that, when applied, deletes the text @chunk 
 * that starts at character offset @position in the buffer. The operation
 * cannot be applied, if there is some other text at that position in the
 * buffer.
 *
 * Return Value: A new #InfTextDefaultDeleteOperation.
 **/
InfTextDefaultDeleteOperation*
inf_text_default_delete_operation_new(guint position,
                                      InfTextChunk* chunk)
{
  GObject* object;

  g_return_val_if_fail(chunk != NULL, NULL);

  object = g_object_new(
    INF_TEXT_TYPE_DEFAULT_DELETE_OPERATION,
    "position", position,
    "chunk", chunk,
    NULL
  );

  return INF_TEXT_DEFAULT_DELETE_OPERATION(object);
}