diff --git core/modules/book/book.module core/modules/book/book.module
index c102849..bbdfab3 100644
--- core/modules/book/book.module
+++ core/modules/book/book.module
@@ -102,7 +102,7 @@ function book_node_view_link(Node $node, $view_mode) {
       if ((user_access('add content to books') || user_access('administer book outlines')) && node_access('create', $child_type) && $node->status == 1 && $node->book['depth'] < MENU_MAX_DEPTH) {
         $links['book_add_child'] = array(
           'title' => t('Add child page'),
-          'href' => 'node/add/' . str_replace('_', '-', $child_type),
+          'href' => 'node/add/' . $child_type,
           'query' => array('parent' => $node->book['mlid']),
         );
       }
diff --git core/modules/comment/comment.module core/modules/comment/comment.module
index 179c46a..79f2ecb 100644
--- core/modules/comment/comment.module
+++ core/modules/comment/comment.module
@@ -135,7 +135,7 @@ function comment_entity_info() {
         // See comment_node_type_load() and comment_menu_alter().
         'path' => 'admin/structure/types/manage/%comment_node_type/comment',
         'bundle argument' => 4,
-        'real path' => 'admin/structure/types/manage/' . str_replace('_', '-', $type) . '/comment',
+        'real path' => 'admin/structure/types/manage/' . $type . '/comment',
         'access arguments' => array('administer content types'),
       ),
     );
