Index: src/wp-admin/includes/class-wp-upgrader.php
===================================================================
--- src/wp-admin/includes/class-wp-upgrader.php	(revision 37319)
+++ src/wp-admin/includes/class-wp-upgrader.php	(working copy)
@@ -3472,7 +3472,10 @@
 	 */
 	protected function send_debug_email() {
 		$update_count = 0;
-		foreach ( $this->update_results as $type => $updates )
+		
+		// Copy class variable to prevent hook conflicts
+		$update_results = $this->update_results;
+		foreach ( $update_results as $type => $updates )
 			$update_count += count( $updates );
 
 		$body = array();
@@ -3481,8 +3484,8 @@
 		$body[] = sprintf( __( 'WordPress site: %s' ), network_home_url( '/' ) );
 
 		// Core
-		if ( isset( $this->update_results['core'] ) ) {
-			$result = $this->update_results['core'][0];
+		if ( isset( $update_results['core'] ) ) {
+			$result = $update_results['core'][0];
 			if ( $result->result && ! is_wp_error( $result->result ) ) {
 				$body[] = sprintf( __( 'SUCCESS: WordPress was successfully updated to %s' ), $result->name );
 			} else {
@@ -3494,9 +3497,34 @@
 
 		// Plugins, Themes, Translations
 		foreach ( array( 'plugin', 'theme', 'translation' ) as $type ) {
-			if ( ! isset( $this->update_results[ $type ] ) )
-				continue;
-			$success_items = wp_list_filter( $this->update_results[ $type ], array( 'result' => true ) );
+			
+			/**  
+			* Filter to disable notification emails on plugins/themes/translation.  
+			*  
+			* By default, administrators are notified when the update offer received  
+			* from WordPress.org sets a particular flag. This allows some discretion  
+			* in if and when to notify. This can be used to disabe automatic
+			* update notifications.  
+			*  
+			* This filter is only evaluated once per update  
+			*.  
+			*  
+			* @since 4.6.0  
+			*  
+			* @param bool   $notify Whether the site administrator is notified.  
+			* @param string $type   The type of update (plugin, theme, translation).  
+			* @param object $this   WP_Automatic_Updater instance  
+			*/  
+			if ( ! apply_filters( 'send_update_notification_email', true, $type, $this ) ) { 
+				if ( isset( $update_results[ $type ] ) ) { 
+					unset( $update_results[ $type ] ); 
+				}  
+			}  
+
+			if ( ! isset( $update_results[ $type ] ) ) 
+				continue; 
+
+			$success_items = wp_list_filter( $update_results[ $type ], array( 'result' => true ) );
 			if ( $success_items ) {
 				$messages = array(
 					'plugin'      => __( 'The following plugins were successfully updated:' ),
@@ -3509,7 +3537,7 @@
 					$body[] = ' * ' . sprintf( __( 'SUCCESS: %s' ), $name );
 				}
 			}
-			if ( $success_items != $this->update_results[ $type ] ) {
+			if ( $success_items != $update_results[ $type ] ) {
 				// Failed updates
 				$messages = array(
 					'plugin'      => __( 'The following plugins failed to update:' ),
@@ -3518,7 +3546,7 @@
 				);
 
 				$body[] = $messages[ $type ];
-				foreach ( $this->update_results[ $type ] as $item ) {
+				foreach ( $update_results[ $type ] as $item ) {
 					if ( ! $item->result || is_wp_error( $item->result ) ) {
 						$body[] = ' * ' . sprintf( __( 'FAILED: %s' ), $item->name );
 						$failures++;
@@ -3528,6 +3556,10 @@
 			$body[] = '';
 		}
 
+		if ( empty( $update_results ) ) {  
+			return; 
+		}
+
 		$site_title = wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES );
 		if ( $failures ) {
 			$body[] = trim( __(
@@ -3554,9 +3586,10 @@
 		$body[] = '';
 
 		foreach ( array( 'core', 'plugin', 'theme', 'translation' ) as $type ) {
-			if ( ! isset( $this->update_results[ $type ] ) )
+			if ( ! isset( $update_results[ $type ] ) )
 				continue;
-			foreach ( $this->update_results[ $type ] as $update ) {
+
+			foreach ( $update_results[ $type ] as $update ) {
 				$body[] = $update->name;
 				$body[] = str_repeat( '-', strlen( $update->name ) );
 				foreach ( $update->messages as $message )
Index: tests/phpunit/includes/bootstrap.php
===================================================================
--- tests/phpunit/includes/bootstrap.php	(revision 37319)
+++ tests/phpunit/includes/bootstrap.php	(working copy)
@@ -94,6 +94,7 @@
 require dirname( __FILE__ ) . '/exceptions.php';
 require dirname( __FILE__ ) . '/utils.php';
 require dirname( __FILE__ ) . '/spy-rest-server.php';
+require dirname( __FILE__ ) . '/mock-automatic-updater.php';
 
 /**
  * A child class of the PHP test runner.
Index: tests/phpunit/includes/mock-automatic-updater.php
===================================================================
--- tests/phpunit/includes/mock-automatic-updater.php	(nonexistent)
+++ tests/phpunit/includes/mock-automatic-updater.php	(working copy)
@@ -0,0 +1,17 @@
+<?php
+require_once( ABSPATH . '/wp-admin/includes/class-wp-upgrader.php' );
+/**
+ * Class Mock_Automatic_Updater
+ */
+class Mock_Automatic_Updater extends WP_Automatic_Updater {
+
+	/**
+	 * Public method to allow manual trigger of the send_debug_emails method.
+	 *
+	 * @param array $update_results The results array we're faking for tests.
+	 */
+	public function trigger_send_debug_email( $update_results ) {
+		$this->update_results = $update_results;
+		$this->send_debug_email();
+	}
+}
Index: tests/phpunit/tests/mail.php
===================================================================
--- tests/phpunit/tests/mail.php	(revision 37319)
+++ tests/phpunit/tests/mail.php	(working copy)
@@ -14,6 +14,11 @@
 		parent::tearDown();
 	}
 
+	function tearDown() {
+		parent::tearDown();
+		unset( $GLOBALS['phpmailer']->mock_sent );
+	}
+
 	/**
 	 * Send a mail with a 1000 char long line.
 	 *
@@ -304,7 +309,11 @@
 			'<p><strong>Wörld</strong></p>',
 			'Content-Type: text/html'
 		);
+		remove_action( 'phpmailer_init', array( $this, 'wp_mail_quoted_printable' ) );
+		remove_action( 'phpmailer_init', array( $this, 'wp_mail_set_text_message' ) );
 
-		$this->assertNotContains( 'quoted-printable', $GLOBALS['phpmailer']->mock_sent[0]['header'] );
+
+		$mailer = tests_retrieve_phpmailer_instance();
+		$this->assertNotContains( 'quoted-printable', $mailer->get_sent()->header );
 	}
 }
Index: tests/phpunit/tests/upgrader/SendDebugEmail.php
===================================================================
--- tests/phpunit/tests/upgrader/SendDebugEmail.php	(nonexistent)
+++ tests/phpunit/tests/upgrader/SendDebugEmail.php	(working copy)
@@ -0,0 +1,189 @@
+<?php
+/**
+ * Tests for the send_debug_email method.
+ *
+ * @group upgrader
+ */
+class Tests_Upgrader_SendDebugEmail extends WP_UnitTestCase {
+
+
+	/**
+	 * Lets be sure the mailer is reset before every test.
+	 */
+	function setUp() {
+		parent::setUp();
+		unset( $GLOBALS['phpmailer']->mock_sent );
+	}
+
+	/**
+	 * Lets be sure the mailer is reset after every test.
+	 */
+	function tearDown() {
+		parent::tearDown();
+		unset( $GLOBALS['phpmailer']->mock_sent );
+	}
+
+
+	/**
+	 * Helper to return some update results
+	 * @return array
+	 */
+	protected function update_results() {
+		return array(
+			'core'        => array( (object) array( 'result' => true, 'name' => 'Unit Test : Core', 'messages' => array( 'Success' ) ) ),
+			'plugin'      => array( (object) array( 'result' => true, 'name' => 'Unit Test : Plugin', 'messages' => array( 'Success' ) ) ),
+			'theme'       => array( (object) array( 'result' => true, 'name' => 'Unit Test : Theme', 'messages' => array( 'Success' ) ) ),
+			'translation' => array( (object) array( 'result' => true, 'name' => 'Unit Test : Translation', 'messages' => array( 'Success' ) ) ),
+		);
+	}
+
+	/**
+	 * Helper to create the updater instance
+	 */
+	protected function setup_and_run_send_debug_email() {
+
+		$upgrader = new Mock_Automatic_Updater();
+		$upgrader->trigger_send_debug_email( $this->update_results() );
+	}
+
+	/**
+	 * Baseline test to ensure that an email is sent that contains info for the 4 areas.
+	 * @ticket 33932
+	 */
+	function test_send_debug_email_sends_emails() {
+
+		$this->setup_and_run_send_debug_email();
+
+		// Retrieve the mailer details.
+		$mailer      = tests_retrieve_phpmailer_instance();
+		$body        = $mailer->get_sent()->body;
+		$core        = strpos( $body, 'Core' );
+		$plugin      = strpos( $body, 'Plugin' );
+		$theme       = strpos( $body, 'Theme' );
+		$translation = strpos( $body, 'Translation' );
+
+		// Assertions.
+		$this->assertNotSame( false, $core, '"Core" was not found in the body string' );
+		$this->assertNotSame( false, $plugin, '"Plugin" was not found in the body string' );
+		$this->assertNotSame( false, $theme, '"Theme" was not found in the body string' );
+		$this->assertNotSame( false, $translation, '"Translation" was not found in the body string' );
+	}
+
+	/**
+	 * Testing the send_update_notification_email filter
+	 *
+	 * @ticket 33932
+	 */
+	function test_send_update_notification_email_filter_no_emails() {
+
+		/**
+		 * Disable all notifications.
+		 */
+		add_filter( 'send_update_notification_email', '__return_false' );
+
+		$this->setup_and_run_send_debug_email();
+
+		// Retrieve the mailer details.
+		$mailer      = tests_retrieve_phpmailer_instance();
+		$body        = $mailer->get_sent()->body;
+		$plugin      = strpos( $body, 'Plugin' );
+		$theme       = strpos( $body, 'Theme' );
+		$translation = strpos( $body, 'Translation' );
+
+		remove_filter( 'send_update_notification_email', '__return_false' );
+
+
+		// Assertions.
+		$this->assertSame( false, $plugin, '"Plugin" was found in the body string' );
+		$this->assertSame( false, $theme, '"Theme" was found in the body string' );
+		$this->assertSame( false, $translation, '"Translation" was found in the body string' );
+	}
+
+
+	/**
+	 * Testing the send_update_notification_email filter
+	 *
+	 * @dataProvider data_send_update_notification_email_filter_remove_single_type
+	 *
+	 * @ticket 33932
+	 */
+	function test_send_update_notification_email_filter_remove_single_type( $type ) {
+
+		/**
+		 * Disable all notifications.
+		 */
+		add_filter( 'send_update_notification_email', array( $this, "remove_{$type}_from_notifications" ), 10, 2 );
+
+		$this->setup_and_run_send_debug_email();
+
+		// Retrieve the mailer details.
+		$mailer      = tests_retrieve_phpmailer_instance();
+		$body        = $mailer->get_sent()->body;
+		$$type      = strpos( $body, ucfirst( $type ) );
+
+		remove_filter( 'send_update_notification_email', array( $this, "remove_{$type}_from_notifications" ), 10, 2 );
+
+
+		// Assertions.
+		$this->assertSame( false, $$type, '"'.ucfirst( $type ).'" was found in the body string' );
+	}
+
+
+	/**
+	 * Data Provider.
+	 *
+	 * Passes the type of update meant to be suppressed.
+	 *
+	 * @since 4.6.0
+	 *
+	 * @return array {
+	 *     @type array {
+	 *         @type string The machine name of the type of update.
+	 *     }
+	 * }
+	 */
+	function data_send_update_notification_email_filter_remove_single_type() {
+		return array(
+			array( 'plugin' ),
+			array( 'theme' ),
+			array( 'translation' ),
+		);
+	}
+
+
+	/**
+	 * Callback for the send_update_notification_email tests.
+	 *
+	 * @param bool   $will_send Will the email be sent.
+	 * @param string $type      The type of update.
+	 *
+	 * @return bool
+	 */
+	function remove_plugin_from_notifications( $will_send, $type ) {
+		return ( 'plugin' === $type ) ? false : true;
+	}
+
+	/**
+	 * Callback for the send_update_notification_email tests.
+	 *
+	 * @param bool   $will_send Will the email be sent.
+	 * @param string $type      The type of update.
+	 *
+	 * @return bool
+	 */
+	function remove_theme_from_notifications( $will_send, $type ) {
+		return ( 'theme' === $type ) ? false : true;
+	}
+
+	/**
+	 * Callback for the send_update_notification_email tests.
+	 *
+	 * @param bool   $will_send Will the email be sent.
+	 * @param string $type      The type of update.
+	 *
+	 * @return bool
+	 */
+	function remove_translation_from_notifications( $will_send, $type ) {
+		return ( 'translation' === $type ) ? false : true;
+	}
+}
