diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 1056b67..c6fe2c4 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -450,6 +450,9 @@ function _drush_bootstrap_drush() {
   // prime the CWD cache
   drush_cwd();
 
+  // Decide which Drupal site drush will later bootstrap
+  _drush_bootstrap_select_drupal_site();
+
   // Set up base environment for system-wide file locations.
   _drush_bootstrap_base_environment();
 
@@ -475,13 +478,26 @@ function _drush_bootstrap_drush() {
   // of the drush and drupal root bootstrap phases are
   // done, since site aliases may set option values that
   // affect these phases.
-  // TODO: Note that this function will call drush_locate_root
-  // (from within _drush_sitealias_find_record_for_local_site),
-  // and drush_locate_root will be called again when bootstrapping
-  // the drupal root below.  Is there a good way to refactor this
-  // so that we do not need to search for the root twice?
   drush_sitealias_check_arg();
 
+  // Load the config options from the Drupal root, even prior to bootstrapping the root
+  drush_load_config('drupal');
+
+  // Similarly, load the Drupal site configuration options upfront.
+  drush_load_config('site');
+
+  // If drush_load_config defined a site alias that did not
+  // exist before, then sitealias check arg might now match
+  // against one of those aliases.
+  if (drush_sitealias_check_arg() === TRUE) {
+    $remote_host = drush_get_option('remote-host');
+    if (!isset($remote_host)) {
+      // Load the config files for the "new" site.
+      drush_load_config('drupal');
+      drush_load_config('site');
+    }
+  }
+
   $backend = drush_set_context('DRUSH_BACKEND', drush_get_option(array('b', 'backend')));
 
   // Pipe implies quiet.
@@ -517,6 +533,22 @@ function _drush_bootstrap_drush() {
   _drush_bootstrap_global_options();
 }
 
+function _drush_bootstrap_select_drupal_site() {
+  $drupal_root = drush_get_option(array('r', 'root'));
+  if (!isset($drupal_root)) {
+    $drupal_root = drush_locate_root();
+  }
+  drush_set_context('DRUSH_SELECTED_DRUPAL_ROOT', $drupal_root);
+  $uri = _drush_bootstrap_selected_uri();
+  drush_set_context('DRUSH_SELECTED_URI', $uri);
+  drush_set_context('DRUSH_SELECTED_DRUPAL_SITE_ROOT', _drush_bootstrap_conf_path($uri));
+
+  if (!empty($drupal_root) && !empty($uri)) {
+    // Create an alias '@self'
+    _drush_sitealias_cache_alias('self', array('root' => $drupal_root, 'uri' => $uri));
+  }
+}
+
 /**
  * Sets up basic environment that controls where Drush looks for files on a
  * system-wide basis. Important to call for "early" functions that need to
@@ -566,7 +598,7 @@ function _drush_bootstrap_global_options() {
  * context and DRUPAL_ROOT constant if it is considered a valid option.
  */
 function _drush_bootstrap_drupal_root_validate() {
-  $drupal_root = drush_get_option(array('r', 'root'), drush_locate_root());
+  $drupal_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT');
 
   if (empty($drupal_root)) {
     return drush_bootstrap_error('DRUSH_NO_DRUPAL_ROOT', dt("A Drupal installation directory could not be found"));
@@ -598,7 +630,6 @@ function _drush_bootstrap_drupal_root() {
   define('DRUPAL_ROOT', $drupal_root);
 
   chdir($drupal_root);
-  drush_load_config('drupal');
   require_once DRUPAL_ROOT . '/' . DRUSH_DRUPAL_SIGNATURE;
   $version = drush_set_context('DRUSH_DRUPAL_VERSION', drush_drupal_version());
   $major_version = drush_set_context('DRUSH_DRUPAL_MAJOR_VERSION', drush_drupal_major_version());
@@ -609,6 +640,67 @@ function _drush_bootstrap_drupal_root() {
 }
 
 /**
+ * Find the URI that has been selected by the --uri / -l option
+ * or the cwd.
+ */
+function _drush_bootstrap_selected_uri() {
+  $uri = drush_get_option(array('l', 'uri'));
+  if (!isset($uri)) {
+    $site_path = drush_site_path();
+    $elements = explode('/', $site_path);
+    $current = array_pop($elements);
+    if (!$current) {
+      $current = 'default';
+    }
+    $uri = 'http://'. $current;
+  }
+
+  return $uri;
+}
+
+function _drush_bootstrap_conf_path($server_uri, $require_settings = TRUE) {
+  $drupal_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT');
+  if(!isset($drupal_root) || !isset($server_uri)) {
+    return NULL;
+  }
+  $parsed_uri = parse_url($server_uri);
+  if (!array_key_exists('scheme', $parsed_uri)) {
+    $parsed_uri = parse_url('http://' . $server_uri);
+  }
+  $server_host = $parsed_uri['host'];
+  if (array_key_exists('path', $parsed_uri)) {
+    $server_uri = $parsed_uri['path'] . '/index.php';
+  }
+  else {
+    $server_uri = "/index.php";
+  }
+  $confdir = 'sites';
+
+  $sites = array();
+  if (file_exists($drupal_root . '/' . $confdir . '/sites.php')) {
+    // This will overwrite $sites with the desired mappings.
+    include($drupal_root . '/' . $confdir . '/sites.php');
+  }
+
+  $uri = explode('/', $server_uri);
+  $server = explode('.', implode('.', array_reverse(explode(':', rtrim($server_host, '.')))));
+  for ($i = count($uri) - 1; $i > 0; $i--) {
+    for ($j = count($server); $j > 0; $j--) {
+      $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
+      if (isset($sites[$dir]) && file_exists($drupal_root . '/' . $confdir . '/' . $sites[$dir])) {
+        $dir = $sites[$dir];
+      }
+      if (file_exists($drupal_root . '/' . $confdir . '/' . $dir . '/settings.php') || (!$require_settings && file_exists(DRUPAL_ROOT . '/' . $confdir . '/' . $dir))) {
+        $conf = "$confdir/$dir";
+        return $conf;
+      }
+    }
+  }
+  $conf = "$confdir/default";
+  return $conf;
+}
+
+/**
  * VALIDATE the DRUSH_BOOTSTRAP_DRUPAL_SITE phase.
  *
  * In this function we determine the URL used for the command,
@@ -619,15 +711,7 @@ function _drush_bootstrap_drupal_root() {
  * as a configuration file.
  */
 function _drush_bootstrap_drupal_site_validate() {
-  $site_path = drush_site_path();
-  $elements = explode('/', $site_path);
-  $current = array_pop($elements);
-  if (!$current) {
-    $current = 'default';
-  }
-  $uri = 'http://'. $current;
-
-  $drush_uri = drush_bootstrap_value('drush_uri', drush_get_option(array('l', 'uri'), $uri));
+  $drush_uri = drush_bootstrap_value('drush_uri', drush_get_context('DRUSH_SELECTED_URI'));
 
   // Fake the necessary HTTP headers that Drupal needs:
   if ($drush_uri) {
@@ -691,11 +775,7 @@ function _drush_bootstrap_do_drupal_site() {
   $site = drush_set_context('DRUSH_DRUPAL_SITE', drush_bootstrap_value('site'));
   $conf_path = drush_set_context('DRUSH_DRUPAL_SITE_ROOT', drush_bootstrap_value('conf_path'));
 
-  // Create an alias '@self'
-  _drush_sitealias_cache_alias('self', array('root' => drush_get_context('DRUSH_DRUPAL_ROOT'), 'uri' => $drush_uri));
-
   drush_log(dt("Initialized Drupal site !site at !site_root", array('!site' => $site, '!site_root' => $conf_path)));
-  drush_load_config('site');
 
   _drush_bootstrap_global_options();
 }
@@ -708,49 +788,12 @@ function _drush_bootstrap_do_drupal_site() {
  */
 function _drush_bootstrap_drupal_site() {
   _drush_bootstrap_do_drupal_site();
-  _drush_bootstrap_redo_drupal_site();
 
   // Set warning for Windows users. We have already loaded site-specific drushrc.
   drush_environment_check_os();
 }
 
 /**
- * Re-do the drupal site bootstrap (and possibly the
- * drupal root bootstrap) if a site alias was processed
- * after the site bootstrap phase completed.  This will
- * happen when processing "drush sitealias command" for
- * a site alias defined in a drushrc.php file in the
- * default site's drush configuration directory.
- */
-function _drush_bootstrap_redo_drupal_site() {
-  // If drush_load_config defined a site alias that did not
-  // exist before, then sitealias check arg might now match
-  // against one of those aliases.
-  if (drush_sitealias_check_arg() === TRUE) {
-    $remote_host = drush_get_option('remote-host');
-    if (!isset($remote_host)) {
-      // Check to see if the drupal root changed.
-      // If it has, we will set remote-host to cause
-      // this command to be executed via the backend invoke
-      // process.
-      $sitealias_drupal_root = drush_get_option(array('r', 'root'));
-      if (($sitealias_drupal_root != null) && (DRUPAL_ROOT != $sitealias_drupal_root)) {
-        drush_set_option('remote-host', 'localhost');
-      }
-      else {
-        // If we set an alias, then we need to bootstrap the
-        // drupal site once again.  It is possible to re-bootstrap
-        // the site at this point because settings.php has not
-        // been included yet.
-        drush_log(dt("Re-bootstrap drupal site."));
-        _drush_bootstrap_drupal_site_validate();
-        _drush_bootstrap_do_drupal_site();
-      }
-    }
-  }
-}
-
-/**
  * Initialize and load the Drupal configuration files.
  *
  * We process and store a normalized set of database credentials
diff --git a/includes/context.inc b/includes/context.inc
index 9f51b67..b78f68d 100644
--- a/includes/context.inc
+++ b/includes/context.inc
@@ -105,12 +105,12 @@ function _drush_config_file($context, $prefix = NULL) {
     $configs['custom'] = $config;
   }
 
-  if ($site_path = drush_get_context('DRUSH_DRUPAL_SITE_ROOT')) {
-    $configs['site'] = $site_path . "/" . $config_file;
-  }
-
-  if ($drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT')) {
+  if ($drupal_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT')) {
     $configs['drupal'] = $drupal_root . '/' . $config_file;
+
+    if ($site_path = $drupal_root . '/' . drush_get_context('DRUSH_SELECTED_DRUPAL_SITE_ROOT')) {
+      $configs['site'] = $site_path . "/" . $config_file;
+    }
   }
 
   // in the user home directory
diff --git a/includes/environment.inc b/includes/environment.inc
index 6323083..6d1a2c2 100644
--- a/includes/environment.inc
+++ b/includes/environment.inc
@@ -237,43 +237,39 @@ function _drush_shift_path_up($path) {
  *   Current site path (folder containing settings.php) or FALSE if not found.
  */
 function drush_site_path($path = NULL) {
-  static $site_path;
+  $site_path = FALSE;
 
-  if (!isset($site_path)) {
-    $site_path = FALSE;
-
-    $path = empty($path) ? drush_cwd() : $path;
-    // Check the current path.
-    if (file_exists($path . '/settings.php')) {
-      $site_path = $path;
-    }
-    else {
-      // Move up dir by dir and check each.
-      while ($path = _drush_shift_path_up($path)) {
-        if (file_exists($path . '/settings.php')) {
-          $site_path = $path;
-          break;
-        }
+  $path = empty($path) ? drush_cwd() : $path;
+  // Check the current path.
+  if (file_exists($path . '/settings.php')) {
+    $site_path = $path;
+  }
+  else {
+    // Move up dir by dir and check each.
+    while ($path = _drush_shift_path_up($path)) {
+      if (file_exists($path . '/settings.php')) {
+        $site_path = $path;
+        break;
       }
     }
+  }
 
-    $site_root = drush_locate_root();
-    if (file_exists($site_root . '/sites/sites.php')) {
-      $sites = array();
-      // This will overwrite $sites with the desired mappings.
-      include($site_root . '/sites/sites.php');
-      // We do a reverse lookup here to determine the URL given the site key.
-      if ($match = array_search($site_path, $sites)) {
-        $site_path = $match;
-      }
+  $site_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT');
+  if (file_exists($site_root . '/sites/sites.php')) {
+    $sites = array();
+    // This will overwrite $sites with the desired mappings.
+    include($site_root . '/sites/sites.php');
+    // We do a reverse lookup here to determine the URL given the site key.
+    if ($match = array_search($site_path, $sites)) {
+      $site_path = $match;
     }
+  }
 
-    // Last resort: try from site root
-    if (!$site_path) {
-      if ($site_root) {
-        if (file_exists($site_root . '/sites/default/settings.php')) {
-          $site_path = $site_root . '/sites/default';
-        }
+  // Last resort: try from site root
+  if (!$site_path) {
+    if ($site_root) {
+      if (file_exists($site_root . '/sites/default/settings.php')) {
+        $site_path = $site_root . '/sites/default';
       }
     }
   }
diff --git a/includes/sitealias.inc b/includes/sitealias.inc
index defcd38..b7c3a68 100644
--- a/includes/sitealias.inc
+++ b/includes/sitealias.inc
@@ -284,10 +284,7 @@ function drush_sitealias_alias_path($alias_path_context = NULL) {
 
     // If the user defined the root of a drupal site, then also
     // look for alias files there.
-    $drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT');
-    if (empty($drupal_root)) {
-      $drupal_root = drush_get_option(array('root', 'r'), NULL);
-    }
+    $drupal_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT');
     if (isset($drupal_root)) {
       $site_paths[] = $drupal_root;
     }
@@ -420,10 +417,7 @@ function _drush_sitealias_find_and_load_alias($aliasname, $alias_path_context =
       }
     }
     else {
-      $drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT');
-      if ($drupal_root == NULL) {
-        $drupal_root = drush_get_option(array('r', 'root'), drush_locate_root());
-      }
+      $drupal_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT');
     }
     if (isset($drupal_root) && !is_array($drupal_root)) {
       drush_sitealias_create_sites_alias($drupal_root);
@@ -1225,8 +1219,7 @@ function _drush_sitealias_find_record_for_local_site($alias, $drupal_root = null
   }
 
   if (!isset($drupal_root)) {
-    //$drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT');
-    $drupal_root = drush_get_option(array('r', 'root'), drush_locate_root());
+    $drupal_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT');
   }
 
   if (isset($drupal_root)) {
@@ -1376,6 +1369,8 @@ function _drush_sitealias_set_context_by_name($alias, $prefix = '') {
     // Create an alias '@self'
     _drush_sitealias_cache_alias('self', $site_alias_settings);
     drush_sitealias_set_alias_context($site_alias_settings, $prefix);
+    // change the selected site to match the new --root and --uri, if any were set
+    _drush_bootstrap_select_drupal_site();
     return TRUE;
   }
   return FALSE;
diff --git a/tests/completeTest.php b/tests/completeTest.php
index 4c57f25..61f42bd 100644
--- a/tests/completeTest.php
+++ b/tests/completeTest.php
@@ -52,7 +52,7 @@ class completeCase extends Drush_CommandTestCase {
     // No context (i.e. "drush <tab>"), should list aliases and commands.
     $this->verifyComplete("''", '@none', 'wd');
     // Site alias alone.
-    $this->verifyComplete('@', '@none', '@stage');
+    $this->verifyComplete('@', '@none', '@dev');
     // Command alone.
     $this->verifyComplete('d', 'drupal-directory', 'download');
     // Command with single result.
