diff --git a/classified.admin.inc b/classified.admin.inc
index 34819ff..c153e86 100644
--- a/classified.admin.inc
+++ b/classified.admin.inc
@@ -232,3 +232,75 @@ function theme_classified_admin_lifetimes($variables) {
   $ret .= drupal_render_children($form);
   return $ret;
 }
+
+/**
+ * Implements hook_form().
+ */
+
+function classified_types_admin_form ($form, &$form_state) {
+  $types = node_type_get_types();
+  $options = array();
+  foreach ($types as $key => $value) {
+    if ($value->type != 'classified' && ($value->base == 'node_content' || $value->base == 'classified')) {
+      $options[$key] = $value->name;
+    }
+    
+  }
+  $form['classified_content_types'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Content Types'),
+    '#description' => t('Select types to make it to a classified type.<strong>Flush Cache</strong> after setting, please.'),
+    '#options' => $options,
+    '#default_value' => _classified_types_variable_get(),
+
+  );
+
+  $form['actions'] = array('#type' => 'actions');
+  $form['actions']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save configuration'),
+  );
+  return $form;
+}
+
+/**
+ * Implements hook_form_submit().
+ */
+
+function classified_types_admin_form_submit ($form, $form_state) {
+  $types = $form_state['values']['classified_content_types'];
+  foreach ($types as $key => $value) {
+    if (isset($value) && strlen(trim($value)) == strlen(trim($key))) {
+      // set selected type to classified if checked
+      classified_types_set_type($key, 'classified');
+    } else {
+      // set selected type to default if unchecked      
+      classified_types_set_type($key);
+    }
+  }
+  variable_set('classified_content_types', $types);
+}
+
+
+function classified_types_set_type ($type, $module = 'node') {
+  // set selected type to classified http://drupal.org/node/350938
+  if ($module == 'node') {
+    $base = 'node_content';
+  } else {
+    $base = $module;
+  }
+
+  $txn = db_transaction();
+  try {
+    db_update('node_type')
+      ->condition('type', $type)
+      ->fields(array('base' => $base, 'module' => $module))
+      ->execute();
+  }
+  catch (Exception $e) {
+    // Something went wrong somewhere, so roll back now.
+    $txn->rollback();
+    // Log the exception to watchdog.
+    watchdog_exception('classified_types', $e);
+  }
+}
diff --git a/classified.info b/classified.info
index cb654bc..caa8804 100644
--- a/classified.info
+++ b/classified.info
@@ -1,7 +1,6 @@
 name = "Classified Ads"
 description = "A classified ads service"
 package = Classified
-configure = admin/config/content/classified
 
 dependencies[] = field
 dependencies[] = taxonomy
@@ -20,3 +19,10 @@ files[] = tests/classified_notifications.test
 ; a context_registry_alter(), ordering prevents proper plugin detection in 
 ; CTools, so the file is declared directly to the core autoloader.
 files[] = plugins/classified_context_condition_path.inc
