diff --git a/captcha.module b/captcha.module
index 3612eca861c5371e94a764dfccfee9011108e438..dc75a5f99f18cf25ff95bac6adb2817963476423 100644
--- a/captcha.module
+++ b/captcha.module
@@ -29,18 +29,45 @@ function captcha_menu($may_cache) {
       'callback' => 'drupal_get_form',
       'callback arguments' => array('captcha_admin_settings'),
       'access' => user_access('administer site configuration'),
-      'type' => MENU_NORMAL_ITEM,
+      'type' => MENU_DEFAULT_LOCAL_TASK,
     );
+    /*$items[] = array(
+      'path' => 'admin/settings/captcha/points',
+      'title' => t('Captcha'),
+      'description' => t('Administer in what forms Captchas are applied.'),
+      'callback' => 'drupal_get_form',
+      'callback arguments' => array('captcha_admin_points'),
+      'access' => user_access('administer site configuration'),
+      'type' => MENU_LOCAL_TASK,
+    );*/
   }
   return $items;
 }
 
-/**
- * Helper function generates admin settings page.
- */
-function captcha_admin_settings() {
 
-  // This is where you can add more captcha points.
+function _captcha_supported_challenges_types(){
+  static $captcha_challenges = NULL;
+  
+  if($captcha_challenges != NULL) {
+  	return $captcha_challenges; 
+  }	
+  
+  $captcha_challenges['none'] = 'none';
+  
+  foreach(module_implements('captcha') as $module) {
+    $result = call_user_func_array($module .'_captcha', 'list');
+    if (isset($result)) { //&& is_array($result)) {
+      foreach($result as $challenge) {
+      	$captcha_challenges[$module.'/'.$challenge] = $module.'/'.$challenge;
+      }
+    }
+  }
+  
+  
+  return $captcha_challenges;
+}
+
+function _captcha_basic_captcha_points() {
   $captcha_points = array(
     'comment_form' => t('Comment form'),
     'user_login' => t('User login form'),
@@ -52,54 +79,37 @@ function captcha_admin_settings() {
     'contact_mail_page' => t('Sitewide contact form'),
     'node_form' => t('Create a node'),
   );
+  return $captcha_points;  
+}
 
-  $roles = user_roles();
-
+/**
+ * Helper function generates admin settings page.
+ */
+function captcha_admin_settings() {  
+  $captcha_points = variable_get('captcha_points',_captcha_basic_captcha_points());
+  $roles = variable_get('captcha_roles',user_roles());
+  $captcha_challenges = _captcha_supported_challenges_types();
+  
   foreach($roles as $role) {
     $varsuffix = strtr($role, ' ', '_') .'_captcha';
     $form[$varsuffix] = array(
       '#type' => 'fieldset',
       '#title' => t('Captcha points for the role @role', array('@role' => $role)),
+      '#description' => t('Select what kind of challenge you want to pose to the user in each captcha point.'),
       '#collapsible' => TRUE,
       '#collapsed' => TRUE,
     );
     foreach($captcha_points as $captcha_point => $captcha_point_description) {
       $varname = $captcha_point .'_'. $varsuffix;
       $form[$varsuffix][$varname] = array(
-        '#type' => 'checkbox',
-        '#title' => $captcha_point_description,
-        '#default_value' => variable_get($varname, NULL),
+        '#type' => 'select',
+        '#title' => t('@point', array('@point' => $captcha_point_description)),
+        '#default_value' => variable_get($varname, 'captcha/Math'),
+        '#options' => $captcha_challenges,
       );
     }
   }
-
-  // preprocess array into a map
-  foreach(module_implements('captchachallenge') as $module) {
-    $captchamodules[$module] = $module;
-  }
-
-  $form['captcha_type'] = array(
-    '#type' => 'select',
-    '#title' => t('Type of captcha to use'),
-    '#default_value' => variable_get('captcha_type', 'captcha'),
-    '#options' => $captchamodules,
-    '#description' => t('Select what kind of challenge you want to pose to the user.'),
-  );
-
-  $form['captcha_description'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Additional response description text'),
-    '#default_value' => variable_get('captcha_description', ''),
-    '#description' => t('This text will be added below the captcha response field.'),
-  );
-
-  $form['captcha_override_module_description'] = array(
-    '#type' => 'checkbox',
-    '#title' => t("Override module's form item description"),
-    '#default_value' => variable_get('captcha_override_module_description', 0),
-    '#description' => t("Override the captcha module's form item description to the one set above."),
-  );
-
+  
   return system_settings_form($form);
 }
 
@@ -107,112 +117,108 @@ function captcha_admin_settings() {
  * Implementation of hook_form_alter().
  */
 function captcha_form_alter($form_id, &$form) {
+  global $captcha;
   global $user;
-  $captcha_type = variable_get("captcha_type", NULL);
 
-  if (!$captcha_type) {
+  $seed = $form['form_token']['#default_value'];
+  if($_SESSION['captcha'][$seed]['success'] === TRUE)
     return;
-  }
 
-  $flag = TRUE;
-  $trigger = NULL;
+  foreach($user->roles as $role) {	
+  	$candidate_trigger = $form_id .'_'. strtr($role, ' ', '_') .'_captcha';
+  	$captcha_type = variable_get($candidate_trigger,NULL);
 
-  foreach($user->roles as $role) {
-    $candidate_trigger = $form_id .'_'. strtr($role, ' ', '_') .'_captcha';
-    if (variable_get($candidate_trigger, NULL)) {
-      $trigger = $candidate_trigger;
-    }
-    else {
-      $flag = FALSE;
-      break;
-    }
+  	if($captcha_type != NULL) {
+  	  //Found one valid captcha challenge for this point.
+  	  break;
+  	}
   }
-  if ($flag && isset($trigger)) {
-    $form['#submit'] = array('captcha_submit' => array()) + $form['#submit'];
-    if (!_captcha_validate($_POST['captcha_response'])) {
-      if (module_hook($captcha_type, 'captchachallenge')) {
-        call_user_func_array($captcha_type .'_captchachallenge', array(&$form, &$_SESSION['captcha']));
-        if(variable_get('captcha_override_module_description', 0)) {
-          unset($form['captcha_response']['#description']);
-        }
-        if (strlen(variable_get('captcha_description', '')) > 0) {
-          if (isset($form['captcha_response']['#description'])) {
-            $form['captcha_response']['#description'] .= ' '. variable_get('captcha_description', '');
-          }
-          else {
-            $form['captcha_response']['#description'] = variable_get('captcha_description', '');
-          }
-        }
-      }
-    }
-  }
-}
 
-/**
- * Implementation of hook_submit().
- *
- * On submit, captcha is reset.
- */
-function captcha_submit() {
-  if($_SESSION['captcha_correct']) {
-    unset($_SESSION['captcha_correct']);
-    unset($_SESSION['captcha']);
+  if($captcha_type == 'none') {
+    //One of the user roles doesn't have captcha challenge for this point, aborting.
+    return;
   }
+  elseif($captcha_type == NULL) {
+  	//captcha_type null;
+  	return;
+  }
+     
+  $challenge = explode('/',$captcha_type);
+   
+  $result = module_invoke($challenge[0], 'captcha', 'generate', $challenge[1]);
+  
+  $form = array_merge($form,$result['form']);
+  
+  $form['#validate'] += array('captcha_validate' => array());
+  $form['#pre_render'] = array('captcha_prerender');
+
+  $_SESSION['captcha'][$seed]['success'] = FALSE;
+  $_SESSION['captcha'][$seed]['form_id'] = $form_id;
+  $_SESSION['captcha'][$seed]['form'] = $result['form'];
+  $_SESSION['captcha'][$seed]['new_value'] = $result['value'];
+  $_SESSION['captcha'][$seed]['preprocess'] = isset($result['preprocess'])? $result['preprocess'] : FALSE;
+  $_SESSION['captcha'][$seed]['module'] = $challenge[0];
+  $_SESSION['captcha'][$seed]['type'] = $challenge[1];
 }
 
-/**
- * Helper function validates captchas.
- */
-function _captcha_validate($captcha_response) {
+function captcha_validate($form_id, $form_item) {
+  $seed = $form_item['form_token'];
 
-  if ($_SESSION['captcha_correct']) {
-    return TRUE;
-  }
-  if (is_array($captcha_response)) {
-    $captcha_response = $captcha_response['#value'];
+  if($_SESSION['captcha'][$seed]['preprocess']) {
+    $value = module_invoke($_SESSION['captcha'][$seed]['module'],'captcha','process',$_SESSION['captcha'][$seed]['type'],$form_item['captcha_challenge']);
   }
+  else {
+  	$value = $form_item['captcha_challenge'];
+  } 
 
-  global $user;
-  $captcha_type = variable_get("captcha_type", NULL);
-  $trigger = NULL;
-
-  if (module_hook($captcha_type, 'captchavalidate')) {
-    call_user_func_array($captcha_type .'_captchavalidate', array(&$captcha_response, &$_SESSION['captcha_correct']));
+  if($value == $_SESSION['captcha'][$seed]['value']) {
+  	$_SESSION['captcha'][$seed]['success'] = TRUE;
+    return;
   }
-
-  return $_SESSION['captcha_correct'];
+  form_set_error('captcha_response', t('The answer you entered to the captcha challenge is incorrect.'));  
 }
 
 /**
- * Default implementation of the captcha challenge & validation
+ * Implementation of form #pre_render.
+ *
  */
-function captcha_captchachallenge(&$form, &$captcha) {
-
-  $x = rand(1,10);
-  $y = rand(1,10);
-
-  $captcha = (string)($x + $y);
-  $form['captcha_response'] = array (
-    '#type' => 'textfield',
-    '#title' => t('Math Question: What is %problem?', array('%problem' => $x .' + '. $y)),
-    '#description' => t('Please solve the math problem above and type in the result. e.g. for 1+1, type 2.'),
-    '#weight' => 0,
-    '#required' => TRUE,
-    '#validate' => array('_captcha_validate' => array()),
-  );
+function captcha_prerender($form_id, $form) {
+  $seed = $form['#post']['form_token'];
+  $_SESSION['captcha'][$seed]['value'] = $_SESSION['captcha'][$seed]['new_value'];
+  if($_SESSION['captcha'][$seed]['success']) {
+  	unset($form['captcha_challenge']);
+  	unset($_SESSION['captcha'][$seed]);
+  }
 }
 
+
+
 /**
- * Default implementation of the captcha validation function.
+ * Default implementation of hook_captcha
  */
-function captcha_captchavalidate(&$captcha_word, &$correct) {
-  $captcha_word = drupal_strtolower($captcha_word);
-  
-  if (($_SESSION['captcha'] != '') && ($captcha_word == $_SESSION['captcha'])) {
-    $correct = TRUE;
-  }
-  else {
-    $correct = FALSE;
-    form_set_error('captcha_response', t('The answer you entered to the math problem is incorrect.'));
+function captcha_captcha() {
+  $args = func_get_args();
+  $op = array_shift($args); 
+  switch($op) {
+  	case 'list':
+  	  return array("Math");
+  	case 'generate':
+  	  $captcha_type = array_shift($args);
+  	  $result = array();
+  	  if($captcha_type == "Math") {
+        $x = rand(1,10);
+        $y = rand(1,10);
+	
+        $result['value'] = (string)($x + $y);
+        $result['form']['captcha_challenge'] = array (
+          '#type' => 'textfield',
+          '#title' => t('Math Question: What is %problem?', array('%problem' => $x .' + '. $y)),
+          '#description' => t('Please solve the math problem above and type in the result. e.g. for 1+1, type 2.'),
+          '#weight' => 0,
+          '#required' => TRUE,
+//          '#validate' => array('_captcha_validate' => array()),
+        );
+  	  }
+	  return $result;
   }
 }