diff --git a/lib/wp/session-item.c b/lib/wp/session-item.c
index d1b90c3fcfa544682c5ee856b68730fa12e139d1..c8b14864362fd5e7bc8c3f5c8008feed22c3aab5 100644
--- a/lib/wp/session-item.c
+++ b/lib/wp/session-item.c
@@ -121,6 +121,13 @@ wp_session_item_finalize (GObject * object)
   G_OBJECT_CLASS (wp_session_item_parent_class)->finalize (object);
 }
 
+static void
+wp_session_item_default_reset (WpSessionItem * self)
+{
+  wp_session_item_unexport (self);
+  wp_session_item_deactivate (self);
+}
+
 static gpointer
 wp_session_item_default_get_associated_proxy (WpSessionItem * self,
     GType proxy_type)
@@ -179,14 +186,16 @@ wp_session_item_default_execute_step (WpSessionItem * self,
 }
 
 static void
-wp_session_item_default_reset (WpSessionItem * self)
+wp_session_item_default_deactivate (WpSessionItem * self)
 {
   WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self);
+  static const guint flags =
+      (WP_SI_FLAG_ACTIVATING | WP_SI_FLAG_ACTIVE | WP_SI_FLAG_IN_ERROR);
 
-  wp_session_item_unexport (self);
-
-  priv->flags &= ~(WP_SI_FLAG_ACTIVE | WP_SI_FLAG_IN_ERROR);
-  g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags);
+  if (priv->flags & flags) {
+    priv->flags &= ~flags;
+    g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags);
+  }
 }
 
 enum {
@@ -223,6 +232,7 @@ default_export_get_next_step (WpSessionItem * self, WpTransition * transition,
     }
 
   case EXPORT_STEP_ENDPOINT:
+    g_return_val_if_fail (WP_IS_SI_ENDPOINT (self), WP_TRANSITION_STEP_ERROR);
     return EXPORT_STEP_STREAMS;
 
   case EXPORT_STEP_STREAMS:
@@ -237,6 +247,7 @@ default_export_get_next_step (WpSessionItem * self, WpTransition * transition,
       return step;
 
   case EXPORT_STEP_LINK:
+    g_return_val_if_fail (WP_IS_SI_LINK (self), WP_TRANSITION_STEP_ERROR);
     return EXPORT_STEP_FINISH;
 
   case EXPORT_STEP_FINISH:
@@ -350,9 +361,6 @@ wp_session_item_default_export (WpSessionItem * self,
   WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self);
   WpTransition *transition;
 
-  g_return_if_fail (priv->flags & WP_SI_FLAG_ACTIVE);
-  g_return_if_fail (!(priv->flags & (WP_SI_FLAG_EXPORTING | WP_SI_FLAG_EXPORTED)));
-
   g_weak_ref_set (&priv->session, session);
 
   transition = wp_transition_new (wp_si_transition_get_type (),
@@ -378,15 +386,16 @@ static void
 wp_session_item_default_unexport (WpSessionItem * self)
 {
   WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self);
-
-  //TODO cancel job if EXPORTING
+  static const guint flags = (WP_SI_FLAG_EXPORTING | WP_SI_FLAG_EXPORTED);
 
   g_clear_pointer (&priv->impl_streams, g_hash_table_unref);
   g_clear_object (&priv->impl_proxy);
   g_weak_ref_set (&priv->session, NULL);
 
-  priv->flags &= ~(WP_SI_FLAG_EXPORTING | WP_SI_FLAG_EXPORTED);
-  g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags);
+  if (priv->flags & flags) {
+    priv->flags &= ~flags;
+    g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags);
+  }
 }
 
 static void
@@ -397,10 +406,11 @@ wp_session_item_class_init (WpSessionItemClass * klass)
   object_class->dispose = wp_session_item_dispose;
   object_class->finalize = wp_session_item_finalize;
 
+  klass->reset = wp_session_item_default_reset;
   klass->get_associated_proxy = wp_session_item_default_get_associated_proxy;
   klass->get_next_step = wp_session_item_default_get_next_step;
   klass->execute_step = wp_session_item_default_execute_step;
