diff -urNP rustemmer.orig/README.txt rustemmer/README.txt
--- rustemmer.orig/README.txt	2011-02-25 05:14:04.000000000 +0300
+++ rustemmer/README.txt	2012-11-01 03:02:52.804752586 +0400
@@ -2,7 +2,7 @@
 ------
 
 This module implements the Russian stemming algorithm to improve Russian-language
-searching with the Drupal built-in search.module.
+searching with the Drupal built-in search.module and with Search API contrib module.
 
 Stemming attempts to reduce a word to its stem or root form. This generally results in more relevant
 results.
diff -urNP rustemmer.orig/rustemmer.info rustemmer/rustemmer.info
--- rustemmer.orig/rustemmer.info	2011-02-25 05:14:04.000000000 +0300
+++ rustemmer/rustemmer.info	2012-11-01 03:04:54.896756431 +0400
@@ -1,3 +1,4 @@
 name = "RussianStemmer"
 description = "Implements the Russian stemming algorithm to improve Russian-language searching."
-core = 6.x
+core = 7.x
+package = Search
diff -urNP rustemmer.orig/rustemmer.module rustemmer/rustemmer.module
--- rustemmer.orig/rustemmer.module	2011-02-25 05:14:04.000000000 +0300
+++ rustemmer/rustemmer.module	2012-11-01 03:39:39.688822093 +0400
@@ -14,24 +14,17 @@
 
 define('RUSTEMMER_CHARS', '_0-9a-zA-ZабвгдежзийклмнопрстуфхцчшщьыъэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ');
 
-/**
- * Implements hook_help().
- */
-function rustemmer_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#rustemmer':
-      return t('Improves search of Russian words by using the stemming algorithm for Russian language.');
-  }
-}
 
 /**
  * Implements hook_search_preprocess().
  */
 function rustemmer_search_preprocess($text) {
-  // Split words from noise and remove apostrophes.
-  $words = str_replace("'", '', $text);
+  $words = $text;
+  $words = str_replace('ё','е', $words);
+  $words = str_replace('Ё','Е', $words);
 
-  $words = preg_split('/([^' . RUSTEMMER_CHARS . ']+)/', $words, -1, PREG_SPLIT_DELIM_CAPTURE);
+  // Split words from noise and remove apostrophes.
+  $words = preg_split('/([^' . RUSTEMMER_CHARS . ']+)/u', str_replace("'", '', $words), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
 
   $stemmer = new RussianStemmer();
   // Process each word.
@@ -42,57 +35,70 @@
     }
     $odd = !$odd;
   }
-
   // Put it all back together.
   return implode('', $words);
 }
 
+
 /**
- * Implements hook_search().
+ * Implements hook_search_admin().
  */
