diff --git src/wp-admin/includes/ajax-actions.php src/wp-admin/includes/ajax-actions.php
index 6a80f06..0aab1ef 100644
--- src/wp-admin/includes/ajax-actions.php
+++ src/wp-admin/includes/ajax-actions.php
@@ -136,9 +136,9 @@ function wp_ajax_ajax_tag_search() {
 	 *
 	 * @since 4.0.0
 	 *
-	 * @param int    $characters The minimum number of characters required. Default 2.
-	 * @param object $tax        The taxonomy object.
-	 * @param string $s          The search term.
+	 * @param int         $characters The minimum number of characters required. Default 2.
+	 * @param WP_Taxonomy $tax        The taxonomy object.
+	 * @param string      $s          The search term.
 	 */
 	$term_search_min_chars = (int) apply_filters( 'term_search_min_chars', 2, $tax, $s );
 
diff --git src/wp-includes/class-wp-taxonomy.php src/wp-includes/class-wp-taxonomy.php
new file mode 100644
index 0000000..f5ee05a
--- /dev/null
+++ src/wp-includes/class-wp-taxonomy.php
@@ -0,0 +1,416 @@
+<?php
+/**
+ * Taxonomy API: WP_Taxonomy class
+ *
+ * @package WordPress
+ * @subpackage Taxonomy
+ * @since 4.6.0
+ */
+
+/**
+ * Core class used for interacting with taxonomies.
+ *
+ * @since 4.6.0
+ */
+final class WP_Taxonomy {
+	/**
+	 * Taxonomy key.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var string
+	 */
+	public $name;
+
+	/**
+	 * Name of the taxonomy shown in the menu. Usually plural.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var string
+	 */
+	public $label;
+
+	/**
+	 * An array of labels for this taxonomy.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var array
+	 */
+	public $labels = array();
+
+	/**
+	 * A short descriptive summary of what the taxonomy is for.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var string
+	 */
+	public $description = '';
+
+	/**
+	 * Whether a taxonomy is intended for use publicly either via the admin interface or by front-end users.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $public = true;
+
+	/**
+	 * Whether the taxonomy is publicly queryable.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $publicly_queryable = true;
+
+	/**
+	 * Whether the taxonomy is hierarchical.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $hierarchical = false;
+
+	/**
+	 * Whether to generate and allow a UI for managing terms in this taxonomy in the admin.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $show_ui = true;
+
+	/**
+	 * Whether to show the taxonomy in the admin menu.
+	 *
+	 * If true, the taxonomy is shown as a submenu of the object type menu. If false, no menu is shown.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $show_in_menu = true;
+
+	/**
+	 * Whether the taxonomy is available for selection in navigation menus.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $show_in_nav_menus = true;
+
+	/**
+	 * Whether to list the taxonomy in the tag cloud widget controls.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $show_tagcloud = true;
+
+	/**
+	 * Whether to show the taxonomy in the quick/bulk edit panel.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $show_in_quick_edit = true;
+
+	/**
+	 * Whether to display a column for the taxonomy on its post type listing screens.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $show_admin_column = false;
+
+	/**
+	 * The callback function for the meta box display.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool|callable
+	 */
+	public $meta_box_cb = null;
+
+	/**
+	 * An array of object types this taxonomy is registered for.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var array
+	 */
+	public $object_type = null;
+
+	/**
+	 * Capabilities for this taxonomy.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var array
+	 */
+	public $cap;
+
+	/**
+	 * Rewrites information for this taxonomy.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var array|false
+	 */
+	public $rewrite;
+
+	/**
+	 * Query var string for this taxonomy.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var string|false
+	 */
+	public $query_var;
+
+	/**
+	 * Function that will be called when the count is updated.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var callable
+	 */
+	public $update_count_callback;
+
+	/**
+	 * Whether it is a built-in taxonomy.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $_builtin;
+
+	/**
+	 * Constructor.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 *
+	 * @global WP $wp WP instance.
+	 *
+	 * @param string       $taxonomy    Taxonomy key, must not exceed 32 characters.
+	 * @param array|string $object_type Name of the object type for the taxonomy object.
+	 * @param array|string $args        Optional. Array or query string of arguments for registering a taxonomy.
+	 *                                  Default empty array.
+	 */
+	public function __construct( $taxonomy, $object_type, $args = array() ) {
+		$this->name = $taxonomy;
+
+		$this->set_props( $object_type, $args );
+	}
+
+	/**
+	 * Sets taxonomy properties.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 *
+	 * @param array|string $object_type Name of the object type for the taxonomy object.
+	 * @param array|string $args        Array or query string of arguments for registering a taxonomy.
+	 */
+	public function set_props( $object_type, $args ) {
+		$args = wp_parse_args( $args );
+
+		/**
+		 * Filters the arguments for registering a taxonomy.
+		 *
+		 * @since 4.4.0
+		 *
+		 * @param array  $args        Array of arguments for registering a taxonomy.
+		 * @param string $taxonomy    Taxonomy key.
+		 * @param array  $object_type Array of names of object types for the taxonomy.
+		 */
+		$args = apply_filters( 'register_taxonomy_args', $args, $this->name, (array) $object_type );
+
+		$defaults = array(
+			'labels'                => array(),
+			'description'           => '',
+			'public'                => true,
+			'publicly_queryable'    => null,
+			'hierarchical'          => false,
+			'show_ui'               => null,
+			'show_in_menu'          => null,
+			'show_in_nav_menus'     => null,
+			'show_tagcloud'         => null,
+			'show_in_quick_edit'    => null,
+			'show_admin_column'     => false,
+			'meta_box_cb'           => null,
+			'capabilities'          => array(),
+			'rewrite'               => true,
+			'query_var'             => $this->name,
+			'update_count_callback' => '',
+			'_builtin'              => false,
+		);
+
+		$args = array_merge( $defaults, $args );
+
+		// If not set, default to the setting for public.
+		if ( null === $args['publicly_queryable'] ) {
+			$args['publicly_queryable'] = $args['public'];
+		}
+
+		if ( false !== $args['query_var'] && ( is_admin() || false !== $args['publicly_queryable'] ) ) {
+			if ( true === $args['query_var'] ) {
+				$args['query_var'] = $this->name;
+			} else {
+				$args['query_var'] = sanitize_title_with_dashes( $args['query_var'] );
+			}
+		} else {
+			// Force query_var to false for non-public taxonomies.
+			$args['query_var'] = false;
+		}
+
+		if ( false !== $args['rewrite'] && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) {
+			$args['rewrite'] = wp_parse_args( $args['rewrite'], array(
+				'with_front'   => true,
+				'hierarchical' => false,
+				'ep_mask'      => EP_NONE,
+			) );
+
+			if ( empty( $args['rewrite']['slug'] ) ) {
+				$args['rewrite']['slug'] = sanitize_title_with_dashes( $this->name );
+			}
+		}
+
+		// If not set, default to the setting for public.
+		if ( null === $args['show_ui'] ) {
+			$args['show_ui'] = $args['public'];
+		}
+
+		// If not set, default to the setting for show_ui.
+		if ( null === $args['show_in_menu'] || ! $args['show_ui'] ) {
+			$args['show_in_menu'] = $args['show_ui'];
+		}
+
+		// If not set, default to the setting for public.
+		if ( null === $args['show_in_nav_menus'] ) {
+			$args['show_in_nav_menus'] = $args['public'];
+		}
+
+		// If not set, default to the setting for show_ui.
+		if ( null === $args['show_tagcloud'] ) {
+			$args['show_tagcloud'] = $args['show_ui'];
+		}
+
+		// If not set, default to the setting for show_ui.
+		if ( null === $args['show_in_quick_edit'] ) {
+			$args['show_in_quick_edit'] = $args['show_ui'];
+		}
+
+		$default_caps = array(
+			'manage_terms' => 'manage_categories',
+			'edit_terms'   => 'manage_categories',
+			'delete_terms' => 'manage_categories',
+			'assign_terms' => 'edit_posts',
+		);
+
+		$args['cap'] = (object) array_merge( $default_caps, $args['capabilities'] );
+		unset( $args['capabilities'] );
+
+		$args['object_type'] = array_unique( (array) $object_type );
+
+		// If not set, use the default meta box
+		if ( null === $args['meta_box_cb'] ) {
+			if ( $args['hierarchical'] ) {
+				$args['meta_box_cb'] = 'post_categories_meta_box';
+			} else {
+				$args['meta_box_cb'] = 'post_tags_meta_box';
+			}
+		}
+
+		foreach ( $args as $property_name => $property_value ) {
+			$this->$property_name = $property_value;
+		}
+
+		$this->labels = get_taxonomy_labels( $this );
+		$this->label = $this->labels->name;
+	}
+
+	/**
+	 * Adds the necessary rewrite rules for the taxonomy.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 *
+	 * @global WP $wp Current WordPress environment instance.
+	 */
+	public function add_rewrite_rules() {
+		/* @var WP $wp */
+		global $wp;
+
+		// Non-publicly queryable taxonomies should not register query vars, except in the admin.
+		if ( false !== $this->query_var && $wp ) {
+			$wp->add_query_var( $this->query_var );
+		}
+
+		if ( false !== $this->rewrite && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) {
+			if ( $this->hierarchical && $this->rewrite['hierarchical'] ) {
+				$tag = '(.+?)';
+			} else {
+				$tag = '([^/]+)';
+			}
+
+			add_rewrite_tag( "%$this->name%", $tag, $this->query_var ? "{$this->query_var}=" : "taxonomy=$this->name&term=" );
+			add_permastruct( $this->name, "{$this->rewrite['slug']}/%$this->name%", $this->rewrite );
+		}
+	}
+
+	/**
+	 * Removes any rewrite rules, permastructs, and rules for the taxonomy.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 *
+	 * @global WP $wp Current WordPress environment instance.
+	 */
+	public function remove_rewrite_rules() {
+		/* @var WP $wp */
+		global $wp;
+
+		// Remove query var.
+		if ( false !== $this->query_var ) {
+			$wp->remove_query_var( $this->query_var );
+		}
+
+		// Remove rewrite tags and permastructs.
+		if ( false !== $this->rewrite ) {
+			remove_rewrite_tag( "%$this->name%" );
+			remove_permastruct( $this->name );
+		}
+	}
+
+	/**
+	 * Registers the ajax callback for the metabox.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 */
+	public function add_hooks() {
+		add_filter( 'wp_ajax_add-' . $this->name, '_wp_ajax_add_hierarchical_term' );
+	}
+
+	/**
+	 * Removes the ajax callback for the metabox.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 */
+	public function remove_hooks() {
+		remove_filter( 'wp_ajax_add-' . $this->name, '_wp_ajax_add_hierarchical_term' );
+	}
+}
diff --git src/wp-includes/class-wp-xmlrpc-server.php src/wp-includes/class-wp-xmlrpc-server.php
index bdabf98..d0f27e3 100644
--- src/wp-includes/class-wp-xmlrpc-server.php
+++ src/wp-includes/class-wp-xmlrpc-server.php
@@ -708,9 +708,9 @@ class wp_xmlrpc_server extends IXR_Server {
 		 *
 		 * @since 3.4.0
 		 *
-		 * @param array  $_taxonomy An array of taxonomy data.
-		 * @param object $taxonomy  Taxonomy object.
-		 * @param array  $fields    The subset of taxonomy fields to return.
+		 * @param array       $_taxonomy An array of taxonomy data.
+		 * @param WP_Taxonomy $taxonomy  Taxonomy object.
+		 * @param array       $fields    The subset of taxonomy fields to return.
 		 */
 		return apply_filters( 'xmlrpc_prepare_taxonomy', $_taxonomy, $taxonomy, $fields );
 	}
diff --git src/wp-includes/taxonomy.php src/wp-includes/taxonomy.php
index a51658f..8edd684 100644
--- src/wp-includes/taxonomy.php
+++ src/wp-includes/taxonomy.php
@@ -211,7 +211,7 @@ function get_object_taxonomies( $object, $output = 'names' ) {
  * @global array $wp_taxonomies The registered taxonomies.
  *
  * @param string $taxonomy Name of taxonomy object to return.
- * @return object|false The Taxonomy Object or false if $taxonomy doesn't exist.
+ * @return WP_Taxonomy|false The Taxonomy Object or false if $taxonomy doesn't exist.
  */
 function get_taxonomy( $taxonomy ) {
 	global $wp_taxonomies;
@@ -278,7 +278,6 @@ function is_taxonomy_hierarchical($taxonomy) {
  * @since 4.5.0 Introduced `publicly_queryable` argument.
  *
  * @global array $wp_taxonomies Registered taxonomies.
- * @global WP    $wp            WP instance.
  *
  * @param string       $taxonomy    Taxonomy key, must not exceed 32 characters.
  * @param array|string $object_type Name of the object type for the taxonomy object.
@@ -349,134 +348,23 @@ function is_taxonomy_hierarchical($taxonomy) {
  * @return WP_Error|void WP_Error, if errors.
  */
 function register_taxonomy( $taxonomy, $object_type, $args = array() ) {
-	global $wp_taxonomies, $wp;
+	global $wp_taxonomies;
 
-	if ( ! is_array( $wp_taxonomies ) )
+	if ( ! is_array( $wp_taxonomies ) ) {
 		$wp_taxonomies = array();
-
-	$args = wp_parse_args( $args );
-
-	/**
-	 * Filters the arguments for registering a taxonomy.
-	 *
-	 * @since 4.4.0
-	 *
-	 * @param array  $args        Array of arguments for registering a taxonomy.
-	 * @param string $taxonomy    Taxonomy key.
-	 * @param array  $object_type Array of names of object types for the taxonomy.
-	 */
-	$args = apply_filters( 'register_taxonomy_args', $args, $taxonomy, (array) $object_type );
-
-	$defaults = array(
-		'labels'                => array(),
-		'description'           => '',
-		'public'                => true,
-		'publicly_queryable'    => null,
-		'hierarchical'          => false,
-		'show_ui'               => null,
-		'show_in_menu'          => null,
-		'show_in_nav_menus'     => null,
-		'show_tagcloud'         => null,
-		'show_in_quick_edit'	=> null,
-		'show_admin_column'     => false,
-		'meta_box_cb'           => null,
-		'capabilities'          => array(),
-		'rewrite'               => true,
-		'query_var'             => $taxonomy,
-		'update_count_callback' => '',
-		'_builtin'              => false,
-	);
-	$args = array_merge( $defaults, $args );
+	}
 
 	if ( empty( $taxonomy ) || strlen( $taxonomy ) > 32 ) {
 		_doing_it_wrong( __FUNCTION__, __( 'Taxonomy names must be between 1 and 32 characters in length.' ), '4.2' );
 		return new WP_Error( 'taxonomy_length_invalid', __( 'Taxonomy names must be between 1 and 32 characters in length.' ) );
 	}
 
-	// If not set, default to the setting for public.
-	if ( null === $args['publicly_queryable'] ) {
-		$args['publicly_queryable'] = $args['public'];
-	}
-
-	// Non-publicly queryable taxonomies should not register query vars, except in the admin.
-	if ( false !== $args['query_var'] && ( is_admin() || false !== $args['publicly_queryable'] ) && ! empty( $wp ) ) {
-		if ( true === $args['query_var'] )
-			$args['query_var'] = $taxonomy;
-		else
-			$args['query_var'] = sanitize_title_with_dashes( $args['query_var'] );
-		$wp->add_query_var( $args['query_var'] );
-	} else {
-		// Force query_var to false for non-public taxonomies.
-		$args['query_var'] = false;
-	}
-
-	if ( false !== $args['rewrite'] && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) {
-		$args['rewrite'] = wp_parse_args( $args['rewrite'], array(
-			'with_front' => true,
-			'hierarchical' => false,
-			'ep_mask' => EP_NONE,
-		) );
+	$taxonomy_object = new WP_Taxonomy( $taxonomy, $object_type, $args );
+	$taxonomy_object->add_rewrite_rules();
 
-		if ( empty( $args['rewrite']['slug'] ) )
-			$args['rewrite']['slug'] = sanitize_title_with_dashes( $taxonomy );
+	$wp_taxonomies[ $taxonomy ] = $taxonomy_object;
 
-		if ( $args['hierarchical'] && $args['rewrite']['hierarchical'] )
-			$tag = '(.+?)';
-		else
-			$tag = '([^/]+)';
-
-		add_rewrite_tag( "%$taxonomy%", $tag, $args['query_var'] ? "{$args['query_var']}=" : "taxonomy=$taxonomy&term=" );
-		add_permastruct( $taxonomy, "{$args['rewrite']['slug']}/%$taxonomy%", $args['rewrite'] );
-	}
-
-	// If not set, default to the setting for public.
-	if ( null === $args['show_ui'] )
-		$args['show_ui'] = $args['public'];
-
-	// If not set, default to the setting for show_ui.
-	if ( null === $args['show_in_menu' ] || ! $args['show_ui'] )
-		$args['show_in_menu' ] = $args['show_ui'];
-
-	// If not set, default to the setting for public.
-	if ( null === $args['show_in_nav_menus'] )
-		$args['show_in_nav_menus'] = $args['public'];
-
-	// If not set, default to the setting for show_ui.
-	if ( null === $args['show_tagcloud'] )
-		$args['show_tagcloud'] = $args['show_ui'];
-
-	// If not set, default to the setting for show_ui.
-	if ( null === $args['show_in_quick_edit'] ) {
-		$args['show_in_quick_edit'] = $args['show_ui'];
-	}
-
-	$default_caps = array(
-		'manage_terms' => 'manage_categories',
-		'edit_terms'   => 'manage_categories',
-		'delete_terms' => 'manage_categories',
-		'assign_terms' => 'edit_posts',
-	);
-	$args['cap'] = (object) array_merge( $default_caps, $args['capabilities'] );
-	unset( $args['capabilities'] );
-
-	$args['name'] = $taxonomy;
-	$args['object_type'] = array_unique( (array) $object_type );
-
-	$args['labels'] = get_taxonomy_labels( (object) $args );
-	$args['label'] = $args['labels']->name;
-
-	// If not set, use the default meta box
-	if ( null === $args['meta_box_cb'] ) {
-		if ( $args['hierarchical'] )
-			$args['meta_box_cb'] = 'post_categories_meta_box';
-		else
-			$args['meta_box_cb'] = 'post_tags_meta_box';
-	}
-
-	$wp_taxonomies[ $taxonomy ] = (object) $args;
-
-	// register callback handling for metabox
- 	add_filter( 'wp_ajax_add-' . $taxonomy, '_wp_ajax_add_hierarchical_term' );
+	$taxonomy_object->add_hooks();
 
 	/**
 	 * Fires after a taxonomy is registered.
@@ -508,28 +396,17 @@ function unregister_taxonomy( $taxonomy ) {
 		return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy' ) );
 	}
 
-	$taxonomy_args = get_taxonomy( $taxonomy );
+	$taxonomy_object = get_taxonomy( $taxonomy );
 
 	// Do not allow unregistering internal taxonomies.
-	if ( $taxonomy_args->_builtin ) {
+	if ( $taxonomy_object->_builtin ) {
 		return new WP_Error( 'invalid_taxonomy', __( 'Unregistering a built-in taxonomy is not allowed' ) );
 	}
 
-	global $wp, $wp_taxonomies;
+	$taxonomy_object->remove_rewrite_rules();
+	$taxonomy_object->remove_hooks();
 
-	// Remove query var.
-	if ( false !== $taxonomy_args->query_var ) {
-		$wp->remove_query_var( $taxonomy_args->query_var );
-	}
-
-	// Remove rewrite tags and permastructs.
-	if ( false !== $taxonomy_args->rewrite ) {
-		remove_rewrite_tag( "%$taxonomy%" );
-		remove_permastruct( $taxonomy );
-	}
-
-	// Unregister callback handling for metabox.
-	remove_filter( 'wp_ajax_add-' . $taxonomy, '_wp_ajax_add_hierarchical_term' );
+	global $wp_taxonomies;
 
 	// Remove the taxonomy.
 	unset( $wp_taxonomies[ $taxonomy ] );
@@ -579,7 +456,7 @@ function unregister_taxonomy( $taxonomy ) {
  * @since 4.3.0 Added the `no_terms` label.
  * @since 4.4.0 Added the `items_list_navigation` and `items_list` labels.
  *
- * @param object $tax Taxonomy object.
+ * @param WP_Taxonomy $tax Taxonomy object.
  * @return object object with all the labels as member variables.
  */
 function get_taxonomy_labels( $tax ) {
diff --git src/wp-settings.php src/wp-settings.php
index ae7a173..ce59856 100644
--- src/wp-settings.php
+++ src/wp-settings.php
@@ -181,6 +181,7 @@ require( ABSPATH . WPINC . '/cron.php' );
 require( ABSPATH . WPINC . '/deprecated.php' );
 require( ABSPATH . WPINC . '/script-loader.php' );
 require( ABSPATH . WPINC . '/taxonomy.php' );
+require( ABSPATH . WPINC . '/class-wp-taxonomy.php' );
 require( ABSPATH . WPINC . '/class-wp-term.php' );
 require( ABSPATH . WPINC . '/class-wp-term-query.php' );
 require( ABSPATH . WPINC . '/class-wp-tax-query.php' );
diff --git tests/phpunit/tests/term/wpTaxonomy.php tests/phpunit/tests/term/wpTaxonomy.php
new file mode 100644
index 0000000..377808c
--- /dev/null
+++ tests/phpunit/tests/term/wpTaxonomy.php
@@ -0,0 +1,90 @@
+<?php
+
+/**
+ * @group taxonomy
+ */
+class Tests_WP_Taxonomy extends WP_UnitTestCase {
+	public function test_instances() {
+		global $wp_taxonomies;
+
+		foreach ( $wp_taxonomies as $taxonomy ) {
+			$this->assertInstanceOf( 'WP_Taxonomy', $taxonomy );
+		}
+	}
+
+	public function test_does_not_add_query_var_if_not_public() {
+		$this->set_permalink_structure( '/%postname%' );
+
+		/* @var WP $wp */
+		global $wp;
+
+		$taxonomy        = rand_str();
+		$taxonomy_object = new WP_Taxonomy( $taxonomy, 'post' );
+
+		$taxonomy_object->add_rewrite_rules();
+		$this->assertFalse( in_array( 'foobar', $wp->public_query_vars ) );
+	}
+
+	public function test_adds_query_var_if_public() {
+		$this->set_permalink_structure( '/%postname%' );
+
+		/* @var WP $wp */
+		global $wp;
+
+		$taxonomy        = rand_str();
+		$taxonomy_object = new WP_Taxonomy( $taxonomy, 'post', array(
+			'public'    => true,
+			'rewrite'   => false,
+			'query_var' => 'foobar',
+		) );
+
+		$taxonomy_object->add_rewrite_rules();
+		$in_array = in_array( 'foobar', $wp->public_query_vars );
+
+		$taxonomy_object->remove_rewrite_rules();
+		$in_array_after = in_array( 'foobar', $wp->public_query_vars );
+
+		$this->assertTrue( $in_array );
+		$this->assertFalse( $in_array_after );
+	}
+
+	public function test_adds_rewrite_rules() {
+		$this->set_permalink_structure( '/%postname%' );
+
+		/* @var WP_Rewrite $wp_rewrite */
+		global $wp_rewrite;
+
+		$taxonomy        = rand_str();
+		$taxonomy_object = new WP_Taxonomy( $taxonomy, 'post', array(
+			'public'  => true,
+			'rewrite' => true,
+		) );
+
+		$taxonomy_object->add_rewrite_rules();
+		$rewrite_tags = $wp_rewrite->rewritecode;
+
+		$taxonomy_object->remove_rewrite_rules();
+		$rewrite_tags_after = $wp_rewrite->rewritecode;
+
+		$this->assertTrue( false !== array_search( "%$taxonomy%", $rewrite_tags ) );
+		$this->assertFalse( array_search( "%$taxonomy%", $rewrite_tags_after ) );
+	}
+
+	public function test_adds_ajax_callback() {
+		$taxonomy        = rand_str();
+		$taxonomy_object = new WP_Taxonomy( $taxonomy, 'post', array(
+			'public'  => true,
+			'rewrite' => true,
+		) );
+
+		$taxonomy_object->add_hooks();
+		$has_action = has_action( "wp_ajax_add-$taxonomy", '_wp_ajax_add_hierarchical_term' );
+
+		$taxonomy_object->remove_hooks();
+		$has_action_after = has_action( "wp_ajax_add-$taxonomy", '_wp_ajax_add_hierarchical_term' );
+
+		$this->assertSame( 10, $has_action );
+		$this->assertFalse( $has_action_after );
+
+	}
+}