-  klass->reset = wp_session_item_default_reset;
+  klass->deactivate = wp_session_item_default_deactivate;
   klass->export = wp_session_item_default_export;
   klass->export_finish = wp_session_item_default_export_finish;
   klass->unexport = wp_session_item_default_unexport;
@@ -416,6 +426,22 @@ wp_session_item_class_init (WpSessionItemClass * klass)
       G_TYPE_NONE, 1, WP_TYPE_SI_FLAGS);
 }
 
+/**
+ * wp_session_item_reset: (virtual reset)
+ * @self: the session item
+ *
+ * Resets the state of the item, deactivating it, unexporting it and
+ * resetting configuration options as well.
+ */
+void
+wp_session_item_reset (WpSessionItem * self)
+{
+  g_return_if_fail (WP_IS_SESSION_ITEM (self));
+  g_return_if_fail (WP_SESSION_ITEM_GET_CLASS (self)->reset);
+
+  WP_SESSION_ITEM_GET_CLASS (self)->reset (self);
+}
+
 /**
  * wp_session_item_get_flags:
  * @self: the session item
@@ -649,19 +675,22 @@ wp_session_item_activate_finish (WpSessionItem * self, GAsyncResult * res,
 }
 
 /**
- * wp_session_item_reset: (virtual reset)
+ * wp_session_item_deactivate: (virtual deactivate)
  * @self: the session item
  *
- * Resets the state of the item, deactivating it, and possibly
- * resetting configuration options as well.
+ * De-activates the item and/or cancels any ongoing activation operation.
+ *
+ * If the item was not activated, this method does nothing.
  */
 void
-wp_session_item_reset (WpSessionItem * self)
+wp_session_item_deactivate (WpSessionItem * self)
 {
   g_return_if_fail (WP_IS_SESSION_ITEM (self));
-  g_return_if_fail (WP_SESSION_ITEM_GET_CLASS (self)->reset);
+  g_return_if_fail (WP_SESSION_ITEM_GET_CLASS (self)->deactivate);
 
-  WP_SESSION_ITEM_GET_CLASS (self)->reset (self);
+  //TODO cancel job if ACTIVATING
+
+  WP_SESSION_ITEM_GET_CLASS (self)->deactivate (self);
 }
 
 /**
@@ -686,6 +715,11 @@ wp_session_item_export (WpSessionItem * self, WpSession * session,
   g_return_if_fail (WP_IS_SESSION (session));
   g_return_if_fail (WP_SESSION_ITEM_GET_CLASS (self)->export);
 
+  WpSessionItemPrivate *priv =
+      wp_session_item_get_instance_private (self);
+
+  g_return_if_fail (!(priv->flags & (WP_SI_FLAG_EXPORTING | WP_SI_FLAG_EXPORTED)));
+
   WP_SESSION_ITEM_GET_CLASS (self)->export (self, session, NULL,
       callback, callback_data);
 }
@@ -726,5 +760,7 @@ wp_session_item_unexport (WpSessionItem * self)
   g_return_if_fail (WP_IS_SESSION_ITEM (self));
   g_return_if_fail (WP_SESSION_ITEM_GET_CLASS (self)->unexport);
 
+  //TODO cancel job if EXPORTING
+
   WP_SESSION_ITEM_GET_CLASS (self)->unexport (self);
 }
diff --git a/lib/wp/session-item.h b/lib/wp/session-item.h
index 92efd2cb1ef0ad02c76031fa47ca82f8d15e1201..554884bc62c73a62e6db91a19eb216d791cb5174 100644
--- a/lib/wp/session-item.h
+++ b/lib/wp/session-item.h
@@ -64,6 +64,7 @@ typedef enum {
 
 /**
  * WpSessionItemClass:
+ * @reset: See wp_session_item_reset()
  * @get_associated_proxy: See wp_session_item_get_associated_proxy()
  * @configure: See wp_session_item_configure()
  * @get_configuration: See wp_session_item_get_configuration()
@@ -71,7 +72,7 @@ typedef enum {
  *   transition of wp_session_item_activate()
  * @execute_step: Implements #WpTransitionClass.execute_step() for the
  *   transition of wp_session_item_activate()
- * @reset: See wp_session_item_reset()
+ * @deactivate: See wp_session_item_deactivate()
  * @export: See wp_session_item_export()
  * @export_finish: See wp_session_item_export_finish()
  * @unexport: See wp_session_item_unexport()
@@ -80,6 +81,8 @@ struct _WpSessionItemClass
 {
   GObjectClass parent_class;
 
+  void (*reset) (WpSessionItem * self);
+
   gpointer (*get_associated_proxy) (WpSessionItem * self, GType proxy_type);
 
   gboolean (*configure) (WpSessionItem * self, GVariant * args);
@@ -89,8 +92,7 @@ struct _WpSessionItemClass
       guint step);
   void (*execute_step) (WpSessionItem * self, WpTransition * transition,
       guint step);
-
-  void (*reset) (WpSessionItem * self);
+  void (*deactivate) (WpSessionItem * self);
 
   void (*export) (WpSessionItem * self,
       WpSession * session, GCancellable * cancellable,
@@ -100,6 +102,9 @@ struct _WpSessionItemClass
   void (*unexport) (WpSessionItem * self);
 };
 
+WP_API
+void wp_session_item_reset (WpSessionItem * self);
+
 /* flags */
 
 WP_API