-function rustemmer_search($op = 'search', $keys = NULL) {
-  if ($op == 'admin') {
-  	$form = array();
-    $form['rustemmer_stemcaching'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Stem caching'),
-      '#default_value' => variable_get('rustemmer_stemcaching', 0),
-      '#description' => t('Apply stem caching while performing search phrase stemming. Warning: This could lead to additional memory consumption while indexing.'),
-    );
-    return $form;
-  }
+function rustemmer_search_admin() {
+  $form = array();
+  $form['indexing_settings']['rustemmer_stemcaching'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Stem caching'),
+    '#default_value' => variable_get('rustemmer_stemcaching', 0),
+    '#description' => t('Apply stem caching while performing search phrase stemming. Warning: This could lead to additional memory consumption while indexing.'),
+  );
+  return $form;
 }
 
+
 /**
- * Class of Russian Stemming algorithm.
+ * Implements hook_search_api_processor_info().
  */
-class RussianStemmer {
-
-  var $VERSION = "0.02";
-
-  var $Stem_Caching = 0;
-
-  var $Stem_Cache = array();
-
-  var $VOWEL = '/аеиоуыэюя/';
-
-  var $PERFECTIVEGROUND = '/((ив|ивши|ившись|ыв|ывши|ывшись)|((?<=[ая])(в|вши|вшись)))$/';
+function rustemmer_search_api_processor_info() {
+  $processors['search_api_russian_stemmer'] = array(
+    'name' => t('Russian stemmer'),
+    'description' => t('This processor improves search of Russian words by using the stemming algorithm for Russian language.'),
+    'class' => 'SearchApiRussianStemmer',
+  );
 
-  var $REFLEXIVE = '/(с[яь])$/';
+  return $processors;
+}
 
-  var $ADJECTIVE = '/(ее|ие|ые|ое|ими|ыми|ей|ий|ый|ой|ем|им|ым|ом|его|ого|ему|ому|их|ых|ую|юю|ая|яя|ою|ею)$/';
 
-  var $PARTICIPLE = '/((ивш|ывш|ующ)|((?<=[ая])(ем|нн|вш|ющ|щ)))$/';
+/**
+ * Processor for making searches case-insensitive.
+ */
+class SearchApiRussianStemmer extends SearchApiAbstractProcessor {
 
-  var $VERB = '/((ила|ыла|ена|ейте|уйте|ите|или|ыли|ей|уй|ил|ыл|им|ым|ен|ило|ыло|ено|ят|ует|уют|ит|ыт|ены|ить|ыть|ишь|ую|ю)|((?<=[ая])(ла|на|ете|йте|ли|й|л|ем|н|ло|но|ет|ют|ны|ть|ешь|нно)))$/';
+  protected function process(&$value) {
+    $value = rustemmer_search_preprocess($value);
+  }
 
-  var $NOUN = '/(а|ев|ов|ие|ье|е|иями|ями|ами|еи|ии|и|ией|ей|ой|ий|й|иям|ям|ием|ем|ам|ом|о|у|ах|иях|ях|ы|ь|ию|ью|ю|ия|ья|я)$/';
+}
 
-  var $RVRE = '/^(.*?[аеиоуыэюя])(.*)$/';
 
-  var $DERIVATIONAL = '/[^аеиоуыэюя][аеиоуыэюя]+[^аеиоуыэюя]+[аеиоуыэюя].*(?<=о)сть?$/';
+/**
+ * Implementation of Russian Stemming algorithm.
+ */
+class RussianStemmer {
+  var $VERSION = "0.02";
+  var $Stem_Caching = 0;
+  var $Stem_Cache = array();
+  var $VOWEL = '/аеиоуыэюя/u';
+  var $PERFECTIVEGROUND = '/((ив|ивши|ившись|ыв|ывши|ывшись)|((?<=[ая])(в|вши|вшись)))$/u';
+  var $REFLEXIVE = '/(с[яь])$/u';
+  var $ADJECTIVE = '/(ее|ие|ые|ое|ими|ыми|ей|ий|ый|ой|ем|им|ым|ом|его|ого|ему|ому|их|ых|ую|юю|ая|яя|ою|ею)$/u';
+  var $PARTICIPLE = '/((ивш|ывш|ующ)|((?<=[ая])(ем|нн|вш|ющ|щ)))$/u';
+  var $VERB = '/((ила|ыла|ена|ейте|уйте|ите|или|ыли|ей|уй|ил|ыл|им|ым|ен|ило|ыло|ено|ят|ует|уют|ит|ыт|ены|ить|ыть|ишь|ую|ю)|((?<=[ая])(ла|на|ете|йте|ли|й|л|ем|н|ло|но|ет|ют|ны|ть|ешь|нно)))$/u';
+  var $NOUN = '/(а|ев|ов|ие|ье|е|иями|ями|ами|еи|ии|и|ией|ей|ой|ий|й|иям|ям|ием|ем|ам|ом|о|у|ах|иях|ях|ы|ь|ию|ью|ю|ия|ья|я)$/u';
+  var $RVRE = '/^(.*?[аеиоуыэюя])(.*)$/u';
+  var $DERIVATIONAL = '/[^аеиоуыэюя][аеиоуыэюя]+[^аеиоуыэюя]+[аеиоуыэюя].*(?<=о)сть?$/u';
 
-  function RussianStemmer() {
+  function __construct() {
     $Stem_Caching = variable_get('rustemmer_stemcaching', 0);
   }
 
@@ -108,15 +114,13 @@
 
   function stem_word($word) {
     $word = drupal_strtolower($word);
-    $trans = array('ё' => 'е');
-    $words = strtr($text, $trans);
-
+    $word = str_replace('ё','е', $word);
     // Check against cache of stemmed words
     if ($this->Stem_Caching && isset($this->Stem_Cache[$word])) {
       return $this->Stem_Cache[$word];
     }
-
     $stem = $word;
+
     do {
       if (!preg_match($this->RVRE, $word, $p)) {
         break;
@@ -142,21 +146,21 @@
       }
 
       // Step 2
-      $this->s($RV, '/и$/', '');
+      $this->s($RV, '/и$/u', '');
 
       // Step 3
       if ($this->m($RV, $this->DERIVATIONAL)) {
-        $this->s($RV, '/ость?$/', '');
+        $this->s($RV, '/ость?$/u', '');
       }
 
       // Step 4
-      if (!$this->s($RV, '/ь$/', '')) {
-        $this->s($RV, '/ейше?/', '');
-        $this->s($RV, '/нн$/', 'н');
+      if (!$this->s($RV, '/ь$/u', '')) {
+        $this->s($RV, '/ейше?/u', '');
+        $this->s($RV, '/нн$/u', 'н');
       }
 
-      $stem = $start.$RV;
-    } while(false);
+      $stem = $start . $RV;
+    } while(FALSE);
 
     if ($this->Stem_Caching) {
       $this->Stem_Cache[$word] = $stem;
@@ -165,18 +169,4 @@
     return $stem;
   }
 
-  function stem_caching($parm_ref) {
-    $caching_level = @$parm_ref['-level'];
-    if ($caching_level) {
-      if (!$this->m($caching_level, '/^[012]$/')) {
-         die(__CLASS__ . "::stem_caching() - Legal values are '0','1' or '2'. '$caching_level' is not a legal value");
-      }
-      $this->Stem_Caching = $caching_level;
-    }
-    return $this->Stem_Caching;
-  }
-
-  function clear_stem_cache() {
-    $this->Stem_Cache = array();
-  }
 }
diff -urNP rustemmer.orig/search-highlight.patch rustemmer/search-highlight.patch
--- rustemmer.orig/search-highlight.patch	2011-02-25 05:14:04.000000000 +0300
+++ rustemmer/search-highlight.patch	1970-01-01 03:00:00.000000000 +0300
@@ -1,47 +0,0 @@
-Index: modules/search/search.info
-===================================================================
-RCS file: /cvs/drupal/drupal/modules/search/search.info,v
-retrieving revision 1.4
-diff -u -p -r1.4 search.info
---- modules/search/search.info	8 Jun 2007 05:50:55 -0000	1.4
-+++ modules/search/search.info	1 Aug 2010 16:47:00 -0000
-@@ -4,3 +4,4 @@ description = Enables site-wide keyword 
- package = Core - optional
- version = VERSION
- core = 6.x
-+dependencies[] = rustemmer
-Index: modules/search/search.module
-===================================================================
-RCS file: /cvs/drupal/drupal/modules/search/search.module,v
-retrieving revision 1.250.2.10
-diff -u -p -r1.250.2.10 search.module
---- modules/search/search.module	28 May 2010 15:20:35 -0000	1.250.2.10
-+++ modules/search/search.module	1 Aug 2010 16:47:01 -0000
-@@ -1202,6 +1202,7 @@ function search_excerpt($keys, $text) {
-   $ranges = array();
-   $included = array();
-   $length = 0;
-+  $stemmer = new RussianStemmer();
-   while ($length < 256 && count($workkeys)) {
-     foreach ($workkeys as $k => $key) {
-       if (strlen($key) == 0) {
-@@ -1219,7 +1220,9 @@ function search_excerpt($keys, $text) {
-       }
-       // Locate a keyword (position $p), then locate a space in front (position
-       // $q) and behind it (position $s)
--      if (preg_match('/'. $boundary . $key . $boundary .'/iu', $text, $match, PREG_OFFSET_CAPTURE, $included[$key])) {
-+      $key = $stemmer->stem_word($key);
-+      $keys[$k] = $key;
-+      if (preg_match('/'. $boundary . '[' . RUSTEMMER_CHARS . ']*' . $key . '[' . RUSTEMMER_CHARS . ']*' . $boundary .'/iu', $text, $match, PREG_OFFSET_CAPTURE, $included[$key])) {
-         $p = $match[0][1];
-         if (($q = strpos($text, ' ', max(0, $p - 60))) !== FALSE) {
-           $end = substr($text, $p, 80);
-@@ -1277,7 +1280,7 @@ function search_excerpt($keys, $text) {
-   $text = (isset($newranges[0]) ? '' : '... ') . implode(' ... ', $out) .' ...';
- 
-   // Highlight keywords. Must be done at once to prevent conflicts ('strong' and '<strong>').
--  $text = preg_replace('/'. $boundary .'('. implode('|', $keys) .')'. $boundary .'/iu', '<strong>\0</strong>', $text);
-+  $text = preg_replace('/'. $boundary . '[' . RUSTEMMER_CHARS . ']*' .'('. implode('|', $keys) .')'. '[' . RUSTEMMER_CHARS . ']*' . $boundary .'/iu', '<strong>\0</strong>', $text);
-   return $text;
- }
- 
