diff --git a/tests/tfa.test b/tests/tfa.test
index e74fc5d..85d049d 100644
--- a/tests/tfa.test
+++ b/tests/tfa.test
@@ -352,7 +352,7 @@ class TfaTestCase extends DrupalWebTestCase {
    * Test TfaBasePlugin encryption methods.
    */
   protected function testEncryption() {
-    $tfa_totp = new TfaTestTotp();
+    $tfa_totp = new TfaTestTotp(array('uid' => 1));
     $plain_text = $this->randomName(rand(6,20));
     $tfa_totp->setInStore($plain_text);
     $this->assertIdentical($plain_text, $tfa_totp->readFromStore());
diff --git a/tests/tfa_test.module b/tests/tfa_test.module
index 6c109c4..9088354 100644
--- a/tests/tfa_test.module
+++ b/tests/tfa_test.module
@@ -89,8 +89,10 @@ function tfa_test_setup_form_submit($form, &$form_state) {
   if (empty($form_state['storage'])) {
     // Unlike the standard Tfa process and tfa_form(). TfaSetup can use
     // $form_state storage to persist user context.
+    $context = array('uid' => $account->uid);
     $class = variable_get('tfa_test_setup_class', '');
-    $tfaSetup = new TfaSetup(array('setup' => $class), array('uid' => $account->uid));
+    $setup_plugin = new $class($context);
+    $tfaSetup = new TfaSetup($setup_plugin, array(), $context);
 
     $form_state['storage']['tfa_setup'] = $tfaSetup;
     $form_state['rebuild'] = TRUE;
diff --git a/tfa.admin.inc b/tfa.admin.inc
index 28319af..39fb4b9 100644
--- a/tfa.admin.inc
+++ b/tfa.admin.inc
@@ -183,6 +183,7 @@ function tfa_admin_settings($form, $form_state) {
  * Admin form submission handler.
  */
 function tfa_admin_settings_submit($form, &$form_state) {
+  dpm($form_state);
   drupal_set_message(t('Configuration saved'));
   $values = $form_state['values'];
   // Set enabled.
diff --git a/tfa.api.php b/tfa.api.php
index 00c536d..1ab5a8d 100644
--- a/tfa.api.php
+++ b/tfa.api.php
@@ -113,8 +113,11 @@ function my_tfa_setup_form_submit($form, &$form_state) {
   if (empty($form_state['storage'])) {
     // Start the TfaSetup process.
 
-    // $class must be defined somehow (e.g. from a variable)
-    $tfaSetup = new TfaSetup(array('setup' => $class), array('uid' => $account->uid));
+    $context = array('uid' => $account->uid);
+    // Setup plugin class must be defined somehow (e.g. from a variable).
+    $class = 'MyTfaPluginSetup';
+    $setup_plugin = $class($context);
+    $tfaSetup = new TfaSetup($setup_plugin, $context);
 
     // Store TfaSetup process for multi-step.
     $form_state['storage']['tfa_setup'] = $tfaSetup;
diff --git a/tfa.inc b/tfa.inc
index 1abcef7..3e27d57 100644
--- a/tfa.inc
+++ b/tfa.inc
@@ -42,21 +42,21 @@ class Tfa {
   /**
    * TFA constructor.
    *
-   * @param array $plugins
-   *   Plugins to instansiate.
-   *
-   *   Must include key:
+   * @param TfaBasePlugin $validate
+   *   Validation plugin.
    *
-   *     - 'validate'
-   *       Class name of TfaBasePlugin implementing TfaValidationPluginInterface.
+   * @param array $plugins
+   *   Additional, optional plugins.
    *
    *   May include keys:
    *
    *     - 'login'
-   *       Array of classes of TfaBasePlugin implementing TfaLoginPluginInterface.
+   *       Array of TfaBasePlugin objects implementing TfaLoginPluginInterface
+   *       indexed by class name.
    *
    *     - 'fallback'
-   *       Array of classes of TfaBasePlugin that can be used as fallback processes.
+   *       Array of TfaBasePlugin objects that can be used as fallback processes
+   *       indexed by class name.
    *
    * @param array $context
    *   Context of TFA process.
@@ -65,42 +65,37 @@ class Tfa {
    *
    *     - 'uid'
    *       Account uid of user in TFA process.
-   *
    */
-  public function __construct(array $plugins, array $context) {
-    if (empty($plugins['validate'])) {
-      // @todo throw exception?
-    }
+  public function __construct(TfaBasePlugin $validate, array $plugins, array $context) {
+    $active_plugins = array();
 
-    $this->validatePlugin = new $plugins['validate']($context);
+    $this->validatePlugin = $validate;
     if (!empty($plugins['login'])) {
-      foreach ($plugins['login'] as $class) {
-        $this->loginPlugins[] = new $class($context);
+      foreach ($plugins['login'] as $pluginClass => $loginPlugin) {
+        $this->loginPlugins[] = $loginPlugin;
+        $active_plugins['login'][] = $pluginClass;
       }
     }
     if (!empty($plugins['fallback'])) {
-      $plugins['fallback'] = array_unique($plugins['fallback']);
-      // @todo consider making plugin->ready a class method?
-      foreach ($plugins['fallback'] as $key => $class) {
-        if ($class === $plugins['validate']) {
-          unset($plugins['fallback'][$key]);
-          continue; // Skip this fallback if its same as validation.
+      foreach ($plugins['fallback'] as $pluginClass => $fallbackPlugin) {
+        // Skip this fallback if its same as validation.
+        if ($pluginClass === get_class($plugins['validate'])) {
+          continue;
         }
-        $fallback = new $class($context);
-        // Only plugins that are ready can stay.
-        if ($fallback->ready()) {
-          $this->fallbackPlugins[] = $class;
-        }
-        else {
-          unset($plugins['fallback'][$key]);
+        // Only use plugins that are ready.
+        if ($fallbackPlugin->ready()) {
+          $this->fallbackPlugins[] = $fallbackPlugin;
+          $active_plugins['validate'][] = $pluginClass;
         }
       }
+      // Mark whether a fallback plugin exists.
       if (!empty($this->fallbackPlugins)) {
         $this->fallback = TRUE;
       }
     }
     $this->context = $context;
-    $this->context['plugins'] = $plugins;
+    // Save only active plugins.
+    $this->context['plugins'] = $active_plugins;
   }
 
   /**
@@ -285,13 +280,8 @@ class TfaSetup {
   /**
    * TFA Setup constructor.
    *
-   * @param array $plugins
-   *   Plugins to instansiate.
-   *
-   *   Must include key:
-   *
-   *     - 'setup'
-   *       Class name of TfaBasePlugin implementing TfaSetupPluginInterface.
+   * @param TfaBasePlugin $setupPlugin
+   *   Plugin being set up.
    *
    * @param array $context
    *   Context of TFA process.
@@ -302,13 +292,9 @@ class TfaSetup {
    *       Account uid of user in TFA process.
    *
    */
-  public function __construct(array $plugins, array $context) {
-    if (empty($plugins['setup'])) {
-      // @todo throw exception?
-    }
-    $this->setupPlugin = new $plugins['setup']($context);
+  public function __construct(TfaBasePlugin $setupPlugin, array $context) {
+    $this->setupPlugin = $setupPlugin;
     $this->context = $context;
-    $this->context['plugins'] = $plugins;
   }
 
   /**
diff --git a/tfa.module b/tfa.module
index 043df03..81e5cae 100644
--- a/tfa.module
+++ b/tfa.module
@@ -59,8 +59,10 @@ function tfa_permission() {
 /**
  * Set context for account's TFA process.
  *
- * @param $account User account
- * @param array $context Context array
+ * @param object $account
+ *   User account
+ * @param array $context
+ *   Context array
  *   @see tfa_start_context() for context format
  */
 function tfa_set_context($account, $context) {
@@ -73,7 +75,8 @@ function tfa_set_context($account, $context) {
 /**
  * Context for account TFA process.
  *
- * @param $account User account
+ * @param object $account
+ *   User account
  * @return array
  *   @see tfa_start_context() for format
  */
@@ -90,7 +93,9 @@ function tfa_get_context($account) {
 /**
  * Start context for TFA.
  *
- * @param $account User account
+ * @param object $account
+ *   User account
+ *
  * @return array
  *   array(
  *     'uid' => 9,
@@ -98,31 +103,37 @@ function tfa_get_context($account) {
  *       'validate' => 'TfaMySendPlugin',
  *       'login' => arrray('TfaMyLoginPlugin'),
  *       'fallback' => array('TfaMyRecoveryCodePlugin'),
- *       'setup' => 'TfaMySetupPlugin',
  *     ),
  */
 function tfa_start_context($account) {
-  $context = array('uid' => $account->uid, 'plugins' => array());
+  $plugins = array(
+    'validate' => '',
+    'fallback' => array(),
+    'login' => array(),
+  );
 
   $api = module_invoke_all('tfa_api');
   // Add login plugins.
   foreach (variable_get('tfa_login_plugins', array()) as $key) {
     if (array_key_exists($key, $api)) {
-      $context['plugins']['login'][] = $api[$key]['class'];
+      $plugins['login'][] = $api[$key]['class'];
     }
   }
   // Add validate.
   $validate = variable_get('tfa_validate_plugin', '');
+  //var_export($validate);
+  //exit;
   if (!empty($validate) && array_key_exists($validate, $api)) {
-    $context['plugins']['validate'] = $api[$validate]['class'];
+    $plugins['validate'] = $api[$validate]['class'];
   }
   // Add fallback plugins.
   foreach (variable_get('tfa_fallback_plugins', array()) as $key) {
     if (array_key_exists($key, $api)) {
-      $context['plugins']['fallback'][] = $api[$key]['class'];
+      $plugins['fallback'][] = $api[$key]['class'];
     }
   }
   // Allow other modules to modify TFA context.
+  $context = array('uid' => $account->uid, 'plugins' => $plugins);
   drupal_alter('tfa_context', $context);
   tfa_set_context($account, $context);
   return $context;
@@ -131,7 +142,8 @@ function tfa_start_context($account) {
 /**
  * Remove context for account.
  *
- * @param $account User account object
+ * @param object $account
+ *   User account object
  */
 function tfa_clear_context($account) {
   unset($_SESSION['tfa'][$account->uid]);
@@ -140,7 +152,9 @@ function tfa_clear_context($account) {
 /**
  * Get Tfa object in the account's current context.
  *
- * @param $account User account object
+ * @param object $account
+ *   User account
+ *
  * @return Tfa
  */
 function tfa_get_process($account) {
@@ -150,8 +164,27 @@ function tfa_get_process($account) {
     if (empty($context)) {
       $context = tfa_start_context($account);
     }
-    $plugins = $context['plugins'];
-    $tfa = new Tfa($plugins, $context);
+    $plugins = array('fallback' => array(), 'login' => array());
+    // Instantiate plugins.
+    $validate_class = $context['plugins']['validate'];
+    //var_export($validate_class);
+    //exit;
+    $validate = new $validate_class($context);
+    if (!empty($context['plugins']['fallback'])) {
+      foreach ($context['plugins']['fallback'] as $class) {
+        if (!array_key_exists($class, $plugins['fallback']) && $class !== $validate_class) {
+          $plugins['fallback'][$class] = new $class($context);
+        }
+      }
+    }
+    if (!empty($context['plugins']['login'])) {
+      foreach ($context['plugins']['login'] as $class) {
+        if (!array_key_exists($class, $plugins['login']) && $class !== $validate_class) {
+          $plugins['login'][$class] = new $class($context);
+        }
+      }
+    }
+    $tfa = new Tfa($validate, $plugins, $context);
   }
   return $tfa;
 }
