diff --git a/README.txt b/README.txt
index 8c1443a..a2037ca 100644
--- a/README.txt
+++ b/README.txt
@@ -130,6 +130,12 @@ Hidden variables
   The maximum number of bytes that can be handled as an HTTP GET query when
   HTTP method is AUTO. Typically Solr can handle up to 65355 bytes, but Tomcat
   and Jetty will error at slightly less than 4096 bytes.
+- search_api_solr_site_hash (default: random)
+  A unique hash specific to the local site, created the first time it is needed.
+  Only change this if you want to display another server's results and you know
+  what you are doing. Old indexed items will be lost when the hash is changed
+  and all items will have to be reindexed. Can only contain alphanumeric
+  characters.
 
 Customizing your Solr server
 ----------------------------
diff --git a/includes/service.inc b/includes/service.inc
index 0be6141..660f5de 100644
--- a/includes/service.inc
+++ b/includes/service.inc
@@ -82,16 +82,17 @@ class SearchApiSolrService extends SearchApiAbstractService {
       'http_method' => 'AUTO',
       // Default to TRUE for new servers, but to FALSE for existing ones.
       'clean_ids' => $this->options ? FALSE : TRUE,
+      'site_hash' => $this->options ? FALSE : TRUE,
       'autocorrect_spell' => TRUE,
       'autocorrect_suggest_words' => TRUE,
     );
 
     if (!$options['clean_ids']) {
       if (module_exists('advanced_help')) {
-        $variables['@url']= url('help/search_api_solr/README.txt');
+        $variables['@url'] = url('help/search_api_solr/README.txt');
       }
       else {
-        $variables['@url']= url(drupal_get_path('module', 'search_api_solr') . '/README.txt');
+        $variables['@url'] = url(drupal_get_path('module', 'search_api_solr') . '/README.txt');
       }
       $description = t('Change Solr field names to be more compatible with advanced features. Doing this leads to re-indexing of all indexes on this server. See <a href="@url">README.txt</a> for details.', $variables);
       $form['clean_ids_form'] = array(
@@ -111,6 +112,25 @@ class SearchApiSolrService extends SearchApiAbstractService {
       '#value' => $options['clean_ids'],
     );
 
+    if (!$options['site_hash']) {
+      $description = t('If you want to index content from multiple sites on a single Solr server, you should enable the multi-site compatibility here. Note, however, that this will completely clear all search indexes (from this site) lying on this server. All content will have to be re-indexed.');
+      $form['site_hash_form'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Multi-site compatibility'),
+        '#description' => $description,
+        '#collapsible' => TRUE,
+      );
+      $form['site_hash_form']['submit'] = array(
+        '#type' => 'submit',
+        '#value' => t('Turn on multi-site compatibility and clear all indexes'),
+        '#submit' => array('_search_api_solr_switch_to_site_hash'),
+      );
+    }
+    $form['site_hash'] = array(
+      '#type' => 'value',
+      '#value' => $options['site_hash'],
+    );
+
     $form['scheme'] = array(
       '#type' => 'select',
       '#title' => t('HTTP protocol'),
@@ -380,12 +400,20 @@ class SearchApiSolrService extends SearchApiAbstractService {
     if (module_exists('search_api_multi') && module_exists('search_api_views')) {
       views_invalidate_cache();
     }
-    $id = is_object($index) ? $index->machine_name : $index;
+    $index_id = is_object($index) ? $index->machine_name : $index;
     // Only delete the index's data if the index isn't read-only.
     if (!is_object($index) || empty($index->read_only)) {
       $this->connect();
       try {
-        $this->solr->deleteByQuery("index_id:" . $this->getIndexId($id));
+        $index_id = $this->getIndexId($index_id);
+        $index_id = call_user_func(array($this->connection_class, 'phrase'), $index_id);
+        $query = "index_id:$index_id";
+        if (!empty($this->options['site_hash'])) {
+          // We don't need to escape the site hash, as that consists only of
+          // alphanumeric characters.
+          $query .= ' hash:' . search_api_solr_site_hash();
+        }
+        $this->solr->deleteByQuery($query);
       }
       catch (Exception $e) {
         throw new SearchApiException($e->getMessage());
@@ -401,14 +429,33 @@ class SearchApiSolrService extends SearchApiAbstractService {
     $ret = array();
     $index_id = $this->getIndexId($index->machine_name);
     $fields = $this->getFieldNames($index);
+    $languages = language_list();
+    $base_urls = array();
 
     foreach ($items as $id => $item) {
       try {
+        // Add basic item and index information.
         $doc = new SearchApiSolrDocument();
         $doc->setField('id', $this->createId($index_id, $id));
         $doc->setField('index_id', $index_id);
         $doc->setField('item_id', $id);
 
+        // If multi-site compatibility is enabled, add the site hash and
+        // language-specific base URL.
+        if (!empty($this->options['site_hash'])) {
+          $doc->setField('hash', search_api_solr_site_hash());
+          $lang = $item['search_api_language']['value'];
+          if (empty($base_urls[$lang])) {
+            $url_options = array('absolute' => TRUE);
+            if (isset($languages[$lang])) {
+              $url_options['language'] = $languages[$lang];
+            }
+            $base_urls[$lang] = url(NULL, $url_options);
+          }
+          $doc->setField('site', $base_urls[$lang]);
+        }
+
+        // Now add all fields contained in the item, with dynamic fields.
         foreach ($item as $key => $field) {
           if (!isset($fields[$key])) {
             throw new SearchApiException(t('Unknown field @field.', array('@field' => $key)));
@@ -448,10 +495,14 @@ class SearchApiSolrService extends SearchApiAbstractService {
   /**
    * Creates an ID used as the unique identifier at the Solr server.
    *
-   * This has to consist of both index and item ID.
+   * This has to consist of both index and item ID. Optionally, the site hash is
+   * also included.
+   *
+   * @see search_api_solr_site_hash()
    */
   protected function createId($index_id, $item_id) {
-    return "$index_id-$item_id";
+    $site_hash = !empty($this->options['site_hash']) ? search_api_solr_site_hash() . '-' : '';
+    return "$site_hash$index_id-$item_id";
   }
 
   /**
@@ -593,25 +644,30 @@ class SearchApiSolrService extends SearchApiAbstractService {
    */
   public function deleteItems($ids = 'all', SearchApiIndex $index = NULL) {
     $this->connect();
-    if ($index) {
+    if (is_array($ids)) {
       $index_id = $this->getIndexId($index->machine_name);
-      if (is_array($ids)) {
-        $solr_ids = array();
-        foreach ($ids as $id) {
-          $solr_ids[] = $this->createId($index_id, $id);
-        }
-        $this->solr->deleteByMultipleIds($solr_ids);
-      }
-      elseif ($ids == 'all') {
-        $this->solr->deleteByQuery("index_id:" . $index_id);
-      }
-      else {
-        $this->solr->deleteByQuery("index_id:" . $index_id . ' (' . $ids . ')');
+      $solr_ids = array();
+      foreach ($ids as $id) {
+        $solr_ids[] = $this->createId($index_id, $id);
       }
+      $this->solr->deleteByMultipleIds($solr_ids);
     }
     else {
-      $q = $ids == 'all' ? '*:*' : $ids;
-      $this->solr->deleteByQuery($q);
+      $query = array();
+      if ($index) {
+        $index_id = $this->getIndexId($index->machine_name);
+        $index_id = call_user_func(array($this->connection_class, 'phrase'), $index_id);
+        $query[] = "index_id:$index_id";
+      }
+      if (!empty($this->options['site_hash'])) {
+        // We don't need to escape the site hash, as that consists only of
+        // alphanumeric characters.
+        $query[] = 'hash:' . search_api_solr_site_hash();
+      }
+      if ($ids != 'all') {
+        $query[] = $query ? "($ids)" : $ids;
+      }
+      $this->solr->deleteByQuery($query ? implode(' ', $query) : '*:*');
     }
     $this->scheduleCommit();
   }
@@ -652,7 +708,12 @@ class SearchApiSolrService extends SearchApiAbstractService {
     // Extract filters.
     $filter = $query->getFilter();
     $fq = $this->createFilterQueries($filter, $fields, $index->options['fields']);
-    $fq[] = 'index_id:' . $index_id;
+    $fq[] = 'index_id:' . call_user_func(array($this->connection_class, 'phrase'), $index_id);
+    if (!empty($this->options['site_hash'])) {
+      // We don't need to escape the site hash, as that consists only of
+      // alphanumeric characters.
+      $fq[] = 'hash:' . search_api_solr_site_hash();
+    }
 
     // Extract sort.
     $sort = array();
@@ -1568,7 +1629,13 @@ class SearchApiSolrService extends SearchApiAbstractService {
 
     // Extract filters
     $fq = $this->createFilterQueries($query->getFilter(), $fields, $index->options['fields']);
-    $fq[] = 'index_id:' . $this->getIndexId($index->machine_name);
+    $index_id = $this->getIndexId($index->machine_name);
+    $fq[] = 'index_id:' . call_user_func(array($this->connection_class, 'phrase'), $index_id);
+    if (!empty($this->options['site_hash'])) {
+      // We don't need to escape the site hash, as that consists only of
+      // alphanumeric characters.
+      $fq[] = 'hash:' . search_api_solr_site_hash();
+    }
 
     // Autocomplete magic
     $facet_fields = array();
@@ -1770,6 +1837,11 @@ class SearchApiSolrService extends SearchApiAbstractService {
       $index_filter[] = 'index_id:' . call_user_func(array($this->connection_class, 'phrase'), $index_id);
     }
     $fq[] = implode(' OR ', $index_filter);
+    if (!empty($this->options['site_hash'])) {
+      // We don't need to escape the site hash, as that consists only of
+      // alphanumeric characters.
+      $fq[] = 'hash:' . search_api_solr_site_hash();
+    }
 
     // Extract sort
     $sort = array();
@@ -2066,4 +2138,5 @@ class SearchApiSolrService extends SearchApiAbstractService {
     $id = variable_get('search_api_solr_index_prefix', '') . $id;
     return $id;
   }
+
 }
diff --git a/search_api_solr.install b/search_api_solr.install
index d67bb4d..062a78e 100644
--- a/search_api_solr.install
+++ b/search_api_solr.install
@@ -63,6 +63,7 @@ function search_api_solr_uninstall() {
   variable_del('search_api_solr_autocomplete_max_occurrences');
   variable_del('search_api_solr_index_prefix');
   variable_del('search_api_solr_http_get_max_length');
+  variable_del('search_api_solr_site_hash');
 }
 
 /**
diff --git a/search_api_solr.module b/search_api_solr.module
index f4f319f..eadba8d 100644
--- a/search_api_solr.module
+++ b/search_api_solr.module
@@ -218,6 +218,25 @@ function search_api_solr_get_data_type_info($type = NULL) {
 }
 
 /**
+ * Returns a unique hash for the current site.
+ *
+ * This is used to identify Solr documents from different sites within a single
+ * Solr server.
+ *
+ * @return string
+ *   A unique site hash, containing only alphanumeric characters.
+ */
+function search_api_solr_site_hash() {
+  // Copied from apachesolr_site_hash().
+  if (!($hash = variable_get('search_api_solr_site_hash', FALSE))) {
+    global $base_url;
+    $hash = substr(base_convert(sha1(uniqid($base_url, TRUE)), 16, 36), 0, 6);
+    variable_set('search_api_solr_site_hash', $hash);
+  }
+  return $hash;
+}
+
+/**
  * Retrieves a list of all config files of a server.
  *
  * @param SearchApiServer $server
@@ -326,3 +345,35 @@ function _search_api_solr_switch_to_clean_ids(array $form, array &$form_state) {
     drupal_set_message($msg);
   }
 }
+
+/**
+ * Switches a server to multi-site compatibility mode.
+ *
+ * Used as a submit callback in SearchApiSolrService::configurationForm().
+ */
+function _search_api_solr_switch_to_site_hash(array $form, array &$form_state) {
+  $server = $form_state['server'];
+
+  try {
+    $conditions['server'] = $server->machine_name;
+    $indexes = search_api_index_load_multiple(FALSE, $conditions);
+    if ($indexes) {
+      foreach ($indexes as $index) {
+        $index->reindex();
+      }
+      $msg = format_plural(count($indexes), '1 index was cleared.', '@count indexes were cleared.');
+      $server->deleteItems('index_id:(' . implode(' ', array_keys($indexes)) . ')');
+      drupal_set_message($msg);
+    }
+  }
+  catch (SearchApiException $e) {
+    $variables = array('@server' => $server->name);
+    watchdog_exception('search_api_solr', $e, '%type while attempting to enable multi-site compatibility mode for Solr server @server: !message in %function (line %line of %file).', $variables);
+    drupal_set_message(t('An error occured while attempting to enable multi-site compatibility mode for Solr server @server. Check the logs for details.', $variables), 'error');
+    return;
+  }
+
+  $server->options['site_hash'] = TRUE;
+  $server->save();
+  drupal_set_message(t('The Solr server was successfully switched to multi-site compatibility mode.'));
+}
