static void
infinoted_plugin_transformation_protection_session_added(
  const InfBrowserIter* iter,
  InfSessionProxy* proxy,
  gpointer plugin_info,
  gpointer session_info)
{
  InfinotedPluginTransformationProtectionSessionInfo* info;
  InfSession* session;
  
  info = (InfinotedPluginTransformationProtectionSessionInfo*)session_info;
  info->plugin = (InfinotedPluginTransformationProtection*)plugin_info;
  info->proxy = proxy;
  info->iter = *iter;
  g_object_ref(proxy);
  
  g_object_get(G_OBJECT(proxy), "session", &session, NULL);
  g_assert(INF_ADOPTED_IS_SESSION(session));

  /* TODO: Check that the subscription group of 
     session uses the central method */

  g_signal_connect(
    G_OBJECT(session),
    "check-request",
    G_CALLBACK(infinoted_plugin_transformation_protection_check_request_cb),
    info
  );

  g_object_unref(session);
}
/**
 * inf_adopted_session_broadcast_request:
 * @session: A #InfAdoptedSession.
 * @request: A #InfAdoptedRequest obtained from @session's algorithm.
 *
 * Sends a request to all subscribed connections. The request should originate
 * from a call to inf_adopted_algorithm_generate_request_noexec(),
 * inf_adopted_algorithm_generate_request(),
 * inf_adopted_algorithm_generate_undo() or
 * inf_adopted_algorithm_generate_redo() with @session's #InfAdoptedAlgorithm.
 **/
void
inf_adopted_session_broadcast_request(InfAdoptedSession* session,
                                      InfAdoptedRequest* request)
{
  g_return_if_fail(INF_ADOPTED_IS_SESSION(session));
  g_return_if_fail(INF_ADOPTED_IS_REQUEST(request));

  inf_adopted_session_broadcast_n_requests(session, request, 1);
}
static void
infinoted_plugin_record_session_added(const InfBrowserIter* iter,
                                      InfSessionProxy* proxy,
                                      gpointer plugin_info,
                                      gpointer session_info)
{
  InfinotedPluginRecord* plugin;
  InfinotedPluginRecordSessionInfo* info;
  InfSession* session;
  gchar* title;
  gchar* pos;
  InfAdoptedSessionRecord* record;

  plugin = (InfinotedPluginRecord*)plugin_info;
  info = (InfinotedPluginRecordSessionInfo*)session_info;

  g_object_get(G_OBJECT(proxy), "session", &session, NULL);
  g_assert(INF_ADOPTED_IS_SESSION(session));

  title = inf_browser_get_path(
    INF_BROWSER(infinoted_plugin_manager_get_directory(plugin->manager)),
    iter
  );

  for(pos = title + 1; *pos != '\0'; ++pos)
    if(*pos == '/')
      *pos = '_';

  info->plugin = plugin;
  info->record = infinoted_plugin_record_start(
    plugin,
    INF_ADOPTED_SESSION(session),
    title + 1
  );

  g_object_set_data(G_OBJECT(session), "infinoted-record", info->record);

  g_object_unref(session);
  g_free(title);
}
/**
 * inf_adopted_session_redo:
 * @session: A #InfAdoptedSession.
 * @user: A local #InfAdoptedUser.
 * @n: The number of redo requests to issue.
 *
 * This is a shortcut for creating @n redo requests and broadcasting them.
 * If @n > 1 then this is also more efficient.
 **/
void
inf_adopted_session_redo(InfAdoptedSession* session,
                         InfAdoptedUser* user,
                         guint n)
{
  InfAdoptedSessionPrivate* priv;
  InfAdoptedRequest* request;
  guint i;

  /* TODO: Check whether we can issue n redo requests before doing anything */

  g_return_if_fail(INF_ADOPTED_IS_SESSION(session));
  g_return_if_fail(INF_ADOPTED_IS_USER(user));
  g_return_if_fail(n >= 1);

  priv = INF_ADOPTED_SESSION_PRIVATE(session);
  request = inf_adopted_algorithm_generate_redo(priv->algorithm, user);
  for(i = 1; i < n; ++i)
    inf_adopted_algorithm_generate_redo(priv->algorithm, user);
  inf_adopted_session_broadcast_n_requests(session, request, n);
  g_object_unref(request);
}
/**
 * inf_adopted_session_get_algorithm:
 * @session: A #InfAdoptedSession.
 *
 * Returns the #InfAdoptedAlgorithm object of @session. Returns %NULL if
 * @session has status %INF_SESSION_PRESYNC or %INF_SESSION_SYNCHRONIZING
 * because there the algorithm object is not yet created before successful
 * synchronization.
 *
 * Return Value: A #InfAdoptedAlgorithm, or %NULL.
 **/
InfAdoptedAlgorithm*
inf_adopted_session_get_algorithm(InfAdoptedSession* session)
{
  g_return_val_if_fail(INF_ADOPTED_IS_SESSION(session), NULL);
  return INF_ADOPTED_SESSION_PRIVATE(session)->algorithm;
}
/**
 * inf_adopted_session_get_io:
 * @session: A #InfAdoptedSession.
 *
 * Returns the #InfIo object of @session.
 *
 * Return Value: A #InfIo.
 **/
InfIo*
inf_adopted_session_get_io(InfAdoptedSession* session)
{
  g_return_val_if_fail(INF_ADOPTED_IS_SESSION(session), NULL);
  return INF_ADOPTED_SESSION_PRIVATE(session)->io;
}