diff --git a/commands/make/make.download.inc b/commands/make/make.download.inc
index 17f5a32..7c7a6de 100644
--- a/commands/make/make.download.inc
+++ b/commands/make/make.download.inc
@@ -176,18 +176,20 @@ function make_download_file_unpack($filename, $download_location, $name, $subtre
   $success = FALSE;
 
   switch (drush_mime_content_type($filename)) {
+    case 'application/x-bzip2':
     case 'application/x-gzip':
-      // I'd like to just use tar -z, but apparently it breaks on windoze. Why
-      // do they always have to ruin everything?
-      $success = make_download_file_unpack_gzip($filename, $download_location, $subtree);
-      break;
-
     case 'application/x-tar':
-      $success = make_download_file_unpack_tar($filename, $download_location, $subtree);
-      break;
-
     case 'application/zip':
-      $success = make_download_file_unpack_zip($filename, $download_location, $subtree);
+      $listing = drush_tarball_extract($filename, FALSE, TRUE);
+      if (!$listing) {
+        return FALSE;
+      }
+
+      $source = dirname($filename) . '/' . $listing[0];
+      if ($subtree) {
+        $source .= '/' . $subtree;
+      }
+      $success = drush_move_dir($source, $download_location, TRUE);
       break;
 
     default:
@@ -199,64 +201,6 @@ function make_download_file_unpack($filename, $download_location, $name, $subtre
   return $success ? $download_location : FALSE;
 }
 
-/**
- * Unpacks a tar file to the specified location.
- *
- * @return boolean
- *   TRUE or FALSE depending on whether the operation was successful.
- */
-function make_download_file_unpack_tar($filename, $download_location, $subtree = NULL) {
-  $tmp_path = make_tmp() . '/__untar__';
-
-  list($main_directory) = array_reverse(explode('/', $download_location));
-
-  drush_mkdir($tmp_path);
-  drush_shell_exec('tar -x -C %s -f %s', $tmp_path, $filename);
-
-  return _make_download_file_move($tmp_path, $filename, $download_location, $subtree);
-}
-
-/**
- * Unpacks a gzip file to the specified location.
- *
- * @return boolean
- *   TRUE or FALSE depending on whether the operation was successful.
- */
-function make_download_file_unpack_gzip($filename, $download_location, $subtree = NULL) {
-  // Find out where contents will end up. Retrieve last column of output using
-  // awk.
-  drush_shell_exec("gzip --list %s", $filename);
-  $info = drush_shell_exec_output();
-  if ($info) {
-    foreach ($info as $line) {
-      $matches = array();
-      preg_match('/^\s+[0-9]+\s+[0-9-]+\s+[0-9\.%]+\s+(.*)$/', $line, $matches);
-      if (isset($matches[1])) {
-        $file = $matches[1];
-        break;
-      }
-    }
-    if (isset($file)) {
-      // Unzip it and then delete the tar file.
-      drush_shell_exec('gzip -d %s', $filename);
-      return make_download_file_unpack_tar($file, $download_location, $subtree);
-    }
-  }
-}
-
-/**
- * Unpack a zip file.
- */
-function make_download_file_unpack_zip($filename, $download_location, $subtree = NULL) {
-  $tmp_path = make_tmp() . '/__unzip__';
-
-  list($main_directory) = array_reverse(explode('/', $download_location));
-
-  drush_mkdir($tmp_path);
-  drush_shell_exec("unzip %s -d %s", $filename, $tmp_path);
-
-  return _make_download_file_move($tmp_path, $filename, $download_location, $subtree);
-}
 
 /**
  * Move a downloaded and unpacked file or directory into place.
diff --git a/includes/drush.inc b/includes/drush.inc
index 43f1879..6726d01 100644
--- a/includes/drush.inc
+++ b/includes/drush.inc
@@ -889,7 +889,7 @@ function _drush_download_file($url, $destination = FALSE, $overwrite = TRUE) {
  * Extract a tarball.
  *
  * @param string $path
- *   The name of the .tar.gz or .tgz file to be extracted.
+ *   The name of the archive to be extracted.
  * @param string $destination
  *   The destination directory the tarball should be extracted into.
  *   Optional, if ommitted the tarball directory will be used as destination.
@@ -901,6 +901,27 @@ function _drush_download_file($url, $destination = FALSE, $overwrite = TRUE) {
  *   tarball is returned if the extraction reported success, instead of TRUE.
  */
 function drush_tarball_extract($path, $destination = FALSE, $listing = FALSE) {
+  $tarball_handler_for_extension = array(
+    '.zip'     => 'zip',
+    '.tar'     => 'tar',
+    '.tar.gz'  => 'tar/gzip',
+    '.tgz'     => 'tar/gzip',
+    '.tar.bz2' => 'tar/bzip2',
+    '.tbz'     => 'tar/bzip2',
+    '.tbz2'    => 'tar/bzip2',
+    '.tb2'     => 'tar/bzip2',
+  );
+  $tarball_handler = NULL;
+  foreach ($tarball_handler_for_extension as $extension => $handler) {
+    if (substr($path, -strlen($extension)) === $extension) {
+      $tarball_extension = $extension;
+      $tarball_handler = $handler;
+    }
+  }
+  if (!$tarball_handler) {
+    return drush_set_error('TARBALL_EXTRACT_UNKNOWN_FORMAT', dt('Tarball !path has unknown file extension.', array('!path' => $path)));
+  }
+
   if (!file_exists($path)) {
     return drush_set_error('TARBALL_EXTRACT_NOT_FOUND', dt('Tarball !path could not be found.', array('!path' => $path)));
   }
@@ -911,41 +932,68 @@ function drush_tarball_extract($path, $destination = FALSE, $listing = FALSE) {
   if (!is_writeable($destination)) {
     return drush_set_error('TARBALL_EXTRACT_DESTINATION', dt('Extracting !path failed, as the destination directory !dest was not found or could not be written to.', array('!path' => $path, '!dest' => $dest)));
   }
+
+  if ($tarball_handler === 'zip') {
+    if (drush_shell_cd_and_exec(dirname($tarball), "unzip %s -d %s", $tarball, $destination)) {
+      if ($listing) {
+        return drush_shell_exec_output();
+      }
+      return TRUE;
+    }
+    else {
+      return FALSE;
+    }
+  }
+  // ...otherwise we have a possibly-compressed Tar file.
+
+  $tar_compression_flag = '';
+  if ($tarball_handler === 'tar/gzip') {
+      $tar_compression_flag = 'z';
+  }
+  else if ($tarball_handler === 'tar/bzip2') {
+      $tar_compression_flag = 'j';
+  }
   // If we are not on Windows, then try to do "tar" in a single operation.
-  if ((!drush_is_windows()) && (drush_shell_cd_and_exec(dirname($path), "tar -C %s -xzf %s", $destination, basename($path)))) {
+  if ((!drush_is_windows()) && (drush_shell_cd_and_exec(dirname($path), "tar -C %s -x%sf %s", $destination, $tar_compression_flag, basename($path)))) {
     if ($listing) {
-      // We use a separate tar -tzf instead of -xvf above because
+      // We use a separate tar -tf instead of -xvf above because
       // the output is not the same in Mac.
-      drush_shell_cd_and_exec(dirname($path), "tar -tzf %s", basename($path));
+      drush_shell_cd_and_exec(dirname($path), "tar -t%sf %s", $tar_compression_flag, basename($path));
       return drush_shell_exec_output();
     }
     return TRUE;
   }
+
   // If we could not get the single-op tar to work, do it in three steps.
   // Copy the source tarball to the destination directory.  Rename to a temp name in case the destination directory == dirname($path)
-  $paths_basename = basename(basename($path, '.tar.gz'), '.tgz');
-  $tarball = drush_tempnam($paths_basename, $destination) . ".tar.gz";
+  $paths_basename = basename($path, $tarball_extension);
+  $tarball = drush_tempnam($paths_basename, $destination) . $tarball_extension;
   drush_register_file_for_deletion($tarball);
   drush_copy_dir($path, $tarball);
-  $unzipped = $destination . '/' . basename($tarball, ".tar.gz") . ".tar";
-  // We used to use gzip --decompress in --stdout > out, but the output redirection sometimes failed on Windows for some binary output
-  drush_shell_cd_and_exec(dirname($tarball), "gzip --decompress %s", $tarball);
-  if (file_exists($unzipped)) {
-    drush_register_file_for_deletion($unzipped);
-    if (drush_shell_cd_and_exec(dirname($unzipped), "tar -xf %s", basename($unzipped))) {
-      if ($listing) {
-        // We use a separate tar -tf instead of -xf above because
-        // the output is not the same in Mac.
-        drush_shell_cd_and_exec(dirname($unzipped), "tar -tf %s", basename($unzipped));
-        return drush_shell_exec_output();
-      }
-      return TRUE;
-    }
-    return drush_set_error('TARBALL_EXTRACT_TAR_FAIL', dt('Extracting !path using the tar command failed.', array('!path' => $path)));
+  $unzipped = $destination . '/' . basename($tarball, $tarball_extension) . ".tar";
+  
+  if ($tarball_handler === 'gzip') {
+      // We used to use gzip --decompress in --stdout > out, but the output redirection sometimes failed on Windows for some binary output
+      drush_shell_cd_and_exec(dirname($tarball), "gzip --decompress %s", $tarball);
   }
-  else {
-    return drush_set_error('TARBALL_EXTRACT_GZIP_FAIL', dt('Uncompressing !path using  the gzip command failed.', array('!path' => $path)));
+  else if ($tarball_handler === 'bzip2') {
+      drush_shell_cd_and_exec(dirname($tarball), "bzip2 --decompress %s", $tarball);
+  }
+  if (!file_exists($unzipped)) {
+    return drush_set_error('TARBALL_EXTRACT_UNCOMPRESS_FAIL', dt('Uncompressing !path failed.', array('!path' => $path)));
+  }
+  drush_register_file_for_deletion($unzipped);
+
+  if (drush_shell_cd_and_exec(dirname($unzipped), "tar -xf %s", basename($unzipped))) {
+    if ($listing) {
+      // We use a separate tar -tf instead of -xf above because
+      // the output is not the same in Mac.
+      drush_shell_cd_and_exec(dirname($unzipped), "tar -tf %s", basename($unzipped));
+      return drush_shell_exec_output();
+    }
+    return TRUE;
   }
+  return drush_set_error('TARBALL_EXTRACT_TAR_FAIL', dt('Extracting !path using the tar command failed.', array('!path' => $path)));
 }
 
 /**
diff --git a/tests/makeTest.php b/tests/makeTest.php
index a40e8f8..db59cc8 100644
--- a/tests/makeTest.php
+++ b/tests/makeTest.php
@@ -167,6 +167,10 @@ class makeMakefileCase extends Drush_CommandTestCase {
     $this->runMakefileTest('file');
   }
 
+  function testMakeBZ2() {
+    $this->runMakefileTest('bz2');
+  }
+
   function testMakeSubtree() {
     $this->runMakefileTest('subtree');
   }
@@ -327,6 +331,13 @@ class makeMakefileCase extends Drush_CommandTestCase {
         'md5' => 'c7cab3930f644961a576d78769498172',
         'options'  => array('no-core' => NULL),
       ),
+      'bz2' => array(
+        'name'     => 'bzip2',
+        'makefile' => 'bz2.make',
+        'build'    => TRUE,
+        'md5'      => '05b6935122a499375a7ea46879a133ab',
+        'options'  => array('no-core' => NULL),
+      ),
       'subtree' => array(
         'name'     => 'Use subtree from downloaded archive',
         'makefile' => 'subtree.make',
diff --git a/tests/makefiles/bz2.make b/tests/makefiles/bz2.make
new file mode 100644
index 0000000..b7838d3
--- /dev/null
+++ b/tests/makefiles/bz2.make
@@ -0,0 +1,6 @@
+core = 6.x
+api = 2
+
+libraries[bison][destination] = libraries
+libraries[bison][download][type] = get
+libraries[bison][download][url] = http://ftp.gnu.org/gnu/bison/bison-1.30.tar.bz2