@@ -150,9 +150,7 @@ function comment_entity_info() {
  * This function is used as a menu loader callback in comment_menu().
  *
  * @param $name
- *   The URL-formatted machine name of the node type whose comment fields are
- *   to be edited. 'URL-formatted' means that underscores are replaced by
- *   hyphens.
+ *   The machine name of the node type whose comment fields are to be edited.
  *
  * @return
  *   The comment bundle name corresponding to the node type.
@@ -160,7 +158,7 @@ function comment_entity_info() {
  * @see comment_menu_alter()
  */
 function comment_node_type_load($name) {
-  if ($type = node_type_get_type(strtr($name, array('-' => '_')))) {
+  if ($type = node_type_load($name)) {
     return 'comment_node_' . $type->type;
   }
 }
diff --git core/modules/entity/entity.api.php core/modules/entity/entity.api.php
index f49b761..8f721cf 100644
--- core/modules/entity/entity.api.php
+++ core/modules/entity/entity.api.php
@@ -186,7 +186,7 @@ function hook_entity_info() {
       'label' => $name,
       'admin' => array(
         'path' => 'admin/structure/types/manage/%node_type',
-        'real path' => 'admin/structure/types/manage/' . str_replace('_', '-', $type),
+        'real path' => 'admin/structure/types/manage/' . $type,
         'bundle argument' => 4,
         'access arguments' => array('administer content types'),
       ),
diff --git core/modules/field/modules/list/tests/list.test core/modules/field/modules/list/tests/list.test
index f441f4d..1c1aa7d 100644
--- core/modules/field/modules/list/tests/list.test
+++ core/modules/field/modules/list/tests/list.test
@@ -219,8 +219,6 @@ class ListFieldUITestCase extends FieldTestCase {
     $type_name = 'test_' . strtolower($this->randomName());
     $type = $this->drupalCreateContentType(array('name' => $type_name, 'type' => $type_name));
     $this->type = $type->type;
-    // Store a valid URL name, with hyphens instead of underscores.
-    $this->hyphen_type = str_replace('_', '-', $this->type);
   }
 
   /**
@@ -426,7 +424,7 @@ class ListFieldUITestCase extends FieldTestCase {
     );
     field_create_instance($instance);
 
-    $this->admin_path = 'admin/structure/types/manage/' . $this->hyphen_type . '/fields/' . $this->field_name;
+    $this->admin_path = 'admin/structure/types/manage/' . $this->type . '/fields/' . $this->field_name;
   }
 
   /**
diff --git core/modules/field/modules/number/number.test core/modules/field/modules/number/number.test
index 99ec6f0..e394aea 100644
--- core/modules/field/modules/number/number.test
+++ core/modules/field/modules/number/number.test
@@ -56,7 +56,7 @@ class NumberFieldTestCase extends DrupalWebTestCase {
     field_create_instance($this->instance);
 
     // Display creation form.
-    $this->drupalGet('test-entity/add/test-bundle');
+    $this->drupalGet('test-entity/add/test_bundle');
     $langcode = LANGUAGE_NOT_SPECIFIED;
     $this->assertFieldByName("{$this->field['field_name']}[$langcode][0][value]", '', t('Widget is displayed'));
 
@@ -81,7 +81,7 @@ class NumberFieldTestCase extends DrupalWebTestCase {
     );
 
     foreach ($wrong_entries as $wrong_entry) {
-      $this->drupalGet('test-entity/add/test-bundle');
+      $this->drupalGet('test-entity/add/test_bundle');
       $edit = array(
         "{$this->field['field_name']}[$langcode][0][value]" => $wrong_entry,
       );
@@ -99,7 +99,7 @@ class NumberFieldTestCase extends DrupalWebTestCase {
     );
 
     foreach ($wrong_entries as $wrong_entry) {
-      $this->drupalGet('test-entity/add/test-bundle');
+      $this->drupalGet('test-entity/add/test_bundle');
       $edit = array(
         "{$this->field['field_name']}[$langcode][0][value]" => $wrong_entry,
       );
diff --git core/modules/field/modules/text/text.test core/modules/field/modules/text/text.test
index 0dbaccc..b5aa5ce 100644
--- core/modules/field/modules/text/text.test
+++ core/modules/field/modules/text/text.test
@@ -109,7 +109,7 @@ class TextFieldTestCase extends DrupalWebTestCase {
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Display creation form.
-    $this->drupalGet('test-entity/add/test-bundle');
+    $this->drupalGet('test-entity/add/test_bundle');
     $this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', t('Widget is displayed'));
     $this->assertNoFieldByName("{$this->field_name}[$langcode][0][format]", '1', t('Format selector is not displayed'));
 
@@ -178,7 +178,7 @@ class TextFieldTestCase extends DrupalWebTestCase {
 
     // Display the creation form. Since the user only has access to one format,
     // no format selector will be displayed.
-    $this->drupalGet('test-entity/add/test-bundle');
+    $this->drupalGet('test-entity/add/test_bundle');
     $this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', t('Widget is displayed'));
     $this->assertNoFieldByName("{$this->field_name}[$langcode][0][format]", '', t('Format selector is not displayed'));
 
diff --git core/modules/field/tests/field.test core/modules/field/tests/field.test
index fc277a5..2130df4 100644
--- core/modules/field/tests/field.test
+++ core/modules/field/tests/field.test
@@ -1323,7 +1323,7 @@ class FieldFormTestCase extends FieldTestCase {
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Display creation form.
-    $this->drupalGet('test-entity/add/test-bundle');
+    $this->drupalGet('test-entity/add/test_bundle');
     $this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', 'Widget is displayed');
     $this->assertNoField("{$this->field_name}[$langcode][1][value]", 'No extraneous widget is displayed');
     // TODO : check that the widget is populated with default value ?
@@ -1378,7 +1378,7 @@ class FieldFormTestCase extends FieldTestCase {
 
     // Submit with missing required value.
     $edit = array();
-    $this->drupalPost('test-entity/add/test-bundle', $edit, t('Save'));
+    $this->drupalPost('test-entity/add/test_bundle', $edit, t('Save'));
     $this->assertRaw(t('!name field is required.', array('!name' => $this->instance['label'])), 'Required field with no value fails validation');
 
     // Create an entity
@@ -1415,7 +1415,7 @@ class FieldFormTestCase extends FieldTestCase {
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Display creation form -> 1 widget.
-    $this->drupalGet('test-entity/add/test-bundle');
+    $this->drupalGet('test-entity/add/test_bundle');
     $this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', 'Widget 1 is displayed');
     $this->assertNoField("{$this->field_name}[$langcode][1][value]", 'No extraneous widget is displayed');
 
@@ -1513,7 +1513,7 @@ class FieldFormTestCase extends FieldTestCase {
     ));
 
     // Display creation form.
-    $this->drupalGet('test-entity/add/test-bundle');
+    $this->drupalGet('test-entity/add/test_bundle');
 
     // Press the 'Add more' button.
     $this->drupalPost(NULL, array(), t('Add another item'));
@@ -1536,7 +1536,7 @@ class FieldFormTestCase extends FieldTestCase {
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Display creation form -> 1 widget.
-    $this->drupalGet('test-entity/add/test-bundle');
+    $this->drupalGet('test-entity/add/test_bundle');
 
     // Press 'add more' button a couple times -> 3 widgets.
     // drupalPostAJAX() will not work iteratively, so we add those through
@@ -1596,7 +1596,7 @@ class FieldFormTestCase extends FieldTestCase {
     $langcode = LANGUAGE_NOT_SPECIFIED;
 
     // Display creation form.
-    $this->drupalGet('test-entity/add/test-bundle');
+    $this->drupalGet('test-entity/add/test_bundle');
     $this->assertFieldByName("{$this->field_name}[$langcode]", '', t('Widget is displayed.'));
 
     // Create entity with three values.
@@ -1663,7 +1663,7 @@ class FieldFormTestCase extends FieldTestCase {
     $this->assertFalse($form[$field_name_no_access]['#access'], 'Field #access is FALSE for the field without edit access.');
 
     // Display creation form.
-    $this->drupalGet('test-entity/add/test-bundle');
+    $this->drupalGet('test-entity/add/test_bundle');
     $this->assertNoFieldByName("{$field_name_no_access}[$langcode][0][value]", '', t('Widget is not displayed if field access is denied.'));
 
     // Create entity.
diff --git core/modules/field/tests/field_test.module core/modules/field/tests/field_test.module
index 90e25c8..205a624 100644
--- core/modules/field/tests/field_test.module
+++ core/modules/field/tests/field_test.module
@@ -42,8 +42,7 @@ function field_test_menu() {
   $bundles = field_info_bundles('test_entity');
 
   foreach ($bundles as $bundle_name => $bundle_info) {
-    $bundle_url_str = str_replace('_', '-', $bundle_name);
-    $items['test-entity/add/' . $bundle_url_str] = array(
+    $items['test-entity/add/' . $bundle_name] = array(
       'title' => t('Add %bundle test_entity', array('%bundle' => $bundle_info['label'])),
       'page callback' => 'field_test_entity_add',
       'page arguments' => array(2),
diff --git core/modules/field_ui/field_ui.test core/modules/field_ui/field_ui.test
index fb71c5d..80edc38 100644
--- core/modules/field_ui/field_ui.test
+++ core/modules/field_ui/field_ui.test
@@ -34,8 +34,6 @@ class FieldUITestCase extends DrupalWebTestCase {
     $type_name = strtolower($this->randomName(8)) . '_test';
     $type = $this->drupalCreateContentType(array('name' => $type_name, 'type' => $type_name));
     $this->type = $type->type;
-    // Store a valid URL name, with hyphens instead of underscores.
-    $this->hyphen_type = str_replace('_', '-', $this->type);
   }
 
   /**
@@ -199,7 +197,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
    * Tests the manage fields page.
    */
   function manageFieldsPage() {
-    $this->drupalGet('admin/structure/types/manage/' . $this->hyphen_type . '/fields');
+    $this->drupalGet('admin/structure/types/manage/' . $this->type . '/fields');
     // Check all table columns.
     $table_headers = array(
       t('Label'),
@@ -232,7 +230,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
       'fields[_add_new_field][label]' => $this->field_label,
       'fields[_add_new_field][field_name]' => $this->field_name_input,
     );
-    $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->hyphen_type, $edit);
+    $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->type, $edit);
 
     // Assert the field appears in the "add existing field" section for
     // different entity types; e.g. if a field was added in a node entity, it
@@ -247,7 +245,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
    */
   function updateField() {
     // Go to the field edit page.
-    $this->drupalGet('admin/structure/types/manage/' . $this->hyphen_type . '/fields/' . $this->field_name);
+    $this->drupalGet('admin/structure/types/manage/' . $this->type . '/fields/' . $this->field_name);
 
     // Populate the field settings with new settings.
     $string = 'updated dummy test string';
@@ -330,7 +328,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
     field_create_instance($instance);
 
     $langcode = LANGUAGE_NOT_SPECIFIED;
-    $admin_path = 'admin/structure/types/manage/' . $this->hyphen_type . '/fields/' . $field_name;
+    $admin_path = 'admin/structure/types/manage/' . $this->type . '/fields/' . $field_name;
     $element_id = "edit-$field_name-$langcode-0-value";
     $element_name = "{$field_name}[$langcode][0][value]";
     $this->drupalGet($admin_path);
@@ -366,7 +364,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
    */
   function testDeleteField() {
     // Create a new field.
-    $bundle_path1 = 'admin/structure/types/manage/' . $this->hyphen_type;
+    $bundle_path1 = 'admin/structure/types/manage/' . $this->type;
     $edit1 = array(
       'fields[_add_new_field][label]' => $this->field_label,
       'fields[_add_new_field][field_name]' => $this->field_name_input,
@@ -377,10 +375,9 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
     $type_name2 = strtolower($this->randomName(8)) . '_test';
     $type2 = $this->drupalCreateContentType(array('name' => $type_name2, 'type' => $type_name2));
     $type_name2 = $type2->type;
-    $hyphen_type2 = str_replace('_', '-', $type_name2);
 
     // Add an instance to the second node type.
-    $bundle_path2 = 'admin/structure/types/manage/' . $hyphen_type2;
+    $bundle_path2 = 'admin/structure/types/manage/' . $type_name2;
     $edit2 = array(
       'fields[_add_existing_field][label]' => $this->field_label,
       'fields[_add_existing_field][field_name]' => $this->field_name,
@@ -412,7 +409,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
    * Tests that Field UI respects the 'no_ui' option in hook_field_info().
    */
   function testHiddenFields() {
-    $bundle_path = 'admin/structure/types/manage/' . $this->hyphen_type . '/fields/';
+    $bundle_path = 'admin/structure/types/manage/' . $this->type . '/fields/';
 
     // Check that the field type is not available in the 'add new field' row.
     $this->drupalGet($bundle_path);
@@ -447,15 +444,14 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
    * Tests renaming a bundle.
    */
   function testRenameBundle() {
-    $type2 = strtolower($this->randomName(8)) . '_' .'test';
-    $hyphen_type2 = str_replace('_', '-', $type2);
+    $type2 = strtolower($this->randomName(8)) . '_test';
 
     $options = array(
       'type' => $type2,
     );
-    $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type, $options, t('Save content type'));
+    $this->drupalPost('admin/structure/types/manage/' . $this->type, $options, t('Save content type'));
 
-    $this->drupalGet('admin/structure/types/manage/' . $hyphen_type2 . '/fields');
+    $this->drupalGet('admin/structure/types/manage/' . $type2 . '/fields');
   }
 
   /**
@@ -470,7 +466,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
       'fields[_add_new_field][type]' => 'taxonomy_term_reference',
       'fields[_add_new_field][widget_type]' => 'options_select',
     );
-    $url = 'admin/structure/types/manage/' . $this->hyphen_type . '/fields';
+    $url = 'admin/structure/types/manage/' . $this->type . '/fields';
     $this->drupalPost($url, $edit, t('Save'));
 
     $this->assertText(t('The machine-readable name is already in use. It must be unique.'));
@@ -498,7 +494,7 @@ class FieldUIManageDisplayTestCase extends FieldUITestCase {
    * Tests formatter settings.
    */
   function testFormatterUI() {
-    $manage_fields = 'admin/structure/types/manage/' . $this->hyphen_type;
+    $manage_fields = 'admin/structure/types/manage/' . $this->type;
     $manage_display = $manage_fields . '/display';
 
     // Create a field, and a node with some data for the field.
@@ -551,7 +547,7 @@ class FieldUIManageDisplayTestCase extends FieldUITestCase {
       'fields[_add_new_field][label]' => 'Test field',
       'fields[_add_new_field][field_name]' => 'test',
     );
-    $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->hyphen_type, $edit);
+    $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->type, $edit);
     // For this test, use a formatter setting value that is an integer unlikely
     // to appear in a rendered node other than as part of the field being tested
     // (for example, unlikely to be part of the "Submitted by ... on ..." line).
@@ -579,14 +575,14 @@ class FieldUIManageDisplayTestCase extends FieldUITestCase {
     $edit = array(
       'fields[field_test][type]' => 'field_test_with_prepare_view',
     );
-    $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display', $edit, t('Save'));
+    $this->drupalPost('admin/structure/types/manage/' . $this->type . '/display', $edit, t('Save'));
     $this->assertNodeViewText($node, 'rss', $output['field_test_with_prepare_view'], t("The field is displayed as expected in view modes that use 'default' settings."));
 
     // Specialize the 'rss' mode, check that the field is displayed the same.
     $edit = array(
       "view_modes_custom[rss]" => TRUE,
     );
-    $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display', $edit, t('Save'));
+    $this->drupalPost('admin/structure/types/manage/' . $this->type . '/display', $edit, t('Save'));
     $this->assertNodeViewText($node, 'rss', $output['field_test_with_prepare_view'], t("The field is displayed as expected in newly specialized 'rss' mode."));
 
     // Set the field to 'hidden' in the view mode, check that the field is
@@ -594,7 +590,7 @@ class FieldUIManageDisplayTestCase extends FieldUITestCase {
     $edit = array(
       'fields[field_test][type]' => 'hidden',
     );
-    $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display/rss', $edit, t('Save'));
+    $this->drupalPost('admin/structure/types/manage/' . $this->type . '/display/rss', $edit, t('Save'));
     $this->assertNodeViewNoText($node, 'rss', $value, t("The field is hidden in 'rss' mode."));
 
     // Set the view mode back to 'default', check that the field is displayed
@@ -602,14 +598,14 @@ class FieldUIManageDisplayTestCase extends FieldUITestCase {
     $edit = array(
       "view_modes_custom[rss]" => FALSE,
     );
-    $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display', $edit, t('Save'));
+    $this->drupalPost('admin/structure/types/manage/' . $this->type . '/display', $edit, t('Save'));
     $this->assertNodeViewText($node, 'rss', $output['field_test_with_prepare_view'], t("The field is displayed as expected when 'rss' mode is set back to 'default' settings."));
 
     // Specialize the view mode again.
     $edit = array(
       "view_modes_custom[rss]" => TRUE,
     );
-    $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display', $edit, t('Save'));
+    $this->drupalPost('admin/structure/types/manage/' . $this->type . '/display', $edit, t('Save'));
     // Check that the previous settings for the view mode have been kept.
     $this->assertNodeViewNoText($node, 'rss', $value, t("The previous settings are kept when 'rss' mode is specialized again."));
   }
diff --git core/modules/forum/forum.module core/modules/forum/forum.module
index 1b0ab98..07bee65 100644
--- core/modules/forum/forum.module
+++ core/modules/forum/forum.module
@@ -180,7 +180,7 @@ function forum_menu_local_tasks_alter(&$data, $router_item, $root_path) {
             '#theme' => 'menu_local_action',
             '#link' => array(
               'title' => t('Add new @node_type', array('@node_type' => node_type_get_name($type))),
-              'href' => 'node/add/' . str_replace('_', '-', $type) . '/' . $forum_term->tid,
+              'href' => 'node/add/' . $type . '/' . $forum_term->tid,
             ),
           );
         }
@@ -710,8 +710,8 @@ function forum_block_view_pre_render($elements) {
 /**
  * Implements hook_form().
  */
-function forum_form($node, $form_state) {
-  $type = node_type_get_type($node);
+function forum_form(Node $node, &$form_state) {
+  $type = node_type_load($node->type);
   $form['title'] = array(
     '#type' => 'textfield',
     '#title' => check_plain($type->title_label),
diff --git core/modules/node/content_types.inc core/modules/node/content_types.inc
index 9ca1e15..9073379 100644
--- core/modules/node/content_types.inc
+++ core/modules/node/content_types.inc
@@ -20,22 +20,21 @@ function node_overview_types() {
   foreach ($names as $key => $name) {
     $type = $types[$key];
     if (node_hook($type->type, 'form')) {
-      $type_url_str = str_replace('_', '-', $type->type);
       $row = array(theme('node_admin_overview', array('name' => $name, 'type' => $type)));
       // Set the edit column.
-      $row[] = array('data' => l(t('edit'), 'admin/structure/types/manage/' . $type_url_str));
+      $row[] = array('data' => l(t('edit'), 'admin/structure/types/manage/' . $type->type));
 
       if ($field_ui) {
         // Manage fields.
-        $row[] = array('data' => l(t('manage fields'), 'admin/structure/types/manage/' . $type_url_str . '/fields'));
+        $row[] = array('data' => l(t('manage fields'), 'admin/structure/types/manage/' . $type->type . '/fields'));
 
         // Display fields.
-        $row[] = array('data' => l(t('manage display'), 'admin/structure/types/manage/' . $type_url_str . '/display'));
+        $row[] = array('data' => l(t('manage display'), 'admin/structure/types/manage/' . $type->type . '/display'));
       }
 
       // Set the delete column.
       if ($type->custom) {
-        $row[] = array('data' => l(t('delete'), 'admin/structure/types/manage/' . $type_url_str . '/delete'));
+        $row[] = array('data' => l(t('delete'), 'admin/structure/types/manage/' . $type->type . '/delete'));
       }
       else {
         $row[] = array('data' => '');
@@ -319,7 +318,7 @@ function node_type_form_submit($form, &$form_state) {
   }
 
   if ($op == t('Delete content type')) {
-    $form_state['redirect'] = 'admin/structure/types/manage/' . str_replace('_', '-', $type->old_type) . '/delete';
+    $form_state['redirect'] = 'admin/structure/types/manage/' . $type->old_type . '/delete';
     return;
   }
 
diff --git core/modules/node/node.api.php core/modules/node/node.api.php
index 783bf6e..ce3b784 100644
--- core/modules/node/node.api.php
+++ core/modules/node/node.api.php
@@ -605,7 +605,8 @@ function hook_node_load($nodes, $types) {
 function hook_node_access($node, $op, $account) {
   $type = is_string($node) ? $node : $node->type;
 
-  if (in_array($type, node_permissions_get_configured_types())) {
+  $configured_types = node_permissions_get_configured_types();
+  if (isset($configured_types[$type])) {
     if ($op == 'create' && user_access('create ' . $type . ' content', $account)) {
       return NODE_ACCESS_ALLOW;
     }
@@ -1096,7 +1097,7 @@ function hook_prepare(Drupal\node\Node $node) {
  * @ingroup node_api_hooks
  */
 function hook_form(Drupal\node\Node $node, &$form_state) {
-  $type = node_type_get_type($node);
+  $type = node_type_load($node->type);
 
   $form['title'] = array(
     '#type' => 'textfield',
diff --git core/modules/node/node.module core/modules/node/node.module
index f9c213d..8dbc060 100644
--- core/modules/node/node.module
+++ core/modules/node/node.module
@@ -133,12 +133,12 @@ function node_help($path, $arg) {
 
     case 'node/%/edit':
       $node = node_load($arg[1]);
-      $type = node_type_get_type($node);
+      $type = node_type_load($node->type);
       return (!empty($type->help) ? '<p>' . filter_xss_admin($type->help) . '</p>' : '');
   }
 
   if ($arg[0] == 'node' && $arg[1] == 'add' && $arg[2]) {
-    $type = node_type_get_type(str_replace('-', '_', $arg[2]));
+    $type = node_type_load($arg[2]);
     return (!empty($type->help) ? '<p>' . filter_xss_admin($type->help) . '</p>' : '');
   }
 }
@@ -247,7 +247,7 @@ function node_entity_info() {
       'label' => $name,
       'admin' => array(
         'path' => 'admin/structure/types/manage/%node_type',
-        'real path' => 'admin/structure/types/manage/' . str_replace('_', '-', $type),
+        'real path' => 'admin/structure/types/manage/' . $type,
         'bundle argument' => 4,
         'access arguments' => array('administer content types'),
       ),
@@ -408,32 +408,13 @@ function _node_extract_type($node) {
  * @return
  *   An array of node types, as objects, keyed by the type.
  *
- * @see node_type_get_type()
+ * @see node_type_load()
  */
 function node_type_get_types() {
   return _node_types_build()->types;
 }
 
 /**
- * Returns the node type of the passed node or node type string.
- *
- * @param Drupal\node\Node|string $node
- *   A node entity 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 object containing fields from hook_node_info() return
- *   values, as well as the field 'type' (the machine-readable type) and other
- *   fields used internally and defined in _node_types_build(),
- *   hook_node_info(), and node_type_set_defaults().
- */
-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 implements this node type and is used to
@@ -498,14 +479,14 @@ function node_types_rebuild() {
  * Menu argument loader: Loads a node type by string.
  *
  * @param $name
- *   The machine-readable name of a node type to load, where '_' is replaced
- *   with '-'.
+ *   The machine name of a node type to load.
  *
  * @return
  *   A node type object or FALSE if $name does not exist.
  */
 function node_type_load($name) {
-  return node_type_get_type(strtr($name, array('-' => '_')));
+  $types = _node_types_build()->types;
+  return isset($types[$name]) ? $types[$name] : FALSE;
 }
 
 /**
@@ -648,16 +629,16 @@ function node_field_extra_fields() {
 /**
  * Deletes a node type from the database.
  *
- * @param $type
- *   The machine-readable name of the node type to be deleted.
+ * @param $name
+ *   The machine name of the node type to delete.
  */
-function node_type_delete($type) {
-  $info = node_type_get_type($type);
+function node_type_delete($name) {
+  $type = node_type_load($name);
   db_delete('node_type')
-    ->condition('type', $type)
+    ->condition('type', $name)
     ->execute();
-  field_attach_delete_bundle('node', $type);
-  module_invoke_all('node_type_delete', $info);
+  field_attach_delete_bundle('node', $name);
+  module_invoke_all('node_type_delete', $type);
 
   // Clear the node type cache.
   node_type_cache_reset();
@@ -1009,8 +990,8 @@ function node_object_prepare(Node $node) {
  *
  * @see node_form_validate()
  */
-function node_validate($node, $form, &$form_state) {
-  $type = node_type_get_type($node);
+function node_validate(Node $node, $form, &$form_state) {
+  $type = node_type_load($node->type);
 
   if (isset($node->nid) && (node_last_changed($node->nid) > $node->changed)) {
     form_set_error('changed', t('The content on this page has either been modified by another user, or you have already submitted modifications using this form. As a result, your changes cannot be saved.'));
@@ -1439,7 +1420,7 @@ function node_permission() {
   );
 
   // Generate standard node permissions for all applicable node types.
-  foreach (node_permissions_get_configured_types() as $type) {
+  foreach (node_permissions_get_configured_types() as $name => $type) {
     $perms += node_list_permissions($type);
   }
 
@@ -1898,8 +1879,7 @@ function node_menu() {
   );
   // @todo Remove this loop when we have a 'description callback' property.
   foreach (node_type_get_types() as $type) {
-    $type_url_str = str_replace('_', '-', $type->type);
-    $items['node/add/' . $type_url_str] = array(
+    $items['node/add/' . $type->type] = array(
       'title' => $type->name,
       'title callback' => 'check_plain',
       'page callback' => 'node_add',
@@ -2924,7 +2904,8 @@ function node_access($op, $node, $account = NULL) {
 function node_node_access($node, $op, $account) {
   $type = is_string($node) ? $node : $node->type;
 
-  if (in_array($type, node_permissions_get_configured_types())) {
+  $configured_types = node_permissions_get_configured_types();
+  if (isset($configured_types[$type])) {
     if ($op == 'create' && user_access('create ' . $type . ' content', $account)) {
       return NODE_ACCESS_ALLOW;
     }
@@ -2948,34 +2929,31 @@ function node_node_access($node, $op, $account) {
 /**
  * Helper function to generate standard node permission list for a given type.
  *
- * @param $type
- *   The machine-readable name of the node type.
+ * @param $name
+ *   The machine name of the node type.
  *
  * @return array
  *   An array of permission names and descriptions.
  */
 function node_list_permissions($type) {
-  $info = node_type_get_type($type);
-
   // Build standard list of node permissions for this type.
   $perms = array(
-    "create $type content" => array(
-      'title' => t('%type_name: Create new content', array('%type_name' => $info->name)),
+    "create $type->type content" => array(
+      'title' => t('%type_name: Create new content', array('%type_name' => $type->name)),
     ),
-    "edit own $type content" => array(
-      'title' => t('%type_name: Edit own content', array('%type_name' => $info->name)),
+    "edit own $type->type content" => array(
+      'title' => t('%type_name: Edit own content', array('%type_name' => $type->name)),
     ),
-    "edit any $type content" => array(
-      'title' => t('%type_name: Edit any content', array('%type_name' => $info->name)),
+    "edit any $type->type content" => array(
+      'title' => t('%type_name: Edit any content', array('%type_name' => $type->name)),
     ),
-    "delete own $type content" => array(
-      'title' => t('%type_name: Delete own content', array('%type_name' => $info->name)),
+    "delete own $type->type content" => array(
+      'title' => t('%type_name: Delete own content', array('%type_name' => $type->name)),
     ),
-    "delete any $type content" => array(
-      'title' => t('%type_name: Delete any content', array('%type_name' => $info->name)),
+    "delete any $type->type content" => array(
+      'title' => t('%type_name: Delete any content', array('%type_name' => $type->name)),
     ),
   );
-
   return $perms;
 }
 
@@ -2994,15 +2972,12 @@ function node_list_permissions($type) {
  *   An array of node types managed by this module.
  */
 function node_permissions_get_configured_types() {
-
   $configured_types = array();
-
-  foreach (node_type_get_types() as $type => $info) {
-    if (variable_get('node_permissions_' . $type, 1)) {
-      $configured_types[] = $type;
+  foreach (node_type_get_types() as $name => $type) {
+    if (variable_get('node_permissions_' . $name, 1)) {
+      $configured_types[$name] = $type;
     }
   }
-
   return $configured_types;
 }
 
@@ -3533,10 +3508,10 @@ function _node_access_rebuild_batch_finished($success, $results, $operations) {
  * Implements hook_form().
  */
 function node_content_form(Node $node, $form_state) {
-  // It is impossible to define a content type without implementing hook_form()
-  // @todo: remove this requirement.
+  // @todo It is impossible to define a content type without implementing
+  //   hook_form(). Remove this requirement.
   $form = array();
-  $type = node_type_get_type($node);
+  $type = node_type_load($node->type);
 
   if ($type->has_title) {
     $form['title'] = array(
diff --git core/modules/node/node.test core/modules/node/node.test
index 655bc0b..c908584 100644
--- core/modules/node/node.test
+++ core/modules/node/node.test
@@ -1317,7 +1317,7 @@ class NodeTypeTestCase extends NodeWebTestCase {
 
     $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'], node_type_load('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.'));
   }
@@ -1336,7 +1336,7 @@ class NodeTypeTestCase extends NodeWebTestCase {
     $web_user = $this->drupalCreateUser(array('create ' . $type->name . ' content'));
     $this->drupalLogin($web_user);
 
-    $this->drupalGet('node/add/' . str_replace('_', '-', $type->name));
+    $this->drupalGet('node/add/' . $type->type);
     $this->assertResponse(200, 'The new content type can be accessed at node/add.');
 
     // Create a content type via the user interface.
diff --git core/modules/poll/poll.module core/modules/poll/poll.module
index b62568c..df3a4eb 100644
--- core/modules/poll/poll.module
+++ core/modules/poll/poll.module
@@ -218,12 +218,12 @@ function poll_field_extra_fields() {
 /**
  * Implements hook_form().
  */
-function poll_form($node, &$form_state) {
+function poll_form(Node $node, &$form_state) {
   global $user;
 
   $admin = user_access('bypass node access') || user_access('edit any poll content') || (user_access('edit own poll content') && $user->uid == $node->uid);
 
-  $type = node_type_get_type($node);
+  $type = node_type_load($node->type);
 
   // The submit handlers to add more poll choices require that this form is
   // cached, regardless of whether Ajax is used.
diff --git core/modules/simpletest/drupal_web_test_case.php core/modules/simpletest/drupal_web_test_case.php
index 23fa526..5dc2dca 100644
--- core/modules/simpletest/drupal_web_test_case.php
+++ core/modules/simpletest/drupal_web_test_case.php
@@ -986,7 +986,7 @@ class DrupalWebTestCase extends DrupalTestCase {
     // Find a non-existent random type name.
     do {
       $name = strtolower($this->randomName(8));
-    } while (node_type_get_type($name));
+    } while (node_type_load($name));
 
     // Populate defaults array.
     $defaults = array(
diff --git core/modules/taxonomy/taxonomy.test core/modules/taxonomy/taxonomy.test
index a26d15f..6c188b3 100644
--- core/modules/taxonomy/taxonomy.test
+++ core/modules/taxonomy/taxonomy.test
@@ -1534,7 +1534,7 @@ class TaxonomyTermFieldTestCase extends TaxonomyWebTestCase {
 
     // Display creation form.
     $langcode = LANGUAGE_NOT_SPECIFIED;
-    $this->drupalGet('test-entity/add/test-bundle');
+    $this->drupalGet('test-entity/add/test_bundle');
     $this->assertFieldByName("{$this->field_name}[$langcode]", '', 'Widget is displayed.');
 
     // Submit with some value.
@@ -1556,7 +1556,7 @@ class TaxonomyTermFieldTestCase extends TaxonomyWebTestCase {
 
     // Delete the vocabulary and verify that the widget is gone.
     taxonomy_vocabulary_delete($this->vocabulary->vid);
-    $this->drupalGet('test-entity/add/test-bundle');
+    $this->drupalGet('test-entity/add/test_bundle');
     $this->assertNoFieldByName("{$this->field_name}[$langcode]", '', 'Widget is not displayed');
   }
 
@@ -1667,7 +1667,7 @@ class TaxonomyTermFieldMultipleVocabularyTestCase extends TaxonomyWebTestCase {
 
     // Submit an entity with both terms.
     $langcode = LANGUAGE_NOT_SPECIFIED;
-    $this->drupalGet('test-entity/add/test-bundle');
+    $this->drupalGet('test-entity/add/test_bundle');
     $this->assertFieldByName("{$this->field_name}[$langcode][]", '', 'Widget is displayed');
     $edit = array(
       "{$this->field_name}[$langcode][]" => array($term1->tid, $term2->tid),
@@ -1706,7 +1706,7 @@ class TaxonomyTermFieldMultipleVocabularyTestCase extends TaxonomyWebTestCase {
     $this->assertEqual(sizeof($field_info['settings']['allowed_values']), 1, 'Only one vocabulary is allowed for the field.');
 
     // The widget should still be displayed.
-    $this->drupalGet('test-entity/add/test-bundle');
+    $this->drupalGet('test-entity/add/test_bundle');
     $this->assertFieldByName("{$this->field_name}[$langcode][]", '', 'Widget is still displayed');
 
     // Term 1 should still pass validation.
diff --git core/modules/translation/translation.pages.inc core/modules/translation/translation.pages.inc
index d85b5e2..a6e8b3c 100644
--- core/modules/translation/translation.pages.inc
+++ core/modules/translation/translation.pages.inc
@@ -62,7 +62,7 @@ function translation_node_overview(Node $node) {
       $title = t('n/a');
       if (node_access('create', $node)) {
         $text = t('add translation');
-        $path = 'node/add/' . str_replace('_', '-', $node->type);
+        $path = 'node/add/' . $node->type;
         $links = language_negotiation_get_switch_links($type, $path);
         $query = array('query' => array('translation' => $node->nid, 'target' => $langcode));
         $options[] = empty($links->links[$langcode]['href']) ? l($text, $path, $query) : l($text, $links->links[$langcode]['href'], array_merge_recursive($links->links[$langcode], $query));
diff --git core/modules/translation/translation.test core/modules/translation/translation.test
index 15a324e..c9b3dcb 100644
--- core/modules/translation/translation.test
+++ core/modules/translation/translation.test
@@ -75,7 +75,7 @@ class TranslationTestCase extends DrupalWebTestCase {
     $languages = language_list();
     $prefixes = language_negotiation_url_prefixes();
     $this->drupalGet('node/' . $node->nid . '/translate');
-    $this->assertLinkByHref($prefixes['es'] . '/node/add/' . str_replace('_', '-', $node->type), 0, t('The "add translation" link for %language points to the localized path of the target language.', array('%language' => $languages['es']->name)));
+    $this->assertLinkByHref($prefixes['es'] . '/node/add/' . $node->type, 0, t('The "add translation" link for %language points to the localized path of the target language.', array('%language' => $languages['es']->name)));
 
     // Submit translation in Spanish.
     $node_translation_title = $this->randomName();
