diff --git a/includes/VersioncontrolBackend.php b/includes/VersioncontrolBackend.php
index 2070939..b6aca72 100644
--- a/includes/VersioncontrolBackend.php
+++ b/includes/VersioncontrolBackend.php
@@ -105,6 +105,7 @@ abstract class VersioncontrolBackend {
       'committer_mapper' => 'VersioncontrolUserMapperInterface',
       'author_mapper' => 'VersioncontrolUserMapperInterface',
       'auth_handler' => 'VersioncontrolAuthHandlerInterface',
+      'event_processor' => 'VersioncontrolSynchronizationEventProcessorInterface',
     ),
   );
 
@@ -357,6 +358,8 @@ abstract class VersioncontrolBackend {
   /**
    * Verify that a plugin object conforms to the required interface.
    *
+   * @todo Plugin slot is a repository specific concept, move this there?
+   *
    * @param mixed $entity
    *   A VersioncontrolEntity object, or string name of a VersioncontrolEntity
    *   class, for which we are verifying a plugin.
diff --git a/includes/VersioncontrolRepository.php b/includes/VersioncontrolRepository.php
index dbe1db2..1031ec5 100644
--- a/includes/VersioncontrolRepository.php
+++ b/includes/VersioncontrolRepository.php
@@ -89,13 +89,14 @@ abstract class VersioncontrolRepository implements VersioncontrolEntityInterface
   /**
    * An array describing the plugins that will be used for this repository.
    *
-   * The current plugin types(array keys) are:
+   * The current plugin slots(array keys) are:
    * - author_mapper
    * - committer_mapper
    * - webviewer_url_handler
    * - repomgr
    * - auth_handler
    * - reposync
+   * - event_processors
    *
    * @var array
    */
@@ -104,6 +105,9 @@ abstract class VersioncontrolRepository implements VersioncontrolEntityInterface
   /**
    * An array of plugin instances (instanciated plugin objects).
    *
+   * There is one plugin per plugin slot in most cases. For now only
+   * event_processors can have multiple plugins associated.
+   *
    * @var array
    */
   protected $pluginInstances = array();
@@ -878,29 +882,59 @@ abstract class VersioncontrolRepository implements VersioncontrolEntityInterface
     return $this->pluginInstances['webviewer_url_handler'];
   }
 
+  protected function isPluginSlotMultiple($plugin_slot) {
+    // @todo Maybe define metadata per plugin slot?
+    return $plugin_slot == 'event_processors';
+  }
+
+  protected function isPluginSlotRequired($plugin_slot) {
+    return $plugin_slot != 'event_processors';
+  }
+
   /**
-   * Get a ctools plugin based on plugin slot passed.
+   * Get a list of ctools plugins based on plugin slot and type passed.
    */
