Index: modules/blog/blog.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/blog/blog.module,v
retrieving revision 1.318
diff -u -p -r1.318 blog.module
--- modules/blog/blog.module	15 Apr 2009 13:50:07 -0000	1.318
+++ modules/blog/blog.module	16 Apr 2009 08:44:03 -0000
@@ -74,7 +74,7 @@ function blog_help($path, $arg) {
  */
 function blog_form($node, $form_state) {
   global $nid;
-  $type = node_get_types('type', $node);
+  $type = node_type_get_type($node);
 
   $form['title'] = array('#type' => 'textfield', '#title' => check_plain($type->title_label), '#required' => TRUE, '#default_value' => !empty($node->title) ? $node->title : NULL, '#weight' => -5);
   $form['body_field'] = node_body_field($node, $type->body_label, $type->min_word_count);
Index: modules/blogapi/blogapi.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/blogapi/blogapi.module,v
retrieving revision 1.147
diff -u -p -r1.147 blogapi.module
--- modules/blogapi/blogapi.module	1 Apr 2009 01:28:24 -0000	1.147
+++ modules/blogapi/blogapi.module	16 Apr 2009 08:44:04 -0000
@@ -719,7 +719,7 @@ function blogapi_blogger_title(&$content
  * Add some settings to the admin_settings form.
  */
 function blogapi_admin_settings() {
-  $node_types = array_map('check_plain', node_get_types('names'));
+  $node_types = array_map('check_plain', node_type_get_names());
   $defaults = isset($node_types['blog']) ? array('blog' => 1) : array();
   $form['blogapi_node_types'] = array(
     '#type' => 'checkboxes',
@@ -959,7 +959,7 @@ function _blogapi_validate_blogid($blogi
 function _blogapi_get_node_types() {
   $available_types = array_keys(array_filter(variable_get('blogapi_node_types', array('blog' => 1))));
   $types = array();
-  foreach (node_get_types() as $type => $name) {
+  foreach (node_type_get_types() as $type => $name) {
     if (node_access('create', $type) && in_array($type, $available_types)) {
       $types[] = $type;
     }
Index: modules/book/book.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.admin.inc,v
retrieving revision 1.19
diff -u -p -r1.19 book.admin.inc
--- modules/book/book.admin.inc	14 Mar 2009 20:13:26 -0000	1.19
+++ modules/book/book.admin.inc	16 Apr 2009 08:44:04 -0000
@@ -35,7 +35,7 @@ function book_admin_overview() {
  * @ingroup forms
  */
 function book_admin_settings() {
-  $types = node_get_types('names');
+  $types = node_type_get_names();
   $form['book_allowed_types'] = array(
     '#type' => 'checkboxes',
     '#title' => t('Allowed book outline types'),
Index: modules/comment/comment.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.install,v
retrieving revision 1.32
diff -u -p -r1.32 comment.install
--- modules/comment/comment.install	26 Feb 2009 07:30:26 -0000	1.32
+++ modules/comment/comment.install	16 Apr 2009 08:44:04 -0000
@@ -18,7 +18,7 @@ function comment_uninstall() {
 
   // Remove variables.
   variable_del('comment_block_count');
-  $node_types = array_keys(node_get_types());
+  $node_types = array_keys(node_type_get_types());
   foreach ($node_types as $node_type) {
     variable_del('comment_' . $node_type);
     variable_del('comment_anonymous_' . $node_type);
@@ -85,7 +85,7 @@ function comment_update_6002() {
     'comment_preview' => COMMENT_PREVIEW_REQUIRED,
     'comment_form_location' => COMMENT_FORM_SEPARATE_PAGE,
   );
-  $types = node_get_types();
+  $types = node_type_get_types();
   foreach ($settings as $setting => $default) {
     $value = variable_get($setting, $default);
     foreach ($types as $type => $object) {
@@ -120,7 +120,7 @@ function comment_update_6003() {
  * Remove comment settings for page ordering.
  */
 function comment_update_7000() {
-  $types = node_get_types();
+  $types = node_type_get_types();
   foreach ($types as $type => $object) {
     variable_del('comment_default_order' . $type);
   }
Index: modules/field/field.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.api.php,v
retrieving revision 1.7
diff -u -p -r1.7 field.api.php
--- modules/field/field.api.php	13 Apr 2009 05:18:17 -0000	1.7
+++ modules/field/field.api.php	16 Apr 2009 08:44:04 -0000
@@ -47,7 +47,7 @@ function hook_fieldable_info() {
       'cacheable' => FALSE,
       // Bundles must provide human readable name so
       // we can create help and error messages about them.
-      'bundles' => node_get_types('names'),
+      'bundles' => node_type_get_names(),
     ),
   );
   return $return;
Index: modules/forum/forum.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.module,v
retrieving revision 1.489
diff -u -p -r1.489 forum.module
--- modules/forum/forum.module	17 Mar 2009 12:41:54 -0000	1.489
+++ modules/forum/forum.module	16 Apr 2009 08:44:04 -0000
@@ -539,7 +539,7 @@ function forum_block_view($delta = '') {
  * Implementation of hook_form().
  */
 function forum_form(&$node, $form_state) {
-  $type = node_get_types('type', $node);
+  $type = node_type_get_type($node);
   $form['title'] = array('#type' => 'textfield', '#title' => check_plain($type->title_label), '#default_value' => !empty($node->title) ? $node->title : '', '#required' => TRUE, '#weight' => -5);
 
   if (!empty($node->nid)) {
@@ -747,7 +747,7 @@ function template_preprocess_forums(&$va
       if (node_access('create', $type)) {
         // Fetch the "General" name of the content type;
         // Push the link with title and url to the array.
-        $forum_types[$type] = array('title' => t('Post new @node_type', array('@node_type' => node_get_types('name', $type))), 'href' => 'node/add/' . str_replace('_', '-', $type) . '/' . $variables['tid']);
+        $forum_types[$type] = array('title' => t('Post new @node_type', array('@node_type' => node_type_get_name($type))), 'href' => 'node/add/' . str_replace('_', '-', $type) . '/' . $variables['tid']);
       }
     }
 
Index: modules/locale/locale.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.install,v
retrieving revision 1.35
diff -u -p -r1.35 locale.install
--- modules/locale/locale.install	1 Apr 2009 20:00:46 -0000	1.35
+++ modules/locale/locale.install	16 Apr 2009 08:44:04 -0000
@@ -166,7 +166,7 @@ function locale_update_6004() {
  * interfere with language variables.
  */
 function locale_update_6005() {
-  foreach (node_get_types() as $type => $content_type) {
+  foreach (node_type_get_types() as $type => $content_type) {
     // Default to NULL, so we can skip dealing with non-existent settings.
     $setting = variable_get('language_' . $type);
     if ($type == 'default' && is_numeric($setting)) {
@@ -226,7 +226,7 @@ function locale_uninstall() {
   variable_del('locale_cache_strings');
   variable_del('locale_js_directory');
   
-  foreach (node_get_types() as $type => $content_type) {
+  foreach (node_type_get_types() as $type => $content_type) {
     $setting = variable_del('language_content_type_' . $type);
   }
   
Index: modules/node/content_types.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/content_types.inc,v
retrieving revision 1.64
diff -u -p -r1.64 content_types.inc
--- modules/node/content_types.inc	26 Jan 2009 14:08:43 -0000	1.64
+++ modules/node/content_types.inc	16 Apr 2009 08:44:04 -0000
@@ -10,14 +10,14 @@
  * Displays the content type admin overview page.
  */
 function node_overview_types() {
-  $types = node_get_types();
-  $names = node_get_types('names');
+  $types = node_type_get_types();
+  $names = node_type_get_names();
   $header = array(t('Name'), array('data' => t('Operations'), 'colspan' => '2'));
   $rows = array();
 
   foreach ($names as $key => $name) {
-    $type = $types[$key];
-    if (node_hook($type, 'form')) {
+    $type = $types[$key]; 
+    if (node_hook($type->type, 'form')) {
       $type_url_str = str_replace('_', '-', $type->type);
       $row = array(theme('node_admin_overview', $name, $type));
       // Set the edit column.
@@ -233,7 +233,7 @@ function node_type_form_validate($form, 
   // Work out what the type was before the user submitted this form
   $old_type = trim($form_state['values']['old_type']);
 
-  $types = node_get_types('names');
+  $types = node_type_get_names();
 
   if (!$form_state['values']['locked']) {
     if (isset($types[$type->type]) && $type->type != $old_type) {
Index: modules/node/node.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.admin.inc,v
retrieving revision 1.43
diff -u -p -r1.43 node.admin.inc
--- modules/node/node.admin.inc	20 Mar 2009 08:14:34 -0000	1.43
+++ modules/node/node.admin.inc	16 Apr 2009 08:44:05 -0000
@@ -150,7 +150,7 @@ function node_filters() {
     );
   }
 
-  $filters['type'] = array('title' => t('type'), 'options' => node_get_types('names'));
+  $filters['type'] = array('title' => t('type'), 'options' => node_type_get_names());
 
   // The taxonomy filter
   if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) {
@@ -512,7 +512,7 @@ function node_admin_nodes() {
     $nodes[$node->nid] = '';
     $options = empty($node->language) ? array() : array('language' => $languages[$node->language]);
     $form['title'][$node->nid] = array('#markup' => l($node->title, 'node/' . $node->nid, $options) . ' ' . theme('mark', node_mark($node->nid, $node->changed)));
-    $form['name'][$node->nid] =  array('#markup' => check_plain(node_get_types('name', $node)));
+    $form['name'][$node->nid] =  array('#markup' => check_plain(node_type_get_name($node)));
     $form['username'][$node->nid] = array('#markup' => theme('username', $node));
     $form['status'][$node->nid] =  array('#markup' => ($node->status ? t('published') : t('not published')));
     $form['changed'][$node->nid] = array('#markup' => format_date($node->changed, 'small'));
Index: modules/node/node.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.api.php,v
retrieving revision 1.13
diff -u -p -r1.13 node.api.php
--- modules/node/node.api.php	17 Mar 2009 12:41:54 -0000	1.13
+++ modules/node/node.api.php	16 Apr 2009 08:44:05 -0000
@@ -620,7 +620,7 @@ function hook_prepare(&$node) {
  * For a detailed usage example, see node_example.module.
  */
 function hook_form(&$node, $form_state) {
-  $type = node_get_types('type', $node);
+  $type = node_type_get_type($node);
 
   $form['title'] = array(
     '#type' => 'textfield',
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1033
diff -u -p -r1.1033 node.module
--- modules/node/node.module	26 Mar 2009 13:31:25 -0000	1.1033
+++ modules/node/node.module	16 Apr 2009 08:44:06 -0000
@@ -80,12 +80,12 @@ function node_help($path, $arg) {
       return '<p>' . t('The revisions let you track differences between multiple versions of a post.') . '</p>';
     case 'node/%/edit':
       $node = node_load($arg[1]);
-      $type = node_get_types('type', $node->type);
+      $type = node_type_get_type($node);
       return (!empty($type->help) ? '<p>' . filter_xss_admin($type->help) . '</p>' : '');
   }
 
   if ($arg[0] == 'node' && $arg[1] == 'add' && $arg[2]) {
-    $type = node_get_types('type', str_replace('-', '_', $arg[2]));
+    $type = node_type_get_type(str_replace('-', '_', $arg[2]));
     return (!empty($type->help) ? '<p>' . filter_xss_admin($type->help) . '</p>' : '');
   }
 }
@@ -165,7 +165,7 @@ function node_fieldable_info() {
       // 'cacheable' => FALSE,
       // Bundles must provide human readable name so
       // we can create help and error messages about them.
-      'bundles' => node_get_types('names'),
+      'bundles' => node_type_get_names(),
     ),
   );
   return $return;
@@ -470,67 +470,13 @@ function node_teaser($body, $format = NU
 }
 
 /**
- * Builds a list of available node types, and returns all of part of this list
- * in the specified format.
- *
- * @param $op
- *   The format in which to return the list. When this is set to 'type',
- *   'base', or 'name', only the specified node type is returned. When set to
- *   'types' or 'names', all node types are returned.
- * @param $node
- *   A node object, array, or string that indicates the node type to return.
- *   Leave at default value (NULL) to return a list of all node types.
- * @param $reset
- *   Whether or not to reset this function's internal cache (defaults to
- *   FALSE).
- *
- * @return
- *   Either an array of all available node types, or a single node type, in a
- *   variable format. Returns FALSE if the node type is not found.
- */
-function node_get_types($op = 'types', $node = NULL, $reset = FALSE) {
-  static $_node_types, $_node_names;
-
-  if ($reset || !isset($_node_types)) {
-    list($_node_types, $_node_names) = _node_types_build();
-  }
-
-  if ($node) {
-    if (is_array($node)) {
-      $type = $node['type'];
-    }
-    elseif (is_object($node)) {
-      $type = $node->type;
-    }
-    elseif (is_string($node)) {
-      $type = $node;
-    }
-    if (!isset($_node_types[$type])) {
-      return FALSE;
-    }
-  }
-  switch ($op) {
-    case 'types':
-      return $_node_types;
-    case 'type':
-      return isset($_node_types[$type]) ? $_node_types[$type] : FALSE;
-    case 'base':
-      return isset($_node_types[$type]->base) ? $_node_types[$type]->base : FALSE;
-    case 'names':
-      return $_node_names;
-    case 'name':
-      return isset($_node_names[$type]) ? $_node_names[$type] : FALSE;
-  }
-}
-
-/**
  * Resets the database cache of node types, and saves all new or non-modified
  * module-defined node types to the database.
  */
 function node_types_rebuild() {
-  _node_types_build();
-
-  $node_types = node_get_types('types', NULL, TRUE);
+  // Reset and load updated node types.
+  drupal_static_reset('_node_types_build');
+  $node_types = node_type_get_types();
 
   foreach ($node_types as $type => $info) {
     if (!empty($info->is_new)) {
@@ -540,13 +486,120 @@ function node_types_rebuild() {
       node_type_delete($info->type);
     }
   }
-
-  _node_types_build();
+  // Reset internal static cache of _node_types_build so that the next access will use the updated data.
+  drupal_static_reset('_node_types_build');
   // This is required for proper menu items at node/add/type.
   menu_rebuild();
 }
 
 /**
+ * Extract the type name.
+ *
+ * The function tries to extract either the property or key type. In case
+ * $node is a string, the value is simply passed back.
+ *
+ * @param $node
+ *   Either a string, array or object, containing the type information.
+ *
+ * @return
+ *   Node type of the passed in data.
+ */
+function _node_extract_type($node) {
+  if (is_object($node)) {
+    return $node->type;
+  }
+  if (is_string($node)) {
+    return $node;
+  }
+  if (is_array($node)) {
+    return $node['type'];
+  }
+}
+
+/**
+ * Returns a list of all the available node types.
+ *
+ * @param $reset
+ *   Whether or not to reset the node list (defaults to FALSE).
+ * @return
+ *   An array of node types, keyed by the type.
+ * @see node_type_get_type()
+ */
+function node_type_get_types() {
+  return _node_types_build()->types;
+}
+
+/**
+ * Returns the node type of the passed node or node type string.
+ *
+ *@param $node
+ *   A node object, array, or string that indicates the node type to return.
+ * @return
+ *   A single node type, as an object or FALSE if the node type is not found.
+ *   The node type is an array with following content:
+ *
+ *   @code
+ *   array(
+ *     'type' => 'Machine readable type name',
+ *     'name' => 'Name of the node type',
+ *     'base' => 'Indicates to which module this node type belongs',
+ *     'description' => 'Description of the node type',
+ *     // ...
+ *   )
+ *   @endcode
+ */
+function node_type_get_type($node) {
+  $type = _node_extract_type($node);
+  $types =  _node_types_build()->types;
+  return isset($types[$type]) ? $types[$type] : FALSE;
+}
+
+/**
+ * Returns the node type base of the passed node or node type string.
+ *
+ * The base indicates which module implement this node type and is used to
+ * execute node type specific hooks.
+ *
+ * @see node_invoke()
+ *
+ * @param $node
+ *   A node object, array, or string that indicates the node type to return.
+ * @return
+ *   The node type base or FALSE if the node type is not found.
+ */
+function node_type_get_base($node) {
+  $type = _node_extract_type($node);
+  $types =  _node_types_build()->types;
+  return isset($types[$type]) && isset($types[$type]->base) ? $types[$type]->base : FALSE;
+}
+
+/**
+ * Returns a list of available node names.
+ *
+ * @return
+ *   An array of node type names, keyed by the type.
+ */
+function node_type_get_names() {
+  return _node_types_build()->names;
+}
+
+/**
+ * Returns the node type name of the passed node or node type string.
+ *
+ * @param $node
+ *   A node object, array, or string that indicates the node type to return.
+ *
+ * @return
+ *   The node type name or FALSE if the node type is not found.
+ */
+function node_type_get_name($node) {
+  $type = _node_extract_type($node);
+  $types =  _node_types_build()->names;
+  return isset($types[$type]) ? $types[$type] : FALSE;
+}
+
+
+/**
  * Saves a node type to the database.
  *
  * @param $info
@@ -604,7 +657,7 @@ function node_type_save($info) {
  *   The machine-readable name of the node type to be deleted.
  */
 function node_type_delete($type) {
-  $info = node_get_types('type', $type);
+  $info = node_type_get_type($type);
   db_query("DELETE FROM {node_type} WHERE type = '%s'", $type);
   module_invoke_all('node_type', 'delete', $info);
 }
@@ -633,14 +686,17 @@ function node_type_update_nodes($old_typ
  *
  */
 function _node_types_build() {
-  $_node_types = array();
-  $_node_names = array();
+  $_node_types = drupal_static(__FUNCTION__);
+  if (is_object($_node_types)) {
+    return $_node_types;
+  }
+  $_node_types = (object) array('types' => array(), 'names' => array());
 
   $info_array = module_invoke_all('node_info');
   foreach ($info_array as $type => $info) {
     $info['type'] = $type;
-    $_node_types[$type] = node_type_set_defaults($info);
-    $_node_names[$type] = $info['name'];
+    $_node_types->types[$type] = node_type_set_defaults($info);
+    $_node_types->names[$type] = $info['name'];
   }
 
   $type_result = db_query(db_rewrite_sql('SELECT nt.type, nt.* FROM {node_type} nt ORDER BY nt.type ASC', 'nt', 'type'));
@@ -652,20 +708,20 @@ function _node_types_build() {
     if (isset($type_object->base) && $type_object->base != 'node_content' && empty($info_array[$type_object->type])) {
       $type_object->disabled = TRUE;
     }
-    if (!isset($_node_types[$type_object->type]) || $type_object->modified) {
-      $_node_types[$type_object->type] = $type_object;
-      $_node_names[$type_object->type] = $type_object->name;
+    if (!isset($_node_types->types[$type_object->type]) || $type_object->modified) {
+      $_node_types->types[$type_object->type] = $type_object;
+      $_node_types->names[$type_object->type] = $type_object->name;
 
       if ($type_object->type != $type_object->orig_type) {
-        unset($_node_types[$type_object->orig_type]);
-        unset($_node_names[$type_object->orig_type]);
+        unset($_node_types->types[$type_object->orig_type]);
+        unset($_node_types->names[$type_object->orig_type]);
       }
     }
   }
 
-  asort($_node_names);
+  asort($_node_types->names);
 
-  return array($_node_types, $_node_names);
+  return $_node_types;
 }
 
 /**
@@ -730,7 +786,7 @@ function node_type_set_defaults($info = 
  *   TRUE iff the $hook exists in the node type of $node.
  */
 function node_hook(&$node, $hook) {
-  $base = node_get_types('base', $node);
+  $base = node_type_get_base($node);
   return module_hook($base, $hook);
 }
 
@@ -748,7 +804,7 @@ function node_hook(&$node, $hook) {
  */
 function node_invoke(&$node, $hook, $a2 = NULL, $a3 = NULL, $a4 = NULL) {
   if (node_hook($node, $hook)) {
-    $base = node_get_types('base', $node);
+    $base = node_type_get_base($node);
     $function = $base . '_' . $hook;
     return ($function($node, $a2, $a3, $a4));
   }
@@ -904,7 +960,7 @@ function node_load_multiple($nids = arra
     // Call node type specific callbacks on each typed array of nodes.
     foreach ($typed_nodes as $type => $nodes_of_type) {
       if (node_hook($type, 'load')) {
-        $function = node_get_types('base', $type) . '_load';
+        $function = node_type_get_base($type) . '_load';
         $function($nodes_of_type);
       }
     }
@@ -970,7 +1026,7 @@ function node_load($nid, $vid = array(),
 function node_validate($node, $form = array()) {
   // Convert the node to an object, if necessary.
   $node = (object)$node;
-  $type = node_get_types('type', $node);
+  $type = node_type_get_type($node);
 
   // Make sure the body has the minimum number of words.
   // TODO : use a better word counting algorithm that will work in other languages
@@ -1183,7 +1239,7 @@ function node_delete($nid) {
       search_wipe($node->nid, 'node');
     }
     watchdog('content', '@type: deleted %title.', array('@type' => $node->type, '%title' => $node->title));
-    drupal_set_message(t('@type %title has been deleted.', array('@type' => node_get_types('name', $node), '%title' => $node->title)));
+    drupal_set_message(t('@type %title has been deleted.', array('@type' => node_type_get_name($node), '%title' => $node->title)));
   }
 }
 
@@ -1345,7 +1401,7 @@ function node_perm() {
     ),
   );
 
-  foreach (node_get_types() as $type) {
+  foreach (node_type_get_types() as $type) {
     if ($type->base == 'node_content') {
       $perms += node_list_permissions($type);
     }
@@ -1504,7 +1560,7 @@ function node_search($op = 'search', $ke
 
         $results[] = array(
           'link' => url('node/' . $item->sid, array('absolute' => TRUE)),
-          'type' => check_plain(node_get_types('name', $node)),
+          'type' => check_plain(node_type_get_name($node)),
           'title' => $node->title,
           'user' => theme('username', $node),
           'date' => $node->changed,
@@ -1662,7 +1718,7 @@ function _node_revision_access($node, $o
 }
 
 function _node_add_access() {
-  $types = node_get_types();
+  $types = node_type_get_types();
   foreach ($types as $type) {
     if (node_hook($type->type, 'form') && node_access('create', $type->type)) {
       return TRUE;
@@ -1742,7 +1798,9 @@ function node_menu() {
     'access arguments' => array('access content'),
     'type' => MENU_CALLBACK,
   );
-  foreach (node_get_types('types', NULL, TRUE) as $type) {
+  // Reset internal static cache of _node_types_build, forces to rebuild the node type information.
+  drupal_static_reset('_node_types_build');
+  foreach (node_type_get_types() as $type) {
     $type_url_str = str_replace('_', '-', $type->type);
     $items['node/add/' . $type_url_str] = array(
       'title' => $type->name,
@@ -2167,7 +2225,7 @@ function node_form_search_form_alter(&$f
     }
 
     // Node types:
-    $types = array_map('check_plain', node_get_types('names'));
+    $types = array_map('check_plain', node_type_get_names());
     $form['advanced']['type'] = array(
       '#type' => 'checkboxes',
       '#title' => t('Only of the type(s)'),
@@ -2324,7 +2382,7 @@ function node_access($op, $node, $accoun
 
   // Can't use node_invoke('access', $node), because the access hook takes the
   // $op parameter before the $node parameter.
-  $base = node_get_types('base', $node);
+  $base = node_type_get_base($node);
   $access = module_invoke($base, 'access', $op, $node, $account);
   if (!is_null($access)) {
     return $access;
@@ -2775,7 +2833,9 @@ function node_content_access($op, $node,
  * Implementation of hook_form().
  */
 function node_content_form($node, $form_state) {
-  $type = node_get_types('type', $node);
+  
+  $type = node_type_get_type($node);
+  
   $form = array();
 
   if ($type->has_title) {
@@ -2805,7 +2865,7 @@ function node_content_form($node, $form_
  */
 function node_forms() {
   $forms = array();
-  if ($types = node_get_types()) {
+  if ($types = node_type_get_types()) {
     foreach (array_keys($types) as $type) {
       $forms[$type . '_node_form']['callback'] = 'node_form';
     }
@@ -2954,7 +3014,7 @@ function node_action_info() {
  */
 function node_publish_action(&$node, $context = array()) {
   $node->status = 1;
-  watchdog('action', 'Set @type %title to published.', array('@type' => node_get_types('name', $node), '%title' => $node->title));
+  watchdog('action', 'Set @type %title to published.', array('@type' => node_type_get_name($node), '%title' => $node->title));
 }
 
 /**
@@ -2963,7 +3023,7 @@ function node_publish_action(&$node, $co
  */
 function node_unpublish_action(&$node, $context = array()) {
   $node->status = 0;
-  watchdog('action', 'Set @type %title to unpublished.', array('@type' => node_get_types('name', $node), '%title' => $node->title));
+  watchdog('action', 'Set @type %title to unpublished.', array('@type' => node_type_get_name($node), '%title' => $node->title));
 }
 
 /**
@@ -2972,7 +3032,7 @@ function node_unpublish_action(&$node, $
  */
 function node_make_sticky_action(&$node, $context = array()) {
   $node->sticky = 1;
-  watchdog('action', 'Set @type %title to sticky.', array('@type' => node_get_types('name', $node), '%title' => $node->title));
+  watchdog('action', 'Set @type %title to sticky.', array('@type' => node_type_get_name($node), '%title' => $node->title));
 }
 
 /**
@@ -2981,7 +3041,7 @@ function node_make_sticky_action(&$node,
  */
 function node_make_unsticky_action(&$node, $context = array()) {
   $node->sticky = 0;
-  watchdog('action', 'Set @type %title to unsticky.', array('@type' => node_get_types('name', $node), '%title' => $node->title));
+  watchdog('action', 'Set @type %title to unsticky.', array('@type' => node_type_get_name($node), '%title' => $node->title));
 }
 
 /**
@@ -2990,7 +3050,7 @@ function node_make_unsticky_action(&$nod
  */
 function node_promote_action(&$node, $context = array()) {
   $node->promote = 1;
-  watchdog('action', 'Promoted @type %title to front page.', array('@type' => node_get_types('name', $node), '%title' => $node->title));
+  watchdog('action', 'Promoted @type %title to front page.', array('@type' => node_type_get_name($node), '%title' => $node->title));
 }
 
 /**
@@ -2999,7 +3059,7 @@ function node_promote_action(&$node, $co
  */
 function node_unpromote_action(&$node, $context = array()) {
   $node->promote = 0;
-  watchdog('action', 'Removed @type %title from front page.', array('@type' => node_get_types('name', $node), '%title' => $node->title));
+  watchdog('action', 'Removed @type %title from front page.', array('@type' => node_type_get_name($node), '%title' => $node->title));
 }
 
 /**
@@ -3008,7 +3068,7 @@ function node_unpromote_action(&$node, $
  */
 function node_save_action($node) {
   node_save($node);
-  watchdog('action', 'Saved @type %title', array('@type' => node_get_types('name', $node), '%title' => $node->title));
+  watchdog('action', 'Saved @type %title', array('@type' => node_type_get_name($node), '%title' => $node->title));
 }
 
 /**
@@ -3018,7 +3078,7 @@ function node_save_action($node) {
 function node_assign_owner_action(&$node, $context) {
   $node->uid = $context['owner_uid'];
   $owner_name = db_result(db_query("SELECT name FROM {users} WHERE uid = %d", $context['owner_uid']));
-  watchdog('action', 'Changed owner of @type %title to uid %name.', array('@type' => node_get_types('type', $node), '%title' => $node->title, '%name' => $owner_name));
+  watchdog('action', 'Changed owner of @type %title to uid %name.', array('@type' => node_type_get_type($node), '%title' => $node->title, '%name' => $owner_name));
 }
 
 function node_assign_owner_action_form($context) {
@@ -3098,7 +3158,7 @@ function node_unpublish_by_keyword_actio
   foreach ($context['keywords'] as $keyword) {
     if (strstr(drupal_render(node_build(clone $node)), $keyword) || strstr($node->title, $keyword)) {
       $node->status = 0;
-      watchdog('action', 'Set @type %title to unpublished.', array('@type' => node_get_types('name', $node), '%title' => $node->title));
+      watchdog('action', 'Set @type %title to unpublished.', array('@type' => node_type_get_name($node), '%title' => $node->title));
       break;
     }
   }
@@ -3113,7 +3173,7 @@ function node_unpublish_by_keyword_actio
  *   An array of permission names and descriptions.
  */
 function node_list_permissions($type) {
-  $info = node_get_types('type', $type);
+  $info = node_type_get_type($type);
   $type = check_plain($info->type);
 
   // Build standard list of node permissions for this type.
Index: modules/node/node.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.pages.inc,v
retrieving revision 1.60
diff -u -p -r1.60 node.pages.inc
--- modules/node/node.pages.inc	15 Apr 2009 13:28:08 -0000	1.60
+++ modules/node/node.pages.inc	16 Apr 2009 08:44:06 -0000
@@ -11,7 +11,7 @@
  * Menu callback; presents the node editing form, or redirects to delete confirmation.
  */
 function node_page_edit($node) {
-  $type_name = node_get_types('name', $node);
+  $type_name = node_type_get_name($node);
   drupal_set_title(t('<em>Edit @type</em> @title', array('@type' => $type_name, '@title' => $node->title)), PASS_THROUGH);
   return drupal_get_form($node->type . '_node_form', $node);
 }
@@ -53,7 +53,7 @@ function theme_node_add_list($content) {
 function node_add($type) {
   global $user;
 
-  $types = node_get_types();
+  $types = node_type_get_types();
   $type = isset($type) ? str_replace('-', '_', $type) : NULL;
   // If a node type has been specified, validate its existence.
   if (isset($types[$type]) && node_access('create', $type)) {
@@ -459,7 +459,7 @@ function node_form_submit($form, &$form_
   node_save($node);
   $node_link = l(t('view'), 'node/' . $node->nid);
   $watchdog_args = array('@type' => $node->type, '%title' => $node->title);
-  $t_args = array('@type' => node_get_types('name', $node), '%title' => $node->title);
+  $t_args = array('@type' => node_type_get_name($node), '%title' => $node->title);
 
   if ($insert) {
     watchdog('content', '@type: added %title.', $watchdog_args, WATCHDOG_NOTICE, $node_link);
@@ -591,7 +591,7 @@ function node_revision_revert_confirm_su
   node_save($node_revision);
 
   watchdog('content', '@type: reverted %title revision %revision.', array('@type' => $node_revision->type, '%title' => $node_revision->title, '%revision' => $node_revision->vid));
-  drupal_set_message(t('@type %title has been reverted back to the revision from %revision-date.', array('@type' => node_get_types('name', $node_revision), '%title' => $node_revision->title, '%revision-date' => format_date($node_revision->revision_timestamp))));
+  drupal_set_message(t('@type %title has been reverted back to the revision from %revision-date.', array('@type' => node_type_get_name($node_revision), '%title' => $node_revision->title, '%revision-date' => format_date($node_revision->revision_timestamp))));
   $form_state['redirect'] = 'node/' . $node_revision->nid . '/revisions';
 }
 
@@ -605,7 +605,7 @@ function node_revision_delete_confirm_su
   db_query("DELETE FROM {node_revision} WHERE nid = %d AND vid = %d", $node_revision->nid, $node_revision->vid);
   node_invoke_node($node_revision, 'delete_revision');
   watchdog('content', '@type: deleted %title revision %revision.', array('@type' => $node_revision->type, '%title' => $node_revision->title, '%revision' => $node_revision->vid));
-  drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($node_revision->revision_timestamp), '@type' => node_get_types('name', $node_revision), '%title' => $node_revision->title)));
+  drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($node_revision->revision_timestamp), '@type' => node_type_get_name($node_revision), '%title' => $node_revision->title)));
   $form_state['redirect'] = 'node/' . $node_revision->nid;
   if (db_result(db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = %d', $node_revision->nid)) > 1) {
     $form_state['redirect'] .= '/revisions';
Index: modules/node/node.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.test,v
retrieving revision 1.20
diff -u -p -r1.20 node.test
--- modules/node/node.test	15 Apr 2009 13:28:08 -0000	1.20
+++ modules/node/node.test	16 Apr 2009 08:44:06 -0000
@@ -664,3 +664,34 @@ class NodeRSSContentTestCase extends Dru
     $this->assertText($test_text, t('Extra node content appears in RSS feed.'));
   }
 }
+
+/**
+ * Tests related to node types.
+ */
+class NodeTypeTestCase extends DrupalWebTestCase {
+  function getInfo() {
+    return array(
+      'name' => t('Node types'),
+      'description' => t('Ensures that node type functions work correctly.'),
+      'group' => t('Node'),
+    );
+  }
+
+  /**
+   * Ensure that node type functions (node_type_get_*) work correctly. Load
+   * available node types and validate the returned data.
+   */
+  function testNodeTypeGetFunctions() {
+    $node_types = node_type_get_types();
+    $node_names = node_type_get_names();
+
+    $this->assertTrue(isset($node_types['article']), t('Node type article is available.'));
+    $this->assertTrue(isset($node_types['page']), t('Node type page is available.'));
+
+    $this->assertEqual($node_types['article']->name, $node_names['article'], t('Correct node type base has been returned.'));
+
+    $this->assertEqual($node_types['article'], node_type_get_type('article'), t('Correct node type has been returned.'));
+    $this->assertEqual($node_types['article']->name, node_type_get_name('article'), t('Correct node type name has been returned.'));
+    $this->assertEqual($node_types['page']->base, node_type_get_base('page'), t('Correct node type base has been returned.'));
+  }
+}
Index: modules/poll/poll.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/poll/poll.module,v
retrieving revision 1.290
diff -u -p -r1.290 poll.module
--- modules/poll/poll.module	9 Mar 2009 20:36:58 -0000	1.290
+++ modules/poll/poll.module	16 Apr 2009 08:44:06 -0000
@@ -206,7 +206,7 @@ function poll_form(&$node, $form_state) 
 
   $admin = user_access('administer nodes') || user_access('edit any poll content') || (user_access('edit own poll content') && $user->uid == $node->uid);
 
-  $type = node_get_types('type', $node);
+  $type = node_type_get_type($node);
 
   $form = array(
     '#cache' => TRUE,
Index: modules/poll/poll.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/poll/poll.test,v
retrieving revision 1.16
diff -u -p -r1.16 poll.test
--- modules/poll/poll.test	31 Mar 2009 01:49:53 -0000	1.16
+++ modules/poll/poll.test	16 Apr 2009 08:44:07 -0000
@@ -41,7 +41,7 @@ class PollTestCase extends DrupalWebTest
 
     $this->drupalPost(NULL, $edit, t('Save'));
     $node = $this->drupalGetNodeByTitle($title);
-    $this->assertRaw(t('@type %title has been created.', array('@type' => node_get_types('name', 'poll'), '%title' => $title)), 'Poll has been created.');
+    $this->assertRaw(t('@type %title has been created.', array('@type' => node_type_get_name('poll'), '%title' => $title)), 'Poll has been created.');
     $this->assertTrue($node->nid, t('Poll has been found in the database'));
 
     return isset($node->nid) ? $node->nid : FALSE;
Index: modules/search/search.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.api.php,v
retrieving revision 1.5
diff -u -p -r1.5 search.api.php
--- modules/search/search.api.php	8 Mar 2009 04:25:05 -0000	1.5
+++ modules/search/search.api.php	16 Apr 2009 08:44:07 -0000
@@ -181,7 +181,7 @@ function hook_search($op = 'search', $ke
 
         $results[] = array(
           'link' => url('node/' . $item->sid, array('absolute' => TRUE)),
-          'type' => check_plain(node_get_types('name', $node)),
+          'type' => check_plain(node_type_get_name($node)),
           'title' => $node->title,
           'user' => theme('username', $node),
           'date' => $node->changed,
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.92
diff -u -p -r1.92 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php	30 Mar 2009 05:35:35 -0000	1.92
+++ modules/simpletest/drupal_web_test_case.php	16 Apr 2009 08:44:07 -0000
@@ -534,7 +534,7 @@ class DrupalWebTestCase {
     // find a non-existent random type name.
     do {
       $name = strtolower($this->randomName(3, 'type_'));
-    } while (node_get_types('type', $name));
+    } while (node_type_get_type($name));
 
     // Populate defaults array
     $defaults = array(
Index: modules/system/system.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.api.php,v
retrieving revision 1.25
diff -u -p -r1.25 system.api.php
--- modules/system/system.api.php	29 Mar 2009 23:11:09 -0000	1.25
+++ modules/system/system.api.php	16 Apr 2009 08:44:08 -0000
@@ -895,7 +895,7 @@ function hook_mail($key, &$message, $par
     $variables += array(
       '%uid' => $node->uid,
       '%node_url' => url('node/' . $node->nid, array('absolute' => TRUE)),
-      '%node_type' => node_get_types('name', $node),
+      '%node_type' => node_type_get_name($node),
       '%title' => $node->title,
       '%teaser' => $node->teaser,
       '%body' => $node->body,
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.314
diff -u -p -r1.314 system.install
--- modules/system/system.install	3 Apr 2009 17:50:21 -0000	1.314
+++ modules/system/system.install	16 Apr 2009 08:44:09 -0000
@@ -3215,7 +3215,7 @@ function system_update_7017() {
  */
 function system_update_7018() {
   $ret = array();
-  $types = node_get_types();
+  $types = node_type_get_types();
   if (count($types)) {
     foreach ($types as $type) {
       $node_info = theme_get_setting('toggle_node_info_' . $type->type);
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.679
diff -u -p -r1.679 system.module
--- modules/system/system.module	15 Apr 2009 23:49:08 -0000	1.679
+++ modules/system/system.module	16 Apr 2009 08:44:09 -0000
@@ -2101,7 +2101,7 @@ function system_mail($key, &$message, $p
     $variables += array(
       '%uid' => $node->uid,
       '%node_url' => url('node/' . $node->nid, array('absolute' => TRUE)),
-      '%node_type' => node_get_types('name', $node),
+      '%node_type' => node_type_get_name($node),
       '%title' => $node->title,
       '%teaser' => $node->teaser,
       '%body' => $node->body,
@@ -2175,7 +2175,7 @@ function system_message_action(&$object,
     $variables = array_merge($variables, array(
       '%uid' => $node->uid,
       '%node_url' => url('node/' . $node->nid, array('absolute' => TRUE)),
-      '%node_type' => check_plain(node_get_types('name', $node)),
+      '%node_type' => check_plain(node_type_get_name($node)),
       '%title' => filter_xss($node->title),
       '%teaser' => filter_xss($node->teaser),
       '%body' => filter_xss($node->body),
Index: modules/taxonomy/taxonomy.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.admin.inc,v
retrieving revision 1.49
diff -u -p -r1.49 taxonomy.admin.inc
--- modules/taxonomy/taxonomy.admin.inc	15 Apr 2009 14:12:55 -0000	1.49
+++ modules/taxonomy/taxonomy.admin.inc	16 Apr 2009 08:44:10 -0000
@@ -19,7 +19,7 @@ function taxonomy_overview_vocabularies(
   foreach ($vocabularies as $vocabulary) {
     $types = array();
     foreach ($vocabulary->nodes as $type) {
-      $node_type = node_get_types('name', $type);
+      $node_type = node_type_get_name($type);
       $types[] = $node_type ? check_plain($node_type) : check_plain($type);
     }
     $form[$vocabulary->vid]['#vocabulary'] = $vocabulary;
@@ -145,7 +145,7 @@ function taxonomy_form_vocabulary(&$form
     '#type' => 'checkboxes',
     '#title' => t('Content types'),
     '#default_value' => $edit['nodes'],
-    '#options' => array_map('check_plain', node_get_types('names')),
+    '#options' => array_map('check_plain', node_type_get_names()),
     '#description' => t('Select content types to categorize using this vocabulary.'),
   );
   $form['settings'] = array(
Index: modules/tracker/tracker.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/tracker/tracker.pages.inc,v
retrieving revision 1.17
diff -u -p -r1.17 tracker.pages.inc
--- modules/tracker/tracker.pages.inc	5 Apr 2009 12:26:12 -0000	1.17
+++ modules/tracker/tracker.pages.inc	16 Apr 2009 08:44:10 -0000
@@ -68,7 +68,7 @@ function tracker_page($account = NULL, $
     }
 
     $rows[] = array(
-      check_plain(node_get_types('name', $node->type)),
+      check_plain(node_type_get_name($node->type)),
       l($node->title, "node/$node->nid") . ' ' . theme('mark', node_mark($node->nid, $node->changed)),
       theme('username', $node),
       array('class' => 'replies', 'data' => $comments),