@@ -140,7 +145,7 @@ gboolean wp_session_item_activate_finish (WpSessionItem * self,
     GAsyncResult * res, GError ** error);
 
 WP_API
-void wp_session_item_reset (WpSessionItem * self);
+void wp_session_item_deactivate (WpSessionItem * self);
 
 /* exporting */
 
diff --git a/modules/module-si-adapter.c b/modules/module-si-adapter.c
index d38fef7bcd1a351ca31f453921872a51206999ea..1b8ebde1db28cca7090c6deb9f7b49041b14fff8 100644
--- a/modules/module-si-adapter.c
+++ b/modules/module-si-adapter.c
@@ -59,24 +59,25 @@ si_adapter_init (WpSiAdapter * self)
 }
 
 static void
-si_adapter_finalize (GObject * object)
+si_adapter_reset (WpSessionItem * item)
 {
-  WpSiAdapter *self = WP_SI_ADAPTER (object);
+  WpSiAdapter *self = WP_SI_ADAPTER (item);
 
-  g_clear_object (&self->node);
+  /* unexport & deactivate first */
+  WP_SESSION_ITEM_CLASS (si_adapter_parent_class)->reset (item);
 
-  G_OBJECT_CLASS (si_adapter_parent_class)->finalize (object);
+  g_clear_object (&self->node);
 }
 
 static void
-si_adapter_reset (WpSessionItem * item)
+si_adapter_deactivate (WpSessionItem * item)
 {
   WpSiAdapter *self = WP_SI_ADAPTER (item);
 
   g_clear_object (&self->ports_om);
   wp_session_item_clear_flag (item, WP_SI_FLAG_CONFIGURED);
 
-  WP_SESSION_ITEM_CLASS (si_adapter_parent_class)->reset (item);
+  WP_SESSION_ITEM_CLASS (si_adapter_parent_class)->deactivate (item);
 }
 
 static gpointer
@@ -362,17 +363,15 @@ si_adapter_execute_step (WpSessionItem * item, WpTransition * transition,
 static void
 si_adapter_class_init (WpSiAdapterClass * klass)
 {
-  GObjectClass *object_class = (GObjectClass *) klass;
   WpSessionItemClass *si_class = (WpSessionItemClass *) klass;
 
-  object_class->finalize = si_adapter_finalize;
-
+  si_class->reset = si_adapter_reset;
   si_class->get_associated_proxy = si_adapter_get_associated_proxy;
   si_class->configure = si_adapter_configure;
   si_class->get_configuration = si_adapter_get_configuration;
   si_class->get_next_step = si_adapter_get_next_step;
   si_class->execute_step = si_adapter_execute_step;
-  si_class->reset = si_adapter_reset;
+  si_class->deactivate = si_adapter_deactivate;
 }
 
 static guint