-  protected function getPlugin($plugin_slot, $plugin_type) {
+  public function getPlugins($plugin_slot, $plugin_type) {
     ctools_include('plugins');
 
-    $plugin_name = $this->getPluginName($plugin_slot);
-
-    $plugin = ctools_get_plugins('versioncontrol', $plugin_type, $plugin_name);
-    if (!is_array($plugin) || empty($plugin)) {
-      throw new Exception("Attempted to get a plugin of type '$plugin_type' named '$plugin_name', but no such plugin could be found.", E_WARNING);
+    // It can be an array, some plugin slots accept multiple values.
+    $plugin_names = $this->getPluginName($plugin_slot);
+    if ($plugin_names == NULL) {
+      return array();
+    }
+    if (!is_array($plugin_names)) {
+      $plugin_names = array($plugin_names);
     }
 
-    // If $plugin_name is empty ctools_get_plugins() returns an array of plugins
-    // instead of a single one. Default to the first one.
-    if (!$plugin_name) {
-      return reset($plugin);
+    // If $plugin_name is empty ctools_get_plugins() returns an array of
+    // plugins.
+    if (empty($plugin_names) && !$multiple) {
+      return ctools_get_plugins('versioncontrol', $plugin_type);
     }
-    else {
-      return $plugin;
+
+    $plugins = array();
+    foreach ($plugin_names as $plugin_name) {
+      $plugin = ctools_get_plugins('versioncontrol', $plugin_type, $plugin_name);
+      if (!is_array($plugin) || empty($plugin)) {
+        throw new Exception("Attempted to get a plugin of type '$plugin_type' named '$plugin_name', but no such plugin could be found.", E_WARNING);
+      }
+      $plugins[] = $plugin;
     }
+    return $plugins;
   }
 
+  /**
+   * Retrieve the first plugin associated with the plugin slot.
+   *
+   * @fixme review visibility
+   */
+  protected function getPlugin($plugin_slot, $plugin_type) {
+    $plugins = $this->getPlugins($plugin_slot, $plugin_type);
+    if ($this->isPluginSlotMultiple($plugin_slot)) {
+      throw new Exception("Attempted to use getPlugin() with a multiple plugin slot named '$plugin_slot' of plugin type '$plugin_type'. Please use getPlugins() instead.", E_WARNING);
+    }
+    return reset($plugins);
+  }
 
   /**
    * Retrieves the ctools plugin name to use, based on the plugin slot passed.
@@ -939,8 +973,11 @@ abstract class VersioncontrolRepository implements VersioncontrolEntityInterface
       return $plugin_name;
     }
 
-    // Could not find any default.
-    throw new Exception("A default plugin name could not be retrieved for plugin type '$plugin_slot'.", E_WARNING);
+    if ($this->isPluginSlotRequired($plugin_slot)) {
+      // Could not find any default.
+      throw new Exception("A default plugin name could not be retrieved for plugin type '$plugin_slot'.", E_WARNING);
+    }
+    return NULL;
   }
 
   public function getSynchronizerOptions() {
@@ -988,6 +1025,26 @@ abstract class VersioncontrolRepository implements VersioncontrolEntityInterface
   }
 
   /**
+   * @see getPluginClass().
+   */
+  protected function getPluginClasses($plugin_slot, $plugin_type, $class_type) {
+    $plugin_objects = array();
+
+    foreach ($this->getPlugins($plugin_slot, $plugin_type) as $plugin) {
+      $class_name = ctools_plugin_get_class($plugin, $class_type);
+      if (!class_exists($class_name)) {
+        throw new Exception("Plugin slot '$plugin_slot' of type '$plugin_type' contains an invalid class name in handler slot '$class_type', named '$class_name' class", E_WARNING);
+        return FALSE;
+      }
+
+      $plugin_object = new $class_name();
+      $this->getBackend()->verifyPluginInterface($this, $plugin_slot, $plugin_object);
+      $plugin_objects[$plugin['name']] = $plugin_object;
+    }
+    return $plugin_objects;
+  }
+
+  /**
   * Return the auth handler plugin object that this repository is
   * configured to use for implementing ACLs on this repository.
   *
@@ -1048,6 +1105,24 @@ abstract class VersioncontrolRepository implements VersioncontrolEntityInterface
   }
 
   /**
+   * Returns the event processor plugin object that this repository is
+   * configured to use.
+   *
+   * @return array(VersioncontrolSynchronizationEventProcessorInterface)
+   *   Keyed by plugin name.
+   */
+  public function getEventProcessors() {
+    if (!isset($this->pluginInstances['event_processors'])) {
+      $this->pluginInstances['event_processors'] = $this->getPluginClasses('event_processors', 'event_processor', 'handler');
+      foreach ($this->pluginInstances['event_processors'] as $event_processor_object) {
+        $event_processor_object->setRepository($this);
+      }
+    }
+
+    return $this->pluginInstances['event_processors'];
+  }
+
+  /**
    * Convenience method to lock the repository in preparation for a
    * synchronization run.
    *
diff --git a/includes/VersioncontrolSynchronizationEventProcessorException.php b/includes/VersioncontrolSynchronizationEventProcessorException.php
new file mode 100644
index 0000000..0811b3e
--- /dev/null
+++ b/includes/VersioncontrolSynchronizationEventProcessorException.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * @file
+ *   An exception to be thrown when an error occurs during event procesing
+ *   after repository synchronization.
+ */
+class VersioncontrolSynchronizationEventProcessorException extends Exception { }
diff --git a/includes/interfaces.inc b/includes/interfaces.inc
index 41b5c81..fccaffa 100644
--- a/includes/interfaces.inc
+++ b/includes/interfaces.inc
@@ -468,3 +468,81 @@ interface VersioncontrolRepositoryHistorySynchronizerInterface {
    */
   public function verifyData();
 }
+
+/**
+ * Defines a versioncontrol synchronization event processor plugin behavior.
+ *
+ * Note: This is similar to hook_versioncontrol_code_arrival(), but this type
+ * of plugins are intended to help different configuration per repository per
+ * plugin.
+ */
+interface VersioncontrolSynchronizationEventProcessorInterface {
+  /**
+   * Reacts when new code has arrived correctly.
+   *
+   * @param VersioncontrolEvent $event
+   *   The event describing the code arrival.
+   *
+   * @throws VersioncontrolSynchronizationEventProcessorException $event
+   *   Something wrong happened during the processing. It let caller knows if
+   *   was executed correctly or not.
+   */
+  public function process(VersioncontrolEvent $event);
+
+  /**
+   * Set the repository object to be used by this plugin object.
+   */
+  public function setRepository(VersioncontrolRepository $repository);
+
+}
+
+/**
+ * Defines a way for plugins to define configuration.
+ *
+ * @todo Currently it is only used on versioncontrol synchronization event
+ * processor plugin. It's pending to be used on other plugins.
+ * @todo Add a way to validate the form. Not added for now until we can pass
+ * context to the plugin to know in which part of the form_state hierarchy to
+ * find the values. Probably make a new method that receives only the known
+ * context of form_state instead of the full context.
+ */
+interface VersioncontrolPluginConfigurationInterface {
+  /**
+   * Build a configuration form to be used to configure a plugin instance.
+   *
+   * @param array $data
+   *   the corresponding data to initialize values.
+   *   i.e.
+   *   array(
+   *     'behavior' => 1,
+   *     'message' => 'test',
+   *   )
+   *
+   * @return array
+   *   A form array to include.
+   */
+  public function buildForm($default_data);
+
+  /**
+   * Converts the buildForm() form data into an array to be saved.
+   *
+   * @param array $form
+   *   A form array.
+   * @param array $form_state_values_data
+   *   A subset of $form_state with corresponding data.
+   */
+  public function getFormData($form_state_values_data);
+
+  /**
+   * Handle any special handling on form submission.
+   *
+   * Probably empty in most cases, getFormData should provide enough for
+   * storing the configuration.
+   *
+   * @param array $form
+   *   A form array.
+   * @param array $form_state
+   *   the corresponding form state.
+   */
+  public function submitForm(&$form, &$form_state);
+}
diff --git a/includes/plugins/event_processor/VersioncontrolEventProcessorNone.inc b/includes/plugins/event_processor/VersioncontrolEventProcessorNone.inc
new file mode 100644
index 0000000..65bd9b7
--- /dev/null
+++ b/includes/plugins/event_processor/VersioncontrolEventProcessorNone.inc
@@ -0,0 +1,61 @@
+<?php
+/**
+ * @file
+ * Basic event processor class doing nothing.
+ */
+
+/**
+ * An example event processor class.
+ */
+class VersioncontrolEventProcessorNone implements VersioncontrolSynchronizationEventProcessorInterface, VersioncontrolPluginConfigurationInterface {
+  const BEHAVIOR_A = 1;
+  const BEHAVIOR_B = 2;
+
+  /**
+   * Associated repository.
+   *
+   * @var VersioncontrolRepository
+   */
+  protected $repository;
+
+  /**
+   * This plugin is an example that does nothing.
+   */
+  public function process(VersioncontrolEvent $event) {
+  }
+
+  public function setRepository(VersioncontrolRepository $repository) {
+    $this->repository = $repository;
+  }
+
+  public function buildForm($default_data) {
+    $form['event-processor-none-behavior'] = array(
+      '#type' => 'select',
+      '#title' => 'Behavior',
+      '#default_value' => !empty($default_data['behavior']) ? $default_data['behavior'] : self::BEHAVIOR_A,
+      '#options' => array(
+        self::BEHAVIOR_A => t('Behavior A'),
+        self:: BEHAVIOR_B => t('Behavior B'),
+      ),
+      '#description' => t('An option that will not change any behavior.'),
+    );
+    $form['event-processor-none-message'] = array(
+      '#type' => 'textfield',
+      '#title' => 'Message',
+      '#description' => t('One message that will not be displayed.'),
+      '#default_value' => !empty($default_data['message']) ? $default_data['message'] : '',
+    );
+    return $form;
+  }
+
+  public function getFormData($form_state_values_data) {
+    return array(
+      'behavior' => $form_state_values_data['event-processor-none-behavior'],
+      'message' => $form_state_values_data['event-processor-none-message'],
+    );
+  }
+
+  public function submitForm(&$form, &$form_state) {
+    // Nothing special.
+  }
+}
diff --git a/includes/plugins/event_processor/none.inc b/includes/plugins/event_processor/none.inc
new file mode 100644
index 0000000..57d53e1
--- /dev/null
+++ b/includes/plugins/event_processor/none.inc
@@ -0,0 +1,25 @@
+<?php
+/**
+ * @file
+ * This plugin contains the main documentation of how to make an event
+ * processor plugin.
+ * It does not really provide any functionallity.
+ */
+
+$plugin = array(
+
+  // The versioncontrol system machine name as the backend declares.
+  'vcs' => VERSIONCONTROL_PLUGIN_VCS_AGNOSTIC,
+
+  // This title is going to be shown on the repository edition, for the
+  // user to identify the plugin.
+  'title' => t('Empty event processor'),
+
+  'handler' => array(
+    'class' => 'VersioncontrolEventProcessorNone',
+    'file' => 'VersioncontrolEventProcessorNone.inc',
+    'path' => drupal_get_path('module', 'versioncontrol') . '/includes/plugins/event_processor',
+  ),
+
+  'has_configuration_form' => TRUE,
+);
diff --git a/versioncontrol.admin.inc b/versioncontrol.admin.inc
index 09abc2f..2ebd077 100644
--- a/versioncontrol.admin.inc
+++ b/versioncontrol.admin.inc
@@ -269,6 +269,95 @@ function versioncontrol_admin_views_sets_edit_submit($form, &$form_state) {
 }
 
 /**
+ * Form callback for 'admin/settings/versioncontrol-settings/event-processors'.
+ */
+function versioncontrol_admin_event_processors_edit($form, &$form_state) {
+  ctools_include('dependent');
+  $form = array();
+
+  $form['info'] = array(
+    '#type' => 'item',
+    '#markup' => t("This form allows you to manage Version Control API's event processors to be used by default on each backend, setting a configuration if it allows it."),
+  );
+
+  $backends = versioncontrol_get_backends();
+  foreach ($backends as $vcs => $backend) {
+    $form[$vcs] = array(
+      '#type' => 'fieldset',
+      '#title' => $backend->name,
+      '#collapsible' => TRUE,
+      '#collapsed' => FALSE,
+      '#tree' => TRUE,
+    );
+    $variable_name = "versioncontrol_repository_plugin_defaults_{$backend->type}_event_processors";
+    $default_event_processor_names = variable_get($variable_name, array());
+    $default_event_processor_data = variable_get("{$variable_name}_data", array());
+    foreach (versioncontrol_plugin_get_by_vcs('event_processor', $vcs) as $processor_name => $processor_plugin) {
+      $form[$vcs]["processor-$processor_name"] = array(
+        '#type' => 'checkbox',
+        '#title' => $processor_plugin['title'],
+        '#default_value' => in_array($processor_name, $default_event_processor_names),
+        '#id' => "processor-$processor_name",
+      );
+      $class_name = ctools_plugin_get_class($processor_plugin, 'handler');
+      $event_processor = new $class_name();
+      if (!$event_processor instanceof VersioncontrolPluginConfigurationInterface) {
+        continue;
+      }
+      $default_data = isset($default_event_processor_data[$vcs][$processor_name]) ? $default_event_processor_data[$vcs][$processor_name] : array();
+      $settings_form = $event_processor->buildForm($default_data);
+      $form[$vcs]["processor-settings-$processor_name"] = array(
+        '#type' => 'fieldset',
+        '#title' => t('%name options', array('%name' => $processor_plugin['title'])),
+        '#process' => array('ctools_dependent_process'),
+        '#dependency' => array("processor-$processor_name" => array(1)),
+      );
+      $form[$vcs]["processor-settings-$processor_name"] += $settings_form;
+    }
+  }
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save configuration'),
+  );
+
+  return $form;
+}
+
+/**
+ * Form submit callback for 'admin/settings/versioncontrol-settings/event-processors'.
+ */
+function versioncontrol_admin_event_processors_edit_submit($form, &$form_state) {
+  $backends = versioncontrol_get_backends();
+  foreach ($backends as $vcs => $backend) {
+    // Remove variables.
+    $variable_name = "versioncontrol_repository_plugin_defaults_{$backend->type}_event_processors";
+    variable_del($variable_name);
+    variable_del("{$variable_name}_data");
+    // Process new values.
+    $active_processors = array();
+    $processors_data = array();
+    foreach (versioncontrol_plugin_get_by_vcs('event_processor', $vcs) as $processor_name => $processor_plugin) {
+      if (empty($form_state['values'][$vcs]["processor-$processor_name"])) {
+        continue;
+      }
+      $active_processors[] = $processor_name;
+      if (!empty($form_state['values'][$vcs]["processor-settings-$processor_name"])) {
+        $class_name = ctools_plugin_get_class($processor_plugin, 'handler');
+        $event_processor = new $class_name();
+        if (!$event_processor instanceof VersioncontrolPluginConfigurationInterface) {
+          continue;
+        }
+        $processors_data[$vcs][$processor_name] = $event_processor->getFormData($form_state['values'][$vcs]["processor-settings-$processor_name"]);
+      }
+    }
+    // Save them.
+    variable_set($variable_name, $active_processors);
+    variable_set("{$variable_name}_data", $processors_data);
+  }
+}
+
+/**
  * Form callback for "admin/settings/versioncontrol-settings/plugins":
  * Provide a form for settings about Version Control API plugins.
  */
@@ -279,6 +368,8 @@ function versioncontrol_admin_settings_plugins($form, &$form_state) {
   $plugin_entity_types = versioncontrol_plugins_get_information();
   // view_sets have its own settings page, so avoid it.
   unset($plugin_entity_types['view']);
+  // event processors has its own settings page too.
+  unset($plugin_entity_types['repository']['event_processor']);
 
   foreach ($backends as $vcs => $backend) {
     $form['versioncontrol_plugins_' . $vcs] = array(
@@ -308,6 +399,7 @@ function versioncontrol_admin_settings_plugins($form, &$form_state) {
         $form['versioncontrol_plugins_' . $vcs][$plugin_slot][$variable_name] = array(
           '#type' => 'select',
           '#title' => t('Plugin name'),
+          '#multiple' => $plugin_slot_data['multiple'],
           '#default_value' => $default_value,
           '#options' => function_exists($callback) ? $options + $callback() : $options,
         );
@@ -319,7 +411,7 @@ function versioncontrol_admin_settings_plugins($form, &$form_state) {
     }
   }
 
-  // Add special configuration for webviewer_url_handler plugin.
+  // Add special configuration for webviewer_url_handler an event_processor plugins.
   foreach ($backends as $vcs => $backend) {
     foreach (ctools_get_plugins('versioncontrol', 'webviewer_url_handlers') as $machine_name => $plugin) {
       $variable = 'versioncontrol_repository_' . $vcs . '_base_url_' . $machine_name;
@@ -550,6 +642,8 @@ function versioncontrol_admin_repository_edit($form, &$form_state, $repository,
     '#weight' => 100,
   );
 
+  //@todo Support per repository configuration for event processor plugins.
+
   return $form;
 }
 
diff --git a/versioncontrol.module b/versioncontrol.module
index 8fe9833..01f5595 100644
--- a/versioncontrol.module
+++ b/versioncontrol.module
@@ -72,6 +72,12 @@ define('VERSIONCONTROL_ITEM_DIRECTORY_DELETED', 4);
 //@}
 
 /**
+ * An identifier to use on vcs key for plugins which can work with any version
+ * control system.
+ */
+define('VERSIONCONTROL_PLUGIN_VCS_AGNOSTIC', 1);
+
+/**
  * Implements hook_flush_caches().
  *
  * Triggers backend mode determination.
@@ -144,6 +150,14 @@ function versioncontrol_menu() {
     'type' => MENU_LOCAL_TASK,
   ) + $admin;
 
+  $items['admin/config/development/versioncontrol-settings/event-processors'] = array(
+    'title' => 'Event processors',
+    'description' => 'Configure default event processors to use per backend.',
+    'page arguments' => array('versioncontrol_admin_event_processors_edit'),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 10,
+  ) + $admin;
+
   $items['admin/config/development/versioncontrol-settings/plugins'] = array(
     'title' => 'Plugins',
     'description' => 'Default plugins and its configuration per backend.',
@@ -537,6 +551,9 @@ function versioncontrol_ctools_plugin_type() {
     'repomgr' => array(
       'classes' => array('worker'),
     ),
+    'event_processor' => array(
+      'classes' => array('handler'),
+    ),
   );
 }
 
@@ -564,6 +581,63 @@ function versioncontrol_plugin_get_names($plugin_type) {
 }
 
 /**
+ * Load the names of all required plugins with the specified vcs.
+ *
+ * To be used at forms.
+ *
+ * @param string $plugin_type
+ *   This can be: webviewer_url_handlers, event_processor.
+ * @param string $vcs
+ *   Version Control System machine name as defined by
+ *   hook_versioncontrol_backends(). If empty, no filter is applied.
+ *
+ * @return array
+ *   The list of plugin titles indexed by plugin name.
+ */
+function versioncontrol_plugin_get_names_by_vcs($plugin_type, $vcs = '') {
+  $names = array();
+  $plugins = versioncontrol_plugin_get_by_vcs($plugin_type, $vcs);
+  foreach ($plugins as $name => $plugin) {
+    $names[$name] = $plugin['title'];
+  }
+  asort($names);
+  return $names;
+}
+
+/**
+ * Load ctools plugins with the specified vcs.
+ *
+ * @todo: Let all plugins to define an optional vcs, so this can live inside
+ *        versioncontrol_plugin_get_names().
+ *
+ * @param string $plugin_type
+ *   This can be: webviewer_url_handlers, event_processor.
+ * @param string $vcs
+ *   Version Control System machine name as defined by
+ *   hook_versioncontrol_backends(). If empty, no filter is applied.
+ *
+ * @return array
+ *   The list of plugins.
+ */
+function versioncontrol_plugin_get_by_vcs($plugin_type, $vcs = '') {
+  ctools_include('plugins');
+
+  $plugins = array();
+  foreach (ctools_get_plugins('versioncontrol', $plugin_type) as $name => $plugin) {
+    if (!empty($vcs)) {
+      if ($plugin['vcs'] == $vcs || $plugin['vcs'] == VERSIONCONTROL_PLUGIN_VCS_AGNOSTIC) {
+        $plugins[$name] = $plugin;
+      }
+    }
+    else {
+      $plugins[$name] = $plugin;
+    }
+  }
+
+  return $plugins;
+}
+
+/**
  * Load the names of all 'user_mapping_methods' for use at forms.
  */
 function versioncontrol_user_mapping_methods_get_names() {
@@ -593,27 +667,16 @@ function versioncontrol_repomgr_get_names() {
 
 /**
  * Load the names of all 'webviewer_url_handlers' for use at forms.
- *
- * @todo: Let all plugins to define an optional vcs, so this can live inside
- *        versioncontrol_plugin_get_names().
  */
-function versioncontrol_webviewer_url_handlers_get_names($vcs='') {
-  ctools_include('plugins');
-
-  $names = array();
-  foreach (ctools_get_plugins('versioncontrol', 'webviewer_url_handlers') as $name => $plugin) {
-    if (!empty($vcs)) {
-      if ($plugin['vcs'] == $vcs) {
-        $names[$name] = $plugin['title'];
-      }
-    }
-    else {
-      $names[$name] = $plugin['title'];
-    }
-  }
+function versioncontrol_webviewer_url_handlers_get_names($vcs = '') {
+  return versioncontrol_plugin_get_names_by_vcs('webviewer_url_handlers', $vcs);
+}
 
-  asort($names);
-  return $names;
+/**
+ * Load the names of all 'event_processor' plugins to be used at forms.
+ */
+function versioncontrol_event_processor_get_names($vcs = '') {
+  return versioncontrol_plugin_get_names_by_vcs('event_processor', $vcs);
 }
 
 /**
@@ -648,7 +711,37 @@ function versioncontrol_webviewer_url_handlers_get_default_plugin($vcs) {
 }
 
 /**
- * Helper function for handlin plugin settings.
+ * Retrieves the default 'event_processor' plugins.
+ *
+ * @param string $vcs
+ *   Version Control System machine name as defined by
+ *   hook_versioncontrol_backends().
+ *
+ * @return array
+ *   A list of plugin machine names. It can be empty.
+ */
+function versioncontrol_event_processor_get_default_plugins($vcs) {
+  $default_event_processors = array();
+  ctools_include('plugins');
+  $default_event_processors = variable_get('versioncontrol_repository_plugin_default_event_processor', array());
+  $valid_plugins = array();
+  foreach (ctools_get_plugins('versioncontrol', 'event_processor') as $name => $plugin) {
+    if ($plugin['vcs'] == $vcs) {
+      $valid_plugins[] = $name;
+    }
+  }
+  asort($valid_plugins);
+
+  foreach ($default_event_processors as $key => $default_event_processor) {
+    if (!in_array($default_event_processor, $valid_plugins)) {
+      unset($default_event_processors[$key]);
+    }
+  }
+  return $default_event_processors;
+}
+
+/**
+ * Helper function for handling plugin settings.
  */
 function versioncontrol_plugins_get_information() {
   return array(
@@ -656,26 +749,37 @@ function versioncontrol_plugins_get_information() {
       'author_mapper' => array(
         'name' => t('Repository author mapping'),
         'fetcher' => 'versioncontrol_user_mapping_methods_get_names',
+        'multiple' => FALSE,
       ),
       'committer_mapper'   => array(
         'name' => t('Repository committer mapping'),
         'fetcher' => 'versioncontrol_user_mapping_methods_get_names',
+        'multiple' => FALSE,
       ),
       'auth_handler' => array(
         'name' => t('Repository versioncontrol authentication'),
         'fetcher' => 'versioncontrol_auth_handlers_get_names',
+        'multiple' => FALSE,
       ),
       'webviewer_url_handler' => array(
         'name' => t('Repository webviewer URL handler'),
         'fetcher' => 'versioncontrol_webviewer_url_handlers_get_names',
+        'multiple' => FALSE,
       ),
       'repomgr' => array(
         'name' => t('Repository manager'),
         'fetcher' => 'versioncontrol_repomgr_get_names',
+        'multiple' => FALSE,
       ),
       'reposync' => array(
         'name' => t('Repository syncronization'),
         'fetcher' => 'versioncontrol_reposync_get_names',
+        'multiple' => FALSE,
+      ),
+      'event_processor' => array(
+        'name' => t('Event processor'),
+        'fetcher' => 'versioncontrol_event_processor_get_names',
+        'multiple' => TRUE,
       ),
     ),
     'view' => array(
@@ -686,3 +790,19 @@ function versioncontrol_plugins_get_information() {
     ),
   );
 }
+
+/**
+ * Implements hook_versioncontrol_code_arrival().
+ *
+ * Calls event processor plugins.
+ */
+function versioncontrol_versioncontrol_code_arrival(VersioncontrolRepository $repository, VersioncontrolEvent $event) {
+  foreach($repository->getEventProcessors() as $event_processor) {
+    try {
+      $event_processor->process($event);
+    }
+    catch (VersioncontrolSynchronizationEventProcessorException $exception) {
+      watchdog('versioncontrol', 'Event processor using class "%class" aborted execution with message "%message".', array('%class' => get_class($event_processor), '%message' => $exception->getMessage()), WATCHDOG_WARNING);
+    }
+  }
+}