+
+; Information added by drupal.org packaging script on 2012-04-02
+version = "7.x-3.0"
+core = "7.x"
+project = "ed_classified"
+datestamp = "1333349450"
+
diff --git a/classified.module b/classified.module
index 61b9a01..89e45f5 100644
--- a/classified.module
+++ b/classified.module
@@ -44,7 +44,7 @@ function _classified_block_view_popular() {
     $results = $q->fields('n', array('nid', 'title'))
       ->fields($td, array('name'))
       ->condition('n.status', 1)
-      ->condition('n.type', 'classified')
+      ->condition('n.type', classified_selected_types_get(), 'IN')
       ->condition("$td.vid", $vid)
       ->addTag('node_access')
       ->orderBy("$nc.totalcount", 'DESC')
@@ -91,7 +91,7 @@ function _classified_block_view_recent() {
   $results = $q->fields('n', array('nid', 'title'))
     ->fields($td, array('name'))
     ->condition('n.status', 1)
-    ->condition('n.type', 'classified')
+    ->condition('n.type', classified_selected_types_get(), 'IN')
     ->condition("$td.vid", $vid)
     ->orderBy('n.created', 'DESC')
     ->orderBy('n.changed', 'DESC')
@@ -133,7 +133,7 @@ function _classified_block_view_stats() {
   $q->addExpression('COUNT(n.nid)', 'nid_count');
   $changed = $q->addExpression('n.changed > :yesterday', 'changed', array(':yesterday' => $yesterday));
   $status = $q->addField('n', 'status');
-  $results = $q->condition('n.type', 'classified')
+  $results = $q->condition('n.type', classified_selected_types_get(), 'IN')
     ->groupBy($changed)
     ->groupBy($status)
     ->execute();
@@ -590,7 +590,7 @@ function _classified_page_term($term) {
   $cn = $q->innerJoin('classified_node', 'cn', 'n.vid = cn.vid');
   $ti = $q->innerJoin('taxonomy_index', 'ti', 'n.nid = ti.nid');
   $nid_alias = $q->addField('n', 'nid', 'id');
-  $q->condition('n.type', 'classified')
+  $q->condition('n.type', classified_selected_types_get(), 'IN')
     ->condition("$ti.tid", $term->tid)
     ->orderBy("$cn.expires")
     ->orderBy("n.changed")
@@ -635,7 +635,7 @@ function _classified_page_user_ads($account) {
     ->limit(10);
   $cn = $q->innerJoin('classified_node', 'cn', 'n.vid = cn.vid');
   $nid_alias = $q->addField('n', 'nid', 'id');
-  $q->condition('n.type', 'classified')
+  $q->condition('n.type', classified_selected_types_get(), 'IN')
     ->condition('n.uid', $account->uid)
     ->condition('n.status', $min_status, '>=')
     ->orderBy("$cn.expires")
@@ -913,22 +913,28 @@ function classified_entity_info_alter(&$entity_info) {
  * Allow repositioning of the expires box
  */
 function classified_field_extra_fields() {
-  $extra['node']['classified'] = array(
-    'form' => array(
-      'expires_fs' => array(
-        'label' => t('Ad Expiration'),
-        'description' => NULL,
-        'weight' => 0,
-      ),
-    ),
-    'display' => array(
-      'expires' => array(
-        'label' => t('Ad expiration'),
-        'description' => t('Publication limit for ad'),
-        'weight' => 2,
-      ),
-    ),
-  );
+  $types = variable_get('classified_content_types', array());
+
+  foreach ($types as $key => $value) {
+    if (isset($value) && strlen(trim($value)) == strlen(trim($key))) {
+      $extra['node']["$key"] = array(
+        'form' => array(
+          'expires_fs' => array(
+            'label' => t('Ad Expiration'),
+            'description' => NULL,
+            'weight' => 0,
+          ),
+        ),
+        'display' => array(
+          'expires' => array(
+            'label' => t('Ad expiration'),
+            'description' => t('Publication limit for ad'),
+            'weight' => 2,
+          ),
+        ),
+      );
+    }
+  }
 
   return $extra;
 }
@@ -1233,6 +1239,15 @@ function classified_menu() {
     'file' => 'classified.admin.inc',
     'access arguments' => array('administer classified ads'),
   );
+  
+  $items['admin/config/content/classified/types'] = array(
+    'title' => 'Classified Types',
+    'description' => 'Configure Content Types to Classified.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('classified_types_admin_form'),
+    'file' => 'classified.admin.inc',
+    'access arguments' => array('administer classified ads'),
+  );
 
   $items['classified'] = array(
     'page callback' => '_classified_page_overview',
@@ -1302,7 +1317,7 @@ function classified_node_access($node, $op, $account) {
     : $node->type;
 
   // Ads admin bypasses checks.
-  if ($type == 'classified' && user_access('administer classified ads', $account)) {
+  if (in_array($type, classified_selected_types_get()) && user_access('administer classified ads', $account)) {
     $ret = NODE_ACCESS_ALLOW;
   }
   // Other checks are defined by node.module permissions. Do not override them.
@@ -1320,19 +1335,37 @@ function classified_node_access($node, $op, $account) {
  *   "match nodeapi $node->type for spam module to add spam reporting links"
  */
 function classified_node_info() {
-  $ret = array(
-    'classified' => array(
-      // Cannot call node_get_types() since it ends up calling this code.
-      'name' => t('Classified Ad'),
+
+  $info = array();
+  // Get selected types infomations
+  $result = db_select('node_type', 'nt')
+    ->fields('nt', array('type', 'name', 'description'))
+    ->condition('type', classified_selected_types_get(),'IN')
+    ->execute();
+  // Build types Info
+  foreach ($result as $type) {
+    $info["$type->type"] = array( 
+      'name' => t($type->name), 
       'base' => 'classified',
-      'description' => t('Contains a title, a body, and an administrator-defined expiration date'),
+      'module' => 'classified', 
+      'description' => t($type->description),
       'has_title' => TRUE,
       'title_label' => t('Ad Title'),
       'locked' => TRUE,
-    ),
+    );
+  }
+
+  $info['classified'] = array(
+    // Cannot call node_get_types() since it ends up calling this code.
+    'name' => t('Classified Ad'),
+    'base' => 'classified',
+    'description' => t('Contains a title, a body, and an administrator-defined expiration date'),
+    'has_title' => TRUE,
+    'title_label' => t('Ad Title'),
+    'locked' => TRUE,
   );
 
-  return $ret;
+  return $info;
 }
 
 /**
@@ -1650,24 +1683,6 @@ function classified_validate($node, &$form) {
   $date = $form['expires_fs']['expire_date']['#value']; // Coder bug #195054.
   $date = _classified_get_timestamp_from_date($date);
 
-  // This can be a user error, as the max_length JS is not being included if form_set_error has been used.
-  $max_length = _classified_get('max-length');
-
-  // Body may include <!--break-->, possibly wrapped with spaces (newlines),
-  // which must not be included in the length count.
-  $body = isset($node->body[LANGUAGE_NONE][0]['value']) ? $node->body[LANGUAGE_NONE][0]['value'] : NULL;
-  $body = preg_replace('/^(.*)\s*<!--break-->\s*(.*)$/sU', '$1$2', $body);
-  // Ignore \r, only count \n
-  $body = str_replace("\r\n", "\n", $body);
-
-  $body_length = drupal_strlen($body);
-  if ($body_length > $max_length) {
-    form_set_error('body', t('Text is longer than maximum authorized length: @body_length characters vs @max_length authorized.', array(
-      '@body_length' => $body_length,
-      '@max_length' => $max_length,
-    )));
-  }
-
   // This is likely a hacking attempt.
   if ($mode == 'force' && !user_access('administer classified ads') && !user_access('reset classified ads expiration')) {
     form_set_error('expire_mode', t('User is not allowed to force expiration date.'));
@@ -1743,3 +1758,33 @@ function classified_url_outbound_alter(&$path, &$options, $original_path) {
     }
   }
 }
+
+/**
+ * Return a classified types variable.
+ */
+function _classified_types_variable_get() {
+  static $variables = array();
+  $variables = variable_get('classified_content_types', array());
+  if (empty($variables)) {
+    $defaults = array('classified_content_types' => array());
+    $variables = array_merge($defaults, $variables);
+  }
+
+  return $variables;
+}
+
+/**
+ * Return selected classified types array.
+ */
+function classified_selected_types_get() {
+  $types = variable_get('classified_content_types', array());
+
+  $classified_types = array();
+  foreach ($types as $key => $value) {
+    if (isset($value) && strlen(trim($value)) == strlen(trim($key))) {
+      $classified_types[] = $key;
+    }
+  }
+
+  return $classified_types;
+}
\ No newline at end of file
diff --git a/classified.scheduled.inc b/classified.scheduled.inc
index a9559d0..e121f04 100644
--- a/classified.scheduled.inc
+++ b/classified.scheduled.inc
@@ -56,7 +56,7 @@ function _classified_scheduled_build_expire($time = NULL) {
   $q = db_select('node', 'n')->comment(__FUNCTION__);
   $cn = $q->innerJoin('classified_node', 'cn', 'n.nid = cn.nid');
   $results = $q->fields('n', array('nid', 'title', 'uid'))
-    ->condition('n.type', 'classified')
+    ->condition('n.type', classified_selected_types_get(), 'IN')
     ->condition('n.status', 1)
     ->condition("$cn.expires", $expires, '<')
     ->execute();
@@ -151,7 +151,7 @@ function _classified_scheduled_build_notify($kind, $time = NULL) {
   switch ($kind) {
     case 'half-life':
       // cn.notify < half-life, now > half-life.
-      $q->condition('n.type', 'classified')
+      $q->condition('n.type', classified_selected_types_get(), 'IN')
         ->condition('n.status', 0, '!=')
         ->where("$cn.notify < (n.changed + $cn.expires) / 2")
         ->where("(n.changed + $cn.expires) / 2 < $now");
@@ -159,7 +159,7 @@ function _classified_scheduled_build_notify($kind, $time = NULL) {
 
     case 'pre-expire':
       // cn.notify < expiration - 1 day, now > expiration - 1 day.
-      $q->condition('n.type', 'classified')
+      $q->condition('n.type', classified_selected_types_get(), 'IN')
         ->condition('n.status', 0, '!=')
         ->where("$cn.notify < $cn.expires - 86400")
         ->condition("$cn.expires", $now + 86400, '<');
@@ -169,7 +169,7 @@ function _classified_scheduled_build_notify($kind, $time = NULL) {
       // cn.notify < purge - 1 day, now > purge - 1 day
       // 'grace' is in days.
       $grace = (_classified_get('grace') - 1) * 24 * 60 * 60;
-      $q->condition('n.type', 'classified')
+      $q->condition('n.type', classified_selected_types_get(), 'IN')
         ->condition('n.status', 0)
         ->where("$cn.notify < $cn.expires + $grace - 86400")
         ->condition("$cn.expires", $now - $grace, '<');
@@ -240,7 +240,7 @@ function _classified_scheduled_build_purge($time = NULL) {
   $cn = $q->innerJoin('classified_node', 'cn', 'n.nid = cn.nid');
 
   $results = $q->fields('n', array('nid', 'title', 'uid'))
-    ->condition('n.type', 'classified')
+    ->condition('n.type', classified_selected_types_get(), 'IN')
     ->condition("$cn.expires", $limit, '<')
     ->execute()
     ->fetchAll();
diff --git a/classified.tokens.inc b/classified.tokens.inc
index b23343c..8fab6ea 100644
--- a/classified.tokens.inc
+++ b/classified.tokens.inc
@@ -101,7 +101,7 @@ function classified_tokens($type, $tokens, array $data = array(), array $options
           ->range(0, 10);
         $cn = $q->innerJoin('classified_node', 'cn', 'n.vid = cn.vid');
         $nid_alias = $q->addField('n', 'nid', 'id');
-        $q->condition('n.type', 'classified')
+        $q->condition('n.type', classified_selected_types_get(), 'IN')
           ->condition('n.uid', $account->uid)
           ->condition('n.status', $min_status, '>=')
           ->orderBy("$cn.expires")
@@ -125,7 +125,7 @@ function classified_tokens($type, $tokens, array $data = array(), array $options
           ->fields('n', array('nid', 'title'))
           ->range(0, 10);
         $cn = $q->innerJoin('classified_node', 'cn', 'n.vid = cn.vid');
-        $q->condition('n.type', 'classified')
+        $q->condition('n.type', classified_selected_types_get(), 'IN')
           ->condition('n.uid', $account->uid)
           ->condition('n.status', $min_status, '>=')
           ->orderBy("$cn.expires")
diff --git a/modules/classified_notifications/classified_notifications.info b/modules/classified_notifications/classified_notifications.info
index 76e4911..07e1695 100644
--- a/modules/classified_notifications/classified_notifications.info
+++ b/modules/classified_notifications/classified_notifications.info
@@ -1,9 +1,15 @@
 name = "Classified Ads Notifications"
 description = "A classified ads service: notifications"
 package = Classified
-configure = admin/config/content/classified/notifications
 
 dependencies[] = classified
 
 core = 7.x
 php = 5.2
+
+; Information added by drupal.org packaging script on 2012-04-02
+version = "7.x-3.0"
+core = "7.x"
+project = "ed_classified"
+datestamp = "1333349450"
+
diff --git a/modules/classified_notifications/classified_notifications.module b/modules/classified_notifications/classified_notifications.module
index 9d0de53..b4a63dc 100644
--- a/modules/classified_notifications/classified_notifications.module
+++ b/modules/classified_notifications/classified_notifications.module
@@ -185,6 +185,7 @@ function classified_notifications_cron_queue_info() {
  * @param array $job
  */
 function classified_notifications_deliver($job) {
+  dsm($job, __FUNCTION__);
   drupal_mail_system('classified_notifications', $job['key'])->mail($job['message']);
 }
 
diff --git a/plugins/content_types/classified_expires.inc b/plugins/content_types/classified_expires.inc
index 432c793..790dfb8 100644
--- a/plugins/content_types/classified_expires.inc
+++ b/plugins/content_types/classified_expires.inc
@@ -53,7 +53,7 @@ function classified_classified_expires_content_type_render($subtype, $conf, $pan
 
   // Get a shortcut to the node.
   $node = $context->data;
-  if ($node->type != 'classified') {
+  if (!in_array($node->type, classified_selected_types_get())) {
     return;
   }
 
diff --git a/tests/classified_basic.test b/tests/classified_basic.test
index 427dd4c..85cdf92 100644
--- a/tests/classified_basic.test
+++ b/tests/classified_basic.test
@@ -288,7 +288,7 @@ class ClassifiedBasicTest extends ClassifiedAbstractTest {
     foreach ($links as $link) {
       $href = (string) $link['href'];
       $parsed = drupal_parse_url($href);
-      $path = $parsed['path'];
+      $path = drupal_substr($parsed['path'], drupal_strlen(base_path()));
       $this->assertTrue(drupal_match_path($path, $pattern), t('Path %path matches %pattern', array(
         '%path' => $path,
         '%pattern' => $pattern,
@@ -535,78 +535,8 @@ class ClassifiedBasicTest extends ClassifiedAbstractTest {
     $token = 'classified-ads-url';
     $translation = token_replace("[user:$token]", array('user' => $this->creatorUser));
     $url = url('user/'. $node->uid . '/classified', array('absolute' => TRUE));
-    // URLs may contain a ?q=, which would be interpreted in a regex
-    $url = str_replace('?', '\?', $url);
     $this->assertTrue(preg_match("@$url@", $translation), t('User ads URL found from %token.', array(
       '%token' => $token,
     )), $this->group);
   }
-
-  /**
-   * Add server-side body length validation.
-   */
-  public function test1653560() {
-    $this->group = __FUNCTION__;
-    $accounts = array('creator');
-    $this->createUsers($accounts);
-    $this->drupalLogin($this->creatorUser);
-
-    // 1. Get the node type name.
-    $type = node_type_get_name('classified');
-
-    // 2. Get the Classified vocabulary id.
-    $vid = _classified_get('vid');
-
-    // 3a. Create a term in it, do not assign a specific lifetime.
-    $term = (object) array(
-      'name' => $this->randomName(8),
-      'description' => $this->randomString(20),
-      'vid' => $vid,
-    );
-    $status = taxonomy_term_save($term);
-    $tid = $term->tid;
-    $this->assertEqual($status, SAVED_NEW, t('Term @tid created in default vocabulary.', array('@tid' => $tid)), 'setup');
-
-    // 3b. Limit the maximum body length.
-    $max_length = 20;
-    variable_set('classified-max-length', $max_length);
-
-    // 4a. Try to create an ad bearing that term, with a body below max length.
-    $count = db_query('SELECT COUNT(nid) FROM {node}')->fetchField();
-    $this->assertEqual(0, $count, t('No node found before creation of first ad'), $this->group);
-
-    $langcode = LANGUAGE_NONE;
-    $body_key = "body[$langcode][0][value]";
-    $term_key = "classified_category[$langcode]";
-    $edit = array(
-      'title' => $this->randomString(10),
-      $term_key => $tid,
-      $body_key => 'A short body',
-    );
-
-    $ret = $this->drupalPost('node/add/classified', $edit, t('Save'));
-    $raw = t('@type %title has been created.', array(
-      '@type' => $type,
-      '%title' => $edit['title'],
-    ));
-    $this->assertRaw($raw, t('Ad with proper body receives creation confirmation'), $this->group);
-    $count = db_query('SELECT COUNT(nid) FROM {node}')->fetchField();
-    $this->assertEqual(1, $count, t('Ad with proper body actually created.'), $this->group);
-
-    // 4b. Try to create an ad bearing that term, with a body above max length.
-    $edit = array(
-      'title' => $this->randomString(10),
-      $term_key => $tid,
-      $body_key => 'A body longer than 20 characters',
-    );
-
-    $ret = $this->drupalPost('node/add/classified', $edit, t('Save'));
-    $raw = t('Text is longer than maximum authorized length: @body_length characters vs @max_length authorized.', array(
-      '@body_length' => drupal_strlen($edit[$body_key]),
-      '@max_length' => $max_length,
-    ));
-    $this->assertRaw($raw, t('Ad with extra-long body receives post error.'), $this->group);
-    $count = db_query('SELECT COUNT(nid) FROM {node}')->fetchField();
-    $this->assertEqual(1, $count, t('Ad with extra-long body actually not created.'), $this->group);
-  }
 }
diff --git a/tests/classified_test.info b/tests/classified_test.info
index 489fc5a..c78464a 100644
--- a/tests/classified_test.info
+++ b/tests/classified_test.info
@@ -4,3 +4,10 @@ package = Classified
 
 core = 7.x
 hidden = TRUE
+
+; Information added by drupal.org packaging script on 2012-04-02
+version = "7.x-3.0"
+core = "7.x"
+project = "ed_classified"
+datestamp = "1333349450"
+
