Merge remote-tracking branch 'origin/upstream' am: 0fe0ed3fe4 am: ec0ba16ba4

Original change: undetermined

Change-Id: I0b0e5d155883b412b56bc68088584797f3cabfee
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..b54d311
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,40 @@
+// This file is generated by cargo_embargo.
+// Do not modify this file after the first "rust_*" or "genrule" module
+// because the changes will be overridden on upgrade.
+// Content before the first "rust_*" or "genrule" module is preserved.
+
+// TODO: Add license
+rust_library {
+    name: "librust_stemmers",
+    host_supported: true,
+    crate_name: "rust_stemmers",
+    cargo_env_compat: true,
+    cargo_pkg_version: "1.2.0",
+    srcs: ["src/lib.rs"],
+    edition: "2015",
+    rustlibs: ["libserde"],
+    proc_macros: ["libserde_derive"],
+    apex_available: [
+        "//apex_available:platform",
+        "//apex_available:anyapex",
+    ],
+    product_available: true,
+    vendor_available: true,
+}
+
+rust_test {
+    name: "rust-stemmers_test_src_lib",
+    host_supported: true,
+    crate_name: "rust_stemmers",
+    cargo_env_compat: true,
+    cargo_pkg_version: "1.2.0",
+    srcs: ["src/lib.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    test_options: {
+        unit_test: true,
+    },
+    edition: "2015",
+    rustlibs: ["libserde"],
+    proc_macros: ["libserde_derive"],
+}
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..6790c08
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,26 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "rust-stemmers"
+version = "1.2.0"
+authors = ["Jakob Demler <[email protected]>", "CurrySoftware <[email protected]>"]
+description = "A rust implementation of some popular snowball stemming algorithms"
+readme = "README.md"
+keywords = ["nlp", "stemming", "information", "retrieval", "language"]
+license = "MIT/BSD-3-Clause"
+repository = "https://github.com/CurrySoftware/rust-stemmers"
+[dependencies.serde]
+version = "^1.0"
+
+[dependencies.serde_derive]
+version = "^1.0"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
new file mode 100644
index 0000000..aff9249
--- /dev/null
+++ b/Cargo.toml.orig
@@ -0,0 +1,13 @@
+[package]
+name = "rust-stemmers"
+version = "1.2.0"
+authors = ["Jakob Demler <[email protected]>", "CurrySoftware <[email protected]>"]
+description = "A rust implementation of some popular snowball stemming algorithms"
+repository = "https://github.com/CurrySoftware/rust-stemmers"
+readme = "README.md"
+keywords = ["nlp", "stemming", "information", "retrieval", "language"]
+license = "MIT/BSD-3-Clause"
+
+[dependencies]
+serde = "^1.0"
+serde_derive = "^1.0"
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..3a15861
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,51 @@
+MIT License
+
+Copyright (c) 2017 Jakob Demler
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-----
+
+Copyright (c) 2001, Dr Martin Porter
+Copyright (c) 2004,2005, Richard Boulton
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+  2. Redistributions in binary form must reproduce the above copyright notice,
+     this list of conditions and the following disclaimer in the documentation
+     and/or other materials provided with the distribution.
+  3. Neither the name of the Snowball project nor the names of its contributors
+     may be used to endorse or promote products derived from this software
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..03723ac
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,20 @@
+name: "rust-stemmers"
+description: "A rust implementation of some popular snowball stemming algorithms"
+third_party {
+  identifier {
+    type: "crates.io"
+    value: "rust-stemmers"
+  }
+  identifier {
+    type: "Archive"
+    value: "https://static.crates.io/crates/rust-stemmers/rust-stemmers-1.2.0.crate"
+    primary_source: true
+  }
+  version: "1.2.0"
+  license_type: NOTICE
+  last_upgrade_date {
+    year: 2024
+    month: 5
+    day: 7
+  }
+}
diff --git a/MODULE_LICENSE_BSD b/MODULE_LICENSE_BSD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_BSD
diff --git a/MODULE_LICENSE_MIT b/MODULE_LICENSE_MIT
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_MIT
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..48bea6e
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 688011
+include platform/prebuilts/rust:main:/OWNERS
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..aeed21b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,43 @@
+# Rust Stemmers
+
+This crate implements some stemmer algorithms found in the [snowball project](http://snowballstem.org/) which are compiled to rust using the rust-backend of the [snowball compiler](https://github.com/snowballstem/snowball).
+
+# Supported Algorithms
+
+-   Arabic
+-   Danish
+-   Dutch
+-   English
+-   French
+-   German
+-   Greek
+-   Hungarian
+-   Italian
+-   Norwegian
+-   Portuguese
+-   Romanian
+-   Russian
+-   Spanish
+-   Swedish
+-   Tamil
+-   Turkish
+
+
+# Usage
+
+```rust
+extern crate rust_stemmers;
+use rust_stemmers::{Algorithm, Stemmer};
+
+// Create a stemmer for the english language
+let en_stemmer = Stemmer::create(Algorithm::English);
+
+// Stemm the word "fruitlessly"
+// Please be aware that all algorithms expect their input to only contain lowercase characters.
+assert_eq!(en_stemmer.stem("fruitlessly"), "fruitless");
+```
+
+# Related Projects
+
+-   The [stemmer](https://github.com/lise-henry/stemmer-rs) crate provides bindings to the C Snowball implementation.
+
diff --git a/algorithms/LICENSE b/algorithms/LICENSE
new file mode 100644
index 0000000..50fd220
--- /dev/null
+++ b/algorithms/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2001, Dr Martin Porter
+Copyright (c) 2004,2005, Richard Boulton
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+  2. Redistributions in binary form must reproduce the above copyright notice,
+     this list of conditions and the following disclaimer in the documentation
+     and/or other materials provided with the distribution.
+  3. Neither the name of the Snowball project nor the names of its contributors
+     may be used to endorse or promote products derived from this software
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/algorithms/README.md b/algorithms/README.md
new file mode 100644
index 0000000..72ca8e4
--- /dev/null
+++ b/algorithms/README.md
@@ -0,0 +1,4 @@
+These algorithms are copies of the algorithms found in the [snowball package](https://github.com/snowballstem/snowball) and are licensed under the [[file:LICENSE][BSD-3 License]].
+To compile them to rust code yourself, please use the rust backend of the snowball compiler.
+
+This library ships with these algorithms already compiled to rust.
diff --git a/algorithms/arabic.sbl b/algorithms/arabic.sbl
new file mode 100644
index 0000000..694721c
--- /dev/null
+++ b/algorithms/arabic.sbl
@@ -0,0 +1,597 @@
+/*
+ * Authors:
+ * - Assem Chelli, < assem [dot] ch [at] gmail >
+ * - Abdelkrim Aries <ab [underscore] aries [at] esi [dot] dz>
+ *
+*/
+
+stringescapes { }
+
+/* the Arabic letters in Unicode */
+// Hamza
+stringdef o     hex '621' // Hamza
+stringdef ao    hex '623' // Hamza above Alef
+stringdef ao_   hex '625' // Hamza below Alef
+stringdef a~    hex '622' // Alef madda
+stringdef wo    hex '624' // Hamza above waw
+stringdef yo    hex '626' // Hamza above yeh
+
+// Letters
+stringdef a     hex '627' // Alef
+stringdef a_    hex '649' // Alef Maksura
+stringdef b     hex '628' // Beh
+stringdef t_    hex '629' // Teh_Marbuta
+stringdef t     hex '62a' // Teh
+stringdef th    hex '62b' // Theh
+stringdef j     hex '62c' // Jeem
+stringdef h     hex '62d' // Hah
+stringdef x     hex '62e' // Khah
+stringdef d     hex '62f' // Dal
+stringdef dz    hex '630' // Thal
+stringdef r     hex '631' // Reh
+stringdef z     hex '632' // Zain
+stringdef s     hex '633' // Seen
+stringdef sh    hex '634' // Sheen
+stringdef c     hex '635' // Sad
+stringdef dh    hex '636' // Dad
+stringdef tt    hex '637' // Tah
+stringdef zh    hex '638' // Zah
+stringdef i     hex '639' // Ain
+stringdef gh    hex '63a' // Ghain
+stringdef f     hex '641' // Feh
+stringdef q     hex '642' // Qaf
+stringdef k     hex '643' // Kaf
+stringdef l     hex '644' // Lam
+stringdef m     hex '645' // Meem
+stringdef n     hex '646' // Noon
+stringdef e     hex '647' // Heh
+stringdef w     hex '648' // Waw
+stringdef y     hex '64a' // Yeh
+
+// Diacritics
+stringdef aan   hex '64b' // FatHatan
+stringdef uun   hex '64c' // Dammatan
+stringdef iin   hex '64d' // Kasratan
+stringdef aa    hex '64e' // FatHa
+stringdef uu    hex '64f' // Damma
+stringdef ii    hex '650' // Kasra
+stringdef oo    hex '652' // Sukun
+stringdef ~     hex '651' // Shadda
+
+// Hindu–Arabic numerals
+stringdef 0     hex '0660'
+stringdef 1     hex '0661'
+stringdef 2     hex '0662'
+stringdef 3     hex '0663'
+stringdef 4     hex '0664'
+stringdef 5     hex '0665'
+stringdef 6     hex '0666'
+stringdef 7     hex '0667'
+stringdef 8     hex '0668'
+stringdef 9     hex '0669'
+stringdef %     hex '066a'  // PERCENT
+stringdef .     hex '066b'  // DECIMAL
+stringdef '     hex '066c'  // THOUSANDS
+
+// Kasheeda
+stringdef _     hex '640' // Kasheeda, Tatweel
+
+// Ponctuation marks
+stringdef ,   hex '060C' // COMMA
+stringdef ;   hex '061B' // SEMICOLON
+stringdef ?   hex '061F' // QUESTION
+
+// Shaped forms
+stringdef o1     hex  'fe80'  // HAMZA
+stringdef ao1    hex  'fe83'  // ALEF_HAMZA_ABOVE
+stringdef ao2    hex  'fe84'  // ALEF_HAMZA_ABOVE
+stringdef ao_1   hex  'fe87'  // ALEF_HAMZA_BELOW
+stringdef ao_2   hex  'fe88'  // ALEF_HAMZA_BELOW
+stringdef yo1    hex  'fe8b'  // YEH_HAMZA
+stringdef yo2    hex  'fe8c'  // YEH_HAMZA
+stringdef yo3    hex  'fe89'  // YEH_HAMZA
+stringdef yo4    hex  'fe8a'  // YEH_HAMZA
+stringdef a~1    hex  'fe81'  // ALEF_MADDA
+stringdef a~2    hex  'fe82'  // ALEF_MADDA
+stringdef wo1    hex  'fe85'  // WAW_HAMZA
+stringdef wo2    hex  'fe86'  // WAW_HAMZA
+stringdef a1     hex  'fe8d'  // ALEF
+stringdef a2     hex  'fe8e'  // ALEF
+stringdef b1     hex  'fe8f'  // BEH
+stringdef b2     hex  'fe90'  // BEH
+stringdef b3     hex  'fe91'  // BEH
+stringdef b4     hex  'fe92'  // BEH
+stringdef t_1    hex  'fe93'  // TEH_MARBUTA
+stringdef t_2    hex  'fe94'  // TEH_MARBUTA
+stringdef t1     hex  'fe97'  // TEH
+stringdef t2     hex  'fe98'  // TEH
+stringdef t3     hex  'fe95'  // TEH
+stringdef t4     hex  'fe96'  // TEH
+stringdef th1    hex  'fe9b'  // THEH
+stringdef th2    hex  'fe9c'  // THEH
+stringdef th3    hex  'fe9a'  // THEH
+stringdef th4    hex  'fe99'  // THEH
+stringdef j1     hex  'fe9f'  // JEEM
+stringdef j2     hex  'fea0'  // JEEM
+stringdef j3     hex  'fe9d'  // JEEM
+stringdef j4     hex  'fe9e'  // JEEM
+stringdef h1     hex  'fea3'  // HAH
+stringdef h2     hex  'fea4'  // HAH
+stringdef h3     hex  'fea1'  // HAH
+stringdef h4     hex  'fea2'  // HAH
+stringdef x1     hex  'fea7'  // KHAH
+stringdef x2     hex  'fea8'  // KHAH
+stringdef x3     hex  'fea5'  // KHAH
+stringdef x4     hex  'fea6'  // KHAH
+stringdef d1     hex  'fea9'  // DAL
+stringdef d2     hex  'feaa'  // DAL
+stringdef dz1    hex  'feab'  // THAL
+stringdef dz2    hex  'feac'  // THAL
+stringdef r1     hex  'fead'  // REH
+stringdef r2     hex  'feae'  // REH
+stringdef z1     hex  'feaf'  // ZAIN
+stringdef z2     hex  'feb0'  // ZAIN
+stringdef s1     hex  'feb3'  // SEEN
+stringdef s2     hex  'feb4'  // SEEN
+stringdef s3     hex  'feb1'  // SEEN
+stringdef s4     hex  'feb2'  // SEEN
+stringdef sh1    hex  'feb7'  // SHEEN
+stringdef sh2    hex  'feb8'  // SHEEN
+stringdef sh3    hex  'feb5'  // SHEEN
+stringdef sh4    hex  'feb6'  // SHEEN
+stringdef c1     hex  'febb'  // SAD
+stringdef c2     hex  'febc'  // SAD
+stringdef c3     hex  'feb9'  // SAD
+stringdef c4     hex  'feba'  // SAD
+stringdef dh1    hex  'febf'  // DAD
+stringdef dh2    hex  'fec0'  // DAD
+stringdef dh3    hex  'febd'  // DAD
+stringdef dh4    hex  'febe'  // DAD
+stringdef tt1    hex  'fec3'  // TAH
+stringdef tt2    hex  'fec4'  // TAH
+stringdef tt3    hex  'fec1'  // TAH
+stringdef tt4    hex  'fec2'  // TAH
+stringdef zh1    hex  'fec7'  // ZAH
+stringdef zh2    hex  'fec8'  // ZAH
+stringdef zh3    hex  'fec5'  // ZAH
+stringdef zh4    hex  'fec6'  // ZAH
+stringdef i1     hex  'fecb'  // AIN
+stringdef i2     hex  'fecc'  // AIN
+stringdef i3     hex  'fec9'  // AIN
+stringdef i4     hex  'feca'  // AIN
+stringdef gh1    hex  'fecf'  // GHAIN
+stringdef gh2    hex  'fed0'  // GHAIN
+stringdef gh3    hex  'fecd'  // GHAIN
+stringdef gh4    hex  'fece'  // GHAIN
+stringdef f1     hex  'fed3'  // FEH
+stringdef f2     hex  'fed4'  // FEH
+stringdef f3     hex  'fed1'  // FEH
+stringdef f4     hex  'fed2'  // FEH
+stringdef q1     hex  'fed7'  // QAF
+stringdef q2     hex  'fed8'  // QAF
+stringdef q3     hex  'fed5'  // QAF
+stringdef q4     hex  'fed6'  // QAF
+stringdef k1     hex  'fedb'  // KAF
+stringdef k2     hex  'fedc'  // KAF
+stringdef k3     hex  'fed9'  // KAF
+stringdef k4     hex  'feda'  // KAF
+stringdef l1     hex  'fedf'  // LAM
+stringdef l2     hex  'fee0'  // LAM
+stringdef l3     hex  'fedd'  // LAM
+stringdef l4     hex  'fede'  // LAM
+stringdef m1     hex  'fee3'  // MEEM
+stringdef m2     hex  'fee4'  // MEEM
+stringdef m3     hex  'fee1'  // MEEM
+stringdef m4     hex  'fee2'  // MEEM
+stringdef n1     hex  'fee7'  // NOON
+stringdef n2     hex  'fee8'  // NOON
+stringdef n3     hex  'fee5'  // NOON
+stringdef n4     hex  'fee6'  // NOON
+stringdef e1     hex  'feeb'  // HEH
+stringdef e2     hex  'feec'  // HEH
+stringdef e3     hex  'fee9'  // HEH
+stringdef e4     hex  'feea'  // HEH
+stringdef w1     hex  'feed'  // WAW
+stringdef w2     hex  'feee'  // WAW
+stringdef a_1    hex  'feef'  // ALEF_MAKSURA
+stringdef a_2    hex  'fef0'  // ALEF_MAKSURA
+stringdef y1     hex  'fef3'  // YEH
+stringdef y2     hex  'fef4'  // YEH
+stringdef y3     hex  'fef1'  // YEH
+stringdef y4     hex  'fef2'  // YEH
+
+// Ligatures Lam-Alef
+stringdef la      hex  'fefb' // LAM_ALEF
+stringdef la2     hex  'fefc' // LAM_ALEF
+stringdef lao     hex  'fef7' // LAM_ALEF_HAMZA_ABOVE
+stringdef lao2    hex  'fef8' // LAM_ALEF_HAMZA_ABOVE
+stringdef lao_    hex  'fef9' // LAM_ALEF_HAMZA_BELOW
+stringdef lao_2   hex  'fefa' // LAM_ALEF_HAMZA_BELOW
+stringdef la~     hex  'fef5' // LAM_ALEF_MADDA_ABOVE
+stringdef la~2    hex  'fef6' // LAM_ALEF_MADDA_ABOVE
+
+
+
+integers (
+            word_len
+         )
+
+booleans (
+            is_noun
+            is_verb
+            is_defined
+         )
+
+routines (
+    Prefix_Step1
+    Prefix_Step2
+    Prefix_Step3a_Noun
+    Prefix_Step3b_Noun
+    Prefix_Step3_Verb
+    Prefix_Step4_Verb
+
+    Suffix_All_alef_maqsura
+    Suffix_Noun_Step1a
+    Suffix_Noun_Step1b
+    Suffix_Noun_Step2a
+    Suffix_Noun_Step2b
+    Suffix_Noun_Step2c1
+    Suffix_Noun_Step2c2
+    Suffix_Noun_Step3
+    Suffix_Verb_Step1
+    Suffix_Verb_Step2a
+    Suffix_Verb_Step2b
+    Suffix_Verb_Step2c
+
+    Normalize_post
+    Normalize_pre
+
+    Checks1
+)
+
+externals ( stem )
+
+groupings (  )
+
+
+// Normalizations
+define Normalize_pre as (
+    loop len (
+        (
+            [substring] among (
+                '{aan}' '{uun}' '{iin}' '{aa}' '{uu}' '{ii}' '{oo}' '{~}'( delete ) // strip vocalization
+                '{_}' ( delete ) // strip kasheeda
+
+                // Ponctuation marks
+                '.' ',' ';' ':'  '?' '!' '/' '*' '%' '\' '"' ( delete) // General
+                '{,}' '{;}' '{?}'  ( delete ) // Arabic-specific
+
+                // Hindu–Arabic numerals
+                '{0}' ( <- '0')
+                '{1}' ( <- '1')
+                '{2}' ( <- '2')
+                '{3}' ( <- '3')
+                '{4}' ( <- '4')
+                '{5}' ( <- '5')
+                '{6}' ( <- '6')
+                '{7}' ( <- '7')
+                '{8}' ( <- '8')
+                '{9}' ( <- '9')
+                '{%}' '{.}' '{'}' ( delete )
+
+                // Shaped forms
+                '{o1}' ( <- '{o}' ) // HAMZA
+                '{ao1}' '{ao2}'  ( <- '{ao}' ) // ALEF_HAMZA_ABOVE
+                '{ao_1}' '{ao_2}' ( <- '{ao_}' ) // ALEF_HAMZA_BELOW
+                '{yo1}'  '{yo2}' '{yo3}'  '{yo4}'  ( <- '{yo}' ) // YEH_HAMZA
+                '{a~1}'  '{a~2}'( <- '{a~}' ) // ALEF_MADDA
+                '{wo1}' '{wo2}'( <- '{wo}' ) // WAW_HAMZA
+                '{a1}' '{a2}' ( <- '{a}' ) // ALEF
+                '{b1}' '{b2}' '{b3}'  '{b4}'  ( <- '{b}' ) // BEH
+                '{t_1}'  '{t_2}' ( <- '{t_}' ) // TEH_MARBUTA
+                '{t1}'   '{t2}' '{t3}' '{t4}'  ( <- '{t}' ) // TEH
+                '{th1}' '{th2}' '{th3}' '{th4}' ( <- '{th}' ) // THEH
+                '{j1}' '{j2}'  '{j3}' '{j4}'(  <- '{j}' ) // JEEM
+                '{h1}' '{h2}' '{h3}' '{h4}' ( <- '{h}' ) // HAH
+                '{x1}' '{x2}' '{x3}' '{x4}'( <- '{x}' ) // KHAH
+                '{d1}'  '{d2}'  ( <- '{d}' ) // DAL
+                '{dz1}''{dz2}' ( <- '{dz}' ) // THAL
+                '{r1}' '{r2}'( <- '{r}' ) // REH
+                '{z1}' '{z2}'  ( <- '{z}' ) // ZAIN
+                '{s1}'  '{s2}'   '{s3}' '{s4}'( <- '{s}' ) // SEEN
+                '{sh1}' '{sh2}' '{sh3}' '{sh4}' ( <- '{sh}' ) // SHEEN
+                '{c1}' '{c2}' '{c3}' '{c4}'( <- '{c}' ) // SAD
+                '{dh1}'    '{dh2}'   '{dh3}'  '{dh4}'( <- '{dh}' ) // DAD
+                '{tt1}'  '{tt2}'  '{tt3}'  '{tt4}' ( <- '{tt}' ) // TAH
+                '{zh1}' '{zh2}' '{zh3}'    '{zh4}'( <- '{zh}' ) // ZAH
+                '{i1}' '{i2}' '{i3}'  '{i4}'( <- '{i}' ) // AIN
+                '{gh1}' '{gh2}' '{gh3}'  '{gh4}'( <- '{gh}' ) // GHAIN
+                '{f1}'  '{f2}' '{f3}'  '{f4}' ( <- '{f}' ) // FEH
+                '{q1}' '{q2}' '{q3}' '{q4}' ( <- '{q}' ) // QAF
+                '{k1}' '{k2}' '{k3}'  '{k4}'( <- '{k}' ) // KAF
+                '{l1}' '{l2}' '{l3}' '{l4}'( <- '{l}' ) // LAM
+                '{m1}' '{m2}'  '{m3}' '{m4}'   ( <- '{m}' ) // MEEM
+                '{n1}'  '{n2}' '{n3}'  '{n4}'( <- '{n}' ) // NOON
+                '{e1}' '{e2}' '{e3}' '{e4}' ( <- '{e}' ) // HEH
+                '{w1}'  '{w2}'  ( <- '{w}' ) // WAW
+                '{a_1}' '{a_2}' ( <- '{a_}' ) // ALEF_MAKSURA
+                '{y1}' '{y2}' '{y3}' '{y4}' ( <- '{y}' ) // YEH
+
+                // Ligatures Lam-Alef
+                '{la}'  '{la2}'     (<- '{l}{a}')
+                '{lao}'  '{lao2}'   (<- '{l}{ao}')
+                '{lao_}'  '{lao_2}' (<- '{l}{ao_}')
+                '{la~}'  '{la~2}'    (<- '{l}{a~}')
+
+            )
+        )
+        or
+        next
+    )
+)
+
+define Normalize_post as (
+
+    do (
+        // normalize last hamza
+        backwards (
+        [substring] among (
+            '{ao}''{ao_}' '{a~}' ( <- '{o}')
+        '{wo}' ( <- '{o}')
+        '{yo}' ( <- '{o}')
+        )
+        )
+    )
+
+    do loop word_len (
+        (
+        // normalize other hamza's
+            [substring] among (
+                '{ao}''{ao_}' '{a~}' ( <- '{a}')
+                '{wo}' ( <- '{w}')
+                '{yo}' ( <- '{y}')
+            )
+        )
+        or
+        next
+    )
+)
+
+// Checks
+define Checks1 as (
+    $word_len = len
+    [substring] among (
+        '{b}{a}{l}' '{k}{a}{l}' ($word_len > 4  set is_noun  unset is_verb set is_defined)
+        '{l}{l}' '{a}{l}' ($word_len > 3  set is_noun unset is_verb set is_defined)
+    )
+)
+
+
+//prefixes
+define Prefix_Step1 as (
+        $word_len = len
+         [substring] among (
+             '{ao}{ao}' ($word_len > 3 <-  '{ao}'  )
+             '{ao}{a~}' ($word_len > 3 <-  '{a~}'  )
+             '{ao}{wo}' ($word_len > 3 <-  '{ao}'  )
+             '{ao}{a}' ($word_len > 3 <-  '{a}'  )
+             '{ao}{ao_}' ($word_len > 3 <-  '{ao_}'  )
+            // '{ao}' ($word_len > 3 delete) //rare case
+        )
+)
+
+define Prefix_Step2 as (
+        $word_len = len
+        not '{f}{a}'
+        not '{w}{a}'
+        [substring] among (
+            '{f}' ($word_len > 3 delete)
+            '{w}' ($word_len > 3 delete)
+        )
+)
+
+define Prefix_Step3a_Noun as ( // it is noun and defined
+        $word_len = len
+        [substring] among (
+            '{b}{a}{l}' '{k}{a}{l}' ($word_len > 5 delete)
+            '{l}{l}' '{a}{l}' ($word_len > 4 delete)
+        )
+)
+
+define Prefix_Step3b_Noun as ( // probably  noun and defined
+        $word_len = len
+        not '{b}{a}' // exception
+        [substring] among (
+            '{b}' ($word_len > 3 delete)
+            // '{k}'  '{l}' ($word_len > 3 delete) // BUG: cause confusion
+            '{b}{b}' ($word_len > 3 <-  '{b}'  )
+            '{k}{k}'  ($word_len > 3 <-  '{k}'  )
+           )
+
+)
+
+define Prefix_Step3_Verb as (
+        $word_len = len
+        [substring] among (
+            //'{s}' ($word_len > 4 delete)// BUG: cause confusion
+            '{s}{y}' ($word_len > 4 <- '{y}' )
+            '{s}{t}' ($word_len > 4 <- '{t}')
+            '{s}{n}' ($word_len > 4 <- '{n}')
+            '{s}{ao}' ($word_len > 4 <- '{ao}')
+        )
+)
+
+define Prefix_Step4_Verb as (
+        $word_len = len
+        [substring] among (
+            '{y}{s}{t}' '{n}{s}{t}' '{t}{s}{t}' ($word_len > 4 set is_verb unset is_noun <-  '{a}{s}{t}' )
+        )
+)
+
+// suffixes
+backwardmode (
+
+        define Suffix_Noun_Step1a as (
+                $word_len = len
+                [substring] among (
+                        '{y}' '{k}' '{e}' ($word_len >= 4 delete)
+                        '{n}{a}' '{k}{m}' '{e}{a}' '{e}{n}' '{e}{m}' ($word_len >= 5  delete)
+                        '{k}{m}{a}' '{e}{m}{a}' ($word_len >= 6 delete)
+                )
+            )
+        define Suffix_Noun_Step1b as (
+            $word_len = len
+            [substring] among (
+                '{n}' ($word_len > 5 delete)
+            )
+        )
+
+        define Suffix_Noun_Step2a as (
+                $word_len = len
+                [substring] among (
+                        '{a}' '{y}' '{w}' ($word_len > 4 delete)
+                )
+            )
+
+        define Suffix_Noun_Step2b as (
+            $word_len = len
+            [substring] among (
+                '{a}{t}' ($word_len >= 5 delete)
+            )
+        )
+
+        define Suffix_Noun_Step2c1 as (
+            $word_len = len
+            [substring] among (
+                '{t}' ($word_len >= 4 delete)
+            )
+        )
+        define Suffix_Noun_Step2c2 as ( // feminine t_
+            $word_len = len
+            [substring] among (
+                '{t_}' ($word_len >= 4 delete)
+            )
+        )
+        define Suffix_Noun_Step3 as ( // ya' nisbiya
+            $word_len = len
+            [substring] among (
+                '{y}' ($word_len >= 3 delete)
+            )
+        )
+
+        define Suffix_Verb_Step1 as (
+                $word_len = len
+                [substring] among (
+                        '{e}' '{k}' ($word_len >= 4 delete)
+                        '{n}{y}' '{n}{a}' '{e}{a}' '{e}{m}' '{e}{n}' '{k}{m}' '{k}{n}' ($word_len >= 5 delete)
+                        '{e}{m}{a}' '{k}{m}{a}' '{k}{m}{w}'($word_len >= 6 delete)
+                )
+            )
+        define Suffix_Verb_Step2a as (
+                $word_len = len
+                [substring] among (
+                       '{t}' ($word_len >= 4  delete)
+                        '{a}' '{n}' '{y}' ($word_len >= 4 delete)
+                        '{n}{a}' '{t}{a}'  '{t}{n}'  ($word_len >= 5 delete)// past
+                        '{a}{n}' '{w}{n}' '{y}{n}' ($word_len > 5 delete) // present
+                        '{t}{m}{a}' ($word_len >= 6 delete)
+                )
+            )
+
+        define Suffix_Verb_Step2b as (
+            $word_len = len
+            [substring] among (
+                '{w}{a}' '{t}{m}' ($word_len >= 5 delete) // len >= 5
+            )
+        )
+
+
+        define Suffix_Verb_Step2c as (
+            $word_len = len
+            [substring] among (
+                '{w}' ($word_len >= 4 delete)
+                '{t}{m}{w}' ($word_len >= 6 delete)
+            )
+        )
+
+        define Suffix_All_alef_maqsura as (
+            $word_len = len
+            [substring] among (
+                '{a_}' ( <- '{y}' ) // spell error
+                // '{a_}' ( delete ) // if noun > 3
+                // '{a_}' ( <- '{a}') // if verb
+            )
+        )
+)
+
+define stem as (
+    // set initial values
+    set is_noun
+    set is_verb
+    unset is_defined
+
+    // guess type and properties
+    do Checks1
+
+    // normalization pre-stemming
+    do Normalize_pre
+
+
+    backwards (
+
+       do (
+              //Suffixes for verbs
+            (
+           is_verb
+           (
+               (
+                  (atleast 1 Suffix_Verb_Step1)
+                  ( Suffix_Verb_Step2a or Suffix_Verb_Step2c  or next)
+                )
+                or Suffix_Verb_Step2b
+                or Suffix_Verb_Step2a
+            )
+           )
+            //Suffixes for nouns
+          or (
+               is_noun
+                (
+
+                 try (
+                     Suffix_Noun_Step2c2
+                     or (not is_defined Suffix_Noun_Step1a (
+                            Suffix_Noun_Step2a
+                            or Suffix_Noun_Step2b
+                            or Suffix_Noun_Step2c1
+                            or next))
+                     or (Suffix_Noun_Step1b (
+                            Suffix_Noun_Step2a
+                            or Suffix_Noun_Step2b
+                            or Suffix_Noun_Step2c1))
+                     or (not is_defined Suffix_Noun_Step2a)
+                     or (Suffix_Noun_Step2b)
+                 )
+                 Suffix_Noun_Step3
+                 )
+
+            )
+
+            // Suffixes for alef maqsura
+            or  Suffix_All_alef_maqsura
+        )
+    )
+
+    //Prefixes
+    do (
+       try Prefix_Step1
+       try Prefix_Step2
+       ( Prefix_Step3a_Noun
+         or (is_noun Prefix_Step3b_Noun)
+         or (is_verb try Prefix_Step3_Verb Prefix_Step4_Verb)
+         )
+    )
+
+    // normalization post-stemming
+    do Normalize_post
+
+)
diff --git a/algorithms/danish.sbl b/algorithms/danish.sbl
new file mode 100644
index 0000000..0a8190a
--- /dev/null
+++ b/algorithms/danish.sbl
@@ -0,0 +1,91 @@
+routines (
+           mark_regions
+           main_suffix
+           consonant_pair
+           other_suffix
+           undouble
+)
+
+externals ( stem )
+
+strings ( ch )
+
+integers ( p1 x )
+
+groupings ( v s_ending )
+
+stringescapes {}
+
+/* special characters (in ISO Latin I) */
+
+stringdef ae   hex 'E6'
+stringdef ao   hex 'E5'
+stringdef o/   hex 'F8'
+
+define v 'aeiouy{ae}{ao}{o/}'
+
+define s_ending  'abcdfghjklmnoprtvyz{ao}'
+
+define mark_regions as (
+
+    $p1 = limit
+
+    test ( hop 3 setmark x )
+    goto v gopast non-v  setmark p1
+    try ( $p1 < x  $p1 = x )
+)
+
+backwardmode (
+
+    define main_suffix as (
+        setlimit tomark p1 for ([substring])
+        among(
+
+            'hed' 'ethed' 'ered' 'e' 'erede' 'ende' 'erende' 'ene' 'erne' 'ere'
+            'en' 'heden' 'eren' 'er' 'heder' 'erer' 'heds' 'es' 'endes'
+            'erendes' 'enes' 'ernes' 'eres' 'ens' 'hedens' 'erens' 'ers' 'ets'
+            'erets' 'et' 'eret'
+                (delete)
+            's'
+                (s_ending delete)
+        )
+    )
+
+    define consonant_pair as (
+        test (
+            setlimit tomark p1 for ([substring])
+            among(
+                'gd' // significant in the call from other_suffix
+                'dt' 'gt' 'kt'
+            )
+        )
+        next] delete
+    )
+
+    define other_suffix as (
+        do ( ['st'] 'ig' delete )
+        setlimit tomark p1 for ([substring])
+        among(
+            'ig' 'lig' 'elig' 'els'
+                (delete do consonant_pair)
+            'l{o/}st'
+                (<-'l{o/}s')
+        )
+    )
+    define undouble as (
+        setlimit tomark p1 for ([non-v] ->ch)
+        ch
+        delete
+    )
+)
+
+define stem as (
+
+    do mark_regions
+    backwards (
+        do main_suffix
+        do consonant_pair
+        do other_suffix
+        do undouble
+    )
+)
diff --git a/algorithms/dutch.sbl b/algorithms/dutch.sbl
new file mode 100644
index 0000000..f7609f7
--- /dev/null
+++ b/algorithms/dutch.sbl
@@ -0,0 +1,164 @@
+routines (
+           prelude postlude
+           e_ending
+           en_ending
+           mark_regions
+           R1 R2
+           undouble
+           standard_suffix
+)
+
+externals ( stem )
+
+booleans ( e_found )
+
+integers ( p1 p2 )
+
+groupings ( v v_I v_j )
+
+stringescapes {}
+
+/* special characters (in ISO Latin I) */
+
+stringdef a"   hex 'E4'
+stringdef e"   hex 'EB'
+stringdef i"   hex 'EF'
+stringdef o"   hex 'F6'
+stringdef u"   hex 'FC'
+
+stringdef a'   hex 'E1'
+stringdef e'   hex 'E9'
+stringdef i'   hex 'ED'
+stringdef o'   hex 'F3'
+stringdef u'   hex 'FA'
+
+stringdef e`   hex 'E8'
+
+define v       'aeiouy{e`}'
+define v_I     v + 'I'
+define v_j     v + 'j'
+
+define prelude as (
+    test repeat (
+        [substring] among(
+            '{a"}' '{a'}'
+                (<- 'a')
+            '{e"}' '{e'}'
+                (<- 'e')
+            '{i"}' '{i'}'
+                (<- 'i')
+            '{o"}' '{o'}'
+                (<- 'o')
+            '{u"}' '{u'}'
+                (<- 'u')
+            ''  (next)
+        ) //or next
+    )
+    try(['y'] <- 'Y')
+    repeat goto (
+        v [('i'] v <- 'I') or
+           ('y']   <- 'Y')
+    )
+)
+
+define mark_regions as (
+
+    $p1 = limit
+    $p2 = limit
+
+    gopast v  gopast non-v  setmark p1
+    try($p1 < 3  $p1 = 3)  // at least 3
+    gopast v  gopast non-v  setmark p2
+
+)
+
+define postlude as repeat (
+
+    [substring] among(
+        'Y'  (<- 'y')
+        'I'  (<- 'i')
+        ''   (next)
+    ) //or next
+
+)
+
+backwardmode (
+
+    define R1 as $p1 <= cursor
+    define R2 as $p2 <= cursor
+
+    define undouble as (
+        test among('kk' 'dd' 'tt') [next] delete
+    )
+
+    define e_ending as (
+        unset e_found
+        ['e'] R1 test non-v delete
+        set e_found
+        undouble
+    )
+
+    define en_ending as (
+        R1 non-v and not 'gem' delete
+        undouble
+    )
+
+    define standard_suffix as (
+        do (
+            [substring] among(
+                'heden'
+                (   R1 <- 'heid'
+                )
+                'en' 'ene'
+                (   en_ending
+                )
+                's' 'se'
+                (   R1 non-v_j delete
+                )
+            )
+        )
+        do e_ending
+
+        do ( ['heid'] R2 not 'c' delete
+             ['en'] en_ending
+           )
+
+        do (
+            [substring] among(
+                'end' 'ing'
+                (   R2 delete
+                    (['ig'] R2 not 'e' delete) or undouble
+                )
+                'ig'
+                (   R2 not 'e' delete
+                )
+                'lijk'
+                (   R2 delete e_ending
+                )
+                'baar'
+                (   R2 delete
+                )
+                'bar'
+                (   R2 e_found delete
+                )
+            )
+        )
+        do (
+            non-v_I
+            test (
+                among ('aa' 'ee' 'oo' 'uu')
+                non-v
+            )
+            [next] delete
+        )
+    )
+)
+
+define stem as (
+
+        do prelude
+        do mark_regions
+        backwards
+            do standard_suffix
+        do postlude
+)
diff --git a/algorithms/english.sbl b/algorithms/english.sbl
new file mode 100644
index 0000000..fe18d7a
--- /dev/null
+++ b/algorithms/english.sbl
@@ -0,0 +1,229 @@
+integers ( p1 p2 )
+booleans ( Y_found )
+
+routines (
+    prelude postlude
+    mark_regions
+    shortv
+    R1 R2
+    Step_1a Step_1b Step_1c Step_2 Step_3 Step_4 Step_5
+    exception1
+    exception2
+)
+
+externals ( stem )
+
+groupings ( v v_WXY valid_LI )
+
+stringescapes {}
+
+define v        'aeiouy'
+define v_WXY    v + 'wxY'
+
+define valid_LI 'cdeghkmnrt'
+
+define prelude as (
+    unset Y_found
+    do ( ['{'}'] delete)
+    do ( ['y'] <-'Y' set Y_found)
+    do repeat(goto (v ['y']) <-'Y' set Y_found)
+)
+
+define mark_regions as (
+    $p1 = limit
+    $p2 = limit
+    do(
+        among (
+            'gener'
+            'commun'  //  added May 2005
+            'arsen'   //  added Nov 2006 (arsenic/arsenal)
+            // ... extensions possible here ...
+        ) or (gopast v  gopast non-v)
+        setmark p1
+        gopast v  gopast non-v  setmark p2
+    )
+)
+
+backwardmode (
+
+    define shortv as (
+        ( non-v_WXY v non-v )
+        or
+        ( non-v v atlimit )
+    )
+
+    define R1 as $p1 <= cursor
+    define R2 as $p2 <= cursor
+
+    define Step_1a as (
+        try (
+            [substring] among (
+                '{'}' '{'}s' '{'}s{'}'
+                       (delete)
+            )
+        )
+        [substring] among (
+            'sses' (<-'ss')
+            'ied' 'ies'
+                   ((hop 2 <-'i') or <-'ie')
+            's'    (next gopast v delete)
+            'us' 'ss'
+        )
+    )
+
+    define Step_1b as (
+        [substring] among (
+            'eed' 'eedly'
+                (R1 <-'ee')
+            'ed' 'edly' 'ing' 'ingly'
+                (
+                test gopast v  delete
+                test substring among(
+                    'at' 'bl' 'iz'
+                         (<+ 'e')
+                    'bb' 'dd' 'ff' 'gg' 'mm' 'nn' 'pp' 'rr' 'tt'
+                    // ignoring double c, h, j, k, q, v, w, and x
+                         ([next]  delete)
+                    ''   (atmark p1  test shortv  <+ 'e')
+                )
+            )
+        )
+    )
+
+    define Step_1c as (
+        ['y' or 'Y']
+        non-v not atlimit
+        <-'i'
+    )
+
+    define Step_2 as (
+        [substring] R1 among (
+            'tional'  (<-'tion')
+            'enci'    (<-'ence')
+            'anci'    (<-'ance')
+            'abli'    (<-'able')
+            'entli'   (<-'ent')
+            'izer' 'ization'
+                      (<-'ize')
+            'ational' 'ation' 'ator'
+                      (<-'ate')
+            'alism' 'aliti' 'alli'
+                      (<-'al')
+            'fulness' (<-'ful')
+            'ousli' 'ousness'
+                      (<-'ous')
+            'iveness' 'iviti'
+                      (<-'ive')
+            'biliti' 'bli'
+                      (<-'ble')
+            'ogi'     ('l' <-'og')
+            'fulli'   (<-'ful')
+            'lessli'  (<-'less')
+            'li'      (valid_LI delete)
+        )
+    )
+
+    define Step_3 as (
+        [substring] R1 among (
+            'tional'  (<- 'tion')
+            'ational' (<- 'ate')
+            'alize'   (<-'al')
+            'icate' 'iciti' 'ical'
+                      (<-'ic')
+            'ful' 'ness'
+                      (delete)
+            'ative'
+                      (R2 delete)  // 'R2' added Dec 2001
+        )
+    )
+
+    define Step_4 as (
+        [substring] R2 among (
+            'al' 'ance' 'ence' 'er' 'ic' 'able' 'ible' 'ant' 'ement'
+            'ment' 'ent' 'ism' 'ate' 'iti' 'ous' 'ive' 'ize'
+                      (delete)
+            'ion'     ('s' or 't' delete)
+        )
+    )
+
+    define Step_5 as (
+        [substring] among (
+            'e' (R2 or (R1 not shortv) delete)
+            'l' (R2 'l' delete)
+        )
+    )
+
+    define exception2 as (
+
+        [substring] atlimit among(
+            'inning' 'outing' 'canning' 'herring' 'earring'
+            'proceed' 'exceed' 'succeed'
+
+            // ... extensions possible here ...
+
+        )
+    )
+)
+
+define exception1 as (
+
+    [substring] atlimit among(
+
+        /* special changes: */
+
+        'skis'      (<-'ski')
+        'skies'     (<-'sky')
+        'dying'     (<-'die')
+        'lying'     (<-'lie')
+        'tying'     (<-'tie')
+
+        /* special -LY cases */
+
+        'idly'      (<-'idl')
+        'gently'    (<-'gentl')
+        'ugly'      (<-'ugli')
+        'early'     (<-'earli')
+        'only'      (<-'onli')
+        'singly'    (<-'singl')
+
+        // ... extensions possible here ...
+
+        /* invariant forms: */
+
+        'sky'
+        'news'
+        'howe'
+
+        'atlas' 'cosmos' 'bias' 'andes' // not plural forms
+
+        // ... extensions possible here ...
+    )
+)
+
+define postlude as (Y_found  repeat(goto (['Y']) <-'y'))
+
+define stem as (
+
+    exception1 or
+    not hop 3 or (
+        do prelude
+        do mark_regions
+        backwards (
+
+            do Step_1a
+
+            exception2 or (
+
+                do Step_1b
+                do Step_1c
+
+                do Step_2
+                do Step_3
+                do Step_4
+
+                do Step_5
+            )
+        )
+        do postlude
+    )
+)
diff --git a/algorithms/finnish.sbl b/algorithms/finnish.sbl
new file mode 100644
index 0000000..1cff66b
--- /dev/null
+++ b/algorithms/finnish.sbl
@@ -0,0 +1,194 @@
+/* Finnish stemmer.
+
+   Numbers in square brackets refer to the sections in
+   Fred Karlsson, Finnish: An Essential Grammar. Routledge, 1999
+   ISBN 0-415-20705-3
+
+*/
+
+routines (
+           mark_regions
+           R2
+           particle_etc possessive
+           LONG VI
+           case_ending
+           i_plural
+           t_plural
+           other_endings
+           tidy
+)
+
+externals ( stem )
+
+integers ( p1 p2 )
+strings ( x )
+booleans ( ending_removed )
+groupings ( AEI V1 V2 particle_end )
+
+stringescapes {}
+
+/* special characters (in ISO Latin I) */
+
+stringdef a"   hex 'E4'
+stringdef o"   hex 'F6'
+
+define AEI 'a{a"}ei'
+define V1 'aeiouy{a"}{o"}'
+define V2 'aeiou{a"}{o"}'
+define particle_end V1 + 'nt'
+
+define mark_regions as (
+
+    $p1 = limit
+    $p2 = limit
+
+    goto V1  gopast non-V1  setmark p1
+    goto V1  gopast non-V1  setmark p2
+)
+
+backwardmode (
+
+    define R2 as $p2 <= cursor
+
+    define particle_etc as (
+        setlimit tomark p1 for ([substring])
+        among(
+            'kin'
+            'kaan' 'k{a"}{a"}n'
+            'ko'   'k{o"}'
+            'han'  'h{a"}n'
+            'pa'   'p{a"}'    // Particles [91]
+                (particle_end)
+            'sti'             // Adverb [87]
+                (R2)
+        )
+        delete
+    )
+    define possessive as (    // [36]
+        setlimit tomark p1 for ([substring])
+        among(
+            'si'
+                (not 'k' delete)  // take 'ksi' as the Comitative case
+            'ni'
+                (delete ['kse'] <- 'ksi') // kseni = ksi + ni
+            'nsa' 'ns{a"}'
+            'mme'
+            'nne'
+                (delete)
+            /* Now for Vn possessives after case endings: [36] */
+            'an'
+                (among('ta' 'ssa' 'sta' 'lla' 'lta' 'na') delete)
+            '{a"}n'
+                (among('t{a"}' 'ss{a"}' 'st{a"}'
+                       'll{a"}' 'lt{a"}' 'n{a"}') delete)
+            'en'
+                (among('lle' 'ine') delete)
+        )
+    )
+
+    define LONG as
+        among('aa' 'ee' 'ii' 'oo' 'uu' '{a"}{a"}' '{o"}{o"}')
+
+    define VI as ('i' V2)
+
+    define case_ending as (
+        setlimit tomark p1 for ([substring])
+        among(
+            'han'    ('a')          //-.
+            'hen'    ('e')          // |
+            'hin'    ('i')          // |
+            'hon'    ('o')          // |
+            'h{a"}n' ('{a"}')       // Illative   [43]
+            'h{o"}n' ('{o"}')       // |
+            'siin'   VI             // |
+            'seen'   LONG           //-'
+
+            'den'    VI
+            'tten'   VI             // Genitive plurals [34]
+                     ()
+            'n'                     // Genitive or Illative
+                ( try ( LONG // Illative
+                        or 'ie' // Genitive
+                          and next ]
+                      )
+                  /* otherwise Genitive */
+                )
+
+            'a' '{a"}'              //-.
+                     (V1 non-V1)    // |
+            'tta' 'tt{a"}'          // Partitive  [32]
+                     ('e')          // |
+            'ta' 't{a"}'            //-'
+
+            'ssa' 'ss{a"}'          // Inessive   [41]
+            'sta' 'st{a"}'          // Elative    [42]
+
+            'lla' 'll{a"}'          // Adessive   [44]
+            'lta' 'lt{a"}'          // Ablative   [51]
+            'lle'                   // Allative   [46]
+            'na' 'n{a"}'            // Essive     [49]
+            'ksi'                   // Translative[50]
+            'ine'                   // Comitative [51]
+
+            /* Abessive and Instructive are too rare for
+               inclusion [51] */
+
+        )
+        delete
+        set ending_removed
+    )
+    define other_endings as (
+        setlimit tomark p2 for ([substring])
+        among(
+            'mpi' 'mpa' 'mp{a"}'
+            'mmi' 'mma' 'mm{a"}'    // Comparative forms [85]
+                (not 'po')          //-improves things
+            'impi' 'impa' 'imp{a"}'
+            'immi' 'imma' 'imm{a"}' // Superlative forms [86]
+            'eja' 'ej{a"}'          // indicates agent [93.1B]
+        )
+        delete
+    )
+    define i_plural as (            // [26]
+        setlimit tomark p1 for ([substring])
+        among(
+            'i'  'j'
+        )
+        delete
+    )
+    define t_plural as (            // [26]
+        setlimit tomark p1 for (
+            ['t'] test V1
+            delete
+        )
+        setlimit tomark p2 for ([substring])
+        among(
+            'mma' (not 'po') //-mmat endings
+            'imma'           //-immat endings
+        )
+        delete
+    )
+    define tidy as (
+        setlimit tomark p1 for (
+            do ( LONG and ([next] delete ) ) // undouble vowel
+            do ( [AEI] non-V1 delete ) // remove trailing a, a", e, i
+            do ( ['j'] 'o' or 'u' delete )
+            do ( ['o'] 'j' delete )
+        )
+        goto non-V1 [next] -> x  x delete // undouble consonant
+    )
+)
+
+define stem as (
+
+    do mark_regions
+    unset ending_removed
+    backwards (
+        do particle_etc
+        do possessive
+        do case_ending
+        do other_endings
+        (ending_removed do i_plural) or do t_plural
+        do tidy
+    )
+)
\ No newline at end of file
diff --git a/algorithms/french.sbl b/algorithms/french.sbl
new file mode 100644
index 0000000..c225ace
--- /dev/null
+++ b/algorithms/french.sbl
@@ -0,0 +1,247 @@
+routines (
+           prelude postlude mark_regions
+           RV R1 R2
+           standard_suffix
+           i_verb_suffix
+           verb_suffix
+           residual_suffix
+           un_double
+           un_accent
+)
+
+externals ( stem )
+
+integers ( pV p1 p2 )
+
+groupings ( v keep_with_s )
+
+stringescapes {}
+
+/* special characters (in ISO Latin I) */
+
+stringdef a^   hex 'E2'  // a-circumflex
+stringdef a`   hex 'E0'  // a-grave
+stringdef c,   hex 'E7'  // c-cedilla
+
+stringdef e"   hex 'EB'  // e-diaeresis (rare)
+stringdef e'   hex 'E9'  // e-acute
+stringdef e^   hex 'EA'  // e-circumflex
+stringdef e`   hex 'E8'  // e-grave
+stringdef i"   hex 'EF'  // i-diaeresis
+stringdef i^   hex 'EE'  // i-circumflex
+stringdef o^   hex 'F4'  // o-circumflex
+stringdef u^   hex 'FB'  // u-circumflex
+stringdef u`   hex 'F9'  // u-grave
+
+define v 'aeiouy{a^}{a`}{e"}{e'}{e^}{e`}{i"}{i^}{o^}{u^}{u`}'
+
+define prelude as repeat goto (
+
+    (  v [ ('u' ] v <- 'U') or
+           ('i' ] v <- 'I') or
+           ('y' ] <- 'Y')
+    )
+    or
+    (  ['y'] v <- 'Y' )
+    or
+    (  'q' ['u'] <- 'U' )
+)
+
+define mark_regions as (
+
+    $pV = limit
+    $p1 = limit
+    $p2 = limit  // defaults
+
+    do (
+        ( v v next )
+        or
+        among ( // this exception list begun Nov 2006
+            'par'  // paris, parie, pari
+            'col'  // colis
+            'tap'  // tapis
+            // extensions possible here
+        )
+        or
+        ( next gopast v )
+        setmark pV
+    )
+    do (
+        gopast v gopast non-v setmark p1
+        gopast v gopast non-v setmark p2
+    )
+)
+
+define postlude as repeat (
+
+    [substring] among(
+        'I' (<- 'i')
+        'U' (<- 'u')
+        'Y' (<- 'y')
+        ''  (next)
+    )
+)
+
+backwardmode (
+
+    define RV as $pV <= cursor
+    define R1 as $p1 <= cursor
+    define R2 as $p2 <= cursor
+
+    define standard_suffix as (
+        [substring] among(
+
+            'ance' 'iqUe' 'isme' 'able' 'iste' 'eux'
+            'ances' 'iqUes' 'ismes' 'ables' 'istes'
+               ( R2 delete )
+            'atrice' 'ateur' 'ation'
+            'atrices' 'ateurs' 'ations'
+               ( R2 delete
+                 try ( ['ic'] (R2 delete) or <-'iqU' )
+               )
+            'logie'
+            'logies'
+               ( R2 <- 'log' )
+            'usion' 'ution'
+            'usions' 'utions'
+               ( R2 <- 'u' )
+            'ence'
+            'ences'
+               ( R2 <- 'ent' )
+            'ement'
+            'ements'
+            (
+                RV delete
+                try (
+                    [substring] among(
+                        'iv'   (R2 delete ['at'] R2 delete)
+                        'eus'  ((R2 delete) or (R1<-'eux'))
+                        'abl' 'iqU'
+                               (R2 delete)
+                        'i{e`}r' 'I{e`}r'      //)
+                               (RV <-'i')      //)--new 2 Sept 02
+                    )
+                )
+            )
+            'it{e'}'
+            'it{e'}s'
+            (
+                R2 delete
+                try (
+                    [substring] among(
+                        'abil' ((R2 delete) or <-'abl')
+                        'ic'   ((R2 delete) or <-'iqU')
+                        'iv'   (R2 delete)
+                    )
+                )
+            )
+            'if' 'ive'
+            'ifs' 'ives'
+            (
+                R2 delete
+                try ( ['at'] R2 delete ['ic'] (R2 delete) or <-'iqU' )
+            )
+            'eaux' (<- 'eau')
+            'aux'  (R1 <- 'al')
+            'euse'
+            'euses'((R2 delete) or (R1<-'eux'))
+
+            'issement'
+            'issements'(R1 non-v delete) // verbal
+
+            // fail(...) below forces entry to verb_suffix. -ment typically
+            // follows the p.p., e.g 'confus{e'}ment'.
+
+            'amment'   (RV fail(<- 'ant'))
+            'emment'   (RV fail(<- 'ent'))
+            'ment'
+            'ments'    (test(v RV) fail(delete))
+                       // v is e,i,u,{e'},I or U
+        )
+    )
+
+    define i_verb_suffix as setlimit tomark pV for (
+        [substring] among (
+            '{i^}mes' '{i^}t' '{i^}tes' 'i' 'ie' 'ies' 'ir' 'ira' 'irai'
+            'iraIent' 'irais' 'irait' 'iras' 'irent' 'irez' 'iriez'
+            'irions' 'irons' 'iront' 'is' 'issaIent' 'issais' 'issait'
+            'issant' 'issante' 'issantes' 'issants' 'isse' 'issent' 'isses'
+            'issez' 'issiez' 'issions' 'issons' 'it'
+                (non-v delete)
+        )
+    )
+
+    define verb_suffix as setlimit tomark pV for (
+        [substring] among (
+            'ions'
+                (R2 delete)
+
+            '{e'}' '{e'}e' '{e'}es' '{e'}s' '{e`}rent' 'er' 'era' 'erai'
+            'eraIent' 'erais' 'erait' 'eras' 'erez' 'eriez' 'erions'
+            'erons' 'eront' 'ez' 'iez'
+
+            // 'ons' //-best omitted
+
+                (delete)
+
+            '{a^}mes' '{a^}t' '{a^}tes' 'a' 'ai' 'aIent' 'ais' 'ait' 'ant'
+            'ante' 'antes' 'ants' 'as' 'asse' 'assent' 'asses' 'assiez'
+            'assions'
+                (delete
+                 try(['e'] delete)
+                )
+        )
+    )
+
+    define keep_with_s 'aiou{e`}s'
+
+    define residual_suffix as (
+        try(['s'] test non-keep_with_s delete)
+        setlimit tomark pV for (
+            [substring] among(
+                'ion'           (R2 's' or 't' delete)
+                'ier' 'i{e`}re'
+                'Ier' 'I{e`}re' (<-'i')
+                'e'             (delete)
+                '{e"}'          ('gu' delete)
+            )
+        )
+    )
+
+    define un_double as (
+        test among('enn' 'onn' 'ett' 'ell' 'eill') [next] delete
+    )
+
+    define un_accent as (
+        atleast 1 non-v
+        [ '{e'}' or '{e`}' ] <-'e'
+    )
+)
+
+define stem as (
+
+    do prelude
+    do mark_regions
+    backwards (
+
+        do (
+            (
+                 ( standard_suffix or
+                   i_verb_suffix or
+                   verb_suffix
+                 )
+                 and
+                 try( [ ('Y'   ] <- 'i' ) or
+                        ('{c,}'] <- 'c' )
+                 )
+            ) or
+            residual_suffix
+        )
+
+        // try(['ent'] RV delete) // is best omitted
+
+        do un_double
+        do un_accent
+    )
+    do postlude
+)
\ No newline at end of file
diff --git a/algorithms/german.sbl b/algorithms/german.sbl
new file mode 100644
index 0000000..b42c405
--- /dev/null
+++ b/algorithms/german.sbl
@@ -0,0 +1,138 @@
+/*
+    Extra rule for -nisse ending added 11 Dec 2009
+*/
+
+routines (
+           prelude postlude
+           mark_regions
+           R1 R2
+           standard_suffix
+)
+
+externals ( stem )
+
+integers ( p1 p2 x )
+
+groupings ( v s_ending st_ending )
+
+stringescapes {}
+
+/* special characters (in ISO Latin I) */
+
+stringdef a"   hex 'E4'
+stringdef o"   hex 'F6'
+stringdef u"   hex 'FC'
+stringdef ss   hex 'DF'
+
+define v 'aeiouy{a"}{o"}{u"}'
+
+define s_ending  'bdfghklmnrt'
+define st_ending s_ending - 'r'
+
+define prelude as (
+
+    test repeat (
+        (
+            ['{ss}'] <- 'ss'
+        ) or next
+    )
+
+    repeat goto (
+        v [('u'] v <- 'U') or
+           ('y'] v <- 'Y')
+    )
+)
+
+define mark_regions as (
+
+    $p1 = limit
+    $p2 = limit
+
+    test(hop 3 setmark x)
+
+    gopast v  gopast non-v  setmark p1
+    try($p1 < x  $p1 = x)  // at least 3
+    gopast v  gopast non-v  setmark p2
+
+)
+
+define postlude as repeat (
+
+    [substring] among(
+        'Y'    (<- 'y')
+        'U'    (<- 'u')
+        '{a"}' (<- 'a')
+        '{o"}' (<- 'o')
+        '{u"}' (<- 'u')
+        ''     (next)
+    )
+
+)
+
+backwardmode (
+
+    define R1 as $p1 <= cursor
+    define R2 as $p2 <= cursor
+
+    define standard_suffix as (
+        do (
+            [substring] R1 among(
+                'em' 'ern' 'er'
+                (   delete
+                )
+                'e' 'en' 'es'
+                (   delete
+                    try (['s'] 'nis' delete)
+                )
+                's'
+                (   s_ending delete
+                )
+            )
+        )
+        do (
+            [substring] R1 among(
+                'en' 'er' 'est'
+                (   delete
+                )
+                'st'
+                (   st_ending hop 3 delete
+                )
+            )
+        )
+        do (
+            [substring] R2 among(
+                'end' 'ung'
+                (   delete
+                    try (['ig'] not 'e' R2 delete)
+                )
+                'ig' 'ik' 'isch'
+                (   not 'e' delete
+                )
+                'lich' 'heit'
+                (   delete
+                    try (
+                        ['er' or 'en'] R1 delete
+                    )
+                )
+                'keit'
+                (   delete
+                    try (
+                        [substring] R2 among(
+                            'lich' 'ig'
+                            (   delete
+                            )
+                        )
+                    )
+                )
+            )
+        )
+    )
+)
+
+define stem as (
+    do prelude
+    do mark_regions
+    backwards
+        do standard_suffix
+    do postlude
+)
\ No newline at end of file
diff --git a/algorithms/greek.sbl b/algorithms/greek.sbl
new file mode 100644
index 0000000..b3fd74e
--- /dev/null
+++ b/algorithms/greek.sbl
@@ -0,0 +1,708 @@
+// A stemmer for Modern Greek language, based on:
+//
+// Ntais, Georgios. Development of a Stemmer for the Greek
+// Language. Diss. Royal Institute of Technology, 2006.
+// https://sais.se/mthprize/2007/ntais2007.pdf
+//
+// Saroukos, Spyridon. Enhancing a Greek language stemmer.
+// University of Tampere, 2008.
+// https://tampub.uta.fi/bitstream/handle/10024/80480/gradu03463.pdf
+
+stringescapes {}
+
+stringdef a    '{U+03B1}' // alpha
+stringdef v    '{U+03B2}' // beta
+stringdef g    '{U+03B3}' // gamma
+stringdef d    '{U+03B4}' // delta
+stringdef e    '{U+03B5}' // epsilon
+stringdef z    '{U+03B6}' // zeta
+stringdef i    '{U+03B7}' // eta
+stringdef th   '{U+03B8}' // theta
+stringdef y    '{U+03B9}' // iota
+stringdef k    '{U+03BA}' // kappa
+stringdef l    '{U+03BB}' // lamda
+stringdef m    '{U+03BC}' // mu
+stringdef n    '{U+03BD}' // nu
+stringdef x    '{U+03BE}' // xi
+stringdef o    '{U+03BF}' // omicron
+stringdef p    '{U+03C0}' // pi
+stringdef r    '{U+03C1}' // rho
+stringdef ss   '{U+03C2}' // sigma final
+stringdef s    '{U+03C3}' // sigma
+stringdef t    '{U+03C4}' // tau
+stringdef u    '{U+03C5}' // upsilon
+stringdef f    '{U+03C6}' // phi
+stringdef ch   '{U+03C7}' // chi
+stringdef ps   '{U+03C8}' // psi
+stringdef oo   '{U+03C9}' // omega
+
+stringdef A    '{U+0391}' // Alpha
+stringdef V    '{U+0392}' // Beta
+stringdef G    '{U+0393}' // Gamma
+stringdef D    '{U+0394}' // Delta
+stringdef E    '{U+0395}' // Epsilon
+stringdef Z    '{U+0396}' // Zeta
+stringdef I    '{U+0397}' // Eta
+stringdef Th   '{U+0398}' // Theta
+stringdef Y    '{U+0399}' // Iota
+stringdef K    '{U+039A}' // Kappa
+stringdef L    '{U+039B}' // Lamda
+stringdef M    '{U+039C}' // Mu
+stringdef N    '{U+039D}' // Nu
+stringdef X    '{U+039E}' // Xi
+stringdef O    '{U+039F}' // Omicron
+stringdef P    '{U+03A0}' // Pi
+stringdef R    '{U+03A1}' // Rho
+stringdef S    '{U+03A3}' // Sigma
+stringdef T    '{U+03A4}' // Tau
+stringdef U    '{U+03A5}' // Upsilon
+stringdef F    '{U+03A6}' // Phi
+stringdef Ch   '{U+03A7}' // Chi
+stringdef Ps   '{U+03A8}' // Psi
+stringdef Oo   '{U+03A9}' // Omega
+
+stringdef Y:   '{U+03AA}' // Iota with dialytika
+stringdef U:   '{U+03AB}' // Upsilon with dialytika
+
+stringdef a'   '{U+03AC}' // alpha with tonos
+stringdef e'   '{U+03AD}' // epsilon with tonos
+stringdef i'   '{U+03AE}' // eta with tonos
+stringdef y'   '{U+03AF}' // iota with tonos
+stringdef o'   '{U+03CC}' // omicron with tonos
+stringdef u'   '{U+03CD}' // upsilon with tonos
+stringdef oo'  '{U+03CE}' // omega with tonos
+
+stringdef i:'  '{U+0390}' // iota with dialytika and tonos
+stringdef u:'  '{U+03B0}' // upsilon with dialytika and tonos
+
+stringdef i:   '{U+03CA}' // iota with dialytika
+stringdef u:   '{U+03CB}' // upsilon with dialytika
+
+stringdef A'   '{U+0386}' // Alpha with tonos
+stringdef E'   '{U+0388}' // Epsilon with tonos
+stringdef I'   '{U+0389}' // Eta with tonos
+stringdef Y'   '{U+038A}' // Iota with tonos
+stringdef O'   '{U+038C}' // Omicron with tonos
+stringdef U'   '{U+038E}' // Upsilon with tonos
+stringdef OO'  '{U+038F}' // Omega with tonos
+
+externals ( stem )
+
+booleans ( test1 )
+
+groupings ( v v2 )
+
+routines ( tolower has_min_length
+           steps1 steps2 steps3 steps4 steps5 steps6 steps7
+           steps8 steps9 steps10
+           step1 step2a step2b step2c step2d step3 step4
+           step5a step5b step5c step5d step5e step5f
+           step5g step5h step5i
+           step5j step5k step5l step5m
+           step6 step7 )
+
+define v '{a}{e}{i}{y}{o}{u}{oo}'
+define v2 '{a}{e}{i}{y}{o}{oo}'
+
+strings ( s )
+
+backwardmode (
+  define has_min_length as (
+    $(len >= 3)
+  )
+
+  define tolower as (
+    repeat (
+      [substring] among (
+        '{A}' (<- '{a}')
+        '{V}' (<- '{v}')
+        '{G}' (<- '{g}')
+        '{D}' (<- '{d}')
+        '{E}' (<- '{e}')
+        '{Z}' (<- '{z}')
+        '{I}' (<- '{i}')
+        '{Th}' (<- '{th}')
+        '{Y}' (<- '{y}')
+        '{K}' (<- '{k}')
+        '{L}' (<- '{l}')
+        '{M}' (<- '{m}')
+        '{N}' (<- '{n}')
+        '{X}' (<- '{x}')
+        '{O}' (<- '{o}')
+        '{P}' (<- '{p}')
+        '{R}' (<- '{r}')
+        '{S}' (<- '{s}')
+        '{T}' (<- '{t}')
+        '{U}' (<- '{u}')
+        '{F}' (<- '{f}')
+        '{Ch}' (<- '{ch}')
+        '{Ps}' (<- '{ps}')
+        '{Oo}' (<- '{oo}')
+        '{Y:}' (<- '{y}')
+        '{U:}' (<- '{u}')
+        '{a'}' (<- '{a}')
+        '{e'}' (<- '{e}')
+        '{i'}' (<- '{i}')
+        '{y'}' (<- '{y}')
+        '{o'}' (<- '{o}')
+        '{u'}' (<- '{u}')
+        '{oo'}' (<- '{oo}')
+        '{i:'}' (<- '{i}')
+        '{u:'}' (<- '{u}')
+        '{i:}' (<- '{i}')
+        '{u:}' (<- '{u}')
+        '{A'}' (<- '{a}')
+        '{E'}' (<- '{e}')
+        '{I'}' (<- '{i}')
+        '{Y'}' (<- '{y}')
+        '{O'}' (<- '{o}')
+        '{U'}' (<- '{u}')
+        '{OO'}' (<- '{oo}')
+        '{ss}' (<- '{s}')
+         '' (next)
+      )
+    )
+  )
+
+  define step1 as (
+    [substring] among (
+      '{f}{a}{g}{y}{a}' '{f}{a}{g}{y}{o}{u}' '{f}{a}{g}{y}{oo}{n}' (<- '{f}{a}')
+      '{s}{k}{a}{g}{y}{a}' '{s}{k}{a}{g}{y}{o}{u}' '{s}{k}{a}{g}{y}{oo}{n}' (<- '{s}{k}{a}')
+      '{o}{l}{o}{g}{y}{o}{u}' '{o}{l}{o}{g}{y}{a}' '{o}{l}{o}{g}{y}{oo}{n}' (<- '{o}{l}{o}')
+      '{s}{o}{g}{y}{o}{u}' '{s}{o}{g}{y}{a}' '{s}{o}{g}{y}{oo}{n}' (<- '{s}{o}')
+      '{t}{a}{t}{o}{g}{y}{a}' '{t}{a}{t}{o}{g}{y}{o}{u}' '{t}{a}{t}{o}{g}{y}{oo}{n}' (<- '{t}{a}{t}{o}')
+      '{k}{r}{e}{a}{s}' '{k}{r}{e}{a}{t}{o}{s}' '{k}{r}{e}{a}{t}{a}' '{k}{r}{e}{a}{t}{oo}{n}' (<- '{k}{r}{e}')
+      '{p}{e}{r}{a}{s}' '{p}{e}{r}{a}{t}{o}{s}' '{p}{e}{r}{a}{t}{i}' '{p}{e}{r}{a}{t}{a}' '{p}{e}{r}{a}{t}{oo}{n}' (<- '{p}{e}{r}')
+      '{t}{e}{r}{a}{s}' '{t}{e}{r}{a}{t}{o}{s}' '{t}{e}{r}{a}{t}{a}' '{t}{e}{r}{a}{t}{oo}{n}' (<- '{t}{e}{r}')
+      '{f}{oo}{s}' '{f}{oo}{t}{o}{s}' '{f}{oo}{t}{a}' '{f}{oo}{t}{oo}{n}' (<- '{f}{oo}')
+      '{k}{a}{th}{e}{s}{t}{oo}{s}' '{k}{a}{th}{e}{s}{t}{oo}{t}{o}{s}' '{k}{a}{th}{e}{s}{t}{oo}{t}{a}' '{k}{a}{th}{e}{s}{t}{oo}{t}{oo}{n}' (<- '{k}{a}{th}{e}{s}{t}')
+      '{g}{e}{g}{o}{n}{o}{s}' '{g}{e}{g}{o}{n}{o}{t}{o}{s}' '{g}{e}{g}{o}{n}{o}{t}{a}' '{g}{e}{g}{o}{n}{o}{t}{oo}{n}' (<- '{g}{e}{g}{o}{n}')
+    )
+    unset test1
+  )
+
+  define steps1 as (
+    [substring] among (
+      '{y}{z}{a}' '{y}{z}{e}{s}' '{y}{z}{e}' '{y}{z}{a}{m}{e}' '{y}{z}{a}{t}{e}' '{y}{z}{a}{n}' '{y}{z}{a}{n}{e}' '{y}{z}{oo}' '{y}{z}{e}{y}{s}' '{y}{z}{e}{y}'
+      '{y}{z}{o}{u}{m}{e}' '{y}{z}{e}{t}{e}' '{y}{z}{o}{u}{n}' '{y}{z}{o}{u}{n}{e}' (
+        delete
+        unset test1
+        ([substring] atlimit among (
+          '{a}{n}{a}{m}{p}{a}' '{e}{m}{p}{a}' '{e}{p}{a}' '{x}{a}{n}{a}{p}{a}' '{p}{a}' '{p}{e}{r}{y}{p}{a}' '{a}{th}{r}{o}' '{s}{u}{n}{a}{th}{r}{o}' '{d}{a}{n}{e}'
+          (-> s <- '{y}' insert s)
+        )) or
+        ([substring] atlimit among (
+          '{m}{a}{r}{k}' '{k}{o}{r}{n}' '{a}{m}{p}{a}{r}' '{a}{r}{r}' '{v}{a}{th}{u}{r}{y}' '{v}{a}{r}{k}' '{v}' '{v}{o}{l}{v}{o}{r}' '{g}{k}{r}'
+          '{g}{l}{u}{k}{o}{r}' '{g}{l}{u}{k}{u}{r}' '{y}{m}{p}' '{l}' '{l}{o}{u}' '{m}{a}{r}' '{m}' '{p}{r}' '{m}{p}{r}' '{p}{o}{l}{u}{r}' '{p}'
+          '{r}' '{p}{y}{p}{e}{r}{o}{r}'
+          (-> s <- '{y}{z}' insert s)
+        ))
+      )
+    )
+  )
+
+  define steps2 as (
+    [substring] among (
+      '{oo}{th}{i}{k}{a}' '{oo}{th}{i}{k}{e}{s}' '{oo}{th}{i}{k}{e}' '{oo}{th}{i}{k}{a}{m}{e}' '{oo}{th}{i}{k}{a}{t}{e}' '{oo}{th}{i}{k}{a}{n}' '{oo}{th}{i}{k}{a}{n}{e}' (
+        delete
+        unset test1
+        [substring] atlimit among (
+          '{a}{l}' '{v}{y}' '{e}{n}' '{u}{ps}' '{l}{y}' '{z}{oo}' '{s}' '{ch}' (-> s <- '{oo}{n}' insert s)
+        )
+      )
+    )
+  )
+
+  define steps3 as (
+    [substring] among (
+      '{y}{s}{a}' '{y}{s}{e}{s}' '{y}{s}{e}' '{y}{s}{a}{m}{e}' '{y}{s}{a}{t}{e}' '{y}{s}{a}{n}' '{y}{s}{a}{n}{e}' (
+        delete
+        unset test1
+        ('{y}{s}{a}' atlimit <- '{y}{s}') or
+        ([substring] atlimit among (
+          '{a}{n}{a}{m}{p}{a}' '{a}{th}{r}{o}' '{e}{m}{p}{a}' '{e}{s}{e}' '{e}{s}{oo}{k}{l}{e}' '{e}{p}{a}' '{x}{a}{n}{a}{p}{a}' '{e}{p}{e}' '{p}{e}{r}{y}{p}{a}'
+          '{s}{u}{n}{a}{th}{r}{o}' '{d}{a}{n}{e}' '{k}{l}{e}' '{ch}{a}{r}{t}{o}{p}{a}' '{e}{x}{a}{r}{ch}{a}' '{m}{e}{t}{e}{p}{e}' '{a}{p}{o}{k}{l}{e}'
+          '{a}{p}{e}{k}{l}{e}' '{e}{k}{l}{e}' '{p}{e}'
+          (-> s <- '{y}' insert s)
+        )) or
+        ([substring] atlimit among (
+          '{a}{n}' '{a}{f}' '{g}{e}' '{g}{y}{g}{a}{n}{t}{o}{a}{f}' '{g}{k}{e}' '{d}{i}{m}{o}{k}{r}{a}{t}' '{k}{o}{m}' '{g}{k}' '{m}' '{p}'
+          '{p}{o}{u}{k}{a}{m}' '{o}{l}{o}' '{l}{a}{r}'
+          (-> s <- '{y}{s}' insert s)
+        ))
+      )
+    )
+  )
+
+  define steps4 as (
+    [substring] among (
+      '{y}{s}{oo}' '{y}{s}{e}{y}{s}' '{y}{s}{e}{y}' '{y}{s}{o}{u}{m}{e}' '{y}{s}{e}{t}{e}' '{y}{s}{o}{u}{n}' '{y}{s}{o}{u}{n}{e}' (
+        delete
+        unset test1
+        [substring] atlimit among (
+          '{a}{n}{a}{m}{p}{a}' '{e}{m}{p}{a}' '{e}{s}{e}' '{e}{s}{oo}{k}{l}{e}' '{e}{p}{a}' '{x}{a}{n}{a}{p}{a}' '{e}{p}{e}' '{p}{e}{r}{y}{p}{a}' '{a}{th}{r}{o}'
+          '{s}{u}{n}{a}{th}{r}{o}' '{d}{a}{n}{e}' '{k}{l}{e}' '{ch}{a}{r}{t}{o}{p}{a}' '{e}{x}{a}{r}{ch}{a}' '{m}{e}{t}{e}{p}{e}' '{a}{p}{o}{k}{l}{e}' '{a}{p}{e}{k}{l}{e}'
+          '{e}{k}{l}{e}' '{p}{e}'
+          (-> s <- '{y}' insert s)
+        )
+      )
+    )
+  )
+
+  define steps5 as (
+    [substring] among (
+      '{y}{s}{t}{o}{s}' '{y}{s}{t}{o}{u}' '{y}{s}{t}{o}' '{y}{s}{t}{e}' '{y}{s}{t}{o}{y}' '{y}{s}{t}{oo}{n}' '{y}{s}{t}{o}{u}{s}' '{y}{s}{t}{i}' '{y}{s}{t}{i}{s}'
+      '{y}{s}{t}{a}' '{y}{s}{t}{e}{s}' (
+        delete
+        unset test1
+        ([substring] atlimit among (
+          '{d}{a}{n}{e}' '{s}{u}{n}{a}{th}{r}{o}' '{k}{l}{e}' '{s}{e}' '{e}{s}{oo}{k}{l}{e}' '{a}{s}{e}' '{p}{l}{e}'
+          (-> s <- '{y}' insert s)
+        )) or
+        ([substring] atlimit among (
+          '{m}' '{p}' '{a}{p}' '{a}{r}' '{i}{d}' '{k}{t}' '{s}{k}' '{s}{ch}' '{u}{ps}' '{f}{a}' '{ch}{r}' '{ch}{t}' '{a}{k}{t}'
+          '{a}{o}{r}' '{a}{s}{ch}' '{a}{t}{a}' '{a}{ch}{n}' '{a}{ch}{t}' '{g}{e}{m}' '{g}{u}{r}' '{e}{m}{p}' '{e}{u}{p}' '{e}{ch}{th}' '{i}{f}{a}'
+          '{k}{a}{th}' '{k}{a}{k}' '{k}{u}{l}' '{l}{u}{g}' '{m}{a}{k}' '{m}{e}{g}' '{t}{a}{ch}' '{f}{y}{l}' '{ch}{oo}{r}'
+          (-> s <- '{y}{s}{t}' insert s)
+        ))
+      )
+    )
+  )
+
+  define steps6 as (
+    [substring] among (
+      '{y}{s}{m}{o}' '{y}{s}{m}{o}{y}' '{y}{s}{m}{o}{s}' '{y}{s}{m}{o}{u}' '{y}{s}{m}{o}{u}{s}' '{y}{s}{m}{oo}{n}' (
+        delete
+        unset test1
+        ([substring] atlimit among (
+          '{s}{e}' '{m}{e}{t}{a}{s}{e}' '{m}{y}{k}{r}{o}{s}{e}' '{e}{g}{k}{l}{e}' '{a}{p}{o}{k}{l}{e}'
+          (-> s <- '{y}{s}{m}' insert s)
+        )) or
+        ([substring] atlimit among (
+          '{d}{a}{n}{e}' '{a}{n}{t}{y}{d}{a}{n}{e}'
+          (-> s <- '{y}' insert s)
+        )) or
+        ([substring] among (
+          '{a}{g}{n}{oo}{s}{t}{y}{k}' (<- '{a}{g}{n}{oo}{s}{t}')
+          '{a}{t}{o}{m}{y}{k}' (<- '{a}{t}{o}{m}')
+          '{g}{n}{oo}{s}{t}{y}{k}' (<- '{g}{n}{oo}{s}{t}')
+          '{e}{th}{n}{y}{k}' (<- '{e}{th}{n}')
+          '{e}{k}{l}{e}{k}{t}{y}{k}' (<- '{e}{k}{l}{e}{k}{t}')
+          '{s}{k}{e}{p}{t}{y}{k}' (<- '{s}{k}{e}{p}{t}')
+          '{t}{o}{p}{y}{k}' (<- '{t}{o}{p}')
+          '{a}{l}{e}{x}{a}{n}{d}{r}{y}{n}' (<- '{a}{l}{e}{x}{a}{n}{d}{r}')
+          '{v}{u}{z}{a}{n}{t}{y}{n}' (<- '{v}{u}{z}{a}{n}{t}')
+          '{th}{e}{a}{t}{r}{y}{n}' (<- '{th}{e}{a}{t}{r}')
+        ))
+      )
+    )
+  )
+
+  define steps7 as (
+    [substring] among (
+      '{a}{r}{a}{k}{y}' '{a}{r}{a}{k}{y}{a}' '{o}{u}{d}{a}{k}{y}' '{o}{u}{d}{a}{k}{y}{a}' (
+        delete
+        unset test1
+        [substring] atlimit among (
+         '{s}' '{ch}'
+         (-> s <- '{a}{r}{a}{k}' insert s)
+        )
+      )
+    )
+  )
+
+  define steps8 as (
+    [substring] among (
+      '{a}{k}{y}' '{a}{k}{y}{a}' '{y}{t}{s}{a}' '{y}{t}{s}{a}{s}' '{y}{t}{s}{e}{s}' '{y}{t}{s}{oo}{n}' '{a}{r}{a}{k}{y}' '{a}{r}{a}{k}{y}{a}' (
+        delete
+        unset test1
+        ([substring] atlimit among (
+          '{v}{a}{m}{v}' '{v}{r}' '{k}{a}{y}{m}' '{k}{o}{n}' '{k}{o}{r}' '{l}{a}{v}{r}' '{l}{o}{u}{l}' '{m}{e}{r}' '{m}{o}{u}{s}{t}'
+          '{n}{a}{g}{k}{a}{s}' '{p}{l}' '{r}' '{r}{u}' '{s}' '{s}{k}' '{s}{o}{k}' '{s}{p}{a}{n}' '{t}{z}' '{f}{a}{r}{m}' '{ch}' '{k}{a}{p}{a}{k}'
+          '{a}{l}{y}{s}{f}' '{a}{m}{v}{r}' '{a}{n}{th}{r}' '{k}' '{f}{u}{l}' '{k}{a}{t}{r}{a}{p}' '{k}{l}{y}{m}' '{m}{a}{l}' '{s}{l}{o}{v}' '{f}'
+          '{s}{f}' '{t}{s}{e}{ch}{o}{s}{l}{o}{v}'
+           (-> s <- '{a}{k}' insert s)
+        )) or
+        ([substring] atlimit among (
+          '{v}' '{v}{a}{l}' '{g}{y}{a}{n}' '{g}{l}' '{z}' '{i}{g}{o}{u}{m}{e}{n}' '{k}{a}{r}{d}' '{k}{o}{n}' '{m}{a}{k}{r}{u}{n}' '{n}{u}{f}'
+          '{p}{a}{t}{e}{r}' '{p}' '{s}{k}' '{t}{o}{s}' '{t}{r}{y}{p}{o}{l}'
+          (-> s <- '{y}{t}{s}' insert s)
+        )) or
+        (['{k}{o}{r}'] -> s <- '{y}{t}{s}' insert s)
+      )
+    )
+  )
+
+  define steps9 as (
+    [substring] among (
+      '{y}{d}{y}{o}' '{y}{d}{y}{a}' '{y}{d}{y}{oo}{n}' (
+        delete
+        unset test1
+        ([substring] atlimit among (
+          '{a}{y}{f}{n}' '{y}{r}' '{o}{l}{o}' '{ps}{a}{l}' (-> s <- '{y}{d}' insert s)
+        )) or
+        ([substring] among (
+          '{e}' '{p}{a}{y}{ch}{n}' (-> s <- '{y}{d}' insert s)
+        ))
+      )
+    )
+  )
+
+  define steps10 as (
+    [substring] among (
+      '{y}{s}{k}{o}{s}' '{y}{s}{k}{o}{u}' '{y}{s}{k}{o}' '{y}{s}{k}{e}' (
+        delete
+        unset test1
+        [substring] atlimit among (
+         '{d}' '{y}{v}' '{m}{i}{n}' '{r}' '{f}{r}{a}{g}{k}' '{l}{u}{k}' '{o}{v}{e}{l}'
+         (-> s <- '{y}{s}{k}' insert s)
+        )
+      )
+    )
+  )
+
+  define step2a as (
+    [substring] among (
+      '{a}{d}{e}{s}' '{a}{d}{oo}{n}' (delete)
+    )
+    not ([substring] among (
+      '{o}{k}' '{m}{a}{m}' '{m}{a}{n}' '{m}{p}{a}{m}{p}' '{p}{a}{t}{e}{r}' '{g}{y}{a}{g}{y}' '{n}{t}{a}{n}{t}' '{k}{u}{r}' '{th}{e}{y}' '{p}{e}{th}{e}{r}'
+    ))
+    insert '{a}{d}'
+  )
+
+  define step2b as (
+    [substring] among (
+      '{e}{d}{e}{s}' '{e}{d}{oo}{n}' (delete)
+    )
+    [substring] among (
+      '{o}{p}' '{y}{p}' '{e}{m}{p}' '{u}{p}' '{g}{i}{p}' '{d}{a}{p}' '{k}{r}{a}{s}{p}' '{m}{y}{l}' (-> s <- '{e}{d}' insert s)
+    )
+  )
+
+  define step2c as (
+    [substring] among (
+      '{o}{u}{d}{e}{s}' '{o}{u}{d}{oo}{n}' (delete)
+    )
+    [substring] among (
+      '{a}{r}{k}' '{k}{a}{l}{y}{a}{k}' '{p}{e}{t}{a}{l}' '{l}{y}{ch}' '{p}{l}{e}{x}' '{s}{k}' '{s}' '{f}{l}' '{f}{r}' '{v}{e}{l}' '{l}{o}{u}{l}' '{ch}{n}'
+      '{s}{p}' '{t}{r}{a}{g}' '{f}{e}' (-> s <- '{o}{u}{d}' insert s)
+    )
+  )
+
+  define step2d as (
+    [substring] among (
+      '{e}{oo}{s}' '{e}{oo}{n}' (delete unset test1)
+    )
+    [substring] atlimit among (
+      '{th}' '{d}' '{e}{l}' '{g}{a}{l}' '{n}' '{p}' '{y}{d}' '{p}{a}{r}' (-> s <- '{e}' insert s)
+    )
+  )
+
+  define step3 as (
+    [substring] among (
+      '{y}{a}' '{y}{o}{u}' '{y}{oo}{n}' (delete unset test1)
+    )
+    ([v] -> s <- '{y}' insert s)
+  )
+
+  define step4 as (
+    [substring] among (
+       '{y}{k}{a}' '{y}{k}{o}' '{y}{k}{o}{u}' '{y}{k}{oo}{n}' (delete unset test1)
+    )
+    ([v] -> s <- '{y}{k}' insert s) or
+    [substring] atlimit among (
+      '{a}{l}' '{a}{d}' '{e}{n}{d}' '{a}{m}{a}{n}' '{a}{m}{m}{o}{ch}{a}{l}' '{i}{th}' '{a}{n}{i}{th}' '{a}{n}{t}{y}{d}' '{f}{u}{s}' '{v}{r}{oo}{m}' '{g}{e}{r}'
+      '{e}{x}{oo}{d}' '{k}{a}{l}{p}' '{k}{a}{l}{l}{y}{n}' '{k}{a}{t}{a}{d}' '{m}{o}{u}{l}' '{m}{p}{a}{n}' '{m}{p}{a}{g}{y}{a}{t}' '{m}{p}{o}{l}' '{m}{p}{o}{s}'
+      '{n}{y}{t}' '{x}{y}{k}' '{s}{u}{n}{o}{m}{i}{l}' '{p}{e}{t}{s}' '{p}{y}{t}{s}' '{p}{y}{k}{a}{n}{t}' '{p}{l}{y}{a}{t}{s}' '{p}{o}{s}{t}{e}{l}{n}' '{p}{r}{oo}{t}{o}{d}'
+      '{s}{e}{r}{t}' '{s}{u}{n}{a}{d}' '{t}{s}{a}{m}' '{u}{p}{o}{d}' '{f}{y}{l}{o}{n}' '{f}{u}{l}{o}{d}' '{ch}{a}{s}'
+      (-> s <- '{y}{k}' insert s)
+    )
+  )
+
+  define step5a as (
+    do ('{a}{g}{a}{m}{e}' atlimit <- '{a}{g}{a}{m}')
+    do (
+      [substring] among (
+        '{a}{g}{a}{m}{e}' '{i}{s}{a}{m}{e}' '{o}{u}{s}{a}{m}{e}' '{i}{k}{a}{m}{e}' '{i}{th}{i}{k}{a}{m}{e}' (delete unset test1)
+      )
+    )
+    ['{a}{m}{e}']
+    delete
+    unset test1
+    [substring] atlimit among (
+      '{a}{n}{a}{p}' '{a}{p}{o}{th}' '{a}{p}{o}{k}' '{a}{p}{o}{s}{t}' '{v}{o}{u}{v}' '{x}{e}{th}' '{o}{u}{l}' '{p}{e}{th}' '{p}{y}{k}{r}' '{p}{o}{t}' '{s}{y}{ch}' '{ch}'
+      (-> s <- '{a}{m}' insert s)
+    )
+  )
+
+  define step5b as (
+    do (
+      [substring] among (
+        '{a}{g}{a}{n}{e}' '{i}{s}{a}{n}{e}' '{o}{u}{s}{a}{n}{e}' '{y}{o}{n}{t}{a}{n}{e}' '{y}{o}{t}{a}{n}{e}' '{y}{o}{u}{n}{t}{a}{n}{e}' '{o}{n}{t}{a}{n}{e}' '{o}{t}{a}{n}{e}'
+        '{o}{u}{n}{t}{a}{n}{e}' '{i}{k}{a}{n}{e}' '{i}{th}{i}{k}{a}{n}{e}' (
+          delete
+          unset test1
+          [substring] atlimit among (
+            '{t}{r}' '{t}{s}' (-> s <- '{a}{g}{a}{n}' insert s)
+          )
+        )
+      )
+    )
+    ['{a}{n}{e}']
+    delete
+    unset test1
+    ([v2] -> s <- '{a}{n}' insert s) or
+    [substring] atlimit among (
+      '{v}{e}{t}{e}{r}' '{v}{o}{u}{l}{k}' '{v}{r}{a}{ch}{m}' '{g}' '{d}{r}{a}{d}{o}{u}{m}'
+      '{th}' '{k}{a}{l}{p}{o}{u}{z}' '{k}{a}{s}{t}{e}{l}' '{k}{o}{r}{m}{o}{r}' '{l}{a}{o}{p}{l}' '{m}{oo}{a}{m}{e}{th}'
+      '{m}' '{m}{o}{u}{s}{o}{u}{l}{m}' '{n}' '{o}{u}{l}' '{p}' '{p}{e}{l}{e}{k}' '{p}{l}' '{p}{o}{l}{y}{s}'
+      '{p}{o}{r}{t}{o}{l}' '{s}{a}{r}{a}{k}{a}{t}{s}' '{s}{o}{u}{l}{t}' '{t}{s}{a}{r}{l}{a}{t}' '{o}{r}{f}'
+      '{t}{s}{y}{g}{g}' '{t}{s}{o}{p}' '{f}{oo}{t}{o}{s}{t}{e}{f}' '{ch}' '{ps}{u}{ch}{o}{p}{l}' '{a}{g}'
+      '{g}{a}{l}' '{g}{e}{r}' '{d}{e}{k}' '{d}{y}{p}{l}' '{a}{m}{e}{r}{y}{k}{a}{n}' '{o}{u}{r}' '{p}{y}{th}'
+      '{p}{o}{u}{r}{y}{t}' '{s}' '{z}{oo}{n}{t}' '{y}{k}' '{k}{a}{s}{t}' '{k}{o}{p}' '{l}{y}{ch}'
+      '{l}{o}{u}{th}{i}{r}' '{m}{a}{y}{n}{t}' '{m}{e}{l}' '{s}{y}{g}' '{s}{p}' '{s}{t}{e}{g}' '{t}{r}{a}{g}'
+      '{t}{s}{a}{g}' '{f}' '{e}{r}' '{a}{d}{a}{p}' '{a}{th}{y}{g}{g}' '{a}{m}{i}{ch}' '{a}{n}{y}{k}'
+      '{a}{n}{o}{r}{g}' '{a}{p}{i}{g}' '{a}{p}{y}{th}' '{a}{t}{s}{y}{g}{g}' '{v}{a}{s}' '{v}{a}{s}{k}'
+      '{v}{a}{th}{u}{g}{a}{l}' '{v}{y}{o}{m}{i}{ch}' '{v}{r}{a}{ch}{u}{k}' '{d}{y}{a}{t}' '{d}{y}{a}{f}' '{e}{n}{o}{r}{g}'
+      '{th}{u}{s}' '{k}{a}{p}{n}{o}{v}{y}{o}{m}{i}{ch}' '{k}{a}{t}{a}{g}{a}{l}' '{k}{l}{y}{v}' '{k}{o}{y}{l}{a}{r}{f}'
+      '{l}{y}{v}' '{m}{e}{g}{l}{o}{v}{y}{o}{m}{i}{ch}' '{m}{y}{k}{r}{o}{v}{y}{o}{m}{i}{ch}' '{n}{t}{a}{v}'
+      '{x}{i}{r}{o}{k}{l}{y}{v}' '{o}{l}{y}{g}{o}{d}{a}{m}' '{o}{l}{o}{g}{a}{l}' '{p}{e}{n}{t}{a}{r}{f}' '{p}{e}{r}{i}{f}'
+      '{p}{e}{r}{y}{t}{r}' '{p}{l}{a}{t}' '{p}{o}{l}{u}{d}{a}{p}' '{p}{o}{l}{u}{m}{i}{ch}' '{s}{t}{e}{f}' '{t}{a}{v}'
+      '{t}{e}{t}' '{u}{p}{e}{r}{i}{f}' '{u}{p}{o}{k}{o}{p}' '{ch}{a}{m}{i}{l}{o}{d}{a}{p}' '{ps}{i}{l}{o}{t}{a}{v}'
+      (-> s <- '{a}{n}' insert s)
+    )
+  )
+
+  define step5c as (
+    do (
+      [substring] among (
+        '{i}{s}{e}{t}{e}' (delete unset test1)
+      )
+    )
+    ['{e}{t}{e}']
+    delete
+    unset test1
+    ([v2] -> s <- '{e}{t}' insert s) or
+    ([substring] among (
+      '{o}{d}' '{a}{y}{r}' '{f}{o}{r}' '{t}{a}{th}' '{d}{y}{a}{th}' '{s}{ch}' '{e}{n}{d}' '{e}{u}{r}' '{t}{y}{th}' '{u}{p}{e}{r}{th}'
+      '{r}{a}{th}' '{e}{n}{th}' '{r}{o}{th}' '{s}{th}' '{p}{u}{r}' '{a}{y}{n}' '{s}{u}{n}{d}' '{s}{u}{n}' '{s}{u}{n}{th}' '{ch}{oo}{r}'
+      '{p}{o}{n}' '{v}{r}' '{k}{a}{th}' '{e}{u}{th}' '{e}{k}{th}' '{n}{e}{t}' '{r}{o}{n}' '{a}{r}{k}' '{v}{a}{r}' '{v}{o}{l}' '{oo}{f}{e}{l}'
+      (-> s <- '{e}{t}' insert s)
+    )) or
+    [substring] atlimit among (
+      '{a}{v}{a}{r}' '{v}{e}{n}' '{e}{n}{a}{r}' '{a}{v}{r}' '{a}{d}' '{a}{th}' '{a}{n}' '{a}{p}{l}' '{v}{a}{r}{o}{n}' '{n}{t}{r}' '{s}{k}' '{k}{o}{p}'
+      '{m}{p}{o}{r}' '{n}{y}{f}' '{p}{a}{g}' '{p}{a}{r}{a}{k}{a}{l}' '{s}{e}{r}{p}' '{s}{k}{e}{l}' '{s}{u}{r}{f}' '{t}{o}{k}' '{u}' '{d}' '{e}{m}'
+      '{th}{a}{r}{r}' '{th}'
+      (-> s <- '{e}{t}' insert s)
+    )
+  )
+
+  define step5d as (
+    [substring] among (
+      '{o}{n}{t}{a}{s}' '{oo}{n}{t}{a}{s}' (
+        delete
+        unset test1
+        (['{a}{r}{ch}'] atlimit -> s <- '{o}{n}{t}' insert s) or
+        (['{k}{r}{e}'] -> s <- '{oo}{n}{t}' insert s)
+      )
+    )
+  )
+
+  define step5e as (
+    [substring] among (
+      '{o}{m}{a}{s}{t}{e}' '{y}{o}{m}{a}{s}{t}{e}' (
+        delete
+        unset test1
+        (['{o}{n}'] atlimit -> s <- '{o}{m}{a}{s}{t}' insert s)
+      )
+    )
+  )
+
+  define step5f as (
+    do (
+      ['{y}{e}{s}{t}{e}']
+      delete
+      unset test1
+      [substring] atlimit among (
+        '{p}' '{a}{p}' '{s}{u}{m}{p}' '{a}{s}{u}{m}{p}' '{a}{k}{a}{t}{a}{p}' '{a}{m}{e}{t}{a}{m}{f}' (-> s <- '{y}{e}{s}{t}' insert s)
+      )
+    )
+    ['{e}{s}{t}{e}']
+    delete
+    unset test1
+    [substring] atlimit among (
+      '{a}{l}' '{a}{r}' '{e}{k}{t}{e}{l}' '{z}' '{m}' '{x}' '{p}{a}{r}{a}{k}{a}{l}' '{p}{r}{o}' '{n}{y}{s}'
+      (-> s <- '{y}{e}{s}{t}' insert s)
+    )
+  )
+
+  define step5g as (
+    do (
+      [substring] among (
+        '{i}{th}{i}{k}{a}' '{i}{th}{i}{k}{e}{s}' '{i}{th}{i}{k}{e}' (delete unset test1)
+      )
+    )
+    [substring] among (
+      '{i}{k}{a}' '{i}{k}{e}{s}' '{i}{k}{e}' (
+        delete
+        unset test1
+        ([substring] among (
+           '{s}{k}{oo}{l}' '{s}{k}{o}{u}{l}' '{n}{a}{r}{th}' '{s}{f}' '{o}{th}' '{p}{y}{th}' (-> s <- '{i}{k}' insert s)
+        )) or
+        ([substring] atlimit among (
+           '{d}{y}{a}{th}' '{th}' '{p}{a}{r}{a}{k}{a}{t}{a}{th}' '{p}{r}{o}{s}{th}' '{s}{u}{n}{th}' (-> s <- '{i}{k}' insert s)
+        ))
+      )
+    )
+  )
+
+  define step5h as (
+    [substring] among (
+      '{o}{u}{s}{a}' '{o}{u}{s}{e}{s}' '{o}{u}{s}{e}' (
+        delete
+        unset test1
+        ([substring] among (
+          '{p}{o}{d}{a}{r}' '{v}{l}{e}{p}' '{p}{a}{n}{t}{a}{ch}' '{f}{r}{u}{d}' '{m}{a}{n}{t}{y}{l}' '{m}{a}{l}{l}' '{k}{u}{m}{a}{t}' '{l}{a}{ch}' '{l}{i}{g}'
+          '{f}{a}{g}' '{o}{m}' '{p}{r}{oo}{t}' (-> s <- '{o}{u}{s}' insert s)
+
+        )) or
+        ([substring] atlimit among (
+          '{f}{a}{r}{m}{a}{k}' '{ch}{a}{d}' '{a}{g}{k}' '{a}{n}{a}{r}{r}' '{v}{r}{o}{m}' '{e}{k}{l}{y}{p}' '{l}{a}{m}{p}{y}{d}' '{l}{e}{ch}' '{m}' '{p}{a}{t}'
+          '{r}' '{l}' '{m}{e}{d}' '{m}{e}{s}{a}{z}' '{u}{p}{o}{t}{e}{y}{n}' '{a}{m}' '{a}{y}{th}' '{a}{n}{i}{k}' '{d}{e}{s}{p}{o}{z}'
+          '{e}{n}{d}{y}{a}{f}{e}{r}' '{d}{e}' '{d}{e}{u}{t}{e}{r}{e}{u}' '{k}{a}{th}{a}{r}{e}{u}' '{p}{l}{e}' '{t}{s}{a}'
+          (-> s <- '{o}{u}{s}' insert s)
+        ))
+      )
+    )
+  )
+
+  define step5i as (
+    [substring] among (
+      '{a}{g}{a}' '{a}{g}{e}{s}' '{a}{g}{e}' (
+        delete
+        unset test1
+        (['{k}{o}{l}{l}'] -> s <- '{a}{g}' insert s) or (
+          not ([substring] among ('{ps}{o}{f}' '{n}{a}{u}{l}{o}{ch}'))
+          ([substring] among (
+            '{o}{f}' '{p}{e}{l}' '{ch}{o}{r}{t}' '{l}{l}' '{s}{f}' '{r}{p}' '{f}{r}' '{p}{r}' '{l}{o}{ch}' '{s}{m}{i}{n}'
+            (-> s <- '{a}{g}' insert s)
+          )) or
+          ([substring] atlimit among (
+            '{a}{v}{a}{s}{t}' '{p}{o}{l}{u}{f}' '{a}{d}{i}{f}' '{p}{a}{m}{f}' '{r}' '{a}{s}{p}' '{a}{f}' '{a}{m}{a}{l}' '{a}{m}{a}{l}{l}{y}'
+            '{a}{n}{u}{s}{t}' '{a}{p}{e}{r}' '{a}{s}{p}{a}{r}' '{a}{ch}{a}{r}' '{d}{e}{r}{v}{e}{n}' '{d}{r}{o}{s}{o}{p}' '{x}{e}{f}' '{n}{e}{o}{p}'
+            '{n}{o}{m}{o}{t}' '{o}{l}{o}{p}' '{o}{m}{o}{t}' '{p}{r}{o}{s}{t}' '{p}{r}{o}{s}{oo}{p}{o}{p}' '{s}{u}{m}{p}' '{s}{u}{n}{t}' '{t}' '{u}{p}{o}{t}'
+            '{ch}{a}{r}' '{a}{e}{y}{p}' '{a}{y}{m}{o}{s}{t}' '{a}{n}{u}{p}' '{a}{p}{o}{t}' '{a}{r}{t}{y}{p}' '{d}{y}{a}{t}' '{e}{n}' '{e}{p}{y}{t}'
+            '{k}{r}{o}{k}{a}{l}{o}{p}' '{s}{y}{d}{i}{r}{o}{p}' '{l}' '{n}{a}{u}' '{o}{u}{l}{a}{m}' '{o}{u}{r}' '{p}' '{t}{r}' '{m}'
+            (-> s <- '{a}{g}' insert s)
+          ))
+        )
+      )
+    )
+  )
+
+  define step5j as (
+    [substring] among (
+      '{i}{s}{e}' '{i}{s}{o}{u}' '{i}{s}{a}' (delete unset test1)
+    )
+    [substring] atlimit among (
+      '{n}' '{ch}{e}{r}{s}{o}{n}' '{d}{oo}{d}{e}{k}{a}{n}' '{e}{r}{i}{m}{o}{n}' '{m}{e}{g}{a}{l}{o}{n}' '{e}{p}{t}{a}{n}' (-> s <- '{i}{s}' insert s)
+    )
+  )
+
+  define step5k as (
+    [substring] among (
+      '{i}{s}{t}{e}' (delete unset test1)
+    )
+    [substring] atlimit among (
+      '{a}{s}{v}' '{s}{v}' '{a}{ch}{r}' '{ch}{r}' '{a}{p}{l}' '{a}{e}{y}{m}{n}' '{d}{u}{s}{ch}{r}' '{e}{u}{ch}{r}' '{k}{o}{y}{n}{o}{ch}{r}' '{p}{a}{l}{y}{m}{ps}'
+      (-> s <- '{i}{s}{t}' insert s)
+    )
+  )
+
+  define step5l as (
+    [substring] among (
+      '{o}{u}{n}{e}' '{i}{s}{o}{u}{n}{e}' '{i}{th}{o}{u}{n}{e}' (delete unset test1)
+    )
+    [substring] atlimit among (
+      '{n}' '{r}' '{s}{p}{y}' '{s}{t}{r}{a}{v}{o}{m}{o}{u}{t}{s}' '{k}{a}{k}{o}{m}{o}{u}{t}{s}' '{e}{x}{oo}{n}' (-> s <- '{o}{u}{n}' insert s)
+    )
+  )
+
+  define step5m as (
+    [substring] among (
+      '{o}{u}{m}{e}' '{i}{s}{o}{u}{m}{e}' '{i}{th}{o}{u}{m}{e}' (delete unset test1)
+    )
+    [substring] atlimit among (
+      '{p}{a}{r}{a}{s}{o}{u}{s}' '{f}' '{ch}' '{oo}{r}{y}{o}{p}{l}' '{a}{z}' '{a}{l}{l}{o}{s}{o}{u}{s}' '{a}{s}{o}{u}{s}'
+      (-> s <- '{o}{u}{m}' insert s)
+    )
+  )
+
+  define step6 as (
+    do (
+      [substring] among (
+        '{m}{a}{t}{a}' '{m}{a}{t}{oo}{n}' '{m}{a}{t}{o}{s}' (<- '{m}{a}')
+      )
+    )
+    test1
+    [substring] among (
+      '{a}' '{a}{g}{a}{t}{e}' '{a}{g}{a}{n}' '{a}{e}{y}' '{a}{m}{a}{y}' '{a}{n}' '{a}{s}' '{a}{s}{a}{y}' '{a}{t}{a}{y}' '{a}{oo}' '{e}' '{e}{y}'
+      '{e}{y}{s}' '{e}{y}{t}{e}' '{e}{s}{a}{y}' '{e}{s}' '{e}{t}{a}{y}' '{y}' '{y}{e}{m}{a}{y}' '{y}{e}{m}{a}{s}{t}{e}' '{y}{e}{t}{a}{y}' '{y}{e}{s}{a}{y}'
+      '{y}{e}{s}{a}{s}{t}{e}' '{y}{o}{m}{a}{s}{t}{a}{n}' '{y}{o}{m}{o}{u}{n}' '{y}{o}{m}{o}{u}{n}{a}' '{y}{o}{n}{t}{a}{n}' '{y}{o}{n}{t}{o}{u}{s}{a}{n}' '{y}{o}{s}{a}{s}{t}{a}{n}'
+      '{y}{o}{s}{a}{s}{t}{e}' '{y}{o}{s}{o}{u}{n}' '{y}{o}{s}{o}{u}{n}{a}' '{y}{o}{t}{a}{n}' '{y}{o}{u}{m}{a}' '{y}{o}{u}{m}{a}{s}{t}{e}' '{y}{o}{u}{n}{t}{a}{y}'
+      '{y}{o}{u}{n}{t}{a}{n}' '{i}' '{i}{d}{e}{s}' '{i}{d}{oo}{n}' '{i}{th}{e}{y}' '{i}{th}{e}{y}{s}' '{i}{th}{e}{y}{t}{e}' '{i}{th}{i}{k}{a}{t}{e}' '{i}{th}{i}{k}{a}{n}'
+      '{i}{th}{o}{u}{n}' '{i}{th}{oo}' '{i}{k}{a}{t}{e}' '{i}{k}{a}{n}' '{i}{s}' '{i}{s}{a}{n}' '{i}{s}{a}{t}{e}' '{i}{s}{e}{y}' '{i}{s}{e}{s}' '{i}{s}{o}{u}{n}'
+      '{i}{s}{oo}' '{o}' '{o}{y}' '{o}{m}{a}{y}' '{o}{m}{a}{s}{t}{a}{n}' '{o}{m}{o}{u}{n}' '{o}{m}{o}{u}{n}{a}' '{o}{n}{t}{a}{y}' '{o}{n}{t}{a}{n}'
+      '{o}{n}{t}{o}{u}{s}{a}{n}' '{o}{s}' '{o}{s}{a}{s}{t}{a}{n}' '{o}{s}{a}{s}{t}{e}' '{o}{s}{o}{u}{n}' '{o}{s}{o}{u}{n}{a}' '{o}{t}{a}{n}' '{o}{u}' '{o}{u}{m}{a}{y}'
+      '{o}{u}{m}{a}{s}{t}{e}' '{o}{u}{n}' '{o}{u}{n}{t}{a}{y}' '{o}{u}{n}{t}{a}{n}' '{o}{u}{s}' '{o}{u}{s}{a}{n}' '{o}{u}{s}{a}{t}{e}' '{u}' '{u}{s}' '{oo}'
+      '{oo}{n}' (delete)
+    )
+  )
+
+  define step7 as (
+    [substring] among (
+      '{e}{s}{t}{e}{r}' '{e}{s}{t}{a}{t}' '{o}{t}{e}{r}' '{o}{t}{a}{t}' '{u}{t}{e}{r}' '{u}{t}{a}{t}' '{oo}{t}{e}{r}' '{oo}{t}{a}{t}' (delete)
+    )
+  )
+)
+
+define stem as (
+    backwards (
+      do tolower
+      has_min_length
+      set test1
+      do step1
+      do steps1
+      do steps2
+      do steps3
+      do steps4
+      do steps5
+      do steps6
+      do steps7
+      do steps8
+      do steps9
+      do steps10
+      do step2a
+      do step2b
+      do step2c
+      do step2d
+      do step3
+      do step4
+      do step5a
+      do step5b
+      do step5c
+      do step5d
+      do step5e
+      do step5f
+      do step5g
+      do step5h
+      do step5j
+      do step5i
+      do step5k
+      do step5l
+      do step5m
+      do step6
+      do step7
+    )
+)
diff --git a/algorithms/hungarian.sbl b/algorithms/hungarian.sbl
new file mode 100644
index 0000000..c812e05
--- /dev/null
+++ b/algorithms/hungarian.sbl
@@ -0,0 +1,241 @@
+/*
+Hungarian Stemmer
+Removes noun inflections
+*/
+
+routines (
+    mark_regions
+    R1
+    v_ending
+    case
+    case_special
+    case_other
+    plural
+    owned
+    sing_owner
+    plur_owner
+    instrum
+    factive
+    undouble
+    double
+)
+
+externals ( stem )
+
+integers ( p1 )
+groupings ( v )
+
+stringescapes {}
+
+/* special characters (in Unicode) */
+
+stringdef a'  hex 'E1'  //a-acute
+stringdef e'  hex 'E9'  //e-acute
+stringdef i'  hex 'ED'  //i-acute
+stringdef o'  hex 'F3'  //o-acute
+stringdef o"  hex 'F6'  //o-umlaut
+stringdef oq  hex '151' //o-double acute
+stringdef u'  hex 'FA'  //u-acute
+stringdef u"  hex 'FC'  //u-umlaut
+stringdef uq  hex '171' //u-double acute
+
+define v 'aeiou{a'}{e'}{i'}{o'}{o"}{oq}{u'}{u"}{uq}'
+
+define mark_regions as (
+
+    $p1 = limit
+
+    (v goto non-v
+     among('cs' 'gy' 'ly' 'ny' 'sz' 'ty' 'zs' 'dzs') or next
+     setmark p1)
+    or
+
+    (non-v gopast v setmark p1)
+)
+
+backwardmode (
+
+    define R1 as $p1 <= cursor
+
+    define v_ending as (
+        [substring] R1 among(
+            '{a'}' (<- 'a')
+            '{e'}' (<- 'e')
+        )
+    )
+
+    define double as (
+        test among('bb' 'cc' 'ccs' 'dd' 'ff' 'gg' 'ggy' 'jj' 'kk' 'll' 'lly' 'mm'
+        'nn' 'nny' 'pp' 'rr' 'ss' 'ssz' 'tt' 'tty' 'vv' 'zz' 'zzs')
+    )
+
+    define undouble as (
+        next [hop 1] delete
+    )
+
+    define instrum as(
+        [substring] R1 among(
+            'al' (double)
+            'el' (double)
+        )
+        delete
+        undouble
+    )
+
+
+    define case as (
+        [substring] R1 among(
+            'ban' 'ben'
+            'ba' 'be'
+            'ra' 're'
+            'nak' 'nek'
+            'val' 'vel'
+            't{o'}l' 't{oq}l'
+            'r{o'}l' 'r{oq}l'
+            'b{o'}l' 'b{oq}l'
+            'hoz' 'hez' 'h{o"}z'
+            'n{a'}l' 'n{e'}l'
+            'ig'
+            'at' 'et' 'ot' '{o"}t'
+            '{e'}rt'
+            'k{e'}pp' 'k{e'}ppen'
+            'kor'
+            'ul' '{u"}l'
+            'v{a'}' 'v{e'}'
+            'onk{e'}nt' 'enk{e'}nt' 'ank{e'}nt'
+            'k{e'}nt'
+            'en' 'on' 'an' '{o"}n'
+            'n'
+            't'
+        )
+        delete
+        v_ending
+    )
+
+    define case_special as(
+        [substring] R1 among(
+            '{e'}n' (<- 'e')
+            '{a'}n' (<- 'a')
+            '{a'}nk{e'}nt' (<- 'a')
+        )
+    )
+
+    define case_other as(
+        [substring] R1 among(
+            'astul' 'est{u"}l' (delete)
+            'stul' 'st{u"}l' (delete)
+            '{a'}stul' (<- 'a')
+            '{e'}st{u"}l' (<- 'e')
+        )
+    )
+
+    define factive as(
+        [substring] R1 among(
+            '{a'}' (double)
+            '{e'}' (double)
+        )
+        delete
+        undouble
+    )
+
+    define plural as (
+        [substring] R1 among(
+            '{a'}k' (<- 'a')
+            '{e'}k' (<- 'e')
+            '{o"}k' (delete)
+            'ak' (delete)
+            'ok' (delete)
+            'ek' (delete)
+            'k' (delete)
+        )
+    )
+
+    define owned as (
+        [substring] R1 among (
+            'ok{e'}' '{o"}k{e'}' 'ak{e'}' 'ek{e'}' (delete)
+            '{e'}k{e'}' (<- 'e')
+            '{a'}k{e'}' (<- 'a')
+            'k{e'}' (delete)
+            '{e'}{e'}i' (<- 'e')
+            '{a'}{e'}i' (<- 'a')
+            '{e'}i'  (delete)
+            '{e'}{e'}' (<- 'e')
+            '{e'}' (delete)
+        )
+    )
+
+    define sing_owner as (
+        [substring] R1 among(
+            '{u"}nk' 'unk' (delete)
+            '{a'}nk' (<- 'a')
+            '{e'}nk' (<- 'e')
+            'nk' (delete)
+            '{a'}juk' (<- 'a')
+            '{e'}j{u"}k' (<- 'e')
+            'juk' 'j{u"}k' (delete)
+            'uk' '{u"}k' (delete)
+            'em' 'om' 'am' (delete)
+            '{a'}m' (<- 'a')
+            '{e'}m' (<- 'e')
+            'm' (delete)
+            'od' 'ed' 'ad' '{o"}d' (delete)
+            '{a'}d' (<- 'a')
+            '{e'}d' (<- 'e')
+            'd' (delete)
+            'ja' 'je' (delete)
+            'a' 'e' 'o' (delete)
+            '{a'}' (<- 'a')
+            '{e'}' (<- 'e')
+        )
+    )
+
+    define plur_owner as (
+        [substring] R1 among(
+            'jaim' 'jeim' (delete)
+            '{a'}im' (<- 'a')
+            '{e'}im' (<- 'e')
+            'aim' 'eim' (delete)
+            'im' (delete)
+            'jaid' 'jeid' (delete)
+            '{a'}id' (<- 'a')
+            '{e'}id' (<- 'e')
+            'aid' 'eid' (delete)
+            'id' (delete)
+            'jai' 'jei' (delete)
+            '{a'}i' (<- 'a')
+            '{e'}i' (<- 'e')
+            'ai' 'ei' (delete)
+            'i' (delete)
+            'jaink' 'jeink' (delete)
+            'eink' 'aink' (delete)
+            '{a'}ink' (<- 'a')
+            '{e'}ink' (<- 'e')
+            'ink'
+            'jaitok' 'jeitek' (delete)
+            'aitok' 'eitek' (delete)
+            '{a'}itok' (<- 'a')
+            '{e'}itek' (<- 'e')
+            'itek' (delete)
+            'jeik' 'jaik' (delete)
+            'aik' 'eik' (delete)
+            '{a'}ik' (<- 'a')
+            '{e'}ik' (<- 'e')
+            'ik' (delete)
+        )
+    )
+)
+
+define stem as (
+    do mark_regions
+    backwards (
+      do instrum
+        do case
+        do case_special
+        do case_other
+        do factive
+        do owned
+        do sing_owner
+        do plur_owner
+        do plural
+    )
+)
diff --git a/algorithms/italian.sbl b/algorithms/italian.sbl
new file mode 100644
index 0000000..e72278b
--- /dev/null
+++ b/algorithms/italian.sbl
@@ -0,0 +1,193 @@
+routines (
+           prelude postlude mark_regions
+           RV R1 R2
+           attached_pronoun
+           standard_suffix
+           verb_suffix
+           vowel_suffix
+)
+
+externals ( stem )
+
+integers ( pV p1 p2 )
+
+groupings ( v AEIO CG )
+
+stringescapes {}
+
+/* special characters (in ISO Latin I) */
+
+stringdef a'   hex 'E1'
+stringdef a`   hex 'E0'
+stringdef e'   hex 'E9'
+stringdef e`   hex 'E8'
+stringdef i'   hex 'ED'
+stringdef i`   hex 'EC'
+stringdef o'   hex 'F3'
+stringdef o`   hex 'F2'
+stringdef u'   hex 'FA'
+stringdef u`   hex 'F9'
+
+define v 'aeiou{a`}{e`}{i`}{o`}{u`}'
+
+define prelude as (
+    test repeat (
+        [substring] among(
+            '{a'}' (<- '{a`}')
+            '{e'}' (<- '{e`}')
+            '{i'}' (<- '{i`}')
+            '{o'}' (<- '{o`}')
+            '{u'}' (<- '{u`}')
+            'qu'   (<- 'qU')
+            ''     (next)
+        )
+    )
+    repeat goto (
+        v [ ('u' ] v <- 'U') or
+            ('i' ] v <- 'I')
+    )
+)
+
+define mark_regions as (
+
+    $pV = limit
+    $p1 = limit
+    $p2 = limit // defaults
+
+    do (
+        ( v (non-v gopast v) or (v gopast non-v) )
+        or
+        ( non-v (non-v gopast v) or (v next) )
+        setmark pV
+    )
+    do (
+        gopast v gopast non-v setmark p1
+        gopast v gopast non-v setmark p2
+    )
+)
+
+define postlude as repeat (
+
+    [substring] among(
+        'I'  (<- 'i')
+        'U'  (<- 'u')
+        ''   (next)
+    )
+
+)
+
+backwardmode (
+
+    define RV as $pV <= cursor
+    define R1 as $p1 <= cursor
+    define R2 as $p2 <= cursor
+
+    define attached_pronoun as (
+        [substring] among(
+            'ci' 'gli' 'la' 'le' 'li' 'lo'
+            'mi' 'ne' 'si'  'ti' 'vi'
+            // the compound forms are:
+            'sene' 'gliela' 'gliele' 'glieli' 'glielo' 'gliene'
+            'mela' 'mele' 'meli' 'melo' 'mene'
+            'tela' 'tele' 'teli' 'telo' 'tene'
+            'cela' 'cele' 'celi' 'celo' 'cene'
+            'vela' 'vele' 'veli' 'velo' 'vene'
+        )
+        among( (RV)
+            'ando' 'endo'   (delete)
+            'ar' 'er' 'ir'  (<- 'e')
+        )
+    )
+
+    define standard_suffix as (
+        [substring] among(
+
+            'anza' 'anze' 'ico' 'ici' 'ica' 'ice' 'iche' 'ichi' 'ismo'
+            'ismi' 'abile' 'abili' 'ibile' 'ibili' 'ista' 'iste' 'isti'
+            'ist{a`}' 'ist{e`}' 'ist{i`}' 'oso' 'osi' 'osa' 'ose' 'mente'
+            'atrice' 'atrici'
+            'ante' 'anti' // Note 1
+               ( R2 delete )
+            'azione' 'azioni' 'atore' 'atori'
+               ( R2 delete
+                 try ( ['ic'] R2 delete )
+               )
+            'logia' 'logie'
+               ( R2 <- 'log' )
+            'uzione' 'uzioni' 'usione' 'usioni'
+               ( R2 <- 'u' )
+            'enza' 'enze'
+               ( R2 <- 'ente' )
+            'amento' 'amenti' 'imento' 'imenti'
+               ( RV delete )
+            'amente' (
+                R1 delete
+                try (
+                    [substring] R2 delete among(
+                        'iv' ( ['at'] R2 delete )
+                        'os' 'ic' 'abil'
+                    )
+                )
+            )
+            'it{a`}' (
+                R2 delete
+                try (
+                    [substring] among(
+                        'abil' 'ic' 'iv' (R2 delete)
+                    )
+                )
+            )
+            'ivo' 'ivi' 'iva' 'ive' (
+                R2 delete
+                try ( ['at'] R2 delete ['ic'] R2 delete )
+            )
+        )
+    )
+
+    define verb_suffix as setlimit tomark pV for (
+        [substring] among(
+            'ammo' 'ando' 'ano' 'are' 'arono' 'asse' 'assero' 'assi'
+            'assimo' 'ata' 'ate' 'ati' 'ato' 'ava' 'avamo' 'avano' 'avate'
+            'avi' 'avo' 'emmo' 'enda' 'ende' 'endi' 'endo' 'er{a`}' 'erai'
+            'eranno' 'ere' 'erebbe' 'erebbero' 'erei' 'eremmo' 'eremo'
+            'ereste' 'eresti' 'erete' 'er{o`}' 'erono' 'essero' 'ete'
+            'eva' 'evamo' 'evano' 'evate' 'evi' 'evo' 'Yamo' 'iamo' 'immo'
+            'ir{a`}' 'irai' 'iranno' 'ire' 'irebbe' 'irebbero' 'irei'
+            'iremmo' 'iremo' 'ireste' 'iresti' 'irete' 'ir{o`}' 'irono'
+            'isca' 'iscano' 'isce' 'isci' 'isco' 'iscono' 'issero' 'ita'
+            'ite' 'iti' 'ito' 'iva' 'ivamo' 'ivano' 'ivate' 'ivi' 'ivo'
+            'ono' 'uta' 'ute' 'uti' 'uto'
+
+            'ar' 'ir' // but 'er' is problematical
+                (delete)
+        )
+    )
+
+    define AEIO 'aeio{a`}{e`}{i`}{o`}'
+    define CG 'cg'
+
+    define vowel_suffix as (
+        try (
+            [AEIO] RV delete
+            ['i'] RV delete
+        )
+        try (
+            ['h'] CG RV delete
+        )
+    )
+)
+
+define stem as (
+    do prelude
+    do mark_regions
+    backwards (
+        do attached_pronoun
+        do (standard_suffix or verb_suffix)
+        do vowel_suffix
+    )
+    do postlude
+)
+
+/*
+    Note 1: additions of 15 Jun 2005
+*/
\ No newline at end of file
diff --git a/algorithms/norwegian.sbl b/algorithms/norwegian.sbl
new file mode 100644
index 0000000..39f4aff
--- /dev/null
+++ b/algorithms/norwegian.sbl
@@ -0,0 +1,80 @@
+routines (
+           mark_regions
+           main_suffix
+           consonant_pair
+           other_suffix
+)
+
+externals ( stem )
+
+integers ( p1 x )
+
+groupings ( v s_ending )
+
+stringescapes {}
+
+/* special characters */
+
+stringdef ae   '{U+00E6}'
+stringdef ao   '{U+00E5}'
+stringdef o/   '{U+00F8}'
+
+define v 'aeiouy{ae}{ao}{o/}'
+
+define s_ending  'bcdfghjlmnoprtvyz'
+
+define mark_regions as (
+
+    $p1 = limit
+
+    test ( hop 3 setmark x )
+    goto v  gopast non-v  setmark p1
+    try ( $p1 < x  $p1 = x )
+)
+
+backwardmode (
+
+    define main_suffix as (
+        setlimit tomark p1 for ([substring])
+        among(
+
+            'a' 'e' 'ede' 'ande' 'ende' 'ane' 'ene' 'hetene' 'en' 'heten' 'ar'
+            'er' 'heter' 'as' 'es' 'edes' 'endes' 'enes' 'hetenes' 'ens'
+            'hetens' 'ers' 'ets' 'et' 'het' 'ast'
+                (delete)
+            's'
+                (s_ending or ('k' non-v) delete)
+            'erte' 'ert'
+                (<-'er')
+        )
+    )
+
+    define consonant_pair as (
+        test (
+            setlimit tomark p1 for ([substring])
+            among(
+                'dt' 'vt'
+            )
+        )
+        next] delete
+    )
+
+    define other_suffix as (
+        setlimit tomark p1 for ([substring])
+        among(
+            'leg' 'eleg' 'ig' 'eig' 'lig' 'elig' 'els' 'lov' 'elov' 'slov'
+            'hetslov'
+                (delete)
+        )
+    )
+)
+
+define stem as (
+
+    do mark_regions
+    backwards (
+        do main_suffix
+        do consonant_pair
+        do other_suffix
+    )
+)
diff --git a/algorithms/portuguese.sbl b/algorithms/portuguese.sbl
new file mode 100644
index 0000000..03b76bb
--- /dev/null
+++ b/algorithms/portuguese.sbl
@@ -0,0 +1,218 @@
+routines (
+           prelude postlude mark_regions
+           RV R1 R2
+           standard_suffix
+           verb_suffix
+           residual_suffix
+           residual_form
+)
+
+externals ( stem )
+
+integers ( pV p1 p2 )
+
+groupings ( v )
+
+stringescapes {}
+
+/* special characters (in ISO Latin I) */
+
+stringdef a'   hex 'E1'  // a-acute
+stringdef a^   hex 'E2'  // a-circumflex e.g. 'bota^nico
+stringdef e'   hex 'E9'  // e-acute
+stringdef e^   hex 'EA'  // e-circumflex
+stringdef i'   hex 'ED'  // i-acute
+stringdef o^   hex 'F4'  // o-circumflex
+stringdef o'   hex 'F3'  // o-acute
+stringdef u'   hex 'FA'  // u-acute
+stringdef c,   hex 'E7'  // c-cedilla
+
+stringdef a~   hex 'E3'  // a-tilde
+stringdef o~   hex 'F5'  // o-tilde
+
+
+define v 'aeiou{a'}{e'}{i'}{o'}{u'}{a^}{e^}{o^}'
+
+define prelude as repeat (
+    [substring] among(
+        '{a~}' (<- 'a~')
+        '{o~}' (<- 'o~')
+        ''     (next)
+    ) //or next
+)
+
+define mark_regions as (
+
+    $pV = limit
+    $p1 = limit
+    $p2 = limit  // defaults
+
+    do (
+        ( v (non-v gopast v) or (v gopast non-v) )
+        or
+        ( non-v (non-v gopast v) or (v next) )
+        setmark pV
+    )
+    do (
+        gopast v gopast non-v setmark p1
+        gopast v gopast non-v setmark p2
+    )
+)
+
+define postlude as repeat (
+    [substring] among(
+        'a~' (<- '{a~}')
+        'o~' (<- '{o~}')
+        ''   (next)
+    ) //or next
+)
+
+backwardmode (
+
+    define RV as $pV <= cursor
+    define R1 as $p1 <= cursor
+    define R2 as $p2 <= cursor
+
+    define standard_suffix as (
+        [substring] among(
+
+            'eza' 'ezas'
+            'ico' 'ica' 'icos' 'icas'
+            'ismo' 'ismos'
+            '{a'}vel'
+            '{i'}vel'
+            'ista' 'istas'
+            'oso' 'osa' 'osos' 'osas'
+            'amento' 'amentos'
+            'imento' 'imentos'
+
+           'adora' 'ador' 'a{c,}a~o'
+           'adoras' 'adores' 'a{c,}o~es'  // no -ic test
+           'ante' 'antes' '{a^}ncia' // Note 1
+            (
+                R2 delete
+            )
+            'logia'
+            'logias'
+            (
+                R2 <- 'log'
+            )
+            'u{c,}a~o' 'u{c,}o~es'
+            (
+                R2 <- 'u'
+            )
+            '{e^}ncia' '{e^}ncias'
+            (
+                R2 <- 'ente'
+            )
+            'amente'
+            (
+                R1 delete
+                try (
+                    [substring] R2 delete among(
+                        'iv' (['at'] R2 delete)
+                        'os'
+                        'ic'
+                        'ad'
+                    )
+                )
+            )
+            'mente'
+            (
+                R2 delete
+                try (
+                    [substring] among(
+                        'ante' // Note 1
+                        'avel'
+                        '{i'}vel' (R2 delete)
+                    )
+                )
+            )
+            'idade'
+            'idades'
+            (
+                R2 delete
+                try (
+                    [substring] among(
+                        'abil'
+                        'ic'
+                        'iv'   (R2 delete)
+                    )
+                )
+            )
+            'iva' 'ivo'
+            'ivas' 'ivos'
+            (
+                R2 delete
+                try (
+                    ['at'] R2 delete // but not a further   ['ic'] R2 delete
+                )
+            )
+            'ira' 'iras'
+            (
+                RV 'e'  // -eira -eiras usually non-verbal
+                <- 'ir'
+            )
+        )
+    )
+
+    define verb_suffix as setlimit tomark pV for (
+        [substring] among(
+            'ada' 'ida' 'ia' 'aria' 'eria' 'iria' 'ar{a'}' 'ara' 'er{a'}'
+            'era' 'ir{a'}' 'ava' 'asse' 'esse' 'isse' 'aste' 'este' 'iste'
+            'ei' 'arei' 'erei' 'irei' 'am' 'iam' 'ariam' 'eriam' 'iriam'
+            'aram' 'eram' 'iram' 'avam' 'em' 'arem' 'erem' 'irem' 'assem'
+            'essem' 'issem' 'ado' 'ido' 'ando' 'endo' 'indo' 'ara~o'
+            'era~o' 'ira~o' 'ar' 'er' 'ir' 'as' 'adas' 'idas' 'ias'
+            'arias' 'erias' 'irias' 'ar{a'}s' 'aras' 'er{a'}s' 'eras'
+            'ir{a'}s' 'avas' 'es' 'ardes' 'erdes' 'irdes' 'ares' 'eres'
+            'ires' 'asses' 'esses' 'isses' 'astes' 'estes' 'istes' 'is'
+            'ais' 'eis' '{i'}eis' 'ar{i'}eis' 'er{i'}eis' 'ir{i'}eis'
+            '{a'}reis' 'areis' '{e'}reis' 'ereis' '{i'}reis' 'ireis'
+            '{a'}sseis' '{e'}sseis' '{i'}sseis' '{a'}veis' 'ados' 'idos'
+            '{a'}mos' 'amos' '{i'}amos' 'ar{i'}amos' 'er{i'}amos'
+            'ir{i'}amos' '{a'}ramos' '{e'}ramos' '{i'}ramos' '{a'}vamos'
+            'emos' 'aremos' 'eremos' 'iremos' '{a'}ssemos' '{e^}ssemos'
+            '{i'}ssemos' 'imos' 'armos' 'ermos' 'irmos' 'eu' 'iu' 'ou'
+
+            'ira' 'iras'
+                (delete)
+        )
+    )
+
+    define residual_suffix as (
+        [substring] among(
+            'os'
+            'a' 'i' 'o' '{a'}' '{i'}' '{o'}'
+                ( RV delete )
+        )
+    )
+
+    define residual_form as (
+        [substring] among(
+            'e' '{e'}' '{e^}'
+                ( RV delete [('u'] test 'g') or
+                             ('i'] test 'c') RV delete )
+            '{c,}' (<-'c')
+        )
+    )
+)
+
+define stem as (
+    do prelude
+    do mark_regions
+    backwards (
+        do (
+            ( ( standard_suffix or verb_suffix )
+              and do ( ['i'] test 'c' RV delete )
+            )
+            or residual_suffix
+        )
+        do residual_form
+    )
+    do postlude
+)
+
+/*
+    Note 1: additions of 15 Jun 2005
+*/
\ No newline at end of file
diff --git a/algorithms/romanian.sbl b/algorithms/romanian.sbl
new file mode 100644
index 0000000..4844423
--- /dev/null
+++ b/algorithms/romanian.sbl
@@ -0,0 +1,234 @@
+routines (
+           prelude postlude mark_regions
+           RV R1 R2
+           step_0
+           standard_suffix combo_suffix
+           verb_suffix
+           vowel_suffix
+)
+
+externals ( stem )
+
+integers ( pV p1 p2 )
+
+groupings ( v )
+
+booleans  ( standard_suffix_removed )
+
+stringescapes {}
+
+/* special characters */
+
+stringdef a^   hex '0E2'  // a circumflex
+stringdef i^   hex '0EE'  // i circumflex
+stringdef a+   hex '103'  // a breve
+stringdef s,   hex '15F'  // s cedilla
+stringdef t,   hex '163'  // t cedilla
+
+define v 'aeiou{a^}{i^}{a+}'
+
+define prelude as (
+    repeat goto (
+        v [ ('u' ] v <- 'U') or
+            ('i' ] v <- 'I')
+    )
+)
+
+define mark_regions as (
+
+    $pV = limit
+    $p1 = limit
+    $p2 = limit // defaults
+
+    do (
+        ( v (non-v gopast v) or (v gopast non-v) )
+        or
+        ( non-v (non-v gopast v) or (v next) )
+        setmark pV
+    )
+    do (
+        gopast v gopast non-v setmark p1
+        gopast v gopast non-v setmark p2
+    )
+)
+
+define postlude as repeat (
+
+    [substring] among(
+        'I'  (<- 'i')
+        'U'  (<- 'u')
+        ''   (next)
+    )
+
+)
+
+backwardmode (
+
+    define RV as $pV <= cursor
+    define R1 as $p1 <= cursor
+    define R2 as $p2 <= cursor
+
+    define step_0 as (
+        [substring] R1 among(
+            'ul' 'ului'
+                ( delete )
+            'aua'
+                ( <-'a' )
+            'ea' 'ele' 'elor'
+                ( <-'e' )
+            'ii' 'iua' 'iei' 'iile' 'iilor' 'ilor'
+                ( <-'i')
+            'ile'
+                ( not 'ab' <- 'i' )
+            'atei'
+                ( <- 'at' )
+            'a{t,}ie' 'a{t,}ia'
+                ( <- 'a{t,}i' )
+        )
+    )
+
+    define combo_suffix as test (
+        [substring] R1 (
+            among(
+            /* 'IST'. alternative: include the following
+                'alism' 'alisme'
+                'alist' 'alista' 'aliste' 'alisti' 'alist{a+}' 'ali{s,}ti' (
+                    <- 'al'
+                )
+            */
+                'abilitate' 'abilitati' 'abilit{a+}i' 'abilit{a+}{t,}i' (
+                    <- 'abil'
+                )
+                'ibilitate' (
+                    <- 'ibil'
+                )
+                'ivitate' 'ivitati' 'ivit{a+}i' 'ivit{a+}{t,}i' (
+                    <- 'iv'
+                )
+                'icitate' 'icitati' 'icit{a+}i' 'icit{a+}{t,}i'
+                'icator' 'icatori'
+                'iciv' 'iciva' 'icive' 'icivi' 'iciv{a+}'
+                'ical' 'icala' 'icale' 'icali' 'ical{a+}' (
+                    <- 'ic'
+                )
+                'ativ' 'ativa' 'ative' 'ativi' 'ativ{a+}' 'a{t,}iune'
+                'atoare' 'ator' 'atori'
+                '{a+}toare' '{a+}tor' '{a+}tori' (
+                    <- 'at'
+                )
+                'itiv' 'itiva' 'itive' 'itivi' 'itiv{a+}' 'i{t,}iune'
+                'itoare' 'itor' 'itori' (
+                    <- 'it'
+                )
+            )
+            set standard_suffix_removed
+        )
+    )
+
+    define standard_suffix as (
+        unset standard_suffix_removed
+        repeat combo_suffix
+        [substring] R2 (
+            among(
+
+                // past participle is treated here, rather than
+                // as a verb ending:
+                'at' 'ata' 'at{a+}' 'ati' 'ate'
+                'ut' 'uta' 'ut{a+}' 'uti' 'ute'
+                'it' 'ita' 'it{a+}' 'iti' 'ite'
+
+                'ic' 'ica' 'ice' 'ici' 'ic{a+}'
+                'abil' 'abila' 'abile' 'abili' 'abil{a+}'
+                'ibil' 'ibila' 'ibile' 'ibili' 'ibil{a+}'
+                'oasa' 'oas{a+}' 'oase' 'os' 'osi' 'o{s,}i'
+                'ant' 'anta' 'ante' 'anti' 'ant{a+}'
+                'ator' 'atori'
+                'itate' 'itati' 'it{a+}i' 'it{a+}{t,}i'
+                'iv' 'iva' 'ive' 'ivi' 'iv{a+}' (
+                    delete
+                )
+                'iune' 'iuni' (
+                    '{t,}'] <- 't'
+                )
+                'ism' 'isme'
+                'ist' 'ista' 'iste' 'isti' 'ist{a+}' 'i{s,}ti' (
+                    <- 'ist'
+                    /* 'IST'. alternative: remove with <- '' */
+                )
+            )
+            set standard_suffix_removed
+        )
+    )
+
+    define verb_suffix as setlimit tomark pV for (
+        [substring] among(
+            // 'long' infinitive:
+            'are' 'ere' 'ire' '{a^}re'
+
+            // gerund:
+            'ind' '{a^}nd'
+            'indu' '{a^}ndu'
+
+            'eze'
+            'easc{a+}'
+            // present:
+            'ez' 'ezi' 'eaz{a+}' 'esc' 'e{s,}ti'
+            'e{s,}te'
+            '{a+}sc' '{a+}{s,}ti'
+            '{a+}{s,}te'
+
+            // imperfect:
+            'am' 'ai' 'au'
+            'eam' 'eai' 'ea' 'ea{t,}i' 'eau'
+            'iam' 'iai' 'ia' 'ia{t,}i' 'iau'
+
+            // past: // (not 'ii')
+            'ui'
+            'a{s,}i' 'ar{a+}m' 'ar{a+}{t,}i' 'ar{a+}'
+            'u{s,}i' 'ur{a+}m' 'ur{a+}{t,}i' 'ur{a+}'
+            'i{s,}i' 'ir{a+}m' 'ir{a+}{t,}i' 'ir{a+}'
+            '{a^}i' '{a^}{s,}i' '{a^}r{a+}m' '{a^}r{a+}{t,}i' '{a^}r{a+}'
+
+            // pluferfect:
+            'asem' 'ase{s,}i' 'ase' 'aser{a+}m' 'aser{a+}{t,}i' 'aser{a+}'
+            'isem' 'ise{s,}i' 'ise' 'iser{a+}m' 'iser{a+}{t,}i' 'iser{a+}'
+            '{a^}sem' '{a^}se{s,}i' '{a^}se' '{a^}ser{a+}m' '{a^}ser{a+}{t,}i'
+            '{a^}ser{a+}'
+            'usem' 'use{s,}i' 'use' 'user{a+}m' 'user{a+}{t,}i' 'user{a+}'
+
+                ( non-v or 'u'  delete )
+
+            // present:
+            '{a+}m' 'a{t,}i'
+            'em' 'e{t,}i'
+            'im' 'i{t,}i'
+            '{a^}m' '{a^}{t,}i'
+
+            // past:
+            'se{s,}i' 'ser{a+}m' 'ser{a+}{t,}i' 'ser{a+}'
+            'sei' 'se'
+
+            // pluperfect:
+            'sesem' 'sese{s,}i' 'sese' 'seser{a+}m' 'seser{a+}{t,}i' 'seser{a+}'
+                (delete)
+        )
+    )
+
+    define vowel_suffix as (
+        [substring] RV among (
+            'a' 'e' 'i' 'ie' '{a+}' ( delete )
+        )
+    )
+)
+
+define stem as (
+    do prelude
+    do mark_regions
+    backwards (
+        do step_0
+        do standard_suffix
+        do ( standard_suffix_removed or verb_suffix )
+        do vowel_suffix
+    )
+    do postlude
+)
\ No newline at end of file
diff --git a/algorithms/russian.sbl b/algorithms/russian.sbl
new file mode 100644
index 0000000..b836b1a
--- /dev/null
+++ b/algorithms/russian.sbl
@@ -0,0 +1,215 @@
+stringescapes {}
+
+/* the 32 Cyrillic letters in Unicode */
+
+stringdef a    hex '430'
+stringdef b    hex '431'
+stringdef v    hex '432'
+stringdef g    hex '433'
+stringdef d    hex '434'
+stringdef e    hex '435'
+stringdef zh   hex '436'
+stringdef z    hex '437'
+stringdef i    hex '438'
+stringdef i`   hex '439'
+stringdef k    hex '43A'
+stringdef l    hex '43B'
+stringdef m    hex '43C'
+stringdef n    hex '43D'
+stringdef o    hex '43E'
+stringdef p    hex '43F'
+stringdef r    hex '440'
+stringdef s    hex '441'
+stringdef t    hex '442'
+stringdef u    hex '443'
+stringdef f    hex '444'
+stringdef kh   hex '445'
+stringdef ts   hex '446'
+stringdef ch   hex '447'
+stringdef sh   hex '448'
+stringdef shch hex '449'
+stringdef "    hex '44A'
+stringdef y    hex '44B'
+stringdef '    hex '44C'
+stringdef e`   hex '44D'
+stringdef iu   hex '44E'
+stringdef ia   hex '44F'
+
+routines ( mark_regions R2
+           perfective_gerund
+           adjective
+           adjectival
+           reflexive
+           verb
+           noun
+           derivational
+           tidy_up
+)
+
+externals ( stem )
+
+integers ( pV p2 )
+
+groupings ( v )
+
+define v '{a}{e}{i}{o}{u}{y}{e`}{iu}{ia}'
+
+define mark_regions as (
+
+    $pV = limit
+    $p2 = limit
+    do (
+        gopast v  setmark pV  gopast non-v
+        gopast v  gopast non-v  setmark p2
+       )
+)
+
+backwardmode (
+
+    define R2 as $p2 <= cursor
+
+    define perfective_gerund as (
+        [substring] among (
+            '{v}'
+            '{v}{sh}{i}'
+            '{v}{sh}{i}{s}{'}'
+                ('{a}' or '{ia}' delete)
+            '{i}{v}'
+            '{i}{v}{sh}{i}'
+            '{i}{v}{sh}{i}{s}{'}'
+            '{y}{v}'
+            '{y}{v}{sh}{i}'
+            '{y}{v}{sh}{i}{s}{'}'
+                (delete)
+        )
+    )
+
+    define adjective as (
+        [substring] among (
+            '{e}{e}' '{i}{e}' '{y}{e}' '{o}{e}' '{i}{m}{i}' '{y}{m}{i}'
+            '{e}{i`}' '{i}{i`}' '{y}{i`}' '{o}{i`}' '{e}{m}' '{i}{m}'
+            '{y}{m}' '{o}{m}' '{e}{g}{o}' '{o}{g}{o}' '{e}{m}{u}'
+            '{o}{m}{u}' '{i}{kh}' '{y}{kh}' '{u}{iu}' '{iu}{iu}' '{a}{ia}'
+            '{ia}{ia}'
+                        // and -
+            '{o}{iu}'   // - which is somewhat archaic
+            '{e}{iu}'   // - soft form of {o}{iu}
+                (delete)
+        )
+    )
+
+    define adjectival as (
+        adjective
+
+        /* of the participle forms, em, vsh, ivsh, yvsh are readily removable.
+           nn, {iu}shch, shch, u{iu}shch can be removed, with a small proportion of
+           errors. Removing im, uem, enn creates too many errors.
+        */
+
+        try (
+            [substring] among (
+                '{e}{m}'                  // present passive participle
+                '{n}{n}'                  // adjective from past passive participle
+                '{v}{sh}'                 // past active participle
+                '{iu}{shch}' '{shch}'     // present active participle
+                    ('{a}' or '{ia}' delete)
+
+     //but not  '{i}{m}' '{u}{e}{m}'      // present passive participle
+     //or       '{e}{n}{n}'               // adjective from past passive participle
+
+                '{i}{v}{sh}' '{y}{v}{sh}'// past active participle
+                '{u}{iu}{shch}'          // present active participle
+                    (delete)
+            )
+        )
+
+    )
+
+    define reflexive as (
+        [substring] among (
+            '{s}{ia}'
+            '{s}{'}'
+                (delete)
+        )
+    )
+
+    define verb as (
+        [substring] among (
+            '{l}{a}' '{n}{a}' '{e}{t}{e}' '{i`}{t}{e}' '{l}{i}' '{i`}'
+            '{l}' '{e}{m}' '{n}' '{l}{o}' '{n}{o}' '{e}{t}' '{iu}{t}'
+            '{n}{y}' '{t}{'}' '{e}{sh}{'}'
+
+            '{n}{n}{o}'
+                ('{a}' or '{ia}' delete)
+
+            '{i}{l}{a}' '{y}{l}{a}' '{e}{n}{a}' '{e}{i`}{t}{e}'
+            '{u}{i`}{t}{e}' '{i}{t}{e}' '{i}{l}{i}' '{y}{l}{i}' '{e}{i`}'
+            '{u}{i`}' '{i}{l}' '{y}{l}' '{i}{m}' '{y}{m}' '{e}{n}'
+            '{i}{l}{o}' '{y}{l}{o}' '{e}{n}{o}' '{ia}{t}' '{u}{e}{t}'
+            '{u}{iu}{t}' '{i}{t}' '{y}{t}' '{e}{n}{y}' '{i}{t}{'}'
+            '{y}{t}{'}' '{i}{sh}{'}' '{u}{iu}' '{iu}'
+                (delete)
+            /* note the short passive participle tests:
+               '{n}{a}' '{n}' '{n}{o}' '{n}{y}'
+               '{e}{n}{a}' '{e}{n}' '{e}{n}{o}' '{e}{n}{y}'
+            */
+        )
+    )
+
+    define noun as (
+        [substring] among (
+            '{a}' '{e}{v}' '{o}{v}' '{i}{e}' '{'}{e}' '{e}'
+            '{i}{ia}{m}{i}' '{ia}{m}{i}' '{a}{m}{i}' '{e}{i}' '{i}{i}'
+            '{i}' '{i}{e}{i`}' '{e}{i`}' '{o}{i`}' '{i}{i`}' '{i`}'
+            '{i}{ia}{m}' '{ia}{m}' '{i}{e}{m}' '{e}{m}' '{a}{m}' '{o}{m}'
+            '{o}' '{u}' '{a}{kh}' '{i}{ia}{kh}' '{ia}{kh}' '{y}' '{'}'
+            '{i}{iu}' '{'}{iu}' '{iu}' '{i}{ia}' '{'}{ia}' '{ia}'
+                (delete)
+            /* the small class of neuter forms '{e}{n}{i}' '{e}{n}{e}{m}'
+               '{e}{n}{a}' '{e}{n}' '{e}{n}{a}{m}' '{e}{n}{a}{m}{i}' '{e}{n}{a}{x}'
+               omitted - they only occur on 12 words.
+            */
+        )
+    )
+
+    define derivational as (
+        [substring] R2 among (
+            '{o}{s}{t}'
+            '{o}{s}{t}{'}'
+                (delete)
+        )
+    )
+
+    define tidy_up as (
+        [substring] among (
+
+            '{e}{i`}{sh}'
+            '{e}{i`}{sh}{e}'  // superlative forms
+               (delete
+                ['{n}'] '{n}' delete
+               )
+            '{n}'
+               ('{n}' delete) // e.g. -nno endings
+            '{'}'
+               (delete)  // with some slight false conflations
+        )
+    )
+)
+
+define stem as (
+
+    do mark_regions
+    backwards setlimit tomark pV for (
+        do (
+             perfective_gerund or
+             ( try reflexive
+               adjectival or verb or noun
+             )
+        )
+        try([ '{i}' ] delete)
+        // because noun ending -i{iu} is being treated as verb ending -{iu}
+
+        do derivational
+        do tidy_up
+    )
+)
\ No newline at end of file
diff --git a/algorithms/spanish.sbl b/algorithms/spanish.sbl
new file mode 100644
index 0000000..97d379c
--- /dev/null
+++ b/algorithms/spanish.sbl
@@ -0,0 +1,230 @@
+routines (
+           postlude mark_regions
+           RV R1 R2
+           attached_pronoun
+           standard_suffix
+           y_verb_suffix
+           verb_suffix
+           residual_suffix
+)
+
+externals ( stem )
+
+integers ( pV p1 p2 )
+
+groupings ( v )
+
+stringescapes {}
+
+/* special characters (in ISO Latin I) */
+
+stringdef a'   hex 'E1'  // a-acute
+stringdef e'   hex 'E9'  // e-acute
+stringdef i'   hex 'ED'  // i-acute
+stringdef o'   hex 'F3'  // o-acute
+stringdef u'   hex 'FA'  // u-acute
+stringdef u"   hex 'FC'  // u-diaeresis
+stringdef n~   hex 'F1'  // n-tilde
+
+define v 'aeiou{a'}{e'}{i'}{o'}{u'}{u"}'
+
+define mark_regions as (
+
+    $pV = limit
+    $p1 = limit
+    $p2 = limit  // defaults
+
+    do (
+        ( v (non-v gopast v) or (v gopast non-v) )
+        or
+        ( non-v (non-v gopast v) or (v next) )
+        setmark pV
+    )
+    do (
+        gopast v gopast non-v setmark p1
+        gopast v gopast non-v setmark p2
+    )
+)
+
+define postlude as repeat (
+    [substring] among(
+        '{a'}' (<- 'a')
+        '{e'}' (<- 'e')
+        '{i'}' (<- 'i')
+        '{o'}' (<- 'o')
+        '{u'}' (<- 'u')
+        // and possibly {u"}->u here, or in prelude
+        ''     (next)
+    ) //or next
+)
+
+backwardmode (
+
+    define RV as $pV <= cursor
+    define R1 as $p1 <= cursor
+    define R2 as $p2 <= cursor
+
+    define attached_pronoun as (
+        [substring] among(
+            'me' 'se'  'sela' 'selo' 'selas' 'selos' 'la' 'le' 'lo'
+            'las' 'les' 'los' 'nos'
+        )
+        substring RV among(
+            'i{e'}ndo' (] <- 'iendo')
+            '{a'}ndo'  (] <- 'ando')
+            '{a'}r'    (] <- 'ar')
+            '{e'}r'    (] <- 'er')
+            '{i'}r'    (] <- 'ir')
+            'ando'
+            'iendo'
+            'ar' 'er' 'ir'
+                       (delete)
+            'yendo'    ('u' delete)
+        )
+    )
+
+    define standard_suffix as (
+        [substring] among(
+
+            'anza' 'anzas'
+            'ico' 'ica' 'icos' 'icas'
+            'ismo' 'ismos'
+            'able' 'ables'
+            'ible' 'ibles'
+            'ista' 'istas'
+            'oso' 'osa' 'osos' 'osas'
+            'amiento' 'amientos'
+            'imiento' 'imientos'
+            (
+                R2 delete
+            )
+            'adora' 'ador' 'aci{o'}n'
+            'adoras' 'adores' 'aciones'
+            'ante' 'antes' 'ancia' 'ancias'// Note 1
+            (
+                R2 delete
+                try ( ['ic'] R2 delete )
+            )
+            'log{i'}a'
+            'log{i'}as'
+            (
+                R2 <- 'log'
+            )
+            'uci{o'}n' 'uciones'
+            (
+                R2 <- 'u'
+            )
+            'encia' 'encias'
+            (
+                R2 <- 'ente'
+            )
+            'amente'
+            (
+                R1 delete
+                try (
+                    [substring] R2 delete among(
+                        'iv' (['at'] R2 delete)
+                        'os'
+                        'ic'
+                        'ad'
+                    )
+                )
+            )
+            'mente'
+            (
+                R2 delete
+                try (
+                    [substring] among(
+                        'ante' // Note 1
+                        'able'
+                        'ible' (R2 delete)
+                    )
+                )
+            )
+            'idad'
+            'idades'
+            (
+                R2 delete
+                try (
+                    [substring] among(
+                        'abil'
+                        'ic'
+                        'iv'   (R2 delete)
+                    )
+                )
+            )
+            'iva' 'ivo'
+            'ivas' 'ivos'
+            (
+                R2 delete
+                try (
+                    ['at'] R2 delete // but not a further   ['ic'] R2 delete
+                )
+            )
+        )
+    )
+
+    define y_verb_suffix as (
+        setlimit tomark pV for ([substring]) among(
+            'ya' 'ye' 'yan' 'yen' 'yeron' 'yendo' 'yo' 'y{o'}'
+            'yas' 'yes' 'yais' 'yamos'
+                ('u' delete)
+        )
+    )
+
+    define verb_suffix as (
+        setlimit tomark pV for ([substring]) among(
+
+            'en' 'es' '{e'}is' 'emos'
+                (try ('u' test 'g') ] delete)
+
+            'ar{i'}an' 'ar{i'}as' 'ar{a'}n' 'ar{a'}s' 'ar{i'}ais'
+            'ar{i'}a' 'ar{e'}is' 'ar{i'}amos' 'aremos' 'ar{a'}'
+            'ar{e'}'
+            'er{i'}an' 'er{i'}as' 'er{a'}n' 'er{a'}s' 'er{i'}ais'
+            'er{i'}a' 'er{e'}is' 'er{i'}amos' 'eremos' 'er{a'}'
+            'er{e'}'
+            'ir{i'}an' 'ir{i'}as' 'ir{a'}n' 'ir{a'}s' 'ir{i'}ais'
+            'ir{i'}a' 'ir{e'}is' 'ir{i'}amos' 'iremos' 'ir{a'}'
+            'ir{e'}'
+
+            'aba' 'ada' 'ida' '{i'}a' 'ara' 'iera' 'ad' 'ed'
+            'id' 'ase' 'iese' 'aste' 'iste' 'an' 'aban' '{i'}an'
+            'aran' 'ieran' 'asen' 'iesen' 'aron' 'ieron' 'ado'
+            'ido' 'ando' 'iendo' 'i{o'}' 'ar' 'er' 'ir' 'as'
+            'abas' 'adas' 'idas' '{i'}as' 'aras' 'ieras' 'ases'
+            'ieses' '{i'}s' '{a'}is' 'abais' '{i'}ais' 'arais'
+            'ierais'  'aseis' 'ieseis' 'asteis' 'isteis' 'ados'
+            'idos' 'amos' '{a'}bamos' '{i'}amos' 'imos'
+            '{a'}ramos' 'i{e'}ramos' 'i{e'}semos' '{a'}semos'
+                (delete)
+        )
+    )
+
+    define residual_suffix as (
+        [substring] among(
+            'os'
+            'a' 'o' '{a'}' '{i'}' '{o'}'
+                ( RV delete )
+            'e' '{e'}'
+                ( RV delete try( ['u'] test 'g' RV delete ) )
+        )
+    )
+)
+
+define stem as (
+    do mark_regions
+    backwards (
+        do attached_pronoun
+        do ( standard_suffix or
+             y_verb_suffix or
+             verb_suffix
+           )
+        do residual_suffix
+    )
+    do postlude
+)
+
+/*
+    Note 1: additions of 15 Jun 2005
+*/
\ No newline at end of file
diff --git a/algorithms/swedish.sbl b/algorithms/swedish.sbl
new file mode 100644
index 0000000..03ce1e2
--- /dev/null
+++ b/algorithms/swedish.sbl
@@ -0,0 +1,72 @@
+routines (
+           mark_regions
+           main_suffix
+           consonant_pair
+           other_suffix
+)
+
+externals ( stem )
+
+integers ( p1 x )
+
+groupings ( v s_ending )
+
+stringescapes {}
+
+/* special characters (in ISO Latin I) */
+
+stringdef a"   hex 'E4'
+stringdef ao   hex 'E5'
+stringdef o"   hex 'F6'
+
+define v 'aeiouy{a"}{ao}{o"}'
+
+define s_ending  'bcdfghjklmnoprtvy'
+
+define mark_regions as (
+
+    $p1 = limit
+    test ( hop 3 setmark x )
+    goto v gopast non-v  setmark p1
+    try ( $p1 < x  $p1 = x )
+)
+
+backwardmode (
+
+    define main_suffix as (
+        setlimit tomark p1 for ([substring])
+        among(
+
+            'a' 'arna' 'erna' 'heterna' 'orna' 'ad' 'e' 'ade' 'ande' 'arne'
+            'are' 'aste' 'en' 'anden' 'aren' 'heten' 'ern' 'ar' 'er' 'heter'
+            'or' 'as' 'arnas' 'ernas' 'ornas' 'es' 'ades' 'andes' 'ens' 'arens'
+            'hetens' 'erns' 'at' 'andet' 'het' 'ast'
+                (delete)
+            's'
+                (s_ending delete)
+        )
+    )
+
+    define consonant_pair as setlimit tomark p1 for (
+        among('dd' 'gd' 'nn' 'dt' 'gt' 'kt' 'tt')
+        and ([next] delete)
+    )
+
+    define other_suffix as setlimit tomark p1 for (
+        [substring] among(
+            'lig' 'ig' 'els' (delete)
+            'l{o"}st'        (<-'l{o"}s')
+            'fullt'          (<-'full')
+        )
+    )
+)
+
+define stem as (
+
+    do mark_regions
+    backwards (
+        do main_suffix
+        do consonant_pair
+        do other_suffix
+    )
+)
diff --git a/algorithms/tamil.sbl b/algorithms/tamil.sbl
new file mode 100644
index 0000000..2232c8a
--- /dev/null
+++ b/algorithms/tamil.sbl
@@ -0,0 +1,415 @@
+/*
+* Affix stripping stemming algorithm for Tamil
+* By Damodharan Rajalingam
+*/
+
+stringescapes {}
+
+/* Aytham */
+stringdef aytham hex '0B83'
+
+/* Uyir - independent vowels */
+stringdef a hex '0B85'
+stringdef aa hex '0B86'
+stringdef i hex '0B87'
+stringdef ii hex '0B88'
+stringdef u hex '0B89'
+stringdef uu hex '0B8A'
+stringdef e hex '0B8E'
+stringdef ee hex '0B8F'
+stringdef ai hex '0B90'
+stringdef o hex '0B92'
+stringdef oo hex '0B93'
+stringdef au hex '0B94'
+
+/* Consonants */
+stringdef ka hex '0B95'
+stringdef nga hex '0B99'
+stringdef ca hex '0B9A'
+stringdef ja hex '0B9C'
+stringdef nya hex '0B9E'
+stringdef tta hex '0B9F'
+stringdef nna hex '0BA3'
+stringdef ta hex '0BA4'
+stringdef tha hex '0BA4'
+stringdef na hex '0BA8'
+stringdef nnna hex '0BA9'
+stringdef pa hex '0BAA'
+stringdef ma hex '0BAE'
+stringdef ya hex '0BAF'
+stringdef ra hex '0BB0'
+stringdef rra hex '0BB1'
+stringdef la hex '0BB2'
+stringdef lla hex '0BB3'
+stringdef llla hex '0BB4'
+stringdef zha hex '0BB4'
+stringdef va hex '0BB5'
+
+/* Vatamozi - borrowed */
+stringdef sha hex '0BB6'
+stringdef ssa hex '0BB7'
+stringdef sa hex '0BB8'
+stringdef ha hex '0BB9'
+
+
+/* Dependent vowel signs (kombu etc.) */
+stringdef vs_aa hex '0BBE'
+stringdef vs_i hex '0BBF'
+stringdef vs_ii hex '0BC0'
+stringdef vs_u hex '0BC1'
+stringdef vs_uu hex '0BC2'
+stringdef vs_e hex '0BC6'
+stringdef vs_ee hex '0BC7'
+stringdef vs_ai hex '0BC8'
+stringdef vs_o hex '0BCA'
+stringdef vs_oo hex '0BCB'
+stringdef vs_au hex '0BCC'
+
+/* Pulli */
+stringdef pulli hex '0BCD'
+
+/* AU length markk */
+stringdef au_lmark hex '0BD7'
+
+
+routines (
+ remove_plural_suffix
+ remove_question_suffixes
+ remove_question_prefixes
+ remove_pronoun_prefixes
+ remove_command_suffixes
+ remove_um
+ remove_vetrumai_urupukal
+ fix_va_start
+ fix_ending
+ fix_endings
+ remove_tense_suffix
+ remove_tense_suffixes
+ remove_common_word_endings
+ has_min_length
+)
+
+externals ( stem )
+
+booleans (
+ found_a_match
+ found_vetrumai_urupu
+ found_wrong_ending
+)
+
+integers (
+ length
+)
+
+define has_min_length as (
+ $length = len
+ $length > 4
+)
+
+define fix_va_start as (
+ (try '{va}{vs_oo}' and [ '{va}{vs_oo}' ] <- '{oo}' ) or
+ (try '{va}{vs_o}' and [ '{va}{vs_o}' ] <- '{o}' ) or
+ (try '{va}{vs_u}' and [ '{va}{vs_u}' ] <- '{u}' ) or
+ (try '{va}{vs_uu}' and [ '{va}{vs_uu}' ] <- '{uu}' )
+)
+
+define fix_endings as (
+ set found_wrong_ending
+ repeat (found_wrong_ending (do fix_ending))
+)
+
+define remove_question_prefixes as (
+ [ ('{e}' ) among('{ka}' '{ca}' '{tha}' '{va}' '{na}' '{pa}' '{ma}' '{ya}' '{nga}' '{nya}') '{pulli}' ] delete
+ do fix_va_start
+)
+
+define fix_ending as (
+ unset found_wrong_ending
+ $length = len
+ $length > 3
+ backwards (
+  ( [among('{na}{pulli}' '{na}{pulli}{ta}' '{na}{pulli}{ta}{pulli}') ] delete )
+  or
+  ( ['{ya}{pulli}' test among('{vs_ai}' '{vs_i}' '{vs_ii}') ] delete )
+  or
+  ( [ '{tta}{pulli}{pa}{pulli}' or '{tta}{pulli}{ka}{pulli}' ] <- '{lla}{pulli}' )
+  or
+  ( [ '{nnna}{pulli}{rra}{pulli}' ] <- '{la}{pulli}' )
+  or
+//		( [ '{rra}{pulli}{ka}{pulli}'  or '{nnna}{pulli}{nnna}{pulli}' ] <- '{la}{pulli}'  )
+  ( [ '{rra}{pulli}{ka}{pulli}' ] <- '{la}{pulli}' )
+  or
+  ( [ '{tta}{pulli}{tta}{pulli}' ] <- '{tta}{vs_u}' )
+  or
+  ( found_vetrumai_urupu [ '{ta}{pulli}{ta}{pulli}' (test not '{vs_ai}') ] <- '{ma}{pulli}' ] )
+  or
+  ( [ '{vs_u}{ka}{pulli}' or '{vs_u}{ka}{pulli}{ka}{pulli}' ] <- '{pulli}' )
+  or
+  ( [ '{pulli}' among('{ka}' '{ca}' '{tta}' '{tha}' '{pa}' '{rra}') '{pulli}' among('{ka}' '{ca}' '{tta}' '{tha}' '{pa}' '{rra}') ] delete )
+  or
+  ( [ '{vs_u}{ka}{pulli}' ] <- '{pulli}' )
+  or
+  ( [ '{pulli}' among('{ka}' '{ca}' '{tta}' '{tha}' '{pa}' '{rra}') ] delete )
+  or
+  ( [ '{pulli}' (among('{ya}' '{ra}' '{la}' '{va}' '{zha}' '{lla}') or among('{nga}' '{nya}' '{nna}' '{na}' '{ma}' '{nnna}')) '{pulli}' ] <- '{pulli}' )
+  or
+  ( [ among('{va}' '{ya}' '{va}{pulli}') ] delete )
+  or
+  ( [ '{nnna}{vs_u}' (test not among('{vs_aa}' '{vs_i}' '{vs_ii}' '{vs_e}' '{vs_ee}' '{vs_u}' '{vs_uu}' '{vs_ai}')) ] delete )
+  or
+  ( [ '{nga}{pulli}' (test not '{vs_ai}')] <- '{ma}{pulli}' )
+  or
+  ( [ '{nga}{pulli}' ] delete )
+  or
+  ( [ '{pulli}' (test (among('{vs_aa}' '{vs_i}' '{vs_ii}' '{vs_e}' '{vs_ee}' '{vs_u}' '{vs_uu}' '{vs_ai}') or '{pulli}')) ] delete )
+  )
+
+ set found_wrong_ending // If any of above test pass set the flag
+)
+
+define remove_pronoun_prefixes as (
+ unset found_a_match
+ [ among('{a}' '{i}' '{u}') among('{ka}' '{ca}' '{tha}' '{va}' '{na}' '{pa}' '{ma}' '{ya}' '{nga}' '{nya}') '{pulli}' ] delete
+ (set found_a_match)
+ do fix_va_start
+)
+
+define remove_plural_suffix as (
+ unset found_a_match
+ backwards (
+  ( [ '{vs_u}{nga}{pulli}{ka}{lla}{pulli}' (test not among('{ka}' '{ca}' '{tta}' '{tha}' '{pa}' '{rra}')) ] <- '{pulli}' ) or
+  ( [ '{rra}{pulli}{ka}{lla}{pulli}' ] <- '{la}{pulli}' ) or
+  ( [ '{tta}{pulli}{ka}{lla}{pulli}' ] <- '{lla}{pulli}' ) or
+  ( [ '{ka}{lla}{pulli}' ] delete )
+  (set found_a_match)
+ )
+)
+
+define remove_question_suffixes as (
+ has_min_length
+ unset found_a_match
+ backwards (
+  do (
+   [ among('{vs_oo}' '{vs_ee}' '{vs_aa}') ] <- '{pulli}'
+   (set found_a_match)
+  )
+ )
+ do fix_endings
+)
+
+define remove_command_suffixes as (
+ has_min_length
+ unset found_a_match
+ backwards (
+  [ among('{pa}{vs_i}' '{va}{vs_i}') ] delete
+  (set found_a_match)
+ )
+)
+
+define remove_um as (
+ unset found_a_match
+ has_min_length
+ backwards ( [ '{vs_u}{ma}{pulli}' ] <- '{pulli}'
+    (set found_a_match)
+    )
+ do fix_ending
+)
+
+define remove_common_word_endings as (
+ // These are not suffixes actually but are
+ // some words that are attached to other words
+ // but can be removed for stemming
+ unset found_a_match
+ has_min_length
+ backwards (
+  test ( [ '{vs_u}{tta}{nnna}{pulli}' or
+     '{vs_i}{la}{pulli}{la}{vs_ai}' or
+     '{vs_i}{tta}{ma}{pulli}' or
+     '{vs_i}{nnna}{pulli}{rra}{vs_i}' or
+     '{vs_aa}{ka}{vs_i}' or
+     '{vs_aa}{ka}{vs_i}{ya}' or
+     '{vs_e}{nnna}{pulli}{rra}{vs_u}' or
+     '{vs_u}{lla}{pulli}{lla}' or
+     '{vs_u}{tta}{vs_ai}{ya}' or
+     '{vs_u}{tta}{vs_ai}' or
+     '{vs_e}{nnna}{vs_u}{ma}{pulli}' or
+     ('{la}{pulli}{la}' test (not among('{vs_aa}' '{vs_i}' '{vs_ii}' '{vs_e}' '{vs_ee}' '{vs_u}' '{vs_uu}' '{vs_ai}'))) or
+     '{vs_e}{nnna}' or
+     '{vs_aa}{ka}{vs_i}' ] <- '{pulli}'
+     (set found_a_match)
+     )
+  or
+  test ( [ among('{pa}{tta}{vs_u}'
+     '{pa}{tta}{pulli}{tta}'
+     '{pa}{tta}{pulli}{tta}{vs_u}'
+     '{pa}{tta}{pulli}{tta}{ta}{vs_u}'
+     '{pa}{tta}{pulli}{tta}{nna}'
+     '{ka}{vs_u}{ra}{vs_i}{ya}'
+     '{pa}{rra}{pulli}{rra}{vs_i}'
+     '{va}{vs_i}{tta}{vs_u}'
+     '{va}{vs_i}{tta}{pulli}{tta}{vs_u}'
+     '{pa}{tta}{vs_i}{ta}{vs_aa}{nnna}'
+     '{pa}{tta}{vs_i}'
+     '{ta}{vs_aa}{nnna}'
+     '{vs_e}{la}{pulli}{la}{vs_aa}{ma}{pulli}')
+    ] delete
+    (set found_a_match)
+    )
+ )
+ do fix_endings
+)
+
+define remove_vetrumai_urupukal as (
+ unset found_a_match
+ unset found_vetrumai_urupu
+ has_min_length
+ backwards (
+  (
+    test ( ['{nnna}{vs_ai}'] delete )
+   or
+    test ([ ( '{vs_i}{nnna}{vs_ai}' or
+     '{vs_ai}' (test not among('{ka}' '{ca}' '{tta}' '{tha}' '{pa}' '{rra}'))) or
+      ( '{vs_ai}' (test (among('{ka}' '{ca}' '{tta}' '{tha}' '{pa}' '{rra}') '{pulli}')))
+    ] <- '{pulli}'
+    )
+   or
+   test ( [
+            '{vs_o}{tta}{vs_u}' or
+            '{vs_oo}{tta}{vs_u}' or
+            '{vs_i}{la}{pulli}' or
+            '{vs_i}{rra}{pulli}' or
+            ('{vs_i}{nnna}{pulli}' (test not '{ma}')) or
+            '{vs_i}{nnna}{pulli}{rra}{vs_u}' or
+            '{vs_i}{ra}{vs_u}{na}{pulli}{ta}{vs_u}' or
+            '{va}{vs_i}{tta}' or
+            ($length >= 7 '{vs_i}{tta}{ma}{pulli}') or
+            '{vs_aa}{la}{pulli}' or
+            '{vs_u}{tta}{vs_ai}' or
+            '{vs_aa}{ma}{la}{pulli}' or
+            ('{la}{pulli}' (test not among('{vs_aa}' '{vs_i}' '{vs_ii}' '{vs_e}' '{vs_ee}' '{vs_u}' '{vs_uu}' '{vs_ai}'))) or
+            '{vs_u}{lla}{pulli}'
+           ] <- '{pulli}'
+     )
+   or
+   test ( [
+           '{ka}{nna}{pulli}' or
+           '{ma}{vs_u}{nnna}{pulli}' or
+           '{ma}{vs_ee}{la}{pulli}' or
+           '{ma}{vs_ee}{rra}{pulli}' or
+           '{ka}{vs_ii}{llla}{pulli}' or
+           '{pa}{vs_i}{nnna}{pulli}' or
+           ('{ta}{vs_u}' (test not among('{vs_aa}' '{vs_i}' '{vs_ii}' '{vs_e}' '{vs_ee}' '{vs_u}' '{vs_uu}' '{vs_ai}')))
+          ] delete
+      )
+   or
+   test ([ '{vs_ii}' ] <- '{vs_i}')
+  )
+  (set found_a_match)
+  (set found_vetrumai_urupu)
+  do ( [ '{vs_i}{nnna}{pulli}' ] <- '{pulli}' )
+ )
+ do fix_endings
+)
+
+define remove_tense_suffixes as (
+ set found_a_match
+ repeat ( found_a_match (do remove_tense_suffix) )
+)
+
+define remove_tense_suffix as (
+ unset found_a_match
+ has_min_length
+ backwards (
+  do (
+   test ( [among(
+           '{ka}{vs_o}{nna}{pulli}{tta}{vs_i}{ra}{pulli}'
+           '{pa}{tta}{vs_u}'
+           )] delete
+     (set found_a_match)
+     )
+   or
+   test ( [
+            '{ma}{vs_aa}{ra}{pulli}' or
+            '{ma}{vs_i}{nnna}{pulli}' or
+            '{nnna}{nnna}{pulli}' or
+            '{nnna}{vs_aa}{nnna}{pulli}' or
+            '{nnna}{vs_aa}{lla}{pulli}' or
+            '{nnna}{vs_aa}{ra}{pulli}' or
+            ('{va}{nnna}{pulli}' test (not among('{a}' '{aa}' '{i}' '{ii}' '{u}' '{uu}' '{e}' '{ee}' '{ai}' '{o}' '{oo}' '{au}')) ) or
+            '{nnna}{lla}{pulli}' or
+            '{va}{lla}{pulli}' or
+            '{nnna}{ra}{pulli}' or
+            '{va}{ra}{pulli}' or
+            '{nnna}' or '{pa}' or '{ka}' or '{ta}' or '{ya}' or
+            '{pa}{nnna}{pulli}' or
+            '{pa}{lla}{pulli}' or
+            '{pa}{ra}{pulli}' or
+            ('{ta}{vs_u}' (test not among('{vs_aa}' '{vs_i}' '{vs_ii}' '{vs_e}' '{vs_ee}' '{vs_u}' '{vs_uu}' '{vs_ai}'))) or
+            '{vs_i}{rra}{pulli}{rra}{vs_u}' or
+            '{pa}{ma}{pulli}' or
+            '{nnna}{ma}{pulli}' or
+            '{ta}{vs_u}{ma}{pulli}' or
+            '{rra}{vs_u}{ma}{pulli}' or
+            '{ka}{vs_u}{ma}{pulli}' or
+            '{nnna}{vs_e}{nnna}{pulli}' or
+            '{nnna}{vs_ai}' or
+            '{va}{vs_ai}'
+       ] delete
+       (set found_a_match)
+       )
+   or
+   test ( [
+           ('{vs_aa}{nnna}{pulli}' test (not '{ca}')) or
+           '{vs_aa}{lla}{pulli}' or
+           '{vs_aa}{ra}{pulli}' or
+           '{vs_ee}{nnna}{pulli}' or
+           '{vs_aa}' or
+           '{vs_aa}{ma}{pulli}' or
+           '{vs_e}{ma}{pulli}' or
+           '{vs_ee}{ma}{pulli}' or
+           '{vs_oo}{ma}{pulli}' or
+           '{ka}{vs_u}{ma}{pulli}' or
+           '{ta}{vs_u}{ma}{pulli}' or
+           '{tta}{vs_u}{ma}{pulli}' or
+           '{rra}{vs_u}{ma}{pulli}' or
+           '{vs_aa}{ya}{pulli}' or
+           '{nnna}{vs_e}{nnna}{pulli}' or
+           '{nnna}{vs_i}{ra}{pulli}' or
+           '{vs_ii}{ra}{pulli}' or
+           '{vs_ii}{ya}{ra}{pulli}'
+          ] <- '{pulli}'
+      (set found_a_match)
+      )
+   or
+   test ( ([ '{ka}{vs_u}' or '{ta}{vs_u}' ) (test '{pulli}') ] delete
+      (set found_a_match)
+      )
+  )
+  do ([among(
+              '{vs_aa}{na}{vs_i}{nnna}{pulli}{rra}'
+              '{vs_aa}{na}{vs_i}{nnna}{pulli}{rra}{pulli}'
+              '{ka}{vs_i}{nnna}{pulli}{rra}'
+              '{ka}{vs_i}{nnna}{pulli}{rra}{pulli}'
+              '{ka}{vs_i}{rra}'
+              '{ka}{vs_i}{rra}{pulli}'
+            )] delete
+    (set found_a_match)
+    )
+ )
+ do fix_endings
+)
+
+define stem as (
+ unset found_vetrumai_urupu
+ do fix_ending
+ has_min_length
+ do remove_question_prefixes
+ do remove_pronoun_prefixes
+ do remove_question_suffixes
+ do remove_um
+ do remove_common_word_endings
+ do remove_vetrumai_urupukal
+ do remove_plural_suffix
+ do remove_command_suffixes
+ do remove_tense_suffixes
+)
diff --git a/algorithms/turkish.sbl b/algorithms/turkish.sbl
new file mode 100644
index 0000000..c2c101b
--- /dev/null
+++ b/algorithms/turkish.sbl
@@ -0,0 +1,477 @@
+/* Stemmer for Turkish
+	* author: Evren (Kapusuz) Çilden
+	* email: evren.kapusuz at gmail.com
+	* version: 1.0 (15.01.2007)
+	
+
+	* stems nominal verb suffixes
+	* stems nominal inflections
+	* more than one syllable word check
+	* (y,n,s,U) context check
+	* vowel harmony check
+	* last consonant check and conversion (b, c, d, ÄŸ to p, ç, t, k)
+	
+	* The stemming algorithm is based on the paper "An Affix Stripping
+	* Morphological Analyzer for Turkish" by GülÅŸen EryiÄŸit and
+	* Eşref Adalı (Proceedings of the IAESTED International Conference
+	* ARTIFICIAL INTELLIGENCE AND APPLICATIONS, February 16-18,2004,
+	* Innsbruck, Austria
+	
+	* Turkish is an agglutinative language and has a very rich morphological
+	* structure. In Turkish, you can form many different words from a single stem
+	* by appending a sequence of suffixes. Eg. The word "doktoruymuÅŸsunuz" means
+	* "You had been the doctor of him". The stem of the word is "doktor" and it
+	* takes three different suffixes -sU, -ymUs, and -sUnUz. The rules about
+	* the append order of suffixes can be clearly described as FSMs.
+	* The paper referenced above defines some FSMs for right to left
+	* morphological analysis. I generated a method for constructing snowball
+	* expressions from right to left FSMs for stemming suffixes.
+*/
+
+routines (
+	append_U_to_stems_ending_with_d_or_g // for preventing some overstemmings
+	check_vowel_harmony	// tests vowel harmony for suffixes
+	is_reserved_word	// tests whether current string is a reserved word ('ad','soyad')
+	mark_cAsInA		// nominal verb suffix
+	mark_DA			// noun suffix
+	mark_DAn		// noun suffix
+	mark_DUr		// nominal verb suffix
+	mark_ki			// noun suffix
+	mark_lAr		// noun suffix, nominal verb suffix
+	mark_lArI		// noun suffix
+	mark_nA			// noun suffix
+	mark_ncA		// noun suffix
+	mark_ndA		// noun suffix
+	mark_ndAn		// noun suffix
+	mark_nU			// noun suffix
+	mark_nUn		// noun suffix
+	mark_nUz		// nominal verb suffix
+	mark_sU			// noun suffix
+	mark_sUn		// nominal verb suffix
+	mark_sUnUz		// nominal verb suffix
+	mark_possessives	// -(U)m,-(U)n,-(U)mUz,-(U)nUz,
+	mark_yA			// noun suffix
+	mark_ylA		// noun suffix
+	mark_yU			// noun suffix
+	mark_yUm		// nominal verb suffix
+	mark_yUz		// nominal verb suffix
+	mark_yDU		// nominal verb suffix
+	mark_yken		// nominal verb suffix
+	mark_ymUs_		// nominal verb suffix
+	mark_ysA		// nominal verb suffix
+	
+	mark_suffix_with_optional_y_consonant
+	mark_suffix_with_optional_U_vowel
+	mark_suffix_with_optional_n_consonant
+	mark_suffix_with_optional_s_consonant
+	
+	more_than_one_syllable_word
+	
+	post_process_last_consonants
+	postlude
+
+	stem_nominal_verb_suffixes
+	stem_noun_suffixes
+	stem_suffix_chain_before_ki
+)
+
+/* Special characters in Unicode Latin-1 and Latin Extended-A */
+stringdef c.   	hex 'E7'	// LATIN SMALL LETTER C WITH CEDILLA
+stringdef g~   	hex '011F'	// LATIN SMALL LETTER G WITH BREVE
+stringdef i'   	hex '0131'	// LATIN SMALL LETTER I WITHOUT DOT
+stringdef o"  	hex 'F6'	// LATIN SMALL LETTER O WITH DIAERESIS
+stringdef s.	hex '015F'	// LATIN SMALL LETTER S WITH CEDILLA
+stringdef u"  	hex 'FC'	// LATIN SMALL LETTER U WITH DIAERESIS
+
+stringescapes 	{ }
+
+integers 	( strlen )	// length of a string
+
+booleans	( continue_stemming_noun_suffixes )
+
+groupings 	( vowel U vowel1 vowel2 vowel3 vowel4 vowel5 vowel6)
+
+define vowel 	'ae{i'}io{o"}u{u"}'
+define U	'{i'}iu{u"}'
+
+// the vowel grouping definitions below are used for checking vowel harmony
+define vowel1  	'a{i'}ou' 		// vowels that can end with suffixes containing 'a'
+define vowel2  	'ei{o"}{u"}' 		// vowels that can end with suffixes containing 'e'
+define vowel3  	'a{i'}' 		// vowels that can end with suffixes containing 'i''
+define vowel4  	'ei'	 		// vowels that can end with suffixes containing 'i'
+define vowel5  	'ou'	 		// vowels that can end with suffixes containing 'o' or 'u'
+define vowel6  	'{o"}{u"}' 		// vowels that can end with suffixes containing 'o"' or 'u"'
+
+externals 	( stem )
+
+backwardmode (
+	// checks vowel harmony for possible suffixes,
+	// helps to detect whether the candidate for suffix applies to vowel harmony
+	// this rule is added to prevent over stemming
+	define check_vowel_harmony as (
+		test
+		(
+			(goto vowel)   // if there is a vowel
+			(
+				('a' goto vowel1) or
+				('e' goto vowel2) or
+				('{i'}' goto vowel3) or
+				('i' goto vowel4) or
+				('o' goto vowel5) or
+				('{o"}' goto vowel6) or
+				('u' goto vowel5) or
+				('{u"}' goto vowel6)
+			)
+		)
+	)
+	
+	// if the last consonant before suffix is vowel and n then advance and delete
+	// if the last consonant before suffix is non vowel and n do nothing
+	// if the last consonant before suffix is not n then only delete the suffix
+	// assumption: slice beginning is set correctly
+	define mark_suffix_with_optional_n_consonant as (
+		('n' (test vowel))
+		or
+		((not(test 'n')) test(next vowel))
+
+	)
+	
+	// if the last consonant before suffix is vowel and s then advance and delete
+	// if the last consonant before suffix is non vowel and s do nothing
+	// if the last consonant before suffix is not s then only delete the suffix
+	// assumption: slice beginning is set correctly
+	define mark_suffix_with_optional_s_consonant as (
+		('s' (test vowel))
+		or
+		((not(test 's')) test(next vowel))
+	)
+	
+	// if the last consonant before suffix is vowel and y then advance and delete
+	// if the last consonant before suffix is non vowel and y do nothing
+	// if the last consonant before suffix is not y then only delete the suffix
+	// assumption: slice beginning is set correctly
+	define mark_suffix_with_optional_y_consonant as (
+		('y' (test vowel))
+		or
+		((not(test 'y')) test(next vowel))
+	)
+	
+	define mark_suffix_with_optional_U_vowel as (
+		(U (test non-vowel))
+		or
+		((not(test U)) test(next non-vowel))
+
+	)
+	
+	define mark_possessives as (
+		among ('m{i'}z' 'miz' 'muz' 'm{u"}z'
+		       'n{i'}z' 'niz' 'nuz' 'n{u"}z' 'm' 'n')
+		(mark_suffix_with_optional_U_vowel)
+	)
+	
+	define mark_sU as (
+		check_vowel_harmony
+		U
+		(mark_suffix_with_optional_s_consonant)
+	)
+	
+	define mark_lArI as (
+		among ('leri' 'lar{i'}')
+	)
+	
+	define mark_yU as (
+		check_vowel_harmony
+		U
+		(mark_suffix_with_optional_y_consonant)	
+	)
+	
+	define mark_nU as (
+		check_vowel_harmony
+		among ('n{i'}' 'ni' 'nu' 'n{u"}')	
+	)
+	
+	define mark_nUn as (
+		check_vowel_harmony
+		among ('{i'}n' 'in' 'un' '{u"}n')	
+		(mark_suffix_with_optional_n_consonant)
+	)
+	
+	define mark_yA as (
+		check_vowel_harmony
+		among('a' 'e')
+		(mark_suffix_with_optional_y_consonant)
+	)
+	
+	define mark_nA as (
+		check_vowel_harmony
+		among('na' 'ne')
+	)
+	
+	define mark_DA as (
+		check_vowel_harmony
+		among('da' 'de' 'ta' 'te')
+	)
+	
+	define mark_ndA as (
+		check_vowel_harmony
+		among('nda' 'nde')
+	)
+	
+	define mark_DAn as (
+		check_vowel_harmony
+		among('dan' 'den' 'tan' 'ten')
+	)
+	
+	define mark_ndAn as (
+		check_vowel_harmony
+		among('ndan' 'nden')
+	)
+	
+	define mark_ylA as (
+		check_vowel_harmony
+		among('la' 'le')
+		(mark_suffix_with_optional_y_consonant)
+	)
+	
+	define mark_ki as (
+		'ki'
+	)
+	
+	define mark_ncA as (
+		check_vowel_harmony
+		among('ca' 'ce')	
+		(mark_suffix_with_optional_n_consonant)
+	)
+	
+	define mark_yUm as (
+		check_vowel_harmony
+		among ('{i'}m' 'im' 'um' '{u"}m')
+		(mark_suffix_with_optional_y_consonant)
+	)
+	
+	define mark_sUn as (
+		check_vowel_harmony
+		among ('s{i'}n' 'sin' 'sun' 's{u"}n' )
+	)
+	
+	define mark_yUz as (
+		check_vowel_harmony
+		among ('{i'}z' 'iz' 'uz' '{u"}z')
+		(mark_suffix_with_optional_y_consonant)
+	)
+	
+	define mark_sUnUz as (
+		among ('s{i'}n{i'}z' 'siniz' 'sunuz' 's{u"}n{u"}z')
+	)
+	
+	define mark_lAr as (
+		check_vowel_harmony
+		among ('ler' 'lar')
+	)
+	
+	define mark_nUz as (
+		check_vowel_harmony
+		among ('n{i'}z' 'niz' 'nuz' 'n{u"}z')
+	)
+	
+	define mark_DUr as (
+		check_vowel_harmony
+		among ('t{i'}r' 'tir' 'tur' 't{u"}r' 'd{i'}r' 'dir' 'dur' 'd{u"}r')
+	)
+	
+	define mark_cAsInA as (
+		among ('cas{i'}na' 'cesine')
+	)
+	
+	define mark_yDU as (
+		check_vowel_harmony
+		among ('t{i'}m' 'tim' 'tum' 't{u"}m' 'd{i'}m' 'dim' 'dum' 'd{u"}m'
+			't{i'}n' 'tin' 'tun' 't{u"}n' 'd{i'}n' 'din' 'dun' 'd{u"}n'
+			't{i'}k' 'tik' 'tuk' 't{u"}k' 'd{i'}k' 'dik' 'duk' 'd{u"}k'
+			't{i'}' 'ti' 'tu' 't{u"}' 'd{i'}' 'di' 'du' 'd{u"}')
+		(mark_suffix_with_optional_y_consonant)
+	)
+
+	// does not fully obey vowel harmony	
+	define mark_ysA as (
+		among ('sam' 'san' 'sak' 'sem' 'sen' 'sek' 'sa' 'se')
+		(mark_suffix_with_optional_y_consonant)
+	)
+	
+	define mark_ymUs_ as (
+		check_vowel_harmony
+		among ('m{i'}{s.}' 'mi{s.}' 'mu{s.}' 'm{u"}{s.}')
+		(mark_suffix_with_optional_y_consonant)
+	)
+	
+	define mark_yken as (
+		'ken' (mark_suffix_with_optional_y_consonant)
+	)
+	
+	define stem_nominal_verb_suffixes as (
+		[	
+			set continue_stemming_noun_suffixes
+			(mark_ymUs_ or mark_yDU or mark_ysA or mark_yken)
+			or
+			(mark_cAsInA (mark_sUnUz or mark_lAr or mark_yUm or mark_sUn or mark_yUz or true) mark_ymUs_)
+			or
+			(
+				mark_lAr ] delete try([(mark_DUr or mark_yDU or mark_ysA or mark_ymUs_))
+				unset continue_stemming_noun_suffixes
+			)
+			or
+			(mark_nUz (mark_yDU or mark_ysA))
+			or
+			((mark_sUnUz or mark_yUz or mark_sUn or mark_yUm) ] delete try([ mark_ymUs_))
+			or
+			(mark_DUr ] delete try([ (mark_sUnUz or mark_lAr or mark_yUm or mark_sUn or mark_yUz or true) mark_ymUs_))
+		]delete
+	)
+	
+	// stems noun suffix chains ending with -ki
+	define stem_suffix_chain_before_ki as (
+		[
+			mark_ki
+			(
+				(mark_DA] delete try([
+					(mark_lAr] delete try(stem_suffix_chain_before_ki))
+					or
+					(mark_possessives] delete try([mark_lAr] delete stem_suffix_chain_before_ki))
+					
+				))
+				or
+				(mark_nUn] delete try([
+					(mark_lArI] delete)
+					or
+					([mark_possessives or mark_sU] delete try([mark_lAr] delete stem_suffix_chain_before_ki))
+					or
+					(stem_suffix_chain_before_ki)
+				))
+				or
+				(mark_ndA (	
+					(mark_lArI] delete)
+					or
+					((mark_sU] delete try([mark_lAr]delete stem_suffix_chain_before_ki)))
+					or
+					(stem_suffix_chain_before_ki)
+				))
+			)
+	)
+	
+	define stem_noun_suffixes as (
+		([mark_lAr] delete try(stem_suffix_chain_before_ki))
+		or
+		([mark_ncA] delete
+			try(
+				([mark_lArI] delete)
+				or
+				([mark_possessives or mark_sU] delete try([mark_lAr] delete stem_suffix_chain_before_ki))
+				or
+				([mark_lAr] delete stem_suffix_chain_before_ki)
+			)
+		)
+		or
+		([(mark_ndA or mark_nA)
+			(
+		  		(mark_lArI] delete)
+		  		or
+		  		(mark_sU] delete try([mark_lAr] delete stem_suffix_chain_before_ki))
+		  		or
+		  		(stem_suffix_chain_before_ki)
+		  	)
+		)
+		or
+		([(mark_ndAn or mark_nU) ((mark_sU ] delete try([mark_lAr] delete stem_suffix_chain_before_ki)) or (mark_lArI)))
+		or
+		( [mark_DAn] delete try ([
+			(
+		 		(mark_possessives ] delete try([mark_lAr] delete stem_suffix_chain_before_ki))
+		 		or
+		 		(mark_lAr] delete try(stem_suffix_chain_before_ki))
+		 		or
+		 		(stem_suffix_chain_before_ki)
+		 	))
+		)
+		or
+		([mark_nUn or mark_ylA] delete
+			try(
+				([mark_lAr] delete stem_suffix_chain_before_ki)
+				or
+				([mark_possessives or mark_sU] delete try([mark_lAr] delete stem_suffix_chain_before_ki))
+				or
+				stem_suffix_chain_before_ki
+			)
+		)
+		or
+		([mark_lArI] delete)
+		or	
+		(stem_suffix_chain_before_ki)
+		or
+		([mark_DA or mark_yU or mark_yA] delete try([((mark_possessives] delete try([mark_lAr)) or mark_lAr) ] delete [ stem_suffix_chain_before_ki))
+		or
+		([mark_possessives or mark_sU] delete try([mark_lAr] delete stem_suffix_chain_before_ki))
+	)
+	
+	define post_process_last_consonants as (	
+		[substring] among (
+			'b' (<- 'p')
+			'c' (<- '{c.}')
+			'd' (<- 't')
+			'{g~}' (<- 'k')
+		)
+	)
+
+	// after stemming if the word ends with 'd' or 'g' most probably last U is overstemmed
+	// like in 'kedim' -> 'ked'
+	// Turkish words don't usually end with 'd' or 'g'
+	// some very well known words are ignored (like 'ad' 'soyad'	
+	// appends U to stems ending with d or g, decides which vowel to add
+	// based on the last vowel in the stem
+	define append_U_to_stems_ending_with_d_or_g as (
+		test('d' or 'g')
+		(test((goto vowel) 'a' or '{i'}') <+ '{i'}')
+		or
+		(test((goto vowel) 'e' or 'i') <+ 'i')
+		or
+		(test((goto vowel) 'o' or 'u') <+ 'u')
+		or
+		(test((goto vowel) '{o"}' or '{u"}') <+ '{u"}')
+	)
+	
+)
+
+// Tests if there are more than one syllables
+// In Turkish each vowel indicates a distinct syllable
+define more_than_one_syllable_word as (
+	test (atleast 2 (gopast vowel))
+)
+
+define is_reserved_word as (
+	test(gopast 'ad' ($strlen = 2) ($strlen == limit))
+	or
+	test(gopast 'soyad' ($strlen = 5) ($strlen == limit))
+)
+
+define postlude as (
+	not(is_reserved_word)
+	backwards (
+		do append_U_to_stems_ending_with_d_or_g
+		do post_process_last_consonants
+		
+	)
+)
+
+define stem as (
+	(more_than_one_syllable_word)
+	(
+		backwards (
+			do stem_nominal_verb_suffixes
+			continue_stemming_noun_suffixes
+			do stem_noun_suffixes
+		)
+		
+	postlude
+	)
+)
+
+
diff --git a/cargo_embargo.json b/cargo_embargo.json
new file mode 100644
index 0000000..c8842d1
--- /dev/null
+++ b/cargo_embargo.json
@@ -0,0 +1,4 @@
+{
+  "run_cargo": false,
+  "tests": true
+}
diff --git a/examples/stem-file/main.rs b/examples/stem-file/main.rs
new file mode 100644
index 0000000..c7e6b7d
--- /dev/null
+++ b/examples/stem-file/main.rs
@@ -0,0 +1,8 @@
+extern crate rust_stemmers;
+
+use rust_stemmers::{Algorithm, Stemmer};
+
+fn main() {
+    let en_stemmer = Stemmer::create(Algorithm::English);
+    assert_eq!(en_stemmer.stem("fruitlessly"), "fruitless");    
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..8ddd244
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,323 @@
+//! This library provides rust implementations for some stemmer algorithms
+//! written in the [snowball language](https://snowballstem.org/).
+//!
+//!
+//! All algorithms expect the input to already be lowercased.
+//!
+//! # Usage
+//! ```toml
+//! [dependencies]
+//! rust-stemmers = "^1.0"
+//! ```
+//!
+//! ```rust
+//! extern crate rust_stemmers;
+//!
+//! use rust_stemmers::{Algorithm, Stemmer};
+//!
+//! fn main() {
+//!    let en_stemmer = Stemmer::create(Algorithm::English);
+//!    assert_eq!(en_stemmer.stem("fruitlessly"), "fruitless");
+//! }
+//! ```
+extern crate serde;
+#[macro_use]
+extern crate serde_derive;
+
+use std::borrow::Cow;
+
+mod snowball;
+
+use snowball::SnowballEnv;
+use snowball::algorithms;
+
+/// Enum of all supported algorithms.
+/// Check the [Snowball-Website](https://snowballstem.org/) for details.
+#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Copy, Clone)]
+pub enum Algorithm {
+    Arabic,
+    Danish,
+    Dutch,
+    English,
+    Finnish,
+    French,
+    German,
+    Greek,
+    Hungarian,
+    Italian,
+    Norwegian,
+    Portuguese,
+    Romanian,
+    Russian,
+    Spanish,
+    Swedish,
+    Tamil,
+    Turkish
+}
+
+/// Wrapps a usable interface around the actual stemmer implementation
+pub struct Stemmer {
+    stemmer: fn(&mut SnowballEnv) -> bool,
+}
+
+impl Stemmer {
+    /// Create a new stemmer from an algorithm
+    pub fn create(lang: Algorithm) -> Self {
+        match lang {
+            Algorithm::Arabic => Stemmer { stemmer: algorithms::arabic::stem },
+            Algorithm::Danish => Stemmer { stemmer: algorithms::danish::stem },
+            Algorithm::Dutch => Stemmer { stemmer: algorithms::dutch::stem },
+            Algorithm::English => Stemmer { stemmer: algorithms::english::stem },
+            Algorithm::Finnish => Stemmer { stemmer: algorithms::finnish::stem },
+            Algorithm::French => Stemmer { stemmer: algorithms::french::stem },
+            Algorithm::German => Stemmer { stemmer: algorithms::german::stem },
+            Algorithm::Greek => Stemmer { stemmer: algorithms::greek::stem },
+            Algorithm::Hungarian => Stemmer { stemmer: algorithms::hungarian::stem },
+            Algorithm::Italian => Stemmer { stemmer: algorithms::italian::stem },
+            Algorithm::Norwegian => Stemmer { stemmer: algorithms::norwegian::stem },
+            Algorithm::Portuguese => Stemmer { stemmer: algorithms::portuguese::stem },
+            Algorithm::Romanian => Stemmer { stemmer: algorithms::romanian::stem },
+            Algorithm::Russian => Stemmer { stemmer: algorithms::russian::stem },
+            Algorithm::Spanish => Stemmer { stemmer: algorithms::spanish::stem },
+            Algorithm::Swedish => Stemmer { stemmer: algorithms::swedish::stem },
+            Algorithm::Tamil => Stemmer { stemmer: algorithms::tamil::stem },
+            Algorithm::Turkish => Stemmer { stemmer: algorithms::turkish::stem },
+        }
+    }
+
+    /// Stem a single word
+    /// Please note, that the input is expected to be all lowercase (if that is applicable).
+    pub fn stem<'a>(&self, input: &'a str) -> Cow<'a, str> {
+        let mut env = SnowballEnv::create(input);
+        (self.stemmer)(&mut env);
+        env.get_current()
+    }
+}
+
+
+
+#[cfg(test)]
+mod tests {
+    use super::{Stemmer, Algorithm};
+
+    fn stemms_to(lhs: &str, rhs: &str, stemmer: Algorithm) {
+        assert_eq!(Stemmer::create(stemmer).stem(lhs), rhs);
+    }
+
+    #[test]
+    fn german_test() {
+        use std::fs;
+        use std::io;
+        use std::io::BufRead;
+
+        let vocab = io::BufReader::new(fs::File::open("test_data/voc_ger.txt").unwrap());
+        let result = io::BufReader::new(fs::File::open("test_data/res_ger.txt").unwrap());
+
+        let lines = vocab.lines().zip(result.lines());
+
+        for (voc, res) in lines {
+            stemms_to(voc.unwrap().as_str(),
+                      res.unwrap().as_str(),
+                      Algorithm::German);
+        }
+    }
+
+    #[test]
+    fn english_test() {
+        use std::fs;
+        use std::io;
+        use std::io::BufRead;
+
+        let vocab = io::BufReader::new(fs::File::open("test_data/voc_en.txt").unwrap());
+        let result = io::BufReader::new(fs::File::open("test_data/res_en.txt").unwrap());
+
+        let lines = vocab.lines().zip(result.lines());
+
+        for (voc, res) in lines {
+            stemms_to(voc.unwrap().as_str(),
+                      res.unwrap().as_str(),
+                      Algorithm::English);
+        }
+    }
+
+    #[test]
+    fn french_test() {
+        use std::fs;
+        use std::io;
+        use std::io::BufRead;
+
+        let vocab = io::BufReader::new(fs::File::open("test_data/voc_fr.txt").unwrap());
+        let result = io::BufReader::new(fs::File::open("test_data/res_fr.txt").unwrap());
+
+        let lines = vocab.lines().zip(result.lines());
+
+        for (voc, res) in lines {
+            stemms_to(voc.unwrap().as_str(),
+                      res.unwrap().as_str(),
+                      Algorithm::French);
+        }
+    }
+
+    #[test]
+    fn spanish_test() {
+        use std::fs;
+        use std::io;
+        use std::io::BufRead;
+
+        let vocab = io::BufReader::new(fs::File::open("test_data/voc_es.txt").unwrap());
+        let result = io::BufReader::new(fs::File::open("test_data/res_es.txt").unwrap());
+
+        let lines = vocab.lines().zip(result.lines());
+
+        for (voc, res) in lines {
+            stemms_to(voc.unwrap().as_str(),
+                      res.unwrap().as_str(),
+                      Algorithm::Spanish);
+        }
+    }
+
+    #[test]
+    fn portuguese_test() {
+        use std::fs;
+        use std::io;
+        use std::io::BufRead;
+
+        let vocab = io::BufReader::new(fs::File::open("test_data/voc_pt.txt").unwrap());
+        let result = io::BufReader::new(fs::File::open("test_data/res_pt.txt").unwrap());
+
+        let lines = vocab.lines().zip(result.lines());
+
+        for (voc, res) in lines {
+            stemms_to(voc.unwrap().as_str(),
+                      res.unwrap().as_str(),
+                      Algorithm::Portuguese);
+        }
+    }
+
+    #[test]
+    fn italian_test() {
+        use std::fs;
+        use std::io;
+        use std::io::BufRead;
+
+        let vocab = io::BufReader::new(fs::File::open("test_data/voc_it.txt").unwrap());
+        let result = io::BufReader::new(fs::File::open("test_data/res_it.txt").unwrap());
+
+        let lines = vocab.lines().zip(result.lines());
+
+        for (voc, res) in lines {
+            stemms_to(voc.unwrap().as_str(),
+                      res.unwrap().as_str(),
+                      Algorithm::Italian);
+        }
+    }
+
+    #[test]
+    fn romanian_test() {
+        use std::fs;
+        use std::io;
+        use std::io::BufRead;
+
+        let vocab = io::BufReader::new(fs::File::open("test_data/voc_ro.txt").unwrap());
+        let result = io::BufReader::new(fs::File::open("test_data/res_ro.txt").unwrap());
+
+        let lines = vocab.lines().zip(result.lines());
+
+        for (voc, res) in lines {
+            stemms_to(voc.unwrap().as_str(),
+                      res.unwrap().as_str(),
+                      Algorithm::Romanian);
+        }
+    }
+
+    #[test]
+    fn russian_test() {
+        use std::fs;
+        use std::io;
+        use std::io::BufRead;
+
+        let vocab = io::BufReader::new(fs::File::open("test_data/voc_ru.txt").unwrap());
+        let result = io::BufReader::new(fs::File::open("test_data/res_ru.txt").unwrap());
+
+        let lines = vocab.lines().zip(result.lines());
+
+        for (voc, res) in lines {
+            stemms_to(voc.unwrap().as_str(),
+                      res.unwrap().as_str(),
+                      Algorithm::Russian);
+        }
+    }
+
+    #[test]
+    fn arabic_test() {
+        use std::fs;
+        use std::io;
+        use std::io::BufRead;
+
+        let vocab = io::BufReader::new(fs::File::open("test_data/voc_ar.txt").unwrap());
+        let result = io::BufReader::new(fs::File::open("test_data/res_ar.txt").unwrap());
+
+        let lines = vocab.lines().zip(result.lines());
+
+        for (voc, res) in lines {
+            stemms_to(voc.unwrap().as_str(),
+                      res.unwrap().as_str(),
+                      Algorithm::Arabic);
+        }
+    }
+
+    #[test]
+    fn finnish_test() {
+        use std::fs;
+        use std::io;
+        use std::io::BufRead;
+
+        let vocab = io::BufReader::new(fs::File::open("test_data/voc_fi.txt").unwrap());
+        let result = io::BufReader::new(fs::File::open("test_data/res_fi.txt").unwrap());
+
+        let lines = vocab.lines().zip(result.lines());
+
+        for (voc, res) in lines {
+            stemms_to(voc.unwrap().as_str(),
+                      res.unwrap().as_str(),
+                      Algorithm::Finnish);
+        }
+    }
+
+    #[test]
+    fn greek_test() {
+        use std::fs;
+        use std::io;
+        use std::io::BufRead;
+
+        let vocab = io::BufReader::new(fs::File::open("test_data/voc_el.txt").unwrap());
+        let result = io::BufReader::new(fs::File::open("test_data/res_el.txt").unwrap());
+
+        let lines = vocab.lines().zip(result.lines());
+
+        for (voc, res) in lines {
+            stemms_to(voc.unwrap().as_str(),
+                      res.unwrap().as_str(),
+                      Algorithm::Greek);
+        }
+    }
+
+    #[test]
+    fn norwegian_test() {
+        use std::fs;
+        use std::io;
+        use std::io::BufRead;
+
+        let vocab = io::BufReader::new(fs::File::open("test_data/voc_no.txt").unwrap());
+        let result = io::BufReader::new(fs::File::open("test_data/res_no.txt").unwrap());
+
+        let lines = vocab.lines().zip(result.lines());
+
+        for (voc, res) in lines {
+            stemms_to(voc.unwrap().as_str(),
+                      res.unwrap().as_str(),
+                      Algorithm::Norwegian);
+        }
+    }
+
+}
diff --git a/src/snowball/algorithms/arabic.rs b/src/snowball/algorithms/arabic.rs
new file mode 100644
index 0000000..7955550
--- /dev/null
+++ b/src/snowball/algorithms/arabic.rs
@@ -0,0 +1,1914 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 161] = &[
+    Among("!", -1, 3, None),
+    Among("\"", -1, 3, None),
+    Among("%", -1, 3, None),
+    Among("*", -1, 3, None),
+    Among(",", -1, 3, None),
+    Among(".", -1, 3, None),
+    Among("/", -1, 3, None),
+    Among(":", -1, 3, None),
+    Among(";", -1, 3, None),
+    Among("?", -1, 3, None),
+    Among("\\", -1, 3, None),
+    Among("\u{060C}", -1, 4, None),
+    Among("\u{061B}", -1, 4, None),
+    Among("\u{061F}", -1, 4, None),
+    Among("\u{0640}", -1, 2, None),
+    Among("\u{064B}", -1, 1, None),
+    Among("\u{064C}", -1, 1, None),
+    Among("\u{064D}", -1, 1, None),
+    Among("\u{064E}", -1, 1, None),
+    Among("\u{064F}", -1, 1, None),
+    Among("\u{0650}", -1, 1, None),
+    Among("\u{0651}", -1, 1, None),
+    Among("\u{0652}", -1, 1, None),
+    Among("\u{0660}", -1, 5, None),
+    Among("\u{0661}", -1, 6, None),
+    Among("\u{0662}", -1, 7, None),
+    Among("\u{0663}", -1, 8, None),
+    Among("\u{0664}", -1, 9, None),
+    Among("\u{0665}", -1, 10, None),
+    Among("\u{0666}", -1, 11, None),
+    Among("\u{0667}", -1, 12, None),
+    Among("\u{0668}", -1, 13, None),
+    Among("\u{0669}", -1, 14, None),
+    Among("\u{066A}", -1, 15, None),
+    Among("\u{066B}", -1, 15, None),
+    Among("\u{066C}", -1, 15, None),
+    Among("\u{FE80}", -1, 16, None),
+    Among("\u{FE81}", -1, 20, None),
+    Among("\u{FE82}", -1, 20, None),
+    Among("\u{FE83}", -1, 17, None),
+    Among("\u{FE84}", -1, 17, None),
+    Among("\u{FE85}", -1, 21, None),
+    Among("\u{FE86}", -1, 21, None),
+    Among("\u{FE87}", -1, 18, None),
+    Among("\u{FE88}", -1, 18, None),
+    Among("\u{FE89}", -1, 19, None),
+    Among("\u{FE8A}", -1, 19, None),
+    Among("\u{FE8B}", -1, 19, None),
+    Among("\u{FE8C}", -1, 19, None),
+    Among("\u{FE8D}", -1, 22, None),
+    Among("\u{FE8E}", -1, 22, None),
+    Among("\u{FE8F}", -1, 23, None),
+    Among("\u{FE90}", -1, 23, None),
+    Among("\u{FE91}", -1, 23, None),
+    Among("\u{FE92}", -1, 23, None),
+    Among("\u{FE93}", -1, 24, None),
+    Among("\u{FE94}", -1, 24, None),
+    Among("\u{FE95}", -1, 25, None),
+    Among("\u{FE96}", -1, 25, None),
+    Among("\u{FE97}", -1, 25, None),
+    Among("\u{FE98}", -1, 25, None),
+    Among("\u{FE99}", -1, 26, None),
+    Among("\u{FE9A}", -1, 26, None),
+    Among("\u{FE9B}", -1, 26, None),
+    Among("\u{FE9C}", -1, 26, None),
+    Among("\u{FE9D}", -1, 27, None),
+    Among("\u{FE9E}", -1, 27, None),
+    Among("\u{FE9F}", -1, 27, None),
+    Among("\u{FEA0}", -1, 27, None),
+    Among("\u{FEA1}", -1, 28, None),
+    Among("\u{FEA2}", -1, 28, None),
+    Among("\u{FEA3}", -1, 28, None),
+    Among("\u{FEA4}", -1, 28, None),
+    Among("\u{FEA5}", -1, 29, None),
+    Among("\u{FEA6}", -1, 29, None),
+    Among("\u{FEA7}", -1, 29, None),
+    Among("\u{FEA8}", -1, 29, None),
+    Among("\u{FEA9}", -1, 30, None),
+    Among("\u{FEAA}", -1, 30, None),
+    Among("\u{FEAB}", -1, 31, None),
+    Among("\u{FEAC}", -1, 31, None),
+    Among("\u{FEAD}", -1, 32, None),
+    Among("\u{FEAE}", -1, 32, None),
+    Among("\u{FEAF}", -1, 33, None),
+    Among("\u{FEB0}", -1, 33, None),
+    Among("\u{FEB1}", -1, 34, None),
+    Among("\u{FEB2}", -1, 34, None),
+    Among("\u{FEB3}", -1, 34, None),
+    Among("\u{FEB4}", -1, 34, None),
+    Among("\u{FEB5}", -1, 35, None),
+    Among("\u{FEB6}", -1, 35, None),
+    Among("\u{FEB7}", -1, 35, None),
+    Among("\u{FEB8}", -1, 35, None),
+    Among("\u{FEB9}", -1, 36, None),
+    Among("\u{FEBA}", -1, 36, None),
+    Among("\u{FEBB}", -1, 36, None),
+    Among("\u{FEBC}", -1, 36, None),
+    Among("\u{FEBD}", -1, 37, None),
+    Among("\u{FEBE}", -1, 37, None),
+    Among("\u{FEBF}", -1, 37, None),
+    Among("\u{FEC0}", -1, 37, None),
+    Among("\u{FEC1}", -1, 38, None),
+    Among("\u{FEC2}", -1, 38, None),
+    Among("\u{FEC3}", -1, 38, None),
+    Among("\u{FEC4}", -1, 38, None),
+    Among("\u{FEC5}", -1, 39, None),
+    Among("\u{FEC6}", -1, 39, None),
+    Among("\u{FEC7}", -1, 39, None),
+    Among("\u{FEC8}", -1, 39, None),
+    Among("\u{FEC9}", -1, 40, None),
+    Among("\u{FECA}", -1, 40, None),
+    Among("\u{FECB}", -1, 40, None),
+    Among("\u{FECC}", -1, 40, None),
+    Among("\u{FECD}", -1, 41, None),
+    Among("\u{FECE}", -1, 41, None),
+    Among("\u{FECF}", -1, 41, None),
+    Among("\u{FED0}", -1, 41, None),
+    Among("\u{FED1}", -1, 42, None),
+    Among("\u{FED2}", -1, 42, None),
+    Among("\u{FED3}", -1, 42, None),
+    Among("\u{FED4}", -1, 42, None),
+    Among("\u{FED5}", -1, 43, None),
+    Among("\u{FED6}", -1, 43, None),
+    Among("\u{FED7}", -1, 43, None),
+    Among("\u{FED8}", -1, 43, None),
+    Among("\u{FED9}", -1, 44, None),
+    Among("\u{FEDA}", -1, 44, None),
+    Among("\u{FEDB}", -1, 44, None),
+    Among("\u{FEDC}", -1, 44, None),
+    Among("\u{FEDD}", -1, 45, None),
+    Among("\u{FEDE}", -1, 45, None),
+    Among("\u{FEDF}", -1, 45, None),
+    Among("\u{FEE0}", -1, 45, None),
+    Among("\u{FEE1}", -1, 46, None),
+    Among("\u{FEE2}", -1, 46, None),
+    Among("\u{FEE3}", -1, 46, None),
+    Among("\u{FEE4}", -1, 46, None),
+    Among("\u{FEE5}", -1, 47, None),
+    Among("\u{FEE6}", -1, 47, None),
+    Among("\u{FEE7}", -1, 47, None),
+    Among("\u{FEE8}", -1, 47, None),
+    Among("\u{FEE9}", -1, 48, None),
+    Among("\u{FEEA}", -1, 48, None),
+    Among("\u{FEEB}", -1, 48, None),
+    Among("\u{FEEC}", -1, 48, None),
+    Among("\u{FEED}", -1, 49, None),
+    Among("\u{FEEE}", -1, 49, None),
+    Among("\u{FEEF}", -1, 50, None),
+    Among("\u{FEF0}", -1, 50, None),
+    Among("\u{FEF1}", -1, 51, None),
+    Among("\u{FEF2}", -1, 51, None),
+    Among("\u{FEF3}", -1, 51, None),
+    Among("\u{FEF4}", -1, 51, None),
+    Among("\u{FEF5}", -1, 55, None),
+    Among("\u{FEF6}", -1, 55, None),
+    Among("\u{FEF7}", -1, 53, None),
+    Among("\u{FEF8}", -1, 53, None),
+    Among("\u{FEF9}", -1, 54, None),
+    Among("\u{FEFA}", -1, 54, None),
+    Among("\u{FEFB}", -1, 52, None),
+    Among("\u{FEFC}", -1, 52, None),
+];
+
+static A_1: &'static [Among<Context>; 5] = &[
+    Among("\u{0622}", -1, 1, None),
+    Among("\u{0623}", -1, 1, None),
+    Among("\u{0624}", -1, 2, None),
+    Among("\u{0625}", -1, 1, None),
+    Among("\u{0626}", -1, 3, None),
+];
+
+static A_2: &'static [Among<Context>; 5] = &[
+    Among("\u{0622}", -1, 1, None),
+    Among("\u{0623}", -1, 1, None),
+    Among("\u{0624}", -1, 2, None),
+    Among("\u{0625}", -1, 1, None),
+    Among("\u{0626}", -1, 3, None),
+];
+
+static A_3: &'static [Among<Context>; 4] = &[
+    Among("\u{0627}\u{0644}", -1, 2, None),
+    Among("\u{0628}\u{0627}\u{0644}", -1, 1, None),
+    Among("\u{0643}\u{0627}\u{0644}", -1, 1, None),
+    Among("\u{0644}\u{0644}", -1, 2, None),
+];
+
+static A_4: &'static [Among<Context>; 5] = &[
+    Among("\u{0623}\u{0622}", -1, 2, None),
+    Among("\u{0623}\u{0623}", -1, 1, None),
+    Among("\u{0623}\u{0624}", -1, 3, None),
+    Among("\u{0623}\u{0625}", -1, 5, None),
+    Among("\u{0623}\u{0627}", -1, 4, None),
+];
+
+static A_5: &'static [Among<Context>; 2] = &[
+    Among("\u{0641}", -1, 1, None),
+    Among("\u{0648}", -1, 2, None),
+];
+
+static A_6: &'static [Among<Context>; 4] = &[
+    Among("\u{0627}\u{0644}", -1, 2, None),
+    Among("\u{0628}\u{0627}\u{0644}", -1, 1, None),
+    Among("\u{0643}\u{0627}\u{0644}", -1, 1, None),
+    Among("\u{0644}\u{0644}", -1, 2, None),
+];
+
+static A_7: &'static [Among<Context>; 3] = &[
+    Among("\u{0628}", -1, 1, None),
+    Among("\u{0628}\u{0628}", 0, 2, None),
+    Among("\u{0643}\u{0643}", -1, 3, None),
+];
+
+static A_8: &'static [Among<Context>; 4] = &[
+    Among("\u{0633}\u{0623}", -1, 4, None),
+    Among("\u{0633}\u{062A}", -1, 2, None),
+    Among("\u{0633}\u{0646}", -1, 3, None),
+    Among("\u{0633}\u{064A}", -1, 1, None),
+];
+
+static A_9: &'static [Among<Context>; 3] = &[
+    Among("\u{062A}\u{0633}\u{062A}", -1, 1, None),
+    Among("\u{0646}\u{0633}\u{062A}", -1, 1, None),
+    Among("\u{064A}\u{0633}\u{062A}", -1, 1, None),
+];
+
+static A_10: &'static [Among<Context>; 10] = &[
+    Among("\u{0643}", -1, 1, None),
+    Among("\u{0643}\u{0645}", -1, 2, None),
+    Among("\u{0647}\u{0645}", -1, 2, None),
+    Among("\u{0647}\u{0646}", -1, 2, None),
+    Among("\u{0647}", -1, 1, None),
+    Among("\u{064A}", -1, 1, None),
+    Among("\u{0643}\u{0645}\u{0627}", -1, 3, None),
+    Among("\u{0647}\u{0645}\u{0627}", -1, 3, None),
+    Among("\u{0646}\u{0627}", -1, 2, None),
+    Among("\u{0647}\u{0627}", -1, 2, None),
+];
+
+static A_11: &'static [Among<Context>; 1] = &[
+    Among("\u{0646}", -1, 1, None),
+];
+
+static A_12: &'static [Among<Context>; 3] = &[
+    Among("\u{0648}", -1, 1, None),
+    Among("\u{064A}", -1, 1, None),
+    Among("\u{0627}", -1, 1, None),
+];
+
+static A_13: &'static [Among<Context>; 1] = &[
+    Among("\u{0627}\u{062A}", -1, 1, None),
+];
+
+static A_14: &'static [Among<Context>; 1] = &[
+    Among("\u{062A}", -1, 1, None),
+];
+
+static A_15: &'static [Among<Context>; 1] = &[
+    Among("\u{0629}", -1, 1, None),
+];
+
+static A_16: &'static [Among<Context>; 1] = &[
+    Among("\u{064A}", -1, 1, None),
+];
+
+static A_17: &'static [Among<Context>; 12] = &[
+    Among("\u{0643}", -1, 1, None),
+    Among("\u{0643}\u{0645}", -1, 2, None),
+    Among("\u{0647}\u{0645}", -1, 2, None),
+    Among("\u{0643}\u{0646}", -1, 2, None),
+    Among("\u{0647}\u{0646}", -1, 2, None),
+    Among("\u{0647}", -1, 1, None),
+    Among("\u{0643}\u{0645}\u{0648}", -1, 3, None),
+    Among("\u{0646}\u{064A}", -1, 2, None),
+    Among("\u{0643}\u{0645}\u{0627}", -1, 3, None),
+    Among("\u{0647}\u{0645}\u{0627}", -1, 3, None),
+    Among("\u{0646}\u{0627}", -1, 2, None),
+    Among("\u{0647}\u{0627}", -1, 2, None),
+];
+
+static A_18: &'static [Among<Context>; 11] = &[
+    Among("\u{0646}", -1, 2, None),
+    Among("\u{0648}\u{0646}", 0, 4, None),
+    Among("\u{064A}\u{0646}", 0, 4, None),
+    Among("\u{0627}\u{0646}", 0, 4, None),
+    Among("\u{062A}\u{0646}", 0, 3, None),
+    Among("\u{064A}", -1, 2, None),
+    Among("\u{0627}", -1, 2, None),
+    Among("\u{062A}\u{0645}\u{0627}", 6, 5, None),
+    Among("\u{0646}\u{0627}", 6, 3, None),
+    Among("\u{062A}\u{0627}", 6, 3, None),
+    Among("\u{062A}", -1, 1, None),
+];
+
+static A_19: &'static [Among<Context>; 2] = &[
+    Among("\u{062A}\u{0645}", -1, 1, None),
+    Among("\u{0648}\u{0627}", -1, 1, None),
+];
+
+static A_20: &'static [Among<Context>; 2] = &[
+    Among("\u{0648}", -1, 1, None),
+    Among("\u{062A}\u{0645}\u{0648}", 0, 2, None),
+];
+
+static A_21: &'static [Among<Context>; 1] = &[
+    Among("\u{0649}", -1, 1, None),
+];
+
+#[derive(Clone)]
+struct Context {
+    b_is_defined: bool,
+    b_is_verb: bool,
+    b_is_noun: bool,
+    i_word_len: usize,
+}
+
+fn r_Normalize_pre(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 258
+    // loop, line 259
+    for _ in 0..env.current.chars().count() {
+        // (, line 259
+        // or, line 328
+        'lab0: loop {
+            let v_2 = env.cursor;
+            'lab1: loop {
+                // (, line 260
+                // [, line 261
+                env.bra = env.cursor;
+                // substring, line 261
+                among_var = env.find_among(A_0, context);
+                if among_var == 0 {
+                    break 'lab1;
+                }
+                // ], line 261
+                env.ket = env.cursor;
+                if among_var == 0 {
+                    break 'lab1;
+                } else if among_var == 1 {
+                    // (, line 262
+                    // delete, line 262
+                    if !env.slice_del() {
+                        return false;
+                    }
+                } else if among_var == 2 {
+                    // (, line 263
+                    // delete, line 263
+                    if !env.slice_del() {
+                        return false;
+                    }
+                } else if among_var == 3 {
+                    // (, line 266
+                    // delete, line 266
+                    if !env.slice_del() {
+                        return false;
+                    }
+                } else if among_var == 4 {
+                    // (, line 267
+                    // delete, line 267
+                    if !env.slice_del() {
+                        return false;
+                    }
+                } else if among_var == 5 {
+                    // (, line 270
+                    // <-, line 270
+                    if !env.slice_from("0") {
+                        return false;
+                    }
+                } else if among_var == 6 {
+                    // (, line 271
+                    // <-, line 271
+                    if !env.slice_from("1") {
+                        return false;
+                    }
+                } else if among_var == 7 {
+                    // (, line 272
+                    // <-, line 272
+                    if !env.slice_from("2") {
+                        return false;
+                    }
+                } else if among_var == 8 {
+                    // (, line 273
+                    // <-, line 273
+                    if !env.slice_from("3") {
+                        return false;
+                    }
+                } else if among_var == 9 {
+                    // (, line 274
+                    // <-, line 274
+                    if !env.slice_from("4") {
+                        return false;
+                    }
+                } else if among_var == 10 {
+                    // (, line 275
+                    // <-, line 275
+                    if !env.slice_from("5") {
+                        return false;
+                    }
+                } else if among_var == 11 {
+                    // (, line 276
+                    // <-, line 276
+                    if !env.slice_from("6") {
+                        return false;
+                    }
+                } else if among_var == 12 {
+                    // (, line 277
+                    // <-, line 277
+                    if !env.slice_from("7") {
+                        return false;
+                    }
+                } else if among_var == 13 {
+                    // (, line 278
+                    // <-, line 278
+                    if !env.slice_from("8") {
+                        return false;
+                    }
+                } else if among_var == 14 {
+                    // (, line 279
+                    // <-, line 279
+                    if !env.slice_from("9") {
+                        return false;
+                    }
+                } else if among_var == 15 {
+                    // (, line 280
+                    // delete, line 280
+                    if !env.slice_del() {
+                        return false;
+                    }
+                } else if among_var == 16 {
+                    // (, line 283
+                    // <-, line 283
+                    if !env.slice_from("\u{0621}") {
+                        return false;
+                    }
+                } else if among_var == 17 {
+                    // (, line 284
+                    // <-, line 284
+                    if !env.slice_from("\u{0623}") {
+                        return false;
+                    }
+                } else if among_var == 18 {
+                    // (, line 285
+                    // <-, line 285
+                    if !env.slice_from("\u{0625}") {
+                        return false;
+                    }
+                } else if among_var == 19 {
+                    // (, line 286
+                    // <-, line 286
+                    if !env.slice_from("\u{0626}") {
+                        return false;
+                    }
+                } else if among_var == 20 {
+                    // (, line 287
+                    // <-, line 287
+                    if !env.slice_from("\u{0622}") {
+                        return false;
+                    }
+                } else if among_var == 21 {
+                    // (, line 288
+                    // <-, line 288
+                    if !env.slice_from("\u{0624}") {
+                        return false;
+                    }
+                } else if among_var == 22 {
+                    // (, line 289
+                    // <-, line 289
+                    if !env.slice_from("\u{0627}") {
+                        return false;
+                    }
+                } else if among_var == 23 {
+                    // (, line 290
+                    // <-, line 290
+                    if !env.slice_from("\u{0628}") {
+                        return false;
+                    }
+                } else if among_var == 24 {
+                    // (, line 291
+                    // <-, line 291
+                    if !env.slice_from("\u{0629}") {
+                        return false;
+                    }
+                } else if among_var == 25 {
+                    // (, line 292
+                    // <-, line 292
+                    if !env.slice_from("\u{062A}") {
+                        return false;
+                    }
+                } else if among_var == 26 {
+                    // (, line 293
+                    // <-, line 293
+                    if !env.slice_from("\u{062B}") {
+                        return false;
+                    }
+                } else if among_var == 27 {
+                    // (, line 294
+                    // <-, line 294
+                    if !env.slice_from("\u{062C}") {
+                        return false;
+                    }
+                } else if among_var == 28 {
+                    // (, line 295
+                    // <-, line 295
+                    if !env.slice_from("\u{062D}") {
+                        return false;
+                    }
+                } else if among_var == 29 {
+                    // (, line 296
+                    // <-, line 296
+                    if !env.slice_from("\u{062E}") {
+                        return false;
+                    }
+                } else if among_var == 30 {
+                    // (, line 297
+                    // <-, line 297
+                    if !env.slice_from("\u{062F}") {
+                        return false;
+                    }
+                } else if among_var == 31 {
+                    // (, line 298
+                    // <-, line 298
+                    if !env.slice_from("\u{0630}") {
+                        return false;
+                    }
+                } else if among_var == 32 {
+                    // (, line 299
+                    // <-, line 299
+                    if !env.slice_from("\u{0631}") {
+                        return false;
+                    }
+                } else if among_var == 33 {
+                    // (, line 300
+                    // <-, line 300
+                    if !env.slice_from("\u{0632}") {
+                        return false;
+                    }
+                } else if among_var == 34 {
+                    // (, line 301
+                    // <-, line 301
+                    if !env.slice_from("\u{0633}") {
+                        return false;
+                    }
+                } else if among_var == 35 {
+                    // (, line 302
+                    // <-, line 302
+                    if !env.slice_from("\u{0634}") {
+                        return false;
+                    }
+                } else if among_var == 36 {
+                    // (, line 303
+                    // <-, line 303
+                    if !env.slice_from("\u{0635}") {
+                        return false;
+                    }
+                } else if among_var == 37 {
+                    // (, line 304
+                    // <-, line 304
+                    if !env.slice_from("\u{0636}") {
+                        return false;
+                    }
+                } else if among_var == 38 {
+                    // (, line 305
+                    // <-, line 305
+                    if !env.slice_from("\u{0637}") {
+                        return false;
+                    }
+                } else if among_var == 39 {
+                    // (, line 306
+                    // <-, line 306
+                    if !env.slice_from("\u{0638}") {
+                        return false;
+                    }
+                } else if among_var == 40 {
+                    // (, line 307
+                    // <-, line 307
+                    if !env.slice_from("\u{0639}") {
+                        return false;
+                    }
+                } else if among_var == 41 {
+                    // (, line 308
+                    // <-, line 308
+                    if !env.slice_from("\u{063A}") {
+                        return false;
+                    }
+                } else if among_var == 42 {
+                    // (, line 309
+                    // <-, line 309
+                    if !env.slice_from("\u{0641}") {
+                        return false;
+                    }
+                } else if among_var == 43 {
+                    // (, line 310
+                    // <-, line 310
+                    if !env.slice_from("\u{0642}") {
+                        return false;
+                    }
+                } else if among_var == 44 {
+                    // (, line 311
+                    // <-, line 311
+                    if !env.slice_from("\u{0643}") {
+                        return false;
+                    }
+                } else if among_var == 45 {
+                    // (, line 312
+                    // <-, line 312
+                    if !env.slice_from("\u{0644}") {
+                        return false;
+                    }
+                } else if among_var == 46 {
+                    // (, line 313
+                    // <-, line 313
+                    if !env.slice_from("\u{0645}") {
+                        return false;
+                    }
+                } else if among_var == 47 {
+                    // (, line 314
+                    // <-, line 314
+                    if !env.slice_from("\u{0646}") {
+                        return false;
+                    }
+                } else if among_var == 48 {
+                    // (, line 315
+                    // <-, line 315
+                    if !env.slice_from("\u{0647}") {
+                        return false;
+                    }
+                } else if among_var == 49 {
+                    // (, line 316
+                    // <-, line 316
+                    if !env.slice_from("\u{0648}") {
+                        return false;
+                    }
+                } else if among_var == 50 {
+                    // (, line 317
+                    // <-, line 317
+                    if !env.slice_from("\u{0649}") {
+                        return false;
+                    }
+                } else if among_var == 51 {
+                    // (, line 318
+                    // <-, line 318
+                    if !env.slice_from("\u{064A}") {
+                        return false;
+                    }
+                } else if among_var == 52 {
+                    // (, line 321
+                    // <-, line 321
+                    if !env.slice_from("\u{0644}\u{0627}") {
+                        return false;
+                    }
+                } else if among_var == 53 {
+                    // (, line 322
+                    // <-, line 322
+                    if !env.slice_from("\u{0644}\u{0623}") {
+                        return false;
+                    }
+                } else if among_var == 54 {
+                    // (, line 323
+                    // <-, line 323
+                    if !env.slice_from("\u{0644}\u{0625}") {
+                        return false;
+                    }
+                } else if among_var == 55 {
+                    // (, line 324
+                    // <-, line 324
+                    if !env.slice_from("\u{0644}\u{0622}") {
+                        return false;
+                    }
+                }
+                break 'lab0;
+            }
+            env.cursor = v_2;
+            // next, line 329
+            if env.cursor >= env.limit {
+                return false;
+            }
+            env.next_char();
+            break 'lab0;
+        }
+    }
+    return true;
+}
+
+fn r_Normalize_post(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 333
+    // do, line 335
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // (, line 335
+        // backwards, line 337
+        env.limit_backward = env.cursor;
+        env.cursor = env.limit;
+        // (, line 337
+        // [, line 338
+        env.ket = env.cursor;
+        // substring, line 338
+        among_var = env.find_among_b(A_1, context);
+        if among_var == 0 {
+            break 'lab0;
+        }
+        // ], line 338
+        env.bra = env.cursor;
+        if among_var == 0 {
+            break 'lab0;
+        } else if among_var == 1 {
+            // (, line 339
+            // <-, line 339
+            if !env.slice_from("\u{0621}") {
+                return false;
+            }
+        } else if among_var == 2 {
+            // (, line 340
+            // <-, line 340
+            if !env.slice_from("\u{0621}") {
+                return false;
+            }
+        } else if among_var == 3 {
+            // (, line 341
+            // <-, line 341
+            if !env.slice_from("\u{0621}") {
+                return false;
+            }
+        }
+        env.cursor = env.limit_backward;
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 346
+    let v_2 = env.cursor;
+    'lab1: loop {
+        // loop, line 346
+        for _ in 0..context.i_word_len {
+            // (, line 346
+            // or, line 355
+            'lab2: loop {
+                let v_4 = env.cursor;
+                'lab3: loop {
+                    // (, line 347
+                    // [, line 349
+                    env.bra = env.cursor;
+                    // substring, line 349
+                    among_var = env.find_among(A_2, context);
+                    if among_var == 0 {
+                        break 'lab3;
+                    }
+                    // ], line 349
+                    env.ket = env.cursor;
+                    if among_var == 0 {
+                        break 'lab3;
+                    } else if among_var == 1 {
+                        // (, line 350
+                        // <-, line 350
+                        if !env.slice_from("\u{0627}") {
+                            return false;
+                        }
+                    } else if among_var == 2 {
+                        // (, line 351
+                        // <-, line 351
+                        if !env.slice_from("\u{0648}") {
+                            return false;
+                        }
+                    } else if among_var == 3 {
+                        // (, line 352
+                        // <-, line 352
+                        if !env.slice_from("\u{064A}") {
+                            return false;
+                        }
+                    }
+                    break 'lab2;
+                }
+                env.cursor = v_4;
+                // next, line 356
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+                break 'lab2;
+            }
+        }
+        break 'lab1;
+    }
+    env.cursor = v_2;
+    return true;
+}
+
+fn r_Checks1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 361
+    context.i_word_len = env.current.chars().count();
+    // [, line 363
+    env.bra = env.cursor;
+    // substring, line 363
+    among_var = env.find_among(A_3, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 363
+    env.ket = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 364
+        if !(context.i_word_len > 4){
+            return false;
+        }
+        // set is_noun, line 364
+        context.b_is_noun = true;
+        // unset is_verb, line 364
+        context.b_is_verb = false;
+        // set is_defined, line 364
+        context.b_is_defined = true;
+    } else if among_var == 2 {
+        // (, line 365
+        if !(context.i_word_len > 3){
+            return false;
+        }
+        // set is_noun, line 365
+        context.b_is_noun = true;
+        // unset is_verb, line 365
+        context.b_is_verb = false;
+        // set is_defined, line 365
+        context.b_is_defined = true;
+    }
+    return true;
+}
+
+fn r_Prefix_Step1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 371
+    context.i_word_len = env.current.chars().count();
+    // [, line 373
+    env.bra = env.cursor;
+    // substring, line 373
+    among_var = env.find_among(A_4, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 373
+    env.ket = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 374
+        if !(context.i_word_len > 3){
+            return false;
+        }
+        // <-, line 374
+        if !env.slice_from("\u{0623}") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 375
+        if !(context.i_word_len > 3){
+            return false;
+        }
+        // <-, line 375
+        if !env.slice_from("\u{0622}") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 376
+        if !(context.i_word_len > 3){
+            return false;
+        }
+        // <-, line 376
+        if !env.slice_from("\u{0623}") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 377
+        if !(context.i_word_len > 3){
+            return false;
+        }
+        // <-, line 377
+        if !env.slice_from("\u{0627}") {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 378
+        if !(context.i_word_len > 3){
+            return false;
+        }
+        // <-, line 378
+        if !env.slice_from("\u{0625}") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Prefix_Step2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 383
+    context.i_word_len = env.current.chars().count();
+    // not, line 385
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // literal, line 385
+        if !env.eq_s(&"\u{0641}\u{0627}") {
+            break 'lab0;
+        }
+        return false;
+    }
+    env.cursor = v_1;
+    // not, line 386
+    let v_2 = env.cursor;
+    'lab1: loop {
+        // literal, line 386
+        if !env.eq_s(&"\u{0648}\u{0627}") {
+            break 'lab1;
+        }
+        return false;
+    }
+    env.cursor = v_2;
+    // [, line 387
+    env.bra = env.cursor;
+    // substring, line 387
+    among_var = env.find_among(A_5, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 387
+    env.ket = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 388
+        if !(context.i_word_len > 3){
+            return false;
+        }
+        // delete, line 388
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 389
+        if !(context.i_word_len > 3){
+            return false;
+        }
+        // delete, line 389
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Prefix_Step3a_Noun(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 393
+    context.i_word_len = env.current.chars().count();
+    // [, line 395
+    env.bra = env.cursor;
+    // substring, line 395
+    among_var = env.find_among(A_6, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 395
+    env.ket = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 396
+        if !(context.i_word_len > 5){
+            return false;
+        }
+        // delete, line 396
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 397
+        if !(context.i_word_len > 4){
+            return false;
+        }
+        // delete, line 397
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Prefix_Step3b_Noun(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 401
+    context.i_word_len = env.current.chars().count();
+    // not, line 403
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // literal, line 403
+        if !env.eq_s(&"\u{0628}\u{0627}") {
+            break 'lab0;
+        }
+        return false;
+    }
+    env.cursor = v_1;
+    // [, line 404
+    env.bra = env.cursor;
+    // substring, line 404
+    among_var = env.find_among(A_7, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 404
+    env.ket = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 405
+        if !(context.i_word_len > 3){
+            return false;
+        }
+        // delete, line 405
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 407
+        if !(context.i_word_len > 3){
+            return false;
+        }
+        // <-, line 407
+        if !env.slice_from("\u{0628}") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 408
+        if !(context.i_word_len > 3){
+            return false;
+        }
+        // <-, line 408
+        if !env.slice_from("\u{0643}") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Prefix_Step3_Verb(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 413
+    context.i_word_len = env.current.chars().count();
+    // [, line 415
+    env.bra = env.cursor;
+    // substring, line 415
+    among_var = env.find_among(A_8, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 415
+    env.ket = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 417
+        if !(context.i_word_len > 4){
+            return false;
+        }
+        // <-, line 417
+        if !env.slice_from("\u{064A}") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 418
+        if !(context.i_word_len > 4){
+            return false;
+        }
+        // <-, line 418
+        if !env.slice_from("\u{062A}") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 419
+        if !(context.i_word_len > 4){
+            return false;
+        }
+        // <-, line 419
+        if !env.slice_from("\u{0646}") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 420
+        if !(context.i_word_len > 4){
+            return false;
+        }
+        // <-, line 420
+        if !env.slice_from("\u{0623}") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Prefix_Step4_Verb(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 424
+    context.i_word_len = env.current.chars().count();
+    // [, line 426
+    env.bra = env.cursor;
+    // substring, line 426
+    among_var = env.find_among(A_9, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 426
+    env.ket = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 427
+        if !(context.i_word_len > 4){
+            return false;
+        }
+        // set is_verb, line 427
+        context.b_is_verb = true;
+        // unset is_noun, line 427
+        context.b_is_noun = false;
+        // <-, line 427
+        if !env.slice_from("\u{0627}\u{0633}\u{062A}") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Suffix_Noun_Step1a(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 434
+    context.i_word_len = env.current.chars().count();
+    // [, line 436
+    env.ket = env.cursor;
+    // substring, line 436
+    among_var = env.find_among_b(A_10, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 436
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 437
+        if !(context.i_word_len >= 4){
+            return false;
+        }
+        // delete, line 437
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 438
+        if !(context.i_word_len >= 5){
+            return false;
+        }
+        // delete, line 438
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 439
+        if !(context.i_word_len >= 6){
+            return false;
+        }
+        // delete, line 439
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Suffix_Noun_Step1b(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 442
+    context.i_word_len = env.current.chars().count();
+    // [, line 444
+    env.ket = env.cursor;
+    // substring, line 444
+    among_var = env.find_among_b(A_11, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 444
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 445
+        if !(context.i_word_len > 5){
+            return false;
+        }
+        // delete, line 445
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Suffix_Noun_Step2a(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 449
+    context.i_word_len = env.current.chars().count();
+    // [, line 451
+    env.ket = env.cursor;
+    // substring, line 451
+    among_var = env.find_among_b(A_12, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 451
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 452
+        if !(context.i_word_len > 4){
+            return false;
+        }
+        // delete, line 452
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Suffix_Noun_Step2b(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 456
+    context.i_word_len = env.current.chars().count();
+    // [, line 458
+    env.ket = env.cursor;
+    // substring, line 458
+    among_var = env.find_among_b(A_13, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 458
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 459
+        if !(context.i_word_len >= 5){
+            return false;
+        }
+        // delete, line 459
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Suffix_Noun_Step2c1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 463
+    context.i_word_len = env.current.chars().count();
+    // [, line 465
+    env.ket = env.cursor;
+    // substring, line 465
+    among_var = env.find_among_b(A_14, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 465
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 466
+        if !(context.i_word_len >= 4){
+            return false;
+        }
+        // delete, line 466
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Suffix_Noun_Step2c2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 469
+    context.i_word_len = env.current.chars().count();
+    // [, line 471
+    env.ket = env.cursor;
+    // substring, line 471
+    among_var = env.find_among_b(A_15, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 471
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 472
+        if !(context.i_word_len >= 4){
+            return false;
+        }
+        // delete, line 472
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Suffix_Noun_Step3(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 475
+    context.i_word_len = env.current.chars().count();
+    // [, line 477
+    env.ket = env.cursor;
+    // substring, line 477
+    among_var = env.find_among_b(A_16, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 477
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 478
+        if !(context.i_word_len >= 3){
+            return false;
+        }
+        // delete, line 478
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Suffix_Verb_Step1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 482
+    context.i_word_len = env.current.chars().count();
+    // [, line 484
+    env.ket = env.cursor;
+    // substring, line 484
+    among_var = env.find_among_b(A_17, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 484
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 485
+        if !(context.i_word_len >= 4){
+            return false;
+        }
+        // delete, line 485
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 486
+        if !(context.i_word_len >= 5){
+            return false;
+        }
+        // delete, line 486
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 487
+        if !(context.i_word_len >= 6){
+            return false;
+        }
+        // delete, line 487
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Suffix_Verb_Step2a(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 490
+    context.i_word_len = env.current.chars().count();
+    // [, line 492
+    env.ket = env.cursor;
+    // substring, line 492
+    among_var = env.find_among_b(A_18, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 492
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 493
+        if !(context.i_word_len >= 4){
+            return false;
+        }
+        // delete, line 493
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 494
+        if !(context.i_word_len >= 4){
+            return false;
+        }
+        // delete, line 494
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 495
+        if !(context.i_word_len >= 5){
+            return false;
+        }
+        // delete, line 495
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 496
+        if !(context.i_word_len > 5){
+            return false;
+        }
+        // delete, line 496
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 497
+        if !(context.i_word_len >= 6){
+            return false;
+        }
+        // delete, line 497
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Suffix_Verb_Step2b(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 501
+    context.i_word_len = env.current.chars().count();
+    // [, line 503
+    env.ket = env.cursor;
+    // substring, line 503
+    among_var = env.find_among_b(A_19, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 503
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 504
+        if !(context.i_word_len >= 5){
+            return false;
+        }
+        // delete, line 504
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Suffix_Verb_Step2c(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 509
+    context.i_word_len = env.current.chars().count();
+    // [, line 511
+    env.ket = env.cursor;
+    // substring, line 511
+    among_var = env.find_among_b(A_20, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 511
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 512
+        if !(context.i_word_len >= 4){
+            return false;
+        }
+        // delete, line 512
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 513
+        if !(context.i_word_len >= 6){
+            return false;
+        }
+        // delete, line 513
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Suffix_All_alef_maqsura(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 517
+    context.i_word_len = env.current.chars().count();
+    // [, line 519
+    env.ket = env.cursor;
+    // substring, line 519
+    among_var = env.find_among_b(A_21, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 519
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 520
+        // <-, line 520
+        if !env.slice_from("\u{064A}") {
+            return false;
+        }
+    }
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        b_is_defined: false,
+        b_is_verb: false,
+        b_is_noun: false,
+        i_word_len: 0,
+    };
+    // (, line 527
+    // set is_noun, line 529
+    context.b_is_noun = true;
+    // set is_verb, line 530
+    context.b_is_verb = true;
+    // unset is_defined, line 531
+    context.b_is_defined = false;
+    // do, line 534
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call Checks1, line 534
+        if !r_Checks1(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 537
+    let v_2 = env.cursor;
+    'lab1: loop {
+        // call Normalize_pre, line 537
+        if !r_Normalize_pre(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = v_2;
+    // backwards, line 540
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 540
+    // do, line 542
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // (, line 542
+        // or, line 556
+        'lab3: loop {
+            let v_4 = env.limit - env.cursor;
+            'lab4: loop {
+                // (, line 544
+                // Boolean test is_verb, line 545
+                if !context.b_is_verb {
+                    break 'lab4;
+                }
+                // (, line 546
+                // or, line 551
+                'lab5: loop {
+                    let v_5 = env.limit - env.cursor;
+                    'lab6: loop {
+                        // (, line 547
+                        // (, line 548
+                        // atleast, line 548
+                        let mut v_6 = 1;
+                        // atleast, line 548
+                        'replab7: loop{
+                            let v_7 = env.limit - env.cursor;
+                            'lab8: for _ in 0..1 {
+                                // call Suffix_Verb_Step1, line 548
+                                if !r_Suffix_Verb_Step1(env, context) {
+                                    break 'lab8;
+                                }
+                                v_6 -= 1;
+                                continue 'replab7;
+                            }
+                            env.cursor = env.limit - v_7;
+                            break 'replab7;
+                        }
+                        if v_6 > 0 {
+                            break 'lab6;
+                        }
+                        // (, line 549
+                        // or, line 549
+                        'lab9: loop {
+                            let v_8 = env.limit - env.cursor;
+                            'lab10: loop {
+                                // call Suffix_Verb_Step2a, line 549
+                                if !r_Suffix_Verb_Step2a(env, context) {
+                                    break 'lab10;
+                                }
+                                break 'lab9;
+                            }
+                            env.cursor = env.limit - v_8;
+                            'lab11: loop {
+                                // call Suffix_Verb_Step2c, line 549
+                                if !r_Suffix_Verb_Step2c(env, context) {
+                                    break 'lab11;
+                                }
+                                break 'lab9;
+                            }
+                            env.cursor = env.limit - v_8;
+                            // next, line 549
+                            if env.cursor <= env.limit_backward {
+                                break 'lab6;
+                            }
+                            env.previous_char();
+                            break 'lab9;
+                        }
+                        break 'lab5;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab12: loop {
+                        // call Suffix_Verb_Step2b, line 551
+                        if !r_Suffix_Verb_Step2b(env, context) {
+                            break 'lab12;
+                        }
+                        break 'lab5;
+                    }
+                    env.cursor = env.limit - v_5;
+                    // call Suffix_Verb_Step2a, line 552
+                    if !r_Suffix_Verb_Step2a(env, context) {
+                        break 'lab4;
+                    }
+                    break 'lab5;
+                }
+                break 'lab3;
+            }
+            env.cursor = env.limit - v_4;
+            'lab13: loop {
+                // (, line 556
+                // Boolean test is_noun, line 557
+                if !context.b_is_noun {
+                    break 'lab13;
+                }
+                // (, line 558
+                // try, line 560
+                let v_9 = env.limit - env.cursor;
+                'lab14: loop {
+                    // (, line 560
+                    // or, line 562
+                    'lab15: loop {
+                        let v_10 = env.limit - env.cursor;
+                        'lab16: loop {
+                            // call Suffix_Noun_Step2c2, line 561
+                            if !r_Suffix_Noun_Step2c2(env, context) {
+                                break 'lab16;
+                            }
+                            break 'lab15;
+                        }
+                        env.cursor = env.limit - v_10;
+                        'lab17: loop {
+                            // (, line 562
+                            // not, line 562
+                            'lab18: loop {
+                                // Boolean test is_defined, line 562
+                                if !context.b_is_defined {
+                                    break 'lab18;
+                                }
+                                break 'lab17;
+                            }
+                            // call Suffix_Noun_Step1a, line 562
+                            if !r_Suffix_Noun_Step1a(env, context) {
+                                break 'lab17;
+                            }
+                            // (, line 562
+                            // or, line 564
+                            'lab19: loop {
+                                let v_12 = env.limit - env.cursor;
+                                'lab20: loop {
+                                    // call Suffix_Noun_Step2a, line 563
+                                    if !r_Suffix_Noun_Step2a(env, context) {
+                                        break 'lab20;
+                                    }
+                                    break 'lab19;
+                                }
+                                env.cursor = env.limit - v_12;
+                                'lab21: loop {
+                                    // call Suffix_Noun_Step2b, line 564
+                                    if !r_Suffix_Noun_Step2b(env, context) {
+                                        break 'lab21;
+                                    }
+                                    break 'lab19;
+                                }
+                                env.cursor = env.limit - v_12;
+                                'lab22: loop {
+                                    // call Suffix_Noun_Step2c1, line 565
+                                    if !r_Suffix_Noun_Step2c1(env, context) {
+                                        break 'lab22;
+                                    }
+                                    break 'lab19;
+                                }
+                                env.cursor = env.limit - v_12;
+                                // next, line 566
+                                if env.cursor <= env.limit_backward {
+                                    break 'lab17;
+                                }
+                                env.previous_char();
+                                break 'lab19;
+                            }
+                            break 'lab15;
+                        }
+                        env.cursor = env.limit - v_10;
+                        'lab23: loop {
+                            // (, line 567
+                            // call Suffix_Noun_Step1b, line 567
+                            if !r_Suffix_Noun_Step1b(env, context) {
+                                break 'lab23;
+                            }
+                            // (, line 567
+                            // or, line 569
+                            'lab24: loop {
+                                let v_13 = env.limit - env.cursor;
+                                'lab25: loop {
+                                    // call Suffix_Noun_Step2a, line 568
+                                    if !r_Suffix_Noun_Step2a(env, context) {
+                                        break 'lab25;
+                                    }
+                                    break 'lab24;
+                                }
+                                env.cursor = env.limit - v_13;
+                                'lab26: loop {
+                                    // call Suffix_Noun_Step2b, line 569
+                                    if !r_Suffix_Noun_Step2b(env, context) {
+                                        break 'lab26;
+                                    }
+                                    break 'lab24;
+                                }
+                                env.cursor = env.limit - v_13;
+                                // call Suffix_Noun_Step2c1, line 570
+                                if !r_Suffix_Noun_Step2c1(env, context) {
+                                    break 'lab23;
+                                }
+                                break 'lab24;
+                            }
+                            break 'lab15;
+                        }
+                        env.cursor = env.limit - v_10;
+                        'lab27: loop {
+                            // (, line 571
+                            // not, line 571
+                            'lab28: loop {
+                                // Boolean test is_defined, line 571
+                                if !context.b_is_defined {
+                                    break 'lab28;
+                                }
+                                break 'lab27;
+                            }
+                            // call Suffix_Noun_Step2a, line 571
+                            if !r_Suffix_Noun_Step2a(env, context) {
+                                break 'lab27;
+                            }
+                            break 'lab15;
+                        }
+                        env.cursor = env.limit - v_10;
+                        // (, line 572
+                        // call Suffix_Noun_Step2b, line 572
+                        if !r_Suffix_Noun_Step2b(env, context) {
+                            env.cursor = env.limit - v_9;
+                            break 'lab14;
+                        }
+                        break 'lab15;
+                    }
+                    break 'lab14;
+                }
+                // call Suffix_Noun_Step3, line 574
+                if !r_Suffix_Noun_Step3(env, context) {
+                    break 'lab13;
+                }
+                break 'lab3;
+            }
+            env.cursor = env.limit - v_4;
+            // call Suffix_All_alef_maqsura, line 580
+            if !r_Suffix_All_alef_maqsura(env, context) {
+                break 'lab2;
+            }
+            break 'lab3;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    env.cursor = env.limit_backward;
+    // do, line 585
+    let v_15 = env.cursor;
+    'lab29: loop {
+        // (, line 585
+        // try, line 586
+        let v_16 = env.cursor;
+        'lab30: loop {
+            // call Prefix_Step1, line 586
+            if !r_Prefix_Step1(env, context) {
+                env.cursor = v_16;
+                break 'lab30;
+            }
+            break 'lab30;
+        }
+        // try, line 587
+        let v_17 = env.cursor;
+        'lab31: loop {
+            // call Prefix_Step2, line 587
+            if !r_Prefix_Step2(env, context) {
+                env.cursor = v_17;
+                break 'lab31;
+            }
+            break 'lab31;
+        }
+        // (, line 588
+        // or, line 589
+        'lab32: loop {
+            let v_18 = env.cursor;
+            'lab33: loop {
+                // call Prefix_Step3a_Noun, line 588
+                if !r_Prefix_Step3a_Noun(env, context) {
+                    break 'lab33;
+                }
+                break 'lab32;
+            }
+            env.cursor = v_18;
+            'lab34: loop {
+                // (, line 589
+                // Boolean test is_noun, line 589
+                if !context.b_is_noun {
+                    break 'lab34;
+                }
+                // call Prefix_Step3b_Noun, line 589
+                if !r_Prefix_Step3b_Noun(env, context) {
+                    break 'lab34;
+                }
+                break 'lab32;
+            }
+            env.cursor = v_18;
+            // (, line 590
+            // Boolean test is_verb, line 590
+            if !context.b_is_verb {
+                break 'lab29;
+            }
+            // try, line 590
+            let v_19 = env.cursor;
+            'lab35: loop {
+                // call Prefix_Step3_Verb, line 590
+                if !r_Prefix_Step3_Verb(env, context) {
+                    env.cursor = v_19;
+                    break 'lab35;
+                }
+                break 'lab35;
+            }
+            // call Prefix_Step4_Verb, line 590
+            if !r_Prefix_Step4_Verb(env, context) {
+                break 'lab29;
+            }
+            break 'lab32;
+        }
+        break 'lab29;
+    }
+    env.cursor = v_15;
+    // do, line 595
+    let v_20 = env.cursor;
+    'lab36: loop {
+        // call Normalize_post, line 595
+        if !r_Normalize_post(env, context) {
+            break 'lab36;
+        }
+        break 'lab36;
+    }
+    env.cursor = v_20;
+    return true;
+}
diff --git a/src/snowball/algorithms/danish.rs b/src/snowball/algorithms/danish.rs
new file mode 100644
index 0000000..ece430c
--- /dev/null
+++ b/src/snowball/algorithms/danish.rs
@@ -0,0 +1,394 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 32] = &[
+    Among("hed", -1, 1, None),
+    Among("ethed", 0, 1, None),
+    Among("ered", -1, 1, None),
+    Among("e", -1, 1, None),
+    Among("erede", 3, 1, None),
+    Among("ende", 3, 1, None),
+    Among("erende", 5, 1, None),
+    Among("ene", 3, 1, None),
+    Among("erne", 3, 1, None),
+    Among("ere", 3, 1, None),
+    Among("en", -1, 1, None),
+    Among("heden", 10, 1, None),
+    Among("eren", 10, 1, None),
+    Among("er", -1, 1, None),
+    Among("heder", 13, 1, None),
+    Among("erer", 13, 1, None),
+    Among("s", -1, 2, None),
+    Among("heds", 16, 1, None),
+    Among("es", 16, 1, None),
+    Among("endes", 18, 1, None),
+    Among("erendes", 19, 1, None),
+    Among("enes", 18, 1, None),
+    Among("ernes", 18, 1, None),
+    Among("eres", 18, 1, None),
+    Among("ens", 16, 1, None),
+    Among("hedens", 24, 1, None),
+    Among("erens", 24, 1, None),
+    Among("ers", 16, 1, None),
+    Among("ets", 16, 1, None),
+    Among("erets", 28, 1, None),
+    Among("et", -1, 1, None),
+    Among("eret", 30, 1, None),
+];
+
+static A_1: &'static [Among<Context>; 4] = &[
+    Among("gd", -1, -1, None),
+    Among("dt", -1, -1, None),
+    Among("gt", -1, -1, None),
+    Among("kt", -1, -1, None),
+];
+
+static A_2: &'static [Among<Context>; 5] = &[
+    Among("ig", -1, 1, None),
+    Among("lig", 0, 1, None),
+    Among("elig", 1, 1, None),
+    Among("els", -1, 1, None),
+    Among("l\u{00F8}st", -1, 2, None),
+];
+
+static G_v: &'static [u8; 19] = &[17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128];
+
+static G_s_ending: &'static [u8; 17] = &[239, 254, 42, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16];
+
+#[derive(Clone)]
+struct Context {
+    i_x: usize,
+    i_p1: usize,
+    S_ch: String,
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 29
+    context.i_p1 = env.limit;
+    // test, line 33
+    let v_1 = env.cursor;
+    // (, line 33
+    // hop, line 33
+    let c = env.byte_index_for_hop(3);
+    if 0 as i32 > c || c > env.limit as i32 {
+        return false;
+    }
+    env.cursor = c as usize;
+    // setmark x, line 33
+    context.i_x = env.cursor;
+    env.cursor = v_1;
+    // goto, line 34
+    'golab0: loop {
+        let v_2 = env.cursor;
+        'lab1: loop {
+            if !env.in_grouping(G_v, 97, 248) {
+                break 'lab1;
+            }
+            env.cursor = v_2;
+            break 'golab0;
+        }
+        env.cursor = v_2;
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // gopast, line 34
+    'golab2: loop {
+        'lab3: loop {
+            if !env.out_grouping(G_v, 97, 248) {
+                break 'lab3;
+            }
+            break 'golab2;
+        }
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // setmark p1, line 34
+    context.i_p1 = env.cursor;
+    // try, line 35
+    'lab4: loop {
+        // (, line 35
+        if !(context.i_p1 < context.i_x){
+            break 'lab4;
+        }
+        context.i_p1 = context.i_x;
+        break 'lab4;
+    }
+    return true;
+}
+
+fn r_main_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 40
+    // setlimit, line 41
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 41
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    env.cursor = context.i_p1;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 41
+    // [, line 41
+    env.ket = env.cursor;
+    // substring, line 41
+    among_var = env.find_among_b(A_0, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 41
+    env.bra = env.cursor;
+    env.limit_backward = v_2;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 48
+        // delete, line 48
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 50
+        if !env.in_grouping_b(G_s_ending, 97, 229) {
+            return false;
+        }
+        // delete, line 50
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_consonant_pair(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 54
+    // test, line 55
+    let v_1 = env.limit - env.cursor;
+    // (, line 55
+    // setlimit, line 56
+    let v_2 = env.limit - env.cursor;
+    // tomark, line 56
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    env.cursor = context.i_p1;
+    let v_3 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_2;
+    // (, line 56
+    // [, line 56
+    env.ket = env.cursor;
+    // substring, line 56
+    if env.find_among_b(A_1, context) == 0 {
+        env.limit_backward = v_3;
+        return false;
+    }
+    // ], line 56
+    env.bra = env.cursor;
+    env.limit_backward = v_3;
+    env.cursor = env.limit - v_1;
+    // next, line 62
+    if env.cursor <= env.limit_backward {
+        return false;
+    }
+    env.previous_char();
+    // ], line 62
+    env.bra = env.cursor;
+    // delete, line 62
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+fn r_other_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 65
+    // do, line 66
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 66
+        // [, line 66
+        env.ket = env.cursor;
+        // literal, line 66
+        if !env.eq_s_b(&"st") {
+            break 'lab0;
+        }
+        // ], line 66
+        env.bra = env.cursor;
+        // literal, line 66
+        if !env.eq_s_b(&"ig") {
+            break 'lab0;
+        }
+        // delete, line 66
+        if !env.slice_del() {
+            return false;
+        }
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    // setlimit, line 67
+    let v_2 = env.limit - env.cursor;
+    // tomark, line 67
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    env.cursor = context.i_p1;
+    let v_3 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_2;
+    // (, line 67
+    // [, line 67
+    env.ket = env.cursor;
+    // substring, line 67
+    among_var = env.find_among_b(A_2, context);
+    if among_var == 0 {
+        env.limit_backward = v_3;
+        return false;
+    }
+    // ], line 67
+    env.bra = env.cursor;
+    env.limit_backward = v_3;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 70
+        // delete, line 70
+        if !env.slice_del() {
+            return false;
+        }
+        // do, line 70
+        let v_4 = env.limit - env.cursor;
+        'lab1: loop {
+            // call consonant_pair, line 70
+            if !r_consonant_pair(env, context) {
+                break 'lab1;
+            }
+            break 'lab1;
+        }
+        env.cursor = env.limit - v_4;
+    } else if among_var == 2 {
+        // (, line 72
+        // <-, line 72
+        if !env.slice_from("l\u{00F8}s") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_undouble(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 75
+    // setlimit, line 76
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 76
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    env.cursor = context.i_p1;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 76
+    // [, line 76
+    env.ket = env.cursor;
+    if !env.out_grouping_b(G_v, 97, 248) {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 76
+    env.bra = env.cursor;
+    // -> ch, line 76
+    context.S_ch = env.slice_to();
+    if context.S_ch.is_empty() {
+        return false;
+    }
+    env.limit_backward = v_2;
+    // name ch, line 77
+    if !env.eq_s_b(&context.S_ch) {
+        return false;
+    }
+    // delete, line 78
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        i_x: 0,
+        i_p1: 0,
+        S_ch: String::new(),
+    };
+    // (, line 82
+    // do, line 84
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call mark_regions, line 84
+        if !r_mark_regions(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // backwards, line 85
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 85
+    // do, line 86
+    let v_2 = env.limit - env.cursor;
+    'lab1: loop {
+        // call main_suffix, line 86
+        if !r_main_suffix(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = env.limit - v_2;
+    // do, line 87
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // call consonant_pair, line 87
+        if !r_consonant_pair(env, context) {
+            break 'lab2;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    // do, line 88
+    let v_4 = env.limit - env.cursor;
+    'lab3: loop {
+        // call other_suffix, line 88
+        if !r_other_suffix(env, context) {
+            break 'lab3;
+        }
+        break 'lab3;
+    }
+    env.cursor = env.limit - v_4;
+    // do, line 89
+    let v_5 = env.limit - env.cursor;
+    'lab4: loop {
+        // call undouble, line 89
+        if !r_undouble(env, context) {
+            break 'lab4;
+        }
+        break 'lab4;
+    }
+    env.cursor = env.limit - v_5;
+    env.cursor = env.limit_backward;
+    return true;
+}
diff --git a/src/snowball/algorithms/dutch.rs b/src/snowball/algorithms/dutch.rs
new file mode 100644
index 0000000..4f235ed
--- /dev/null
+++ b/src/snowball/algorithms/dutch.rs
@@ -0,0 +1,770 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 11] = &[
+    Among("", -1, 6, None),
+    Among("\u{00E1}", 0, 1, None),
+    Among("\u{00E4}", 0, 1, None),
+    Among("\u{00E9}", 0, 2, None),
+    Among("\u{00EB}", 0, 2, None),
+    Among("\u{00ED}", 0, 3, None),
+    Among("\u{00EF}", 0, 3, None),
+    Among("\u{00F3}", 0, 4, None),
+    Among("\u{00F6}", 0, 4, None),
+    Among("\u{00FA}", 0, 5, None),
+    Among("\u{00FC}", 0, 5, None),
+];
+
+static A_1: &'static [Among<Context>; 3] = &[
+    Among("", -1, 3, None),
+    Among("I", 0, 2, None),
+    Among("Y", 0, 1, None),
+];
+
+static A_2: &'static [Among<Context>; 3] = &[
+    Among("dd", -1, -1, None),
+    Among("kk", -1, -1, None),
+    Among("tt", -1, -1, None),
+];
+
+static A_3: &'static [Among<Context>; 5] = &[
+    Among("ene", -1, 2, None),
+    Among("se", -1, 3, None),
+    Among("en", -1, 2, None),
+    Among("heden", 2, 1, None),
+    Among("s", -1, 3, None),
+];
+
+static A_4: &'static [Among<Context>; 6] = &[
+    Among("end", -1, 1, None),
+    Among("ig", -1, 2, None),
+    Among("ing", -1, 1, None),
+    Among("lijk", -1, 3, None),
+    Among("baar", -1, 4, None),
+    Among("bar", -1, 5, None),
+];
+
+static A_5: &'static [Among<Context>; 4] = &[
+    Among("aa", -1, -1, None),
+    Among("ee", -1, -1, None),
+    Among("oo", -1, -1, None),
+    Among("uu", -1, -1, None),
+];
+
+static G_v: &'static [u8; 17] = &[17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128];
+
+static G_v_I: &'static [u8; 20] = &[1, 0, 0, 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128];
+
+static G_v_j: &'static [u8; 17] = &[17, 67, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128];
+
+#[derive(Clone)]
+struct Context {
+    i_p2: usize,
+    i_p1: usize,
+    b_e_found: bool,
+}
+
+fn r_prelude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 41
+    // test, line 42
+    let v_1 = env.cursor;
+    // repeat, line 42
+    'replab0: loop{
+        let v_2 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 42
+            // [, line 43
+            env.bra = env.cursor;
+            // substring, line 43
+            among_var = env.find_among(A_0, context);
+            if among_var == 0 {
+                break 'lab1;
+            }
+            // ], line 43
+            env.ket = env.cursor;
+            if among_var == 0 {
+                break 'lab1;
+            } else if among_var == 1 {
+                // (, line 45
+                // <-, line 45
+                if !env.slice_from("a") {
+                    return false;
+                }
+            } else if among_var == 2 {
+                // (, line 47
+                // <-, line 47
+                if !env.slice_from("e") {
+                    return false;
+                }
+            } else if among_var == 3 {
+                // (, line 49
+                // <-, line 49
+                if !env.slice_from("i") {
+                    return false;
+                }
+            } else if among_var == 4 {
+                // (, line 51
+                // <-, line 51
+                if !env.slice_from("o") {
+                    return false;
+                }
+            } else if among_var == 5 {
+                // (, line 53
+                // <-, line 53
+                if !env.slice_from("u") {
+                    return false;
+                }
+            } else if among_var == 6 {
+                // (, line 54
+                // next, line 54
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_2;
+        break 'replab0;
+    }
+    env.cursor = v_1;
+    // try, line 57
+    let v_3 = env.cursor;
+    'lab2: loop {
+        // (, line 57
+        // [, line 57
+        env.bra = env.cursor;
+        // literal, line 57
+        if !env.eq_s(&"y") {
+            env.cursor = v_3;
+            break 'lab2;
+        }
+        // ], line 57
+        env.ket = env.cursor;
+        // <-, line 57
+        if !env.slice_from("Y") {
+            return false;
+        }
+        break 'lab2;
+    }
+    // repeat, line 58
+    'replab3: loop{
+        let v_4 = env.cursor;
+        'lab4: for _ in 0..1 {
+            // goto, line 58
+            'golab5: loop {
+                let v_5 = env.cursor;
+                'lab6: loop {
+                    // (, line 58
+                    if !env.in_grouping(G_v, 97, 232) {
+                        break 'lab6;
+                    }
+                    // [, line 59
+                    env.bra = env.cursor;
+                    // or, line 59
+                    'lab7: loop {
+                        let v_6 = env.cursor;
+                        'lab8: loop {
+                            // (, line 59
+                            // literal, line 59
+                            if !env.eq_s(&"i") {
+                                break 'lab8;
+                            }
+                            // ], line 59
+                            env.ket = env.cursor;
+                            if !env.in_grouping(G_v, 97, 232) {
+                                break 'lab8;
+                            }
+                            // <-, line 59
+                            if !env.slice_from("I") {
+                                return false;
+                            }
+                            break 'lab7;
+                        }
+                        env.cursor = v_6;
+                        // (, line 60
+                        // literal, line 60
+                        if !env.eq_s(&"y") {
+                            break 'lab6;
+                        }
+                        // ], line 60
+                        env.ket = env.cursor;
+                        // <-, line 60
+                        if !env.slice_from("Y") {
+                            return false;
+                        }
+                        break 'lab7;
+                    }
+                    env.cursor = v_5;
+                    break 'golab5;
+                }
+                env.cursor = v_5;
+                if env.cursor >= env.limit {
+                    break 'lab4;
+                }
+                env.next_char();
+            }
+            continue 'replab3;
+        }
+        env.cursor = v_4;
+        break 'replab3;
+    }
+    return true;
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 64
+    context.i_p1 = env.limit;
+    context.i_p2 = env.limit;
+    // gopast, line 69
+    'golab0: loop {
+        'lab1: loop {
+            if !env.in_grouping(G_v, 97, 232) {
+                break 'lab1;
+            }
+            break 'golab0;
+        }
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // gopast, line 69
+    'golab2: loop {
+        'lab3: loop {
+            if !env.out_grouping(G_v, 97, 232) {
+                break 'lab3;
+            }
+            break 'golab2;
+        }
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // setmark p1, line 69
+    context.i_p1 = env.cursor;
+    // try, line 70
+    'lab4: loop {
+        // (, line 70
+        if !(context.i_p1 < 3){
+            break 'lab4;
+        }
+        context.i_p1 = 3;
+        break 'lab4;
+    }
+    // gopast, line 71
+    'golab5: loop {
+        'lab6: loop {
+            if !env.in_grouping(G_v, 97, 232) {
+                break 'lab6;
+            }
+            break 'golab5;
+        }
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // gopast, line 71
+    'golab7: loop {
+        'lab8: loop {
+            if !env.out_grouping(G_v, 97, 232) {
+                break 'lab8;
+            }
+            break 'golab7;
+        }
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // setmark p2, line 71
+    context.i_p2 = env.cursor;
+    return true;
+}
+
+fn r_postlude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // repeat, line 75
+    'replab0: loop{
+        let v_1 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 75
+            // [, line 77
+            env.bra = env.cursor;
+            // substring, line 77
+            among_var = env.find_among(A_1, context);
+            if among_var == 0 {
+                break 'lab1;
+            }
+            // ], line 77
+            env.ket = env.cursor;
+            if among_var == 0 {
+                break 'lab1;
+            } else if among_var == 1 {
+                // (, line 78
+                // <-, line 78
+                if !env.slice_from("y") {
+                    return false;
+                }
+            } else if among_var == 2 {
+                // (, line 79
+                // <-, line 79
+                if !env.slice_from("i") {
+                    return false;
+                }
+            } else if among_var == 3 {
+                // (, line 80
+                // next, line 80
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+fn r_R1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p1 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_R2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p2 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_undouble(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 90
+    // test, line 91
+    let v_1 = env.limit - env.cursor;
+    // among, line 91
+    if env.find_among_b(A_2, context) == 0 {
+        return false;
+    }
+    env.cursor = env.limit - v_1;
+    // [, line 91
+    env.ket = env.cursor;
+    // next, line 91
+    if env.cursor <= env.limit_backward {
+        return false;
+    }
+    env.previous_char();
+    // ], line 91
+    env.bra = env.cursor;
+    // delete, line 91
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+fn r_e_ending(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 94
+    // unset e_found, line 95
+    context.b_e_found = false;
+    // [, line 96
+    env.ket = env.cursor;
+    // literal, line 96
+    if !env.eq_s_b(&"e") {
+        return false;
+    }
+    // ], line 96
+    env.bra = env.cursor;
+    // call R1, line 96
+    if !r_R1(env, context) {
+        return false;
+    }
+    // test, line 96
+    let v_1 = env.limit - env.cursor;
+    if !env.out_grouping_b(G_v, 97, 232) {
+        return false;
+    }
+    env.cursor = env.limit - v_1;
+    // delete, line 96
+    if !env.slice_del() {
+        return false;
+    }
+    // set e_found, line 97
+    context.b_e_found = true;
+    // call undouble, line 98
+    if !r_undouble(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_en_ending(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 101
+    // call R1, line 102
+    if !r_R1(env, context) {
+        return false;
+    }
+    // and, line 102
+    let v_1 = env.limit - env.cursor;
+    if !env.out_grouping_b(G_v, 97, 232) {
+        return false;
+    }
+    env.cursor = env.limit - v_1;
+    // not, line 102
+    let v_2 = env.limit - env.cursor;
+    'lab0: loop {
+        // literal, line 102
+        if !env.eq_s_b(&"gem") {
+            break 'lab0;
+        }
+        return false;
+    }
+    env.cursor = env.limit - v_2;
+    // delete, line 102
+    if !env.slice_del() {
+        return false;
+    }
+    // call undouble, line 103
+    if !r_undouble(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_standard_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 106
+    // do, line 107
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 107
+        // [, line 108
+        env.ket = env.cursor;
+        // substring, line 108
+        among_var = env.find_among_b(A_3, context);
+        if among_var == 0 {
+            break 'lab0;
+        }
+        // ], line 108
+        env.bra = env.cursor;
+        if among_var == 0 {
+            break 'lab0;
+        } else if among_var == 1 {
+            // (, line 110
+            // call R1, line 110
+            if !r_R1(env, context) {
+                break 'lab0;
+            }
+            // <-, line 110
+            if !env.slice_from("heid") {
+                return false;
+            }
+        } else if among_var == 2 {
+            // (, line 113
+            // call en_ending, line 113
+            if !r_en_ending(env, context) {
+                break 'lab0;
+            }
+        } else if among_var == 3 {
+            // (, line 116
+            // call R1, line 116
+            if !r_R1(env, context) {
+                break 'lab0;
+            }
+            if !env.out_grouping_b(G_v_j, 97, 232) {
+                break 'lab0;
+            }
+            // delete, line 116
+            if !env.slice_del() {
+                return false;
+            }
+        }
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    // do, line 120
+    let v_2 = env.limit - env.cursor;
+    'lab1: loop {
+        // call e_ending, line 120
+        if !r_e_ending(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = env.limit - v_2;
+    // do, line 122
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // (, line 122
+        // [, line 122
+        env.ket = env.cursor;
+        // literal, line 122
+        if !env.eq_s_b(&"heid") {
+            break 'lab2;
+        }
+        // ], line 122
+        env.bra = env.cursor;
+        // call R2, line 122
+        if !r_R2(env, context) {
+            break 'lab2;
+        }
+        // not, line 122
+        let v_4 = env.limit - env.cursor;
+        'lab3: loop {
+            // literal, line 122
+            if !env.eq_s_b(&"c") {
+                break 'lab3;
+            }
+            break 'lab2;
+        }
+        env.cursor = env.limit - v_4;
+        // delete, line 122
+        if !env.slice_del() {
+            return false;
+        }
+        // [, line 123
+        env.ket = env.cursor;
+        // literal, line 123
+        if !env.eq_s_b(&"en") {
+            break 'lab2;
+        }
+        // ], line 123
+        env.bra = env.cursor;
+        // call en_ending, line 123
+        if !r_en_ending(env, context) {
+            break 'lab2;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    // do, line 126
+    let v_5 = env.limit - env.cursor;
+    'lab4: loop {
+        // (, line 126
+        // [, line 127
+        env.ket = env.cursor;
+        // substring, line 127
+        among_var = env.find_among_b(A_4, context);
+        if among_var == 0 {
+            break 'lab4;
+        }
+        // ], line 127
+        env.bra = env.cursor;
+        if among_var == 0 {
+            break 'lab4;
+        } else if among_var == 1 {
+            // (, line 129
+            // call R2, line 129
+            if !r_R2(env, context) {
+                break 'lab4;
+            }
+            // delete, line 129
+            if !env.slice_del() {
+                return false;
+            }
+            // or, line 130
+            'lab5: loop {
+                let v_6 = env.limit - env.cursor;
+                'lab6: loop {
+                    // (, line 130
+                    // [, line 130
+                    env.ket = env.cursor;
+                    // literal, line 130
+                    if !env.eq_s_b(&"ig") {
+                        break 'lab6;
+                    }
+                    // ], line 130
+                    env.bra = env.cursor;
+                    // call R2, line 130
+                    if !r_R2(env, context) {
+                        break 'lab6;
+                    }
+                    // not, line 130
+                    let v_7 = env.limit - env.cursor;
+                    'lab7: loop {
+                        // literal, line 130
+                        if !env.eq_s_b(&"e") {
+                            break 'lab7;
+                        }
+                        break 'lab6;
+                    }
+                    env.cursor = env.limit - v_7;
+                    // delete, line 130
+                    if !env.slice_del() {
+                        return false;
+                    }
+                    break 'lab5;
+                }
+                env.cursor = env.limit - v_6;
+                // call undouble, line 130
+                if !r_undouble(env, context) {
+                    break 'lab4;
+                }
+                break 'lab5;
+            }
+        } else if among_var == 2 {
+            // (, line 133
+            // call R2, line 133
+            if !r_R2(env, context) {
+                break 'lab4;
+            }
+            // not, line 133
+            let v_8 = env.limit - env.cursor;
+            'lab8: loop {
+                // literal, line 133
+                if !env.eq_s_b(&"e") {
+                    break 'lab8;
+                }
+                break 'lab4;
+            }
+            env.cursor = env.limit - v_8;
+            // delete, line 133
+            if !env.slice_del() {
+                return false;
+            }
+        } else if among_var == 3 {
+            // (, line 136
+            // call R2, line 136
+            if !r_R2(env, context) {
+                break 'lab4;
+            }
+            // delete, line 136
+            if !env.slice_del() {
+                return false;
+            }
+            // call e_ending, line 136
+            if !r_e_ending(env, context) {
+                break 'lab4;
+            }
+        } else if among_var == 4 {
+            // (, line 139
+            // call R2, line 139
+            if !r_R2(env, context) {
+                break 'lab4;
+            }
+            // delete, line 139
+            if !env.slice_del() {
+                return false;
+            }
+        } else if among_var == 5 {
+            // (, line 142
+            // call R2, line 142
+            if !r_R2(env, context) {
+                break 'lab4;
+            }
+            // Boolean test e_found, line 142
+            if !context.b_e_found {
+                break 'lab4;
+            }
+            // delete, line 142
+            if !env.slice_del() {
+                return false;
+            }
+        }
+        break 'lab4;
+    }
+    env.cursor = env.limit - v_5;
+    // do, line 146
+    let v_9 = env.limit - env.cursor;
+    'lab9: loop {
+        // (, line 146
+        if !env.out_grouping_b(G_v_I, 73, 232) {
+            break 'lab9;
+        }
+        // test, line 148
+        let v_10 = env.limit - env.cursor;
+        // (, line 148
+        // among, line 149
+        if env.find_among_b(A_5, context) == 0 {
+            break 'lab9;
+        }
+        if !env.out_grouping_b(G_v, 97, 232) {
+            break 'lab9;
+        }
+        env.cursor = env.limit - v_10;
+        // [, line 152
+        env.ket = env.cursor;
+        // next, line 152
+        if env.cursor <= env.limit_backward {
+            break 'lab9;
+        }
+        env.previous_char();
+        // ], line 152
+        env.bra = env.cursor;
+        // delete, line 152
+        if !env.slice_del() {
+            return false;
+        }
+        break 'lab9;
+    }
+    env.cursor = env.limit - v_9;
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        i_p2: 0,
+        i_p1: 0,
+        b_e_found: false,
+    };
+    // (, line 157
+    // do, line 159
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call prelude, line 159
+        if !r_prelude(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 160
+    let v_2 = env.cursor;
+    'lab1: loop {
+        // call mark_regions, line 160
+        if !r_mark_regions(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = v_2;
+    // backwards, line 161
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // do, line 162
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // call standard_suffix, line 162
+        if !r_standard_suffix(env, context) {
+            break 'lab2;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    env.cursor = env.limit_backward;
+    // do, line 163
+    let v_4 = env.cursor;
+    'lab3: loop {
+        // call postlude, line 163
+        if !r_postlude(env, context) {
+            break 'lab3;
+        }
+        break 'lab3;
+    }
+    env.cursor = v_4;
+    return true;
+}
diff --git a/src/snowball/algorithms/english.rs b/src/snowball/algorithms/english.rs
new file mode 100644
index 0000000..9ce6da9
--- /dev/null
+++ b/src/snowball/algorithms/english.rs
@@ -0,0 +1,1249 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 3] = &[
+    Among("arsen", -1, -1, None),
+    Among("commun", -1, -1, None),
+    Among("gener", -1, -1, None),
+];
+
+static A_1: &'static [Among<Context>; 3] = &[
+    Among("'", -1, 1, None),
+    Among("'s'", 0, 1, None),
+    Among("'s", -1, 1, None),
+];
+
+static A_2: &'static [Among<Context>; 6] = &[
+    Among("ied", -1, 2, None),
+    Among("s", -1, 3, None),
+    Among("ies", 1, 2, None),
+    Among("sses", 1, 1, None),
+    Among("ss", 1, -1, None),
+    Among("us", 1, -1, None),
+];
+
+static A_3: &'static [Among<Context>; 13] = &[
+    Among("", -1, 3, None),
+    Among("bb", 0, 2, None),
+    Among("dd", 0, 2, None),
+    Among("ff", 0, 2, None),
+    Among("gg", 0, 2, None),
+    Among("bl", 0, 1, None),
+    Among("mm", 0, 2, None),
+    Among("nn", 0, 2, None),
+    Among("pp", 0, 2, None),
+    Among("rr", 0, 2, None),
+    Among("at", 0, 1, None),
+    Among("tt", 0, 2, None),
+    Among("iz", 0, 1, None),
+];
+
+static A_4: &'static [Among<Context>; 6] = &[
+    Among("ed", -1, 2, None),
+    Among("eed", 0, 1, None),
+    Among("ing", -1, 2, None),
+    Among("edly", -1, 2, None),
+    Among("eedly", 3, 1, None),
+    Among("ingly", -1, 2, None),
+];
+
+static A_5: &'static [Among<Context>; 24] = &[
+    Among("anci", -1, 3, None),
+    Among("enci", -1, 2, None),
+    Among("ogi", -1, 13, None),
+    Among("li", -1, 16, None),
+    Among("bli", 3, 12, None),
+    Among("abli", 4, 4, None),
+    Among("alli", 3, 8, None),
+    Among("fulli", 3, 14, None),
+    Among("lessli", 3, 15, None),
+    Among("ousli", 3, 10, None),
+    Among("entli", 3, 5, None),
+    Among("aliti", -1, 8, None),
+    Among("biliti", -1, 12, None),
+    Among("iviti", -1, 11, None),
+    Among("tional", -1, 1, None),
+    Among("ational", 14, 7, None),
+    Among("alism", -1, 8, None),
+    Among("ation", -1, 7, None),
+    Among("ization", 17, 6, None),
+    Among("izer", -1, 6, None),
+    Among("ator", -1, 7, None),
+    Among("iveness", -1, 11, None),
+    Among("fulness", -1, 9, None),
+    Among("ousness", -1, 10, None),
+];
+
+static A_6: &'static [Among<Context>; 9] = &[
+    Among("icate", -1, 4, None),
+    Among("ative", -1, 6, None),
+    Among("alize", -1, 3, None),
+    Among("iciti", -1, 4, None),
+    Among("ical", -1, 4, None),
+    Among("tional", -1, 1, None),
+    Among("ational", 5, 2, None),
+    Among("ful", -1, 5, None),
+    Among("ness", -1, 5, None),
+];
+
+static A_7: &'static [Among<Context>; 18] = &[
+    Among("ic", -1, 1, None),
+    Among("ance", -1, 1, None),
+    Among("ence", -1, 1, None),
+    Among("able", -1, 1, None),
+    Among("ible", -1, 1, None),
+    Among("ate", -1, 1, None),
+    Among("ive", -1, 1, None),
+    Among("ize", -1, 1, None),
+    Among("iti", -1, 1, None),
+    Among("al", -1, 1, None),
+    Among("ism", -1, 1, None),
+    Among("ion", -1, 2, None),
+    Among("er", -1, 1, None),
+    Among("ous", -1, 1, None),
+    Among("ant", -1, 1, None),
+    Among("ent", -1, 1, None),
+    Among("ment", 15, 1, None),
+    Among("ement", 16, 1, None),
+];
+
+static A_8: &'static [Among<Context>; 2] = &[
+    Among("e", -1, 1, None),
+    Among("l", -1, 2, None),
+];
+
+static A_9: &'static [Among<Context>; 8] = &[
+    Among("succeed", -1, -1, None),
+    Among("proceed", -1, -1, None),
+    Among("exceed", -1, -1, None),
+    Among("canning", -1, -1, None),
+    Among("inning", -1, -1, None),
+    Among("earring", -1, -1, None),
+    Among("herring", -1, -1, None),
+    Among("outing", -1, -1, None),
+];
+
+static A_10: &'static [Among<Context>; 18] = &[
+    Among("andes", -1, -1, None),
+    Among("atlas", -1, -1, None),
+    Among("bias", -1, -1, None),
+    Among("cosmos", -1, -1, None),
+    Among("dying", -1, 3, None),
+    Among("early", -1, 9, None),
+    Among("gently", -1, 7, None),
+    Among("howe", -1, -1, None),
+    Among("idly", -1, 6, None),
+    Among("lying", -1, 4, None),
+    Among("news", -1, -1, None),
+    Among("only", -1, 10, None),
+    Among("singly", -1, 11, None),
+    Among("skies", -1, 2, None),
+    Among("skis", -1, 1, None),
+    Among("sky", -1, -1, None),
+    Among("tying", -1, 5, None),
+    Among("ugly", -1, 8, None),
+];
+
+static G_v: &'static [u8; 4] = &[17, 65, 16, 1];
+
+static G_v_WXY: &'static [u8; 5] = &[1, 17, 65, 208, 1];
+
+static G_valid_LI: &'static [u8; 3] = &[55, 141, 2];
+
+#[derive(Clone)]
+struct Context {
+    b_Y_found: bool,
+    i_p2: usize,
+    i_p1: usize,
+}
+
+fn r_prelude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 25
+    // unset Y_found, line 26
+    context.b_Y_found = false;
+    // do, line 27
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // (, line 27
+        // [, line 27
+        env.bra = env.cursor;
+        // literal, line 27
+        if !env.eq_s(&"'") {
+            break 'lab0;
+        }
+        // ], line 27
+        env.ket = env.cursor;
+        // delete, line 27
+        if !env.slice_del() {
+            return false;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 28
+    let v_2 = env.cursor;
+    'lab1: loop {
+        // (, line 28
+        // [, line 28
+        env.bra = env.cursor;
+        // literal, line 28
+        if !env.eq_s(&"y") {
+            break 'lab1;
+        }
+        // ], line 28
+        env.ket = env.cursor;
+        // <-, line 28
+        if !env.slice_from("Y") {
+            return false;
+        }
+        // set Y_found, line 28
+        context.b_Y_found = true;
+        break 'lab1;
+    }
+    env.cursor = v_2;
+    // do, line 29
+    let v_3 = env.cursor;
+    'lab2: loop {
+        // repeat, line 29
+        'replab3: loop{
+            let v_4 = env.cursor;
+            'lab4: for _ in 0..1 {
+                // (, line 29
+                // goto, line 29
+                'golab5: loop {
+                    let v_5 = env.cursor;
+                    'lab6: loop {
+                        // (, line 29
+                        if !env.in_grouping(G_v, 97, 121) {
+                            break 'lab6;
+                        }
+                        // [, line 29
+                        env.bra = env.cursor;
+                        // literal, line 29
+                        if !env.eq_s(&"y") {
+                            break 'lab6;
+                        }
+                        // ], line 29
+                        env.ket = env.cursor;
+                        env.cursor = v_5;
+                        break 'golab5;
+                    }
+                    env.cursor = v_5;
+                    if env.cursor >= env.limit {
+                        break 'lab4;
+                    }
+                    env.next_char();
+                }
+                // <-, line 29
+                if !env.slice_from("Y") {
+                    return false;
+                }
+                // set Y_found, line 29
+                context.b_Y_found = true;
+                continue 'replab3;
+            }
+            env.cursor = v_4;
+            break 'replab3;
+        }
+        break 'lab2;
+    }
+    env.cursor = v_3;
+    return true;
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 32
+    context.i_p1 = env.limit;
+    context.i_p2 = env.limit;
+    // do, line 35
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // (, line 35
+        // or, line 41
+        'lab1: loop {
+            let v_2 = env.cursor;
+            'lab2: loop {
+                // among, line 36
+                if env.find_among(A_0, context) == 0 {
+                    break 'lab2;
+                }
+                break 'lab1;
+            }
+            env.cursor = v_2;
+            // (, line 41
+            // gopast, line 41
+            'golab3: loop {
+                'lab4: loop {
+                    if !env.in_grouping(G_v, 97, 121) {
+                        break 'lab4;
+                    }
+                    break 'golab3;
+                }
+                if env.cursor >= env.limit {
+                    break 'lab0;
+                }
+                env.next_char();
+            }
+            // gopast, line 41
+            'golab5: loop {
+                'lab6: loop {
+                    if !env.out_grouping(G_v, 97, 121) {
+                        break 'lab6;
+                    }
+                    break 'golab5;
+                }
+                if env.cursor >= env.limit {
+                    break 'lab0;
+                }
+                env.next_char();
+            }
+            break 'lab1;
+        }
+        // setmark p1, line 42
+        context.i_p1 = env.cursor;
+        // gopast, line 43
+        'golab7: loop {
+            'lab8: loop {
+                if !env.in_grouping(G_v, 97, 121) {
+                    break 'lab8;
+                }
+                break 'golab7;
+            }
+            if env.cursor >= env.limit {
+                break 'lab0;
+            }
+            env.next_char();
+        }
+        // gopast, line 43
+        'golab9: loop {
+            'lab10: loop {
+                if !env.out_grouping(G_v, 97, 121) {
+                    break 'lab10;
+                }
+                break 'golab9;
+            }
+            if env.cursor >= env.limit {
+                break 'lab0;
+            }
+            env.next_char();
+        }
+        // setmark p2, line 43
+        context.i_p2 = env.cursor;
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    return true;
+}
+
+fn r_shortv(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 49
+    // or, line 51
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 50
+            if !env.out_grouping_b(G_v_WXY, 89, 121) {
+                break 'lab1;
+            }
+            if !env.in_grouping_b(G_v, 97, 121) {
+                break 'lab1;
+            }
+            if !env.out_grouping_b(G_v, 97, 121) {
+                break 'lab1;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 52
+        if !env.out_grouping_b(G_v, 97, 121) {
+            return false;
+        }
+        if !env.in_grouping_b(G_v, 97, 121) {
+            return false;
+        }
+        // atlimit, line 52
+        if env.cursor > env.limit_backward {
+            return false;
+        }
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_R1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p1 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_R2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p2 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_Step_1a(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 58
+    // try, line 59
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 59
+        // [, line 60
+        env.ket = env.cursor;
+        // substring, line 60
+        among_var = env.find_among_b(A_1, context);
+        if among_var == 0 {
+            env.cursor = env.limit - v_1;
+            break 'lab0;
+        }
+        // ], line 60
+        env.bra = env.cursor;
+        if among_var == 0 {
+            env.cursor = env.limit - v_1;
+            break 'lab0;
+        } else if among_var == 1 {
+            // (, line 62
+            // delete, line 62
+            if !env.slice_del() {
+                return false;
+            }
+        }
+        break 'lab0;
+    }
+    // [, line 65
+    env.ket = env.cursor;
+    // substring, line 65
+    among_var = env.find_among_b(A_2, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 65
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 66
+        // <-, line 66
+        if !env.slice_from("ss") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 68
+        // or, line 68
+        'lab1: loop {
+            let v_2 = env.limit - env.cursor;
+            'lab2: loop {
+                // (, line 68
+                // hop, line 68
+                let c = env.byte_index_for_hop(-2);
+                if env.limit_backward as i32 > c || c > env.limit as i32 {
+                    break 'lab2;
+                }
+                env.cursor = c as usize;
+                // <-, line 68
+                if !env.slice_from("i") {
+                    return false;
+                }
+                break 'lab1;
+            }
+            env.cursor = env.limit - v_2;
+            // <-, line 68
+            if !env.slice_from("ie") {
+                return false;
+            }
+            break 'lab1;
+        }
+    } else if among_var == 3 {
+        // (, line 69
+        // next, line 69
+        if env.cursor <= env.limit_backward {
+            return false;
+        }
+        env.previous_char();
+        // gopast, line 69
+        'golab3: loop {
+            'lab4: loop {
+                if !env.in_grouping_b(G_v, 97, 121) {
+                    break 'lab4;
+                }
+                break 'golab3;
+            }
+            if env.cursor <= env.limit_backward {
+                return false;
+            }
+            env.previous_char();
+        }
+        // delete, line 69
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Step_1b(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 74
+    // [, line 75
+    env.ket = env.cursor;
+    // substring, line 75
+    among_var = env.find_among_b(A_4, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 75
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 77
+        // call R1, line 77
+        if !r_R1(env, context) {
+            return false;
+        }
+        // <-, line 77
+        if !env.slice_from("ee") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 79
+        // test, line 80
+        let v_1 = env.limit - env.cursor;
+        // gopast, line 80
+        'golab0: loop {
+            'lab1: loop {
+                if !env.in_grouping_b(G_v, 97, 121) {
+                    break 'lab1;
+                }
+                break 'golab0;
+            }
+            if env.cursor <= env.limit_backward {
+                return false;
+            }
+            env.previous_char();
+        }
+        env.cursor = env.limit - v_1;
+        // delete, line 80
+        if !env.slice_del() {
+            return false;
+        }
+        // test, line 81
+        let v_3 = env.limit - env.cursor;
+        // substring, line 81
+        among_var = env.find_among_b(A_3, context);
+        if among_var == 0 {
+            return false;
+        }
+        env.cursor = env.limit - v_3;
+        if among_var == 0 {
+            return false;
+        } else if among_var == 1 {
+            // (, line 83
+            // <+, line 83
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, "e");
+            env.cursor = c;
+        } else if among_var == 2 {
+            // (, line 86
+            // [, line 86
+            env.ket = env.cursor;
+            // next, line 86
+            if env.cursor <= env.limit_backward {
+                return false;
+            }
+            env.previous_char();
+            // ], line 86
+            env.bra = env.cursor;
+            // delete, line 86
+            if !env.slice_del() {
+                return false;
+            }
+        } else if among_var == 3 {
+            // (, line 87
+            // atmark, line 87
+            if env.cursor != context.i_p1 {
+                return false;
+            }
+            // test, line 87
+            let v_4 = env.limit - env.cursor;
+            // call shortv, line 87
+            if !r_shortv(env, context) {
+                return false;
+            }
+            env.cursor = env.limit - v_4;
+            // <+, line 87
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, "e");
+            env.cursor = c;
+        }
+    }
+    return true;
+}
+
+fn r_Step_1c(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 93
+    // [, line 94
+    env.ket = env.cursor;
+    // or, line 94
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // literal, line 94
+            if !env.eq_s_b(&"y") {
+                break 'lab1;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // literal, line 94
+        if !env.eq_s_b(&"Y") {
+            return false;
+        }
+        break 'lab0;
+    }
+    // ], line 94
+    env.bra = env.cursor;
+    if !env.out_grouping_b(G_v, 97, 121) {
+        return false;
+    }
+    // not, line 95
+    let v_2 = env.limit - env.cursor;
+    'lab2: loop {
+        // atlimit, line 95
+        if env.cursor > env.limit_backward {
+            break 'lab2;
+        }
+        return false;
+    }
+    env.cursor = env.limit - v_2;
+    // <-, line 96
+    if !env.slice_from("i") {
+        return false;
+    }
+    return true;
+}
+
+fn r_Step_2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 99
+    // [, line 100
+    env.ket = env.cursor;
+    // substring, line 100
+    among_var = env.find_among_b(A_5, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 100
+    env.bra = env.cursor;
+    // call R1, line 100
+    if !r_R1(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 101
+        // <-, line 101
+        if !env.slice_from("tion") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 102
+        // <-, line 102
+        if !env.slice_from("ence") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 103
+        // <-, line 103
+        if !env.slice_from("ance") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 104
+        // <-, line 104
+        if !env.slice_from("able") {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 105
+        // <-, line 105
+        if !env.slice_from("ent") {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 107
+        // <-, line 107
+        if !env.slice_from("ize") {
+            return false;
+        }
+    } else if among_var == 7 {
+        // (, line 109
+        // <-, line 109
+        if !env.slice_from("ate") {
+            return false;
+        }
+    } else if among_var == 8 {
+        // (, line 111
+        // <-, line 111
+        if !env.slice_from("al") {
+            return false;
+        }
+    } else if among_var == 9 {
+        // (, line 112
+        // <-, line 112
+        if !env.slice_from("ful") {
+            return false;
+        }
+    } else if among_var == 10 {
+        // (, line 114
+        // <-, line 114
+        if !env.slice_from("ous") {
+            return false;
+        }
+    } else if among_var == 11 {
+        // (, line 116
+        // <-, line 116
+        if !env.slice_from("ive") {
+            return false;
+        }
+    } else if among_var == 12 {
+        // (, line 118
+        // <-, line 118
+        if !env.slice_from("ble") {
+            return false;
+        }
+    } else if among_var == 13 {
+        // (, line 119
+        // literal, line 119
+        if !env.eq_s_b(&"l") {
+            return false;
+        }
+        // <-, line 119
+        if !env.slice_from("og") {
+            return false;
+        }
+    } else if among_var == 14 {
+        // (, line 120
+        // <-, line 120
+        if !env.slice_from("ful") {
+            return false;
+        }
+    } else if among_var == 15 {
+        // (, line 121
+        // <-, line 121
+        if !env.slice_from("less") {
+            return false;
+        }
+    } else if among_var == 16 {
+        // (, line 122
+        if !env.in_grouping_b(G_valid_LI, 99, 116) {
+            return false;
+        }
+        // delete, line 122
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Step_3(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 126
+    // [, line 127
+    env.ket = env.cursor;
+    // substring, line 127
+    among_var = env.find_among_b(A_6, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 127
+    env.bra = env.cursor;
+    // call R1, line 127
+    if !r_R1(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 128
+        // <-, line 128
+        if !env.slice_from("tion") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 129
+        // <-, line 129
+        if !env.slice_from("ate") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 130
+        // <-, line 130
+        if !env.slice_from("al") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 132
+        // <-, line 132
+        if !env.slice_from("ic") {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 134
+        // delete, line 134
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 136
+        // call R2, line 136
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 136
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Step_4(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 140
+    // [, line 141
+    env.ket = env.cursor;
+    // substring, line 141
+    among_var = env.find_among_b(A_7, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 141
+    env.bra = env.cursor;
+    // call R2, line 141
+    if !r_R2(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 144
+        // delete, line 144
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 145
+        // or, line 145
+        'lab0: loop {
+            let v_1 = env.limit - env.cursor;
+            'lab1: loop {
+                // literal, line 145
+                if !env.eq_s_b(&"s") {
+                    break 'lab1;
+                }
+                break 'lab0;
+            }
+            env.cursor = env.limit - v_1;
+            // literal, line 145
+            if !env.eq_s_b(&"t") {
+                return false;
+            }
+            break 'lab0;
+        }
+        // delete, line 145
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_Step_5(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 149
+    // [, line 150
+    env.ket = env.cursor;
+    // substring, line 150
+    among_var = env.find_among_b(A_8, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 150
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 151
+        // or, line 151
+        'lab0: loop {
+            let v_1 = env.limit - env.cursor;
+            'lab1: loop {
+                // call R2, line 151
+                if !r_R2(env, context) {
+                    break 'lab1;
+                }
+                break 'lab0;
+            }
+            env.cursor = env.limit - v_1;
+            // (, line 151
+            // call R1, line 151
+            if !r_R1(env, context) {
+                return false;
+            }
+            // not, line 151
+            let v_2 = env.limit - env.cursor;
+            'lab2: loop {
+                // call shortv, line 151
+                if !r_shortv(env, context) {
+                    break 'lab2;
+                }
+                return false;
+            }
+            env.cursor = env.limit - v_2;
+            break 'lab0;
+        }
+        // delete, line 151
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 152
+        // call R2, line 152
+        if !r_R2(env, context) {
+            return false;
+        }
+        // literal, line 152
+        if !env.eq_s_b(&"l") {
+            return false;
+        }
+        // delete, line 152
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_exception2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 156
+    // [, line 158
+    env.ket = env.cursor;
+    // substring, line 158
+    if env.find_among_b(A_9, context) == 0 {
+        return false;
+    }
+    // ], line 158
+    env.bra = env.cursor;
+    // atlimit, line 158
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    return true;
+}
+
+fn r_exception1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 168
+    // [, line 170
+    env.bra = env.cursor;
+    // substring, line 170
+    among_var = env.find_among(A_10, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 170
+    env.ket = env.cursor;
+    // atlimit, line 170
+    if env.cursor < env.limit {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 174
+        // <-, line 174
+        if !env.slice_from("ski") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 175
+        // <-, line 175
+        if !env.slice_from("sky") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 176
+        // <-, line 176
+        if !env.slice_from("die") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 177
+        // <-, line 177
+        if !env.slice_from("lie") {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 178
+        // <-, line 178
+        if !env.slice_from("tie") {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 182
+        // <-, line 182
+        if !env.slice_from("idl") {
+            return false;
+        }
+    } else if among_var == 7 {
+        // (, line 183
+        // <-, line 183
+        if !env.slice_from("gentl") {
+            return false;
+        }
+    } else if among_var == 8 {
+        // (, line 184
+        // <-, line 184
+        if !env.slice_from("ugli") {
+            return false;
+        }
+    } else if among_var == 9 {
+        // (, line 185
+        // <-, line 185
+        if !env.slice_from("earli") {
+            return false;
+        }
+    } else if among_var == 10 {
+        // (, line 186
+        // <-, line 186
+        if !env.slice_from("onli") {
+            return false;
+        }
+    } else if among_var == 11 {
+        // (, line 187
+        // <-, line 187
+        if !env.slice_from("singl") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_postlude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 203
+    // Boolean test Y_found, line 203
+    if !context.b_Y_found {
+        return false;
+    }
+    // repeat, line 203
+    'replab0: loop{
+        let v_1 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 203
+            // goto, line 203
+            'golab2: loop {
+                let v_2 = env.cursor;
+                'lab3: loop {
+                    // (, line 203
+                    // [, line 203
+                    env.bra = env.cursor;
+                    // literal, line 203
+                    if !env.eq_s(&"Y") {
+                        break 'lab3;
+                    }
+                    // ], line 203
+                    env.ket = env.cursor;
+                    env.cursor = v_2;
+                    break 'golab2;
+                }
+                env.cursor = v_2;
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            // <-, line 203
+            if !env.slice_from("y") {
+                return false;
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        b_Y_found: false,
+        i_p2: 0,
+        i_p1: 0,
+    };
+    // (, line 205
+    // or, line 207
+    'lab0: loop {
+        let v_1 = env.cursor;
+        'lab1: loop {
+            // call exception1, line 207
+            if !r_exception1(env, context) {
+                break 'lab1;
+            }
+            break 'lab0;
+        }
+        env.cursor = v_1;
+        'lab2: loop {
+            // not, line 208
+            let v_2 = env.cursor;
+            'lab3: loop {
+                // hop, line 208
+                let c = env.byte_index_for_hop(3);
+                if 0 as i32 > c || c > env.limit as i32 {
+                    break 'lab3;
+                }
+                env.cursor = c as usize;
+                break 'lab2;
+            }
+            env.cursor = v_2;
+            break 'lab0;
+        }
+        env.cursor = v_1;
+        // (, line 208
+        // do, line 209
+        let v_3 = env.cursor;
+        'lab4: loop {
+            // call prelude, line 209
+            if !r_prelude(env, context) {
+                break 'lab4;
+            }
+            break 'lab4;
+        }
+        env.cursor = v_3;
+        // do, line 210
+        let v_4 = env.cursor;
+        'lab5: loop {
+            // call mark_regions, line 210
+            if !r_mark_regions(env, context) {
+                break 'lab5;
+            }
+            break 'lab5;
+        }
+        env.cursor = v_4;
+        // backwards, line 211
+        env.limit_backward = env.cursor;
+        env.cursor = env.limit;
+        // (, line 211
+        // do, line 213
+        let v_5 = env.limit - env.cursor;
+        'lab6: loop {
+            // call Step_1a, line 213
+            if !r_Step_1a(env, context) {
+                break 'lab6;
+            }
+            break 'lab6;
+        }
+        env.cursor = env.limit - v_5;
+        // or, line 215
+        'lab7: loop {
+            let v_6 = env.limit - env.cursor;
+            'lab8: loop {
+                // call exception2, line 215
+                if !r_exception2(env, context) {
+                    break 'lab8;
+                }
+                break 'lab7;
+            }
+            env.cursor = env.limit - v_6;
+            // (, line 215
+            // do, line 217
+            let v_7 = env.limit - env.cursor;
+            'lab9: loop {
+                // call Step_1b, line 217
+                if !r_Step_1b(env, context) {
+                    break 'lab9;
+                }
+                break 'lab9;
+            }
+            env.cursor = env.limit - v_7;
+            // do, line 218
+            let v_8 = env.limit - env.cursor;
+            'lab10: loop {
+                // call Step_1c, line 218
+                if !r_Step_1c(env, context) {
+                    break 'lab10;
+                }
+                break 'lab10;
+            }
+            env.cursor = env.limit - v_8;
+            // do, line 220
+            let v_9 = env.limit - env.cursor;
+            'lab11: loop {
+                // call Step_2, line 220
+                if !r_Step_2(env, context) {
+                    break 'lab11;
+                }
+                break 'lab11;
+            }
+            env.cursor = env.limit - v_9;
+            // do, line 221
+            let v_10 = env.limit - env.cursor;
+            'lab12: loop {
+                // call Step_3, line 221
+                if !r_Step_3(env, context) {
+                    break 'lab12;
+                }
+                break 'lab12;
+            }
+            env.cursor = env.limit - v_10;
+            // do, line 222
+            let v_11 = env.limit - env.cursor;
+            'lab13: loop {
+                // call Step_4, line 222
+                if !r_Step_4(env, context) {
+                    break 'lab13;
+                }
+                break 'lab13;
+            }
+            env.cursor = env.limit - v_11;
+            // do, line 224
+            let v_12 = env.limit - env.cursor;
+            'lab14: loop {
+                // call Step_5, line 224
+                if !r_Step_5(env, context) {
+                    break 'lab14;
+                }
+                break 'lab14;
+            }
+            env.cursor = env.limit - v_12;
+            break 'lab7;
+        }
+        env.cursor = env.limit_backward;
+        // do, line 227
+        let v_13 = env.cursor;
+        'lab15: loop {
+            // call postlude, line 227
+            if !r_postlude(env, context) {
+                break 'lab15;
+            }
+            break 'lab15;
+        }
+        env.cursor = v_13;
+        break 'lab0;
+    }
+    return true;
+}
diff --git a/src/snowball/algorithms/finnish.rs b/src/snowball/algorithms/finnish.rs
new file mode 100644
index 0000000..21d4084
--- /dev/null
+++ b/src/snowball/algorithms/finnish.rs
@@ -0,0 +1,941 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 10] = &[
+    Among("pa", -1, 1, None),
+    Among("sti", -1, 2, None),
+    Among("kaan", -1, 1, None),
+    Among("han", -1, 1, None),
+    Among("kin", -1, 1, None),
+    Among("h\u{00E4}n", -1, 1, None),
+    Among("k\u{00E4}\u{00E4}n", -1, 1, None),
+    Among("ko", -1, 1, None),
+    Among("p\u{00E4}", -1, 1, None),
+    Among("k\u{00F6}", -1, 1, None),
+];
+
+static A_1: &'static [Among<Context>; 6] = &[
+    Among("lla", -1, -1, None),
+    Among("na", -1, -1, None),
+    Among("ssa", -1, -1, None),
+    Among("ta", -1, -1, None),
+    Among("lta", 3, -1, None),
+    Among("sta", 3, -1, None),
+];
+
+static A_2: &'static [Among<Context>; 6] = &[
+    Among("ll\u{00E4}", -1, -1, None),
+    Among("n\u{00E4}", -1, -1, None),
+    Among("ss\u{00E4}", -1, -1, None),
+    Among("t\u{00E4}", -1, -1, None),
+    Among("lt\u{00E4}", 3, -1, None),
+    Among("st\u{00E4}", 3, -1, None),
+];
+
+static A_3: &'static [Among<Context>; 2] = &[
+    Among("lle", -1, -1, None),
+    Among("ine", -1, -1, None),
+];
+
+static A_4: &'static [Among<Context>; 9] = &[
+    Among("nsa", -1, 3, None),
+    Among("mme", -1, 3, None),
+    Among("nne", -1, 3, None),
+    Among("ni", -1, 2, None),
+    Among("si", -1, 1, None),
+    Among("an", -1, 4, None),
+    Among("en", -1, 6, None),
+    Among("\u{00E4}n", -1, 5, None),
+    Among("ns\u{00E4}", -1, 3, None),
+];
+
+static A_5: &'static [Among<Context>; 7] = &[
+    Among("aa", -1, -1, None),
+    Among("ee", -1, -1, None),
+    Among("ii", -1, -1, None),
+    Among("oo", -1, -1, None),
+    Among("uu", -1, -1, None),
+    Among("\u{00E4}\u{00E4}", -1, -1, None),
+    Among("\u{00F6}\u{00F6}", -1, -1, None),
+];
+
+static A_6: &'static [Among<Context>; 30] = &[
+    Among("a", -1, 8, None),
+    Among("lla", 0, -1, None),
+    Among("na", 0, -1, None),
+    Among("ssa", 0, -1, None),
+    Among("ta", 0, -1, None),
+    Among("lta", 4, -1, None),
+    Among("sta", 4, -1, None),
+    Among("tta", 4, 9, None),
+    Among("lle", -1, -1, None),
+    Among("ine", -1, -1, None),
+    Among("ksi", -1, -1, None),
+    Among("n", -1, 7, None),
+    Among("han", 11, 1, None),
+    Among("den", 11, -1, Some(&r_VI)),
+    Among("seen", 11, -1, Some(&r_LONG)),
+    Among("hen", 11, 2, None),
+    Among("tten", 11, -1, Some(&r_VI)),
+    Among("hin", 11, 3, None),
+    Among("siin", 11, -1, Some(&r_VI)),
+    Among("hon", 11, 4, None),
+    Among("h\u{00E4}n", 11, 5, None),
+    Among("h\u{00F6}n", 11, 6, None),
+    Among("\u{00E4}", -1, 8, None),
+    Among("ll\u{00E4}", 22, -1, None),
+    Among("n\u{00E4}", 22, -1, None),
+    Among("ss\u{00E4}", 22, -1, None),
+    Among("t\u{00E4}", 22, -1, None),
+    Among("lt\u{00E4}", 26, -1, None),
+    Among("st\u{00E4}", 26, -1, None),
+    Among("tt\u{00E4}", 26, 9, None),
+];
+
+static A_7: &'static [Among<Context>; 14] = &[
+    Among("eja", -1, -1, None),
+    Among("mma", -1, 1, None),
+    Among("imma", 1, -1, None),
+    Among("mpa", -1, 1, None),
+    Among("impa", 3, -1, None),
+    Among("mmi", -1, 1, None),
+    Among("immi", 5, -1, None),
+    Among("mpi", -1, 1, None),
+    Among("impi", 7, -1, None),
+    Among("ej\u{00E4}", -1, -1, None),
+    Among("mm\u{00E4}", -1, 1, None),
+    Among("imm\u{00E4}", 10, -1, None),
+    Among("mp\u{00E4}", -1, 1, None),
+    Among("imp\u{00E4}", 12, -1, None),
+];
+
+static A_8: &'static [Among<Context>; 2] = &[
+    Among("i", -1, -1, None),
+    Among("j", -1, -1, None),
+];
+
+static A_9: &'static [Among<Context>; 2] = &[
+    Among("mma", -1, 1, None),
+    Among("imma", 0, -1, None),
+];
+
+static G_AEI: &'static [u8; 17] = &[17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8];
+
+static G_V1: &'static [u8; 19] = &[17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32];
+
+static G_V2: &'static [u8; 19] = &[17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32];
+
+static G_particle_end: &'static [u8; 19] = &[17, 97, 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32];
+
+#[derive(Clone)]
+struct Context {
+    b_ending_removed: bool,
+    S_x: String,
+    i_p2: usize,
+    i_p1: usize,
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 40
+    context.i_p1 = env.limit;
+    context.i_p2 = env.limit;
+    // goto, line 45
+    'golab0: loop {
+        let v_1 = env.cursor;
+        'lab1: loop {
+            if !env.in_grouping(G_V1, 97, 246) {
+                break 'lab1;
+            }
+            env.cursor = v_1;
+            break 'golab0;
+        }
+        env.cursor = v_1;
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // gopast, line 45
+    'golab2: loop {
+        'lab3: loop {
+            if !env.out_grouping(G_V1, 97, 246) {
+                break 'lab3;
+            }
+            break 'golab2;
+        }
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // setmark p1, line 45
+    context.i_p1 = env.cursor;
+    // goto, line 46
+    'golab4: loop {
+        let v_3 = env.cursor;
+        'lab5: loop {
+            if !env.in_grouping(G_V1, 97, 246) {
+                break 'lab5;
+            }
+            env.cursor = v_3;
+            break 'golab4;
+        }
+        env.cursor = v_3;
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // gopast, line 46
+    'golab6: loop {
+        'lab7: loop {
+            if !env.out_grouping(G_V1, 97, 246) {
+                break 'lab7;
+            }
+            break 'golab6;
+        }
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // setmark p2, line 46
+    context.i_p2 = env.cursor;
+    return true;
+}
+
+fn r_R2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p2 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_particle_etc(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 53
+    // setlimit, line 54
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 54
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    env.cursor = context.i_p1;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 54
+    // [, line 54
+    env.ket = env.cursor;
+    // substring, line 54
+    among_var = env.find_among_b(A_0, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 54
+    env.bra = env.cursor;
+    env.limit_backward = v_2;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 61
+        if !env.in_grouping_b(G_particle_end, 97, 246) {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 63
+        // call R2, line 63
+        if !r_R2(env, context) {
+            return false;
+        }
+    }
+    // delete, line 65
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+fn r_possessive(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 67
+    // setlimit, line 68
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 68
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    env.cursor = context.i_p1;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 68
+    // [, line 68
+    env.ket = env.cursor;
+    // substring, line 68
+    among_var = env.find_among_b(A_4, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 68
+    env.bra = env.cursor;
+    env.limit_backward = v_2;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 71
+        // not, line 71
+        let v_3 = env.limit - env.cursor;
+        'lab0: loop {
+            // literal, line 71
+            if !env.eq_s_b(&"k") {
+                break 'lab0;
+            }
+            return false;
+        }
+        env.cursor = env.limit - v_3;
+        // delete, line 71
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 73
+        // delete, line 73
+        if !env.slice_del() {
+            return false;
+        }
+        // [, line 73
+        env.ket = env.cursor;
+        // literal, line 73
+        if !env.eq_s_b(&"kse") {
+            return false;
+        }
+        // ], line 73
+        env.bra = env.cursor;
+        // <-, line 73
+        if !env.slice_from("ksi") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 77
+        // delete, line 77
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 80
+        // among, line 80
+        if env.find_among_b(A_1, context) == 0 {
+            return false;
+        }
+        // delete, line 80
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 82
+        // among, line 82
+        if env.find_among_b(A_2, context) == 0 {
+            return false;
+        }
+        // delete, line 83
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 85
+        // among, line 85
+        if env.find_among_b(A_3, context) == 0 {
+            return false;
+        }
+        // delete, line 85
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_LONG(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // among, line 90
+    if env.find_among_b(A_5, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_VI(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 92
+    // literal, line 92
+    if !env.eq_s_b(&"i") {
+        return false;
+    }
+    if !env.in_grouping_b(G_V2, 97, 246) {
+        return false;
+    }
+    return true;
+}
+
+fn r_case_ending(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 94
+    // setlimit, line 95
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 95
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    env.cursor = context.i_p1;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 95
+    // [, line 95
+    env.ket = env.cursor;
+    // substring, line 95
+    among_var = env.find_among_b(A_6, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 95
+    env.bra = env.cursor;
+    env.limit_backward = v_2;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 97
+        // literal, line 97
+        if !env.eq_s_b(&"a") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 98
+        // literal, line 98
+        if !env.eq_s_b(&"e") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 99
+        // literal, line 99
+        if !env.eq_s_b(&"i") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 100
+        // literal, line 100
+        if !env.eq_s_b(&"o") {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 101
+        // literal, line 101
+        if !env.eq_s_b(&"\u{00E4}") {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 102
+        // literal, line 102
+        if !env.eq_s_b(&"\u{00F6}") {
+            return false;
+        }
+    } else if among_var == 7 {
+        // (, line 110
+        // try, line 110
+        let v_3 = env.limit - env.cursor;
+        'lab0: loop {
+            // (, line 110
+            // and, line 112
+            let v_4 = env.limit - env.cursor;
+            // or, line 111
+            'lab1: loop {
+                let v_5 = env.limit - env.cursor;
+                'lab2: loop {
+                    // call LONG, line 110
+                    if !r_LONG(env, context) {
+                        break 'lab2;
+                    }
+                    break 'lab1;
+                }
+                env.cursor = env.limit - v_5;
+                // literal, line 111
+                if !env.eq_s_b(&"ie") {
+                    env.cursor = env.limit - v_3;
+                    break 'lab0;
+                }
+                break 'lab1;
+            }
+            env.cursor = env.limit - v_4;
+            // next, line 112
+            if env.cursor <= env.limit_backward {
+                env.cursor = env.limit - v_3;
+                break 'lab0;
+            }
+            env.previous_char();
+            // ], line 112
+            env.bra = env.cursor;
+            break 'lab0;
+        }
+    } else if among_var == 8 {
+        // (, line 118
+        if !env.in_grouping_b(G_V1, 97, 246) {
+            return false;
+        }
+        if !env.out_grouping_b(G_V1, 97, 246) {
+            return false;
+        }
+    } else if among_var == 9 {
+        // (, line 120
+        // literal, line 120
+        if !env.eq_s_b(&"e") {
+            return false;
+        }
+    }
+    // delete, line 137
+    if !env.slice_del() {
+        return false;
+    }
+    // set ending_removed, line 138
+    context.b_ending_removed = true;
+    return true;
+}
+
+fn r_other_endings(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 140
+    // setlimit, line 141
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 141
+    if env.cursor < context.i_p2 {
+        return false;
+    }
+    env.cursor = context.i_p2;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 141
+    // [, line 141
+    env.ket = env.cursor;
+    // substring, line 141
+    among_var = env.find_among_b(A_7, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 141
+    env.bra = env.cursor;
+    env.limit_backward = v_2;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 145
+        // not, line 145
+        let v_3 = env.limit - env.cursor;
+        'lab0: loop {
+            // literal, line 145
+            if !env.eq_s_b(&"po") {
+                break 'lab0;
+            }
+            return false;
+        }
+        env.cursor = env.limit - v_3;
+    }
+    // delete, line 150
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+fn r_i_plural(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 152
+    // setlimit, line 153
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 153
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    env.cursor = context.i_p1;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 153
+    // [, line 153
+    env.ket = env.cursor;
+    // substring, line 153
+    if env.find_among_b(A_8, context) == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 153
+    env.bra = env.cursor;
+    env.limit_backward = v_2;
+    // delete, line 157
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+fn r_t_plural(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 159
+    // setlimit, line 160
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 160
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    env.cursor = context.i_p1;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 160
+    // [, line 161
+    env.ket = env.cursor;
+    // literal, line 161
+    if !env.eq_s_b(&"t") {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 161
+    env.bra = env.cursor;
+    // test, line 161
+    let v_3 = env.limit - env.cursor;
+    if !env.in_grouping_b(G_V1, 97, 246) {
+        env.limit_backward = v_2;
+        return false;
+    }
+    env.cursor = env.limit - v_3;
+    // delete, line 162
+    if !env.slice_del() {
+        return false;
+    }
+    env.limit_backward = v_2;
+    // setlimit, line 164
+    let v_4 = env.limit - env.cursor;
+    // tomark, line 164
+    if env.cursor < context.i_p2 {
+        return false;
+    }
+    env.cursor = context.i_p2;
+    let v_5 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_4;
+    // (, line 164
+    // [, line 164
+    env.ket = env.cursor;
+    // substring, line 164
+    among_var = env.find_among_b(A_9, context);
+    if among_var == 0 {
+        env.limit_backward = v_5;
+        return false;
+    }
+    // ], line 164
+    env.bra = env.cursor;
+    env.limit_backward = v_5;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 166
+        // not, line 166
+        let v_6 = env.limit - env.cursor;
+        'lab0: loop {
+            // literal, line 166
+            if !env.eq_s_b(&"po") {
+                break 'lab0;
+            }
+            return false;
+        }
+        env.cursor = env.limit - v_6;
+    }
+    // delete, line 169
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+fn r_tidy(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 171
+    // setlimit, line 172
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 172
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    env.cursor = context.i_p1;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 172
+    // do, line 173
+    let v_3 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 173
+        // and, line 173
+        let v_4 = env.limit - env.cursor;
+        // call LONG, line 173
+        if !r_LONG(env, context) {
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_4;
+        // (, line 173
+        // [, line 173
+        env.ket = env.cursor;
+        // next, line 173
+        if env.cursor <= env.limit_backward {
+            break 'lab0;
+        }
+        env.previous_char();
+        // ], line 173
+        env.bra = env.cursor;
+        // delete, line 173
+        if !env.slice_del() {
+            return false;
+        }
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_3;
+    // do, line 174
+    let v_5 = env.limit - env.cursor;
+    'lab1: loop {
+        // (, line 174
+        // [, line 174
+        env.ket = env.cursor;
+        if !env.in_grouping_b(G_AEI, 97, 228) {
+            break 'lab1;
+        }
+        // ], line 174
+        env.bra = env.cursor;
+        if !env.out_grouping_b(G_V1, 97, 246) {
+            break 'lab1;
+        }
+        // delete, line 174
+        if !env.slice_del() {
+            return false;
+        }
+        break 'lab1;
+    }
+    env.cursor = env.limit - v_5;
+    // do, line 175
+    let v_6 = env.limit - env.cursor;
+    'lab2: loop {
+        // (, line 175
+        // [, line 175
+        env.ket = env.cursor;
+        // literal, line 175
+        if !env.eq_s_b(&"j") {
+            break 'lab2;
+        }
+        // ], line 175
+        env.bra = env.cursor;
+        // or, line 175
+        'lab3: loop {
+            let v_7 = env.limit - env.cursor;
+            'lab4: loop {
+                // literal, line 175
+                if !env.eq_s_b(&"o") {
+                    break 'lab4;
+                }
+                break 'lab3;
+            }
+            env.cursor = env.limit - v_7;
+            // literal, line 175
+            if !env.eq_s_b(&"u") {
+                break 'lab2;
+            }
+            break 'lab3;
+        }
+        // delete, line 175
+        if !env.slice_del() {
+            return false;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_6;
+    // do, line 176
+    let v_8 = env.limit - env.cursor;
+    'lab5: loop {
+        // (, line 176
+        // [, line 176
+        env.ket = env.cursor;
+        // literal, line 176
+        if !env.eq_s_b(&"o") {
+            break 'lab5;
+        }
+        // ], line 176
+        env.bra = env.cursor;
+        // literal, line 176
+        if !env.eq_s_b(&"j") {
+            break 'lab5;
+        }
+        // delete, line 176
+        if !env.slice_del() {
+            return false;
+        }
+        break 'lab5;
+    }
+    env.cursor = env.limit - v_8;
+    env.limit_backward = v_2;
+    // goto, line 178
+    'golab6: loop {
+        let v_9 = env.limit - env.cursor;
+        'lab7: loop {
+            if !env.out_grouping_b(G_V1, 97, 246) {
+                break 'lab7;
+            }
+            env.cursor = env.limit - v_9;
+            break 'golab6;
+        }
+        env.cursor = env.limit - v_9;
+        if env.cursor <= env.limit_backward {
+            return false;
+        }
+        env.previous_char();
+    }
+    // [, line 178
+    env.ket = env.cursor;
+    // next, line 178
+    if env.cursor <= env.limit_backward {
+        return false;
+    }
+    env.previous_char();
+    // ], line 178
+    env.bra = env.cursor;
+    // -> x, line 178
+    context.S_x = env.slice_to();
+    if context.S_x.is_empty() {
+        return false;
+    }
+    // name x, line 178
+    if !env.eq_s_b(&context.S_x) {
+        return false;
+    }
+    // delete, line 178
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        b_ending_removed: false,
+        S_x: String::new(),
+        i_p2: 0,
+        i_p1: 0,
+    };
+    // (, line 182
+    // do, line 184
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call mark_regions, line 184
+        if !r_mark_regions(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // unset ending_removed, line 185
+    context.b_ending_removed = false;
+    // backwards, line 186
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 186
+    // do, line 187
+    let v_2 = env.limit - env.cursor;
+    'lab1: loop {
+        // call particle_etc, line 187
+        if !r_particle_etc(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = env.limit - v_2;
+    // do, line 188
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // call possessive, line 188
+        if !r_possessive(env, context) {
+            break 'lab2;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    // do, line 189
+    let v_4 = env.limit - env.cursor;
+    'lab3: loop {
+        // call case_ending, line 189
+        if !r_case_ending(env, context) {
+            break 'lab3;
+        }
+        break 'lab3;
+    }
+    env.cursor = env.limit - v_4;
+    // do, line 190
+    let v_5 = env.limit - env.cursor;
+    'lab4: loop {
+        // call other_endings, line 190
+        if !r_other_endings(env, context) {
+            break 'lab4;
+        }
+        break 'lab4;
+    }
+    env.cursor = env.limit - v_5;
+    // or, line 191
+    'lab5: loop {
+        let v_6 = env.limit - env.cursor;
+        'lab6: loop {
+            // (, line 191
+            // Boolean test ending_removed, line 191
+            if !context.b_ending_removed {
+                break 'lab6;
+            }
+            // do, line 191
+            let v_7 = env.limit - env.cursor;
+            'lab7: loop {
+                // call i_plural, line 191
+                if !r_i_plural(env, context) {
+                    break 'lab7;
+                }
+                break 'lab7;
+            }
+            env.cursor = env.limit - v_7;
+            break 'lab5;
+        }
+        env.cursor = env.limit - v_6;
+        // do, line 191
+        let v_8 = env.limit - env.cursor;
+        'lab8: loop {
+            // call t_plural, line 191
+            if !r_t_plural(env, context) {
+                break 'lab8;
+            }
+            break 'lab8;
+        }
+        env.cursor = env.limit - v_8;
+        break 'lab5;
+    }
+    // do, line 192
+    let v_9 = env.limit - env.cursor;
+    'lab9: loop {
+        // call tidy, line 192
+        if !r_tidy(env, context) {
+            break 'lab9;
+        }
+        break 'lab9;
+    }
+    env.cursor = env.limit - v_9;
+    env.cursor = env.limit_backward;
+    return true;
+}
diff --git a/src/snowball/algorithms/french.rs b/src/snowball/algorithms/french.rs
new file mode 100644
index 0000000..e8a59c7
--- /dev/null
+++ b/src/snowball/algorithms/french.rs
@@ -0,0 +1,1447 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 3] = &[
+    Among("col", -1, -1, None),
+    Among("par", -1, -1, None),
+    Among("tap", -1, -1, None),
+];
+
+static A_1: &'static [Among<Context>; 4] = &[
+    Among("", -1, 4, None),
+    Among("I", 0, 1, None),
+    Among("U", 0, 2, None),
+    Among("Y", 0, 3, None),
+];
+
+static A_2: &'static [Among<Context>; 6] = &[
+    Among("iqU", -1, 3, None),
+    Among("abl", -1, 3, None),
+    Among("I\u{00E8}r", -1, 4, None),
+    Among("i\u{00E8}r", -1, 4, None),
+    Among("eus", -1, 2, None),
+    Among("iv", -1, 1, None),
+];
+
+static A_3: &'static [Among<Context>; 3] = &[
+    Among("ic", -1, 2, None),
+    Among("abil", -1, 1, None),
+    Among("iv", -1, 3, None),
+];
+
+static A_4: &'static [Among<Context>; 43] = &[
+    Among("iqUe", -1, 1, None),
+    Among("atrice", -1, 2, None),
+    Among("ance", -1, 1, None),
+    Among("ence", -1, 5, None),
+    Among("logie", -1, 3, None),
+    Among("able", -1, 1, None),
+    Among("isme", -1, 1, None),
+    Among("euse", -1, 11, None),
+    Among("iste", -1, 1, None),
+    Among("ive", -1, 8, None),
+    Among("if", -1, 8, None),
+    Among("usion", -1, 4, None),
+    Among("ation", -1, 2, None),
+    Among("ution", -1, 4, None),
+    Among("ateur", -1, 2, None),
+    Among("iqUes", -1, 1, None),
+    Among("atrices", -1, 2, None),
+    Among("ances", -1, 1, None),
+    Among("ences", -1, 5, None),
+    Among("logies", -1, 3, None),
+    Among("ables", -1, 1, None),
+    Among("ismes", -1, 1, None),
+    Among("euses", -1, 11, None),
+    Among("istes", -1, 1, None),
+    Among("ives", -1, 8, None),
+    Among("ifs", -1, 8, None),
+    Among("usions", -1, 4, None),
+    Among("ations", -1, 2, None),
+    Among("utions", -1, 4, None),
+    Among("ateurs", -1, 2, None),
+    Among("ments", -1, 15, None),
+    Among("ements", 30, 6, None),
+    Among("issements", 31, 12, None),
+    Among("it\u{00E9}s", -1, 7, None),
+    Among("ment", -1, 15, None),
+    Among("ement", 34, 6, None),
+    Among("issement", 35, 12, None),
+    Among("amment", 34, 13, None),
+    Among("emment", 34, 14, None),
+    Among("aux", -1, 10, None),
+    Among("eaux", 39, 9, None),
+    Among("eux", -1, 1, None),
+    Among("it\u{00E9}", -1, 7, None),
+];
+
+static A_5: &'static [Among<Context>; 35] = &[
+    Among("ira", -1, 1, None),
+    Among("ie", -1, 1, None),
+    Among("isse", -1, 1, None),
+    Among("issante", -1, 1, None),
+    Among("i", -1, 1, None),
+    Among("irai", 4, 1, None),
+    Among("ir", -1, 1, None),
+    Among("iras", -1, 1, None),
+    Among("ies", -1, 1, None),
+    Among("\u{00EE}mes", -1, 1, None),
+    Among("isses", -1, 1, None),
+    Among("issantes", -1, 1, None),
+    Among("\u{00EE}tes", -1, 1, None),
+    Among("is", -1, 1, None),
+    Among("irais", 13, 1, None),
+    Among("issais", 13, 1, None),
+    Among("irions", -1, 1, None),
+    Among("issions", -1, 1, None),
+    Among("irons", -1, 1, None),
+    Among("issons", -1, 1, None),
+    Among("issants", -1, 1, None),
+    Among("it", -1, 1, None),
+    Among("irait", 21, 1, None),
+    Among("issait", 21, 1, None),
+    Among("issant", -1, 1, None),
+    Among("iraIent", -1, 1, None),
+    Among("issaIent", -1, 1, None),
+    Among("irent", -1, 1, None),
+    Among("issent", -1, 1, None),
+    Among("iront", -1, 1, None),
+    Among("\u{00EE}t", -1, 1, None),
+    Among("iriez", -1, 1, None),
+    Among("issiez", -1, 1, None),
+    Among("irez", -1, 1, None),
+    Among("issez", -1, 1, None),
+];
+
+static A_6: &'static [Among<Context>; 38] = &[
+    Among("a", -1, 3, None),
+    Among("era", 0, 2, None),
+    Among("asse", -1, 3, None),
+    Among("ante", -1, 3, None),
+    Among("\u{00E9}e", -1, 2, None),
+    Among("ai", -1, 3, None),
+    Among("erai", 5, 2, None),
+    Among("er", -1, 2, None),
+    Among("as", -1, 3, None),
+    Among("eras", 8, 2, None),
+    Among("\u{00E2}mes", -1, 3, None),
+    Among("asses", -1, 3, None),
+    Among("antes", -1, 3, None),
+    Among("\u{00E2}tes", -1, 3, None),
+    Among("\u{00E9}es", -1, 2, None),
+    Among("ais", -1, 3, None),
+    Among("erais", 15, 2, None),
+    Among("ions", -1, 1, None),
+    Among("erions", 17, 2, None),
+    Among("assions", 17, 3, None),
+    Among("erons", -1, 2, None),
+    Among("ants", -1, 3, None),
+    Among("\u{00E9}s", -1, 2, None),
+    Among("ait", -1, 3, None),
+    Among("erait", 23, 2, None),
+    Among("ant", -1, 3, None),
+    Among("aIent", -1, 3, None),
+    Among("eraIent", 26, 2, None),
+    Among("\u{00E8}rent", -1, 2, None),
+    Among("assent", -1, 3, None),
+    Among("eront", -1, 2, None),
+    Among("\u{00E2}t", -1, 3, None),
+    Among("ez", -1, 2, None),
+    Among("iez", 32, 2, None),
+    Among("eriez", 33, 2, None),
+    Among("assiez", 33, 3, None),
+    Among("erez", 32, 2, None),
+    Among("\u{00E9}", -1, 2, None),
+];
+
+static A_7: &'static [Among<Context>; 7] = &[
+    Among("e", -1, 3, None),
+    Among("I\u{00E8}re", 0, 2, None),
+    Among("i\u{00E8}re", 0, 2, None),
+    Among("ion", -1, 1, None),
+    Among("Ier", -1, 2, None),
+    Among("ier", -1, 2, None),
+    Among("\u{00EB}", -1, 4, None),
+];
+
+static A_8: &'static [Among<Context>; 5] = &[
+    Among("ell", -1, -1, None),
+    Among("eill", -1, -1, None),
+    Among("enn", -1, -1, None),
+    Among("onn", -1, -1, None),
+    Among("ett", -1, -1, None),
+];
+
+static G_v: &'static [u8; 20] = &[17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 130, 103, 8, 5];
+
+static G_keep_with_s: &'static [u8; 17] = &[1, 65, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128];
+
+#[derive(Clone)]
+struct Context {
+    i_p2: usize,
+    i_p1: usize,
+    i_pV: usize,
+}
+
+fn r_prelude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // repeat, line 38
+    'replab0: loop{
+        let v_1 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // goto, line 38
+            'golab2: loop {
+                let v_2 = env.cursor;
+                'lab3: loop {
+                    // (, line 38
+                    // or, line 44
+                    'lab4: loop {
+                        let v_3 = env.cursor;
+                        'lab5: loop {
+                            // (, line 40
+                            if !env.in_grouping(G_v, 97, 251) {
+                                break 'lab5;
+                            }
+                            // [, line 40
+                            env.bra = env.cursor;
+                            // or, line 40
+                            'lab6: loop {
+                                let v_4 = env.cursor;
+                                'lab7: loop {
+                                    // (, line 40
+                                    // literal, line 40
+                                    if !env.eq_s(&"u") {
+                                        break 'lab7;
+                                    }
+                                    // ], line 40
+                                    env.ket = env.cursor;
+                                    if !env.in_grouping(G_v, 97, 251) {
+                                        break 'lab7;
+                                    }
+                                    // <-, line 40
+                                    if !env.slice_from("U") {
+                                        return false;
+                                    }
+                                    break 'lab6;
+                                }
+                                env.cursor = v_4;
+                                'lab8: loop {
+                                    // (, line 41
+                                    // literal, line 41
+                                    if !env.eq_s(&"i") {
+                                        break 'lab8;
+                                    }
+                                    // ], line 41
+                                    env.ket = env.cursor;
+                                    if !env.in_grouping(G_v, 97, 251) {
+                                        break 'lab8;
+                                    }
+                                    // <-, line 41
+                                    if !env.slice_from("I") {
+                                        return false;
+                                    }
+                                    break 'lab6;
+                                }
+                                env.cursor = v_4;
+                                // (, line 42
+                                // literal, line 42
+                                if !env.eq_s(&"y") {
+                                    break 'lab5;
+                                }
+                                // ], line 42
+                                env.ket = env.cursor;
+                                // <-, line 42
+                                if !env.slice_from("Y") {
+                                    return false;
+                                }
+                                break 'lab6;
+                            }
+                            break 'lab4;
+                        }
+                        env.cursor = v_3;
+                        'lab9: loop {
+                            // (, line 45
+                            // [, line 45
+                            env.bra = env.cursor;
+                            // literal, line 45
+                            if !env.eq_s(&"y") {
+                                break 'lab9;
+                            }
+                            // ], line 45
+                            env.ket = env.cursor;
+                            if !env.in_grouping(G_v, 97, 251) {
+                                break 'lab9;
+                            }
+                            // <-, line 45
+                            if !env.slice_from("Y") {
+                                return false;
+                            }
+                            break 'lab4;
+                        }
+                        env.cursor = v_3;
+                        // (, line 47
+                        // literal, line 47
+                        if !env.eq_s(&"q") {
+                            break 'lab3;
+                        }
+                        // [, line 47
+                        env.bra = env.cursor;
+                        // literal, line 47
+                        if !env.eq_s(&"u") {
+                            break 'lab3;
+                        }
+                        // ], line 47
+                        env.ket = env.cursor;
+                        // <-, line 47
+                        if !env.slice_from("U") {
+                            return false;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = v_2;
+                    break 'golab2;
+                }
+                env.cursor = v_2;
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 50
+    context.i_pV = env.limit;
+    context.i_p1 = env.limit;
+    context.i_p2 = env.limit;
+    // do, line 56
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // (, line 56
+        // or, line 58
+        'lab1: loop {
+            let v_2 = env.cursor;
+            'lab2: loop {
+                // (, line 57
+                if !env.in_grouping(G_v, 97, 251) {
+                    break 'lab2;
+                }
+                if !env.in_grouping(G_v, 97, 251) {
+                    break 'lab2;
+                }
+                // next, line 57
+                if env.cursor >= env.limit {
+                    break 'lab2;
+                }
+                env.next_char();
+                break 'lab1;
+            }
+            env.cursor = v_2;
+            'lab3: loop {
+                // among, line 59
+                if env.find_among(A_0, context) == 0 {
+                    break 'lab3;
+                }
+                break 'lab1;
+            }
+            env.cursor = v_2;
+            // (, line 66
+            // next, line 66
+            if env.cursor >= env.limit {
+                break 'lab0;
+            }
+            env.next_char();
+            // gopast, line 66
+            'golab4: loop {
+                'lab5: loop {
+                    if !env.in_grouping(G_v, 97, 251) {
+                        break 'lab5;
+                    }
+                    break 'golab4;
+                }
+                if env.cursor >= env.limit {
+                    break 'lab0;
+                }
+                env.next_char();
+            }
+            break 'lab1;
+        }
+        // setmark pV, line 67
+        context.i_pV = env.cursor;
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 69
+    let v_4 = env.cursor;
+    'lab6: loop {
+        // (, line 69
+        // gopast, line 70
+        'golab7: loop {
+            'lab8: loop {
+                if !env.in_grouping(G_v, 97, 251) {
+                    break 'lab8;
+                }
+                break 'golab7;
+            }
+            if env.cursor >= env.limit {
+                break 'lab6;
+            }
+            env.next_char();
+        }
+        // gopast, line 70
+        'golab9: loop {
+            'lab10: loop {
+                if !env.out_grouping(G_v, 97, 251) {
+                    break 'lab10;
+                }
+                break 'golab9;
+            }
+            if env.cursor >= env.limit {
+                break 'lab6;
+            }
+            env.next_char();
+        }
+        // setmark p1, line 70
+        context.i_p1 = env.cursor;
+        // gopast, line 71
+        'golab11: loop {
+            'lab12: loop {
+                if !env.in_grouping(G_v, 97, 251) {
+                    break 'lab12;
+                }
+                break 'golab11;
+            }
+            if env.cursor >= env.limit {
+                break 'lab6;
+            }
+            env.next_char();
+        }
+        // gopast, line 71
+        'golab13: loop {
+            'lab14: loop {
+                if !env.out_grouping(G_v, 97, 251) {
+                    break 'lab14;
+                }
+                break 'golab13;
+            }
+            if env.cursor >= env.limit {
+                break 'lab6;
+            }
+            env.next_char();
+        }
+        // setmark p2, line 71
+        context.i_p2 = env.cursor;
+        break 'lab6;
+    }
+    env.cursor = v_4;
+    return true;
+}
+
+fn r_postlude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // repeat, line 75
+    'replab0: loop{
+        let v_1 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 75
+            // [, line 77
+            env.bra = env.cursor;
+            // substring, line 77
+            among_var = env.find_among(A_1, context);
+            if among_var == 0 {
+                break 'lab1;
+            }
+            // ], line 77
+            env.ket = env.cursor;
+            if among_var == 0 {
+                break 'lab1;
+            } else if among_var == 1 {
+                // (, line 78
+                // <-, line 78
+                if !env.slice_from("i") {
+                    return false;
+                }
+            } else if among_var == 2 {
+                // (, line 79
+                // <-, line 79
+                if !env.slice_from("u") {
+                    return false;
+                }
+            } else if among_var == 3 {
+                // (, line 80
+                // <-, line 80
+                if !env.slice_from("y") {
+                    return false;
+                }
+            } else if among_var == 4 {
+                // (, line 81
+                // next, line 81
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+fn r_RV(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_pV <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_R1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p1 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_R2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p2 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_standard_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 91
+    // [, line 92
+    env.ket = env.cursor;
+    // substring, line 92
+    among_var = env.find_among_b(A_4, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 92
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 96
+        // call R2, line 96
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 96
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 99
+        // call R2, line 99
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 99
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 100
+        let v_1 = env.limit - env.cursor;
+        'lab0: loop {
+            // (, line 100
+            // [, line 100
+            env.ket = env.cursor;
+            // literal, line 100
+            if !env.eq_s_b(&"ic") {
+                env.cursor = env.limit - v_1;
+                break 'lab0;
+            }
+            // ], line 100
+            env.bra = env.cursor;
+            // or, line 100
+            'lab1: loop {
+                let v_2 = env.limit - env.cursor;
+                'lab2: loop {
+                    // (, line 100
+                    // call R2, line 100
+                    if !r_R2(env, context) {
+                        break 'lab2;
+                    }
+                    // delete, line 100
+                    if !env.slice_del() {
+                        return false;
+                    }
+                    break 'lab1;
+                }
+                env.cursor = env.limit - v_2;
+                // <-, line 100
+                if !env.slice_from("iqU") {
+                    return false;
+                }
+                break 'lab1;
+            }
+            break 'lab0;
+        }
+    } else if among_var == 3 {
+        // (, line 104
+        // call R2, line 104
+        if !r_R2(env, context) {
+            return false;
+        }
+        // <-, line 104
+        if !env.slice_from("log") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 107
+        // call R2, line 107
+        if !r_R2(env, context) {
+            return false;
+        }
+        // <-, line 107
+        if !env.slice_from("u") {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 110
+        // call R2, line 110
+        if !r_R2(env, context) {
+            return false;
+        }
+        // <-, line 110
+        if !env.slice_from("ent") {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 113
+        // call RV, line 114
+        if !r_RV(env, context) {
+            return false;
+        }
+        // delete, line 114
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 115
+        let v_3 = env.limit - env.cursor;
+        'lab3: loop {
+            // (, line 115
+            // [, line 116
+            env.ket = env.cursor;
+            // substring, line 116
+            among_var = env.find_among_b(A_2, context);
+            if among_var == 0 {
+                env.cursor = env.limit - v_3;
+                break 'lab3;
+            }
+            // ], line 116
+            env.bra = env.cursor;
+            if among_var == 0 {
+                env.cursor = env.limit - v_3;
+                break 'lab3;
+            } else if among_var == 1 {
+                // (, line 117
+                // call R2, line 117
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_3;
+                    break 'lab3;
+                }
+                // delete, line 117
+                if !env.slice_del() {
+                    return false;
+                }
+                // [, line 117
+                env.ket = env.cursor;
+                // literal, line 117
+                if !env.eq_s_b(&"at") {
+                    env.cursor = env.limit - v_3;
+                    break 'lab3;
+                }
+                // ], line 117
+                env.bra = env.cursor;
+                // call R2, line 117
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_3;
+                    break 'lab3;
+                }
+                // delete, line 117
+                if !env.slice_del() {
+                    return false;
+                }
+            } else if among_var == 2 {
+                // (, line 118
+                // or, line 118
+                'lab4: loop {
+                    let v_4 = env.limit - env.cursor;
+                    'lab5: loop {
+                        // (, line 118
+                        // call R2, line 118
+                        if !r_R2(env, context) {
+                            break 'lab5;
+                        }
+                        // delete, line 118
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_4;
+                    // (, line 118
+                    // call R1, line 118
+                    if !r_R1(env, context) {
+                        env.cursor = env.limit - v_3;
+                        break 'lab3;
+                    }
+                    // <-, line 118
+                    if !env.slice_from("eux") {
+                        return false;
+                    }
+                    break 'lab4;
+                }
+            } else if among_var == 3 {
+                // (, line 120
+                // call R2, line 120
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_3;
+                    break 'lab3;
+                }
+                // delete, line 120
+                if !env.slice_del() {
+                    return false;
+                }
+            } else if among_var == 4 {
+                // (, line 122
+                // call RV, line 122
+                if !r_RV(env, context) {
+                    env.cursor = env.limit - v_3;
+                    break 'lab3;
+                }
+                // <-, line 122
+                if !env.slice_from("i") {
+                    return false;
+                }
+            }
+            break 'lab3;
+        }
+    } else if among_var == 7 {
+        // (, line 128
+        // call R2, line 129
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 129
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 130
+        let v_5 = env.limit - env.cursor;
+        'lab6: loop {
+            // (, line 130
+            // [, line 131
+            env.ket = env.cursor;
+            // substring, line 131
+            among_var = env.find_among_b(A_3, context);
+            if among_var == 0 {
+                env.cursor = env.limit - v_5;
+                break 'lab6;
+            }
+            // ], line 131
+            env.bra = env.cursor;
+            if among_var == 0 {
+                env.cursor = env.limit - v_5;
+                break 'lab6;
+            } else if among_var == 1 {
+                // (, line 132
+                // or, line 132
+                'lab7: loop {
+                    let v_6 = env.limit - env.cursor;
+                    'lab8: loop {
+                        // (, line 132
+                        // call R2, line 132
+                        if !r_R2(env, context) {
+                            break 'lab8;
+                        }
+                        // delete, line 132
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        break 'lab7;
+                    }
+                    env.cursor = env.limit - v_6;
+                    // <-, line 132
+                    if !env.slice_from("abl") {
+                        return false;
+                    }
+                    break 'lab7;
+                }
+            } else if among_var == 2 {
+                // (, line 133
+                // or, line 133
+                'lab9: loop {
+                    let v_7 = env.limit - env.cursor;
+                    'lab10: loop {
+                        // (, line 133
+                        // call R2, line 133
+                        if !r_R2(env, context) {
+                            break 'lab10;
+                        }
+                        // delete, line 133
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        break 'lab9;
+                    }
+                    env.cursor = env.limit - v_7;
+                    // <-, line 133
+                    if !env.slice_from("iqU") {
+                        return false;
+                    }
+                    break 'lab9;
+                }
+            } else if among_var == 3 {
+                // (, line 134
+                // call R2, line 134
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_5;
+                    break 'lab6;
+                }
+                // delete, line 134
+                if !env.slice_del() {
+                    return false;
+                }
+            }
+            break 'lab6;
+        }
+    } else if among_var == 8 {
+        // (, line 140
+        // call R2, line 141
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 141
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 142
+        let v_8 = env.limit - env.cursor;
+        'lab11: loop {
+            // (, line 142
+            // [, line 142
+            env.ket = env.cursor;
+            // literal, line 142
+            if !env.eq_s_b(&"at") {
+                env.cursor = env.limit - v_8;
+                break 'lab11;
+            }
+            // ], line 142
+            env.bra = env.cursor;
+            // call R2, line 142
+            if !r_R2(env, context) {
+                env.cursor = env.limit - v_8;
+                break 'lab11;
+            }
+            // delete, line 142
+            if !env.slice_del() {
+                return false;
+            }
+            // [, line 142
+            env.ket = env.cursor;
+            // literal, line 142
+            if !env.eq_s_b(&"ic") {
+                env.cursor = env.limit - v_8;
+                break 'lab11;
+            }
+            // ], line 142
+            env.bra = env.cursor;
+            // or, line 142
+            'lab12: loop {
+                let v_9 = env.limit - env.cursor;
+                'lab13: loop {
+                    // (, line 142
+                    // call R2, line 142
+                    if !r_R2(env, context) {
+                        break 'lab13;
+                    }
+                    // delete, line 142
+                    if !env.slice_del() {
+                        return false;
+                    }
+                    break 'lab12;
+                }
+                env.cursor = env.limit - v_9;
+                // <-, line 142
+                if !env.slice_from("iqU") {
+                    return false;
+                }
+                break 'lab12;
+            }
+            break 'lab11;
+        }
+    } else if among_var == 9 {
+        // (, line 144
+        // <-, line 144
+        if !env.slice_from("eau") {
+            return false;
+        }
+    } else if among_var == 10 {
+        // (, line 145
+        // call R1, line 145
+        if !r_R1(env, context) {
+            return false;
+        }
+        // <-, line 145
+        if !env.slice_from("al") {
+            return false;
+        }
+    } else if among_var == 11 {
+        // (, line 147
+        // or, line 147
+        'lab14: loop {
+            let v_10 = env.limit - env.cursor;
+            'lab15: loop {
+                // (, line 147
+                // call R2, line 147
+                if !r_R2(env, context) {
+                    break 'lab15;
+                }
+                // delete, line 147
+                if !env.slice_del() {
+                    return false;
+                }
+                break 'lab14;
+            }
+            env.cursor = env.limit - v_10;
+            // (, line 147
+            // call R1, line 147
+            if !r_R1(env, context) {
+                return false;
+            }
+            // <-, line 147
+            if !env.slice_from("eux") {
+                return false;
+            }
+            break 'lab14;
+        }
+    } else if among_var == 12 {
+        // (, line 150
+        // call R1, line 150
+        if !r_R1(env, context) {
+            return false;
+        }
+        if !env.out_grouping_b(G_v, 97, 251) {
+            return false;
+        }
+        // delete, line 150
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 13 {
+        // (, line 155
+        // call RV, line 155
+        if !r_RV(env, context) {
+            return false;
+        }
+        // fail, line 155
+        // (, line 155
+        // <-, line 155
+        if !env.slice_from("ant") {
+            return false;
+        }
+        return false;
+    } else if among_var == 14 {
+        // (, line 156
+        // call RV, line 156
+        if !r_RV(env, context) {
+            return false;
+        }
+        // fail, line 156
+        // (, line 156
+        // <-, line 156
+        if !env.slice_from("ent") {
+            return false;
+        }
+        return false;
+    } else if among_var == 15 {
+        // (, line 158
+        // test, line 158
+        let v_11 = env.limit - env.cursor;
+        // (, line 158
+        if !env.in_grouping_b(G_v, 97, 251) {
+            return false;
+        }
+        // call RV, line 158
+        if !r_RV(env, context) {
+            return false;
+        }
+        env.cursor = env.limit - v_11;
+        // fail, line 158
+        // (, line 158
+        // delete, line 158
+        if !env.slice_del() {
+            return false;
+        }
+        return false;
+    }
+    return true;
+}
+
+fn r_i_verb_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // setlimit, line 163
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 163
+    if env.cursor < context.i_pV {
+        return false;
+    }
+    env.cursor = context.i_pV;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 163
+    // [, line 164
+    env.ket = env.cursor;
+    // substring, line 164
+    among_var = env.find_among_b(A_5, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 164
+    env.bra = env.cursor;
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    } else if among_var == 1 {
+        // (, line 170
+        if !env.out_grouping_b(G_v, 97, 251) {
+            env.limit_backward = v_2;
+            return false;
+        }
+        // delete, line 170
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    env.limit_backward = v_2;
+    return true;
+}
+
+fn r_verb_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // setlimit, line 174
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 174
+    if env.cursor < context.i_pV {
+        return false;
+    }
+    env.cursor = context.i_pV;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 174
+    // [, line 175
+    env.ket = env.cursor;
+    // substring, line 175
+    among_var = env.find_among_b(A_6, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 175
+    env.bra = env.cursor;
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    } else if among_var == 1 {
+        // (, line 177
+        // call R2, line 177
+        if !r_R2(env, context) {
+            env.limit_backward = v_2;
+            return false;
+        }
+        // delete, line 177
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 185
+        // delete, line 185
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 190
+        // delete, line 190
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 191
+        let v_3 = env.limit - env.cursor;
+        'lab0: loop {
+            // (, line 191
+            // [, line 191
+            env.ket = env.cursor;
+            // literal, line 191
+            if !env.eq_s_b(&"e") {
+                env.cursor = env.limit - v_3;
+                break 'lab0;
+            }
+            // ], line 191
+            env.bra = env.cursor;
+            // delete, line 191
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab0;
+        }
+    }
+    env.limit_backward = v_2;
+    return true;
+}
+
+fn r_residual_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 198
+    // try, line 199
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 199
+        // [, line 199
+        env.ket = env.cursor;
+        // literal, line 199
+        if !env.eq_s_b(&"s") {
+            env.cursor = env.limit - v_1;
+            break 'lab0;
+        }
+        // ], line 199
+        env.bra = env.cursor;
+        // test, line 199
+        let v_2 = env.limit - env.cursor;
+        if !env.out_grouping_b(G_keep_with_s, 97, 232) {
+            env.cursor = env.limit - v_1;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_2;
+        // delete, line 199
+        if !env.slice_del() {
+            return false;
+        }
+        break 'lab0;
+    }
+    // setlimit, line 200
+    let v_3 = env.limit - env.cursor;
+    // tomark, line 200
+    if env.cursor < context.i_pV {
+        return false;
+    }
+    env.cursor = context.i_pV;
+    let v_4 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_3;
+    // (, line 200
+    // [, line 201
+    env.ket = env.cursor;
+    // substring, line 201
+    among_var = env.find_among_b(A_7, context);
+    if among_var == 0 {
+        env.limit_backward = v_4;
+        return false;
+    }
+    // ], line 201
+    env.bra = env.cursor;
+    if among_var == 0 {
+        env.limit_backward = v_4;
+        return false;
+    } else if among_var == 1 {
+        // (, line 202
+        // call R2, line 202
+        if !r_R2(env, context) {
+            env.limit_backward = v_4;
+            return false;
+        }
+        // or, line 202
+        'lab1: loop {
+            let v_5 = env.limit - env.cursor;
+            'lab2: loop {
+                // literal, line 202
+                if !env.eq_s_b(&"s") {
+                    break 'lab2;
+                }
+                break 'lab1;
+            }
+            env.cursor = env.limit - v_5;
+            // literal, line 202
+            if !env.eq_s_b(&"t") {
+                env.limit_backward = v_4;
+                return false;
+            }
+            break 'lab1;
+        }
+        // delete, line 202
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 204
+        // <-, line 204
+        if !env.slice_from("i") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 205
+        // delete, line 205
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 206
+        // literal, line 206
+        if !env.eq_s_b(&"gu") {
+            env.limit_backward = v_4;
+            return false;
+        }
+        // delete, line 206
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    env.limit_backward = v_4;
+    return true;
+}
+
+fn r_un_double(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 211
+    // test, line 212
+    let v_1 = env.limit - env.cursor;
+    // among, line 212
+    if env.find_among_b(A_8, context) == 0 {
+        return false;
+    }
+    env.cursor = env.limit - v_1;
+    // [, line 212
+    env.ket = env.cursor;
+    // next, line 212
+    if env.cursor <= env.limit_backward {
+        return false;
+    }
+    env.previous_char();
+    // ], line 212
+    env.bra = env.cursor;
+    // delete, line 212
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+fn r_un_accent(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 215
+    // atleast, line 216
+    let mut v_1 = 1;
+    // atleast, line 216
+    'replab0: loop{
+        'lab1: for _ in 0..1 {
+            if !env.out_grouping_b(G_v, 97, 251) {
+                break 'lab1;
+            }
+            v_1 -= 1;
+            continue 'replab0;
+        }
+        break 'replab0;
+    }
+    if v_1 > 0 {
+        return false;
+    }
+    // [, line 217
+    env.ket = env.cursor;
+    // or, line 217
+    'lab2: loop {
+        let v_3 = env.limit - env.cursor;
+        'lab3: loop {
+            // literal, line 217
+            if !env.eq_s_b(&"\u{00E9}") {
+                break 'lab3;
+            }
+            break 'lab2;
+        }
+        env.cursor = env.limit - v_3;
+        // literal, line 217
+        if !env.eq_s_b(&"\u{00E8}") {
+            return false;
+        }
+        break 'lab2;
+    }
+    // ], line 217
+    env.bra = env.cursor;
+    // <-, line 217
+    if !env.slice_from("e") {
+        return false;
+    }
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        i_p2: 0,
+        i_p1: 0,
+        i_pV: 0,
+    };
+    // (, line 221
+    // do, line 223
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call prelude, line 223
+        if !r_prelude(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 224
+    let v_2 = env.cursor;
+    'lab1: loop {
+        // call mark_regions, line 224
+        if !r_mark_regions(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = v_2;
+    // backwards, line 225
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 225
+    // do, line 227
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // (, line 227
+        // or, line 237
+        'lab3: loop {
+            let v_4 = env.limit - env.cursor;
+            'lab4: loop {
+                // (, line 228
+                // and, line 233
+                let v_5 = env.limit - env.cursor;
+                // (, line 229
+                // or, line 229
+                'lab5: loop {
+                    let v_6 = env.limit - env.cursor;
+                    'lab6: loop {
+                        // call standard_suffix, line 229
+                        if !r_standard_suffix(env, context) {
+                            break 'lab6;
+                        }
+                        break 'lab5;
+                    }
+                    env.cursor = env.limit - v_6;
+                    'lab7: loop {
+                        // call i_verb_suffix, line 230
+                        if !r_i_verb_suffix(env, context) {
+                            break 'lab7;
+                        }
+                        break 'lab5;
+                    }
+                    env.cursor = env.limit - v_6;
+                    // call verb_suffix, line 231
+                    if !r_verb_suffix(env, context) {
+                        break 'lab4;
+                    }
+                    break 'lab5;
+                }
+                env.cursor = env.limit - v_5;
+                // try, line 234
+                let v_7 = env.limit - env.cursor;
+                'lab8: loop {
+                    // (, line 234
+                    // [, line 234
+                    env.ket = env.cursor;
+                    // or, line 234
+                    'lab9: loop {
+                        let v_8 = env.limit - env.cursor;
+                        'lab10: loop {
+                            // (, line 234
+                            // literal, line 234
+                            if !env.eq_s_b(&"Y") {
+                                break 'lab10;
+                            }
+                            // ], line 234
+                            env.bra = env.cursor;
+                            // <-, line 234
+                            if !env.slice_from("i") {
+                                return false;
+                            }
+                            break 'lab9;
+                        }
+                        env.cursor = env.limit - v_8;
+                        // (, line 235
+                        // literal, line 235
+                        if !env.eq_s_b(&"\u{00E7}") {
+                            env.cursor = env.limit - v_7;
+                            break 'lab8;
+                        }
+                        // ], line 235
+                        env.bra = env.cursor;
+                        // <-, line 235
+                        if !env.slice_from("c") {
+                            return false;
+                        }
+                        break 'lab9;
+                    }
+                    break 'lab8;
+                }
+                break 'lab3;
+            }
+            env.cursor = env.limit - v_4;
+            // call residual_suffix, line 238
+            if !r_residual_suffix(env, context) {
+                break 'lab2;
+            }
+            break 'lab3;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    // do, line 243
+    let v_9 = env.limit - env.cursor;
+    'lab11: loop {
+        // call un_double, line 243
+        if !r_un_double(env, context) {
+            break 'lab11;
+        }
+        break 'lab11;
+    }
+    env.cursor = env.limit - v_9;
+    // do, line 244
+    let v_10 = env.limit - env.cursor;
+    'lab12: loop {
+        // call un_accent, line 244
+        if !r_un_accent(env, context) {
+            break 'lab12;
+        }
+        break 'lab12;
+    }
+    env.cursor = env.limit - v_10;
+    env.cursor = env.limit_backward;
+    // do, line 246
+    let v_11 = env.cursor;
+    'lab13: loop {
+        // call postlude, line 246
+        if !r_postlude(env, context) {
+            break 'lab13;
+        }
+        break 'lab13;
+    }
+    env.cursor = v_11;
+    return true;
+}
diff --git a/src/snowball/algorithms/german.rs b/src/snowball/algorithms/german.rs
new file mode 100644
index 0000000..18c8731
--- /dev/null
+++ b/src/snowball/algorithms/german.rs
@@ -0,0 +1,668 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 6] = &[
+    Among("", -1, 6, None),
+    Among("U", 0, 2, None),
+    Among("Y", 0, 1, None),
+    Among("\u{00E4}", 0, 3, None),
+    Among("\u{00F6}", 0, 4, None),
+    Among("\u{00FC}", 0, 5, None),
+];
+
+static A_1: &'static [Among<Context>; 7] = &[
+    Among("e", -1, 2, None),
+    Among("em", -1, 1, None),
+    Among("en", -1, 2, None),
+    Among("ern", -1, 1, None),
+    Among("er", -1, 1, None),
+    Among("s", -1, 3, None),
+    Among("es", 5, 2, None),
+];
+
+static A_2: &'static [Among<Context>; 4] = &[
+    Among("en", -1, 1, None),
+    Among("er", -1, 1, None),
+    Among("st", -1, 2, None),
+    Among("est", 2, 1, None),
+];
+
+static A_3: &'static [Among<Context>; 2] = &[
+    Among("ig", -1, 1, None),
+    Among("lich", -1, 1, None),
+];
+
+static A_4: &'static [Among<Context>; 8] = &[
+    Among("end", -1, 1, None),
+    Among("ig", -1, 2, None),
+    Among("ung", -1, 1, None),
+    Among("lich", -1, 3, None),
+    Among("isch", -1, 2, None),
+    Among("ik", -1, 2, None),
+    Among("heit", -1, 3, None),
+    Among("keit", -1, 4, None),
+];
+
+static G_v: &'static [u8; 20] = &[17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32, 8];
+
+static G_s_ending: &'static [u8; 3] = &[117, 30, 5];
+
+static G_st_ending: &'static [u8; 3] = &[117, 30, 4];
+
+#[derive(Clone)]
+struct Context {
+    i_x: usize,
+    i_p2: usize,
+    i_p1: usize,
+}
+
+fn r_prelude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 32
+    // test, line 34
+    let v_1 = env.cursor;
+    // repeat, line 34
+    'replab0: loop{
+        let v_2 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 34
+            // or, line 37
+            'lab2: loop {
+                let v_3 = env.cursor;
+                'lab3: loop {
+                    // (, line 35
+                    // [, line 36
+                    env.bra = env.cursor;
+                    // literal, line 36
+                    if !env.eq_s(&"\u{00DF}") {
+                        break 'lab3;
+                    }
+                    // ], line 36
+                    env.ket = env.cursor;
+                    // <-, line 36
+                    if !env.slice_from("ss") {
+                        return false;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = v_3;
+                // next, line 37
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+                break 'lab2;
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_2;
+        break 'replab0;
+    }
+    env.cursor = v_1;
+    // repeat, line 40
+    'replab4: loop{
+        let v_4 = env.cursor;
+        'lab5: for _ in 0..1 {
+            // goto, line 40
+            'golab6: loop {
+                let v_5 = env.cursor;
+                'lab7: loop {
+                    // (, line 40
+                    if !env.in_grouping(G_v, 97, 252) {
+                        break 'lab7;
+                    }
+                    // [, line 41
+                    env.bra = env.cursor;
+                    // or, line 41
+                    'lab8: loop {
+                        let v_6 = env.cursor;
+                        'lab9: loop {
+                            // (, line 41
+                            // literal, line 41
+                            if !env.eq_s(&"u") {
+                                break 'lab9;
+                            }
+                            // ], line 41
+                            env.ket = env.cursor;
+                            if !env.in_grouping(G_v, 97, 252) {
+                                break 'lab9;
+                            }
+                            // <-, line 41
+                            if !env.slice_from("U") {
+                                return false;
+                            }
+                            break 'lab8;
+                        }
+                        env.cursor = v_6;
+                        // (, line 42
+                        // literal, line 42
+                        if !env.eq_s(&"y") {
+                            break 'lab7;
+                        }
+                        // ], line 42
+                        env.ket = env.cursor;
+                        if !env.in_grouping(G_v, 97, 252) {
+                            break 'lab7;
+                        }
+                        // <-, line 42
+                        if !env.slice_from("Y") {
+                            return false;
+                        }
+                        break 'lab8;
+                    }
+                    env.cursor = v_5;
+                    break 'golab6;
+                }
+                env.cursor = v_5;
+                if env.cursor >= env.limit {
+                    break 'lab5;
+                }
+                env.next_char();
+            }
+            continue 'replab4;
+        }
+        env.cursor = v_4;
+        break 'replab4;
+    }
+    return true;
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 46
+    context.i_p1 = env.limit;
+    context.i_p2 = env.limit;
+    // test, line 51
+    let v_1 = env.cursor;
+    // (, line 51
+    // hop, line 51
+    let c = env.byte_index_for_hop(3);
+    if 0 as i32 > c || c > env.limit as i32 {
+        return false;
+    }
+    env.cursor = c as usize;
+    // setmark x, line 51
+    context.i_x = env.cursor;
+    env.cursor = v_1;
+    // gopast, line 53
+    'golab0: loop {
+        'lab1: loop {
+            if !env.in_grouping(G_v, 97, 252) {
+                break 'lab1;
+            }
+            break 'golab0;
+        }
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // gopast, line 53
+    'golab2: loop {
+        'lab3: loop {
+            if !env.out_grouping(G_v, 97, 252) {
+                break 'lab3;
+            }
+            break 'golab2;
+        }
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // setmark p1, line 53
+    context.i_p1 = env.cursor;
+    // try, line 54
+    'lab4: loop {
+        // (, line 54
+        if !(context.i_p1 < context.i_x){
+            break 'lab4;
+        }
+        context.i_p1 = context.i_x;
+        break 'lab4;
+    }
+    // gopast, line 55
+    'golab5: loop {
+        'lab6: loop {
+            if !env.in_grouping(G_v, 97, 252) {
+                break 'lab6;
+            }
+            break 'golab5;
+        }
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // gopast, line 55
+    'golab7: loop {
+        'lab8: loop {
+            if !env.out_grouping(G_v, 97, 252) {
+                break 'lab8;
+            }
+            break 'golab7;
+        }
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // setmark p2, line 55
+    context.i_p2 = env.cursor;
+    return true;
+}
+
+fn r_postlude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // repeat, line 59
+    'replab0: loop{
+        let v_1 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 59
+            // [, line 61
+            env.bra = env.cursor;
+            // substring, line 61
+            among_var = env.find_among(A_0, context);
+            if among_var == 0 {
+                break 'lab1;
+            }
+            // ], line 61
+            env.ket = env.cursor;
+            if among_var == 0 {
+                break 'lab1;
+            } else if among_var == 1 {
+                // (, line 62
+                // <-, line 62
+                if !env.slice_from("y") {
+                    return false;
+                }
+            } else if among_var == 2 {
+                // (, line 63
+                // <-, line 63
+                if !env.slice_from("u") {
+                    return false;
+                }
+            } else if among_var == 3 {
+                // (, line 64
+                // <-, line 64
+                if !env.slice_from("a") {
+                    return false;
+                }
+            } else if among_var == 4 {
+                // (, line 65
+                // <-, line 65
+                if !env.slice_from("o") {
+                    return false;
+                }
+            } else if among_var == 5 {
+                // (, line 66
+                // <-, line 66
+                if !env.slice_from("u") {
+                    return false;
+                }
+            } else if among_var == 6 {
+                // (, line 67
+                // next, line 67
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+fn r_R1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p1 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_R2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p2 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_standard_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 77
+    // do, line 78
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 78
+        // [, line 79
+        env.ket = env.cursor;
+        // substring, line 79
+        among_var = env.find_among_b(A_1, context);
+        if among_var == 0 {
+            break 'lab0;
+        }
+        // ], line 79
+        env.bra = env.cursor;
+        // call R1, line 79
+        if !r_R1(env, context) {
+            break 'lab0;
+        }
+        if among_var == 0 {
+            break 'lab0;
+        } else if among_var == 1 {
+            // (, line 81
+            // delete, line 81
+            if !env.slice_del() {
+                return false;
+            }
+        } else if among_var == 2 {
+            // (, line 84
+            // delete, line 84
+            if !env.slice_del() {
+                return false;
+            }
+            // try, line 85
+            let v_2 = env.limit - env.cursor;
+            'lab1: loop {
+                // (, line 85
+                // [, line 85
+                env.ket = env.cursor;
+                // literal, line 85
+                if !env.eq_s_b(&"s") {
+                    env.cursor = env.limit - v_2;
+                    break 'lab1;
+                }
+                // ], line 85
+                env.bra = env.cursor;
+                // literal, line 85
+                if !env.eq_s_b(&"nis") {
+                    env.cursor = env.limit - v_2;
+                    break 'lab1;
+                }
+                // delete, line 85
+                if !env.slice_del() {
+                    return false;
+                }
+                break 'lab1;
+            }
+        } else if among_var == 3 {
+            // (, line 88
+            if !env.in_grouping_b(G_s_ending, 98, 116) {
+                break 'lab0;
+            }
+            // delete, line 88
+            if !env.slice_del() {
+                return false;
+            }
+        }
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    // do, line 92
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // (, line 92
+        // [, line 93
+        env.ket = env.cursor;
+        // substring, line 93
+        among_var = env.find_among_b(A_2, context);
+        if among_var == 0 {
+            break 'lab2;
+        }
+        // ], line 93
+        env.bra = env.cursor;
+        // call R1, line 93
+        if !r_R1(env, context) {
+            break 'lab2;
+        }
+        if among_var == 0 {
+            break 'lab2;
+        } else if among_var == 1 {
+            // (, line 95
+            // delete, line 95
+            if !env.slice_del() {
+                return false;
+            }
+        } else if among_var == 2 {
+            // (, line 98
+            if !env.in_grouping_b(G_st_ending, 98, 116) {
+                break 'lab2;
+            }
+            // hop, line 98
+            let c = env.byte_index_for_hop(-3);
+            if env.limit_backward as i32 > c || c > env.limit as i32 {
+                break 'lab2;
+            }
+            env.cursor = c as usize;
+            // delete, line 98
+            if !env.slice_del() {
+                return false;
+            }
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    // do, line 102
+    let v_4 = env.limit - env.cursor;
+    'lab3: loop {
+        // (, line 102
+        // [, line 103
+        env.ket = env.cursor;
+        // substring, line 103
+        among_var = env.find_among_b(A_4, context);
+        if among_var == 0 {
+            break 'lab3;
+        }
+        // ], line 103
+        env.bra = env.cursor;
+        // call R2, line 103
+        if !r_R2(env, context) {
+            break 'lab3;
+        }
+        if among_var == 0 {
+            break 'lab3;
+        } else if among_var == 1 {
+            // (, line 105
+            // delete, line 105
+            if !env.slice_del() {
+                return false;
+            }
+            // try, line 106
+            let v_5 = env.limit - env.cursor;
+            'lab4: loop {
+                // (, line 106
+                // [, line 106
+                env.ket = env.cursor;
+                // literal, line 106
+                if !env.eq_s_b(&"ig") {
+                    env.cursor = env.limit - v_5;
+                    break 'lab4;
+                }
+                // ], line 106
+                env.bra = env.cursor;
+                // not, line 106
+                let v_6 = env.limit - env.cursor;
+                'lab5: loop {
+                    // literal, line 106
+                    if !env.eq_s_b(&"e") {
+                        break 'lab5;
+                    }
+                    env.cursor = env.limit - v_5;
+                    break 'lab4;
+                }
+                env.cursor = env.limit - v_6;
+                // call R2, line 106
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_5;
+                    break 'lab4;
+                }
+                // delete, line 106
+                if !env.slice_del() {
+                    return false;
+                }
+                break 'lab4;
+            }
+        } else if among_var == 2 {
+            // (, line 109
+            // not, line 109
+            let v_7 = env.limit - env.cursor;
+            'lab6: loop {
+                // literal, line 109
+                if !env.eq_s_b(&"e") {
+                    break 'lab6;
+                }
+                break 'lab3;
+            }
+            env.cursor = env.limit - v_7;
+            // delete, line 109
+            if !env.slice_del() {
+                return false;
+            }
+        } else if among_var == 3 {
+            // (, line 112
+            // delete, line 112
+            if !env.slice_del() {
+                return false;
+            }
+            // try, line 113
+            let v_8 = env.limit - env.cursor;
+            'lab7: loop {
+                // (, line 113
+                // [, line 114
+                env.ket = env.cursor;
+                // or, line 114
+                'lab8: loop {
+                    let v_9 = env.limit - env.cursor;
+                    'lab9: loop {
+                        // literal, line 114
+                        if !env.eq_s_b(&"er") {
+                            break 'lab9;
+                        }
+                        break 'lab8;
+                    }
+                    env.cursor = env.limit - v_9;
+                    // literal, line 114
+                    if !env.eq_s_b(&"en") {
+                        env.cursor = env.limit - v_8;
+                        break 'lab7;
+                    }
+                    break 'lab8;
+                }
+                // ], line 114
+                env.bra = env.cursor;
+                // call R1, line 114
+                if !r_R1(env, context) {
+                    env.cursor = env.limit - v_8;
+                    break 'lab7;
+                }
+                // delete, line 114
+                if !env.slice_del() {
+                    return false;
+                }
+                break 'lab7;
+            }
+        } else if among_var == 4 {
+            // (, line 118
+            // delete, line 118
+            if !env.slice_del() {
+                return false;
+            }
+            // try, line 119
+            let v_10 = env.limit - env.cursor;
+            'lab10: loop {
+                // (, line 119
+                // [, line 120
+                env.ket = env.cursor;
+                // substring, line 120
+                among_var = env.find_among_b(A_3, context);
+                if among_var == 0 {
+                    env.cursor = env.limit - v_10;
+                    break 'lab10;
+                }
+                // ], line 120
+                env.bra = env.cursor;
+                // call R2, line 120
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_10;
+                    break 'lab10;
+                }
+                if among_var == 0 {
+                    env.cursor = env.limit - v_10;
+                    break 'lab10;
+                } else if among_var == 1 {
+                    // (, line 122
+                    // delete, line 122
+                    if !env.slice_del() {
+                        return false;
+                    }
+                }
+                break 'lab10;
+            }
+        }
+        break 'lab3;
+    }
+    env.cursor = env.limit - v_4;
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        i_x: 0,
+        i_p2: 0,
+        i_p1: 0,
+    };
+    // (, line 132
+    // do, line 133
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call prelude, line 133
+        if !r_prelude(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 134
+    let v_2 = env.cursor;
+    'lab1: loop {
+        // call mark_regions, line 134
+        if !r_mark_regions(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = v_2;
+    // backwards, line 135
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // do, line 136
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // call standard_suffix, line 136
+        if !r_standard_suffix(env, context) {
+            break 'lab2;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    env.cursor = env.limit_backward;
+    // do, line 137
+    let v_4 = env.cursor;
+    'lab3: loop {
+        // call postlude, line 137
+        if !r_postlude(env, context) {
+            break 'lab3;
+        }
+        break 'lab3;
+    }
+    env.cursor = v_4;
+    return true;
+}
diff --git a/src/snowball/algorithms/greek.rs b/src/snowball/algorithms/greek.rs
new file mode 100644
index 0000000..c81558c
--- /dev/null
+++ b/src/snowball/algorithms/greek.rs
@@ -0,0 +1,3992 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 46] = &[
+    Among("", -1, 25, None),
+    Among("\u{03C2}", 0, 18, None),
+    Among("\u{0386}", 0, 1, None),
+    Among("\u{0388}", 0, 5, None),
+    Among("\u{0389}", 0, 7, None),
+    Among("\u{038A}", 0, 9, None),
+    Among("\u{03CA}", 0, 7, None),
+    Among("\u{03CB}", 0, 20, None),
+    Among("\u{038C}", 0, 15, None),
+    Among("\u{03CC}", 0, 15, None),
+    Among("\u{03CD}", 0, 20, None),
+    Among("\u{038E}", 0, 20, None),
+    Among("\u{03CE}", 0, 24, None),
+    Among("\u{038F}", 0, 24, None),
+    Among("\u{0390}", 0, 7, None),
+    Among("\u{0391}", 0, 1, None),
+    Among("\u{0392}", 0, 2, None),
+    Among("\u{0393}", 0, 3, None),
+    Among("\u{0394}", 0, 4, None),
+    Among("\u{0395}", 0, 5, None),
+    Among("\u{0396}", 0, 6, None),
+    Among("\u{0397}", 0, 7, None),
+    Among("\u{0398}", 0, 8, None),
+    Among("\u{0399}", 0, 9, None),
+    Among("\u{039A}", 0, 10, None),
+    Among("\u{039B}", 0, 11, None),
+    Among("\u{039C}", 0, 12, None),
+    Among("\u{039D}", 0, 13, None),
+    Among("\u{039E}", 0, 14, None),
+    Among("\u{039F}", 0, 15, None),
+    Among("\u{03A0}", 0, 16, None),
+    Among("\u{03A1}", 0, 17, None),
+    Among("\u{03A3}", 0, 18, None),
+    Among("\u{03A4}", 0, 19, None),
+    Among("\u{03A5}", 0, 20, None),
+    Among("\u{03A6}", 0, 21, None),
+    Among("\u{03A7}", 0, 22, None),
+    Among("\u{03A8}", 0, 23, None),
+    Among("\u{03A9}", 0, 24, None),
+    Among("\u{03AA}", 0, 9, None),
+    Among("\u{03AB}", 0, 20, None),
+    Among("\u{03AC}", 0, 1, None),
+    Among("\u{03AD}", 0, 5, None),
+    Among("\u{03AE}", 0, 7, None),
+    Among("\u{03AF}", 0, 9, None),
+    Among("\u{03B0}", 0, 20, None),
+];
+
+static A_1: &'static [Among<Context>; 40] = &[
+    Among("\u{03BA}\u{03B1}\u{03B8}\u{03B5}\u{03C3}\u{03C4}\u{03C9}\u{03C3}", -1, 10, None),
+    Among("\u{03C6}\u{03C9}\u{03C3}", -1, 9, None),
+    Among("\u{03C0}\u{03B5}\u{03C1}\u{03B1}\u{03C3}", -1, 7, None),
+    Among("\u{03C4}\u{03B5}\u{03C1}\u{03B1}\u{03C3}", -1, 8, None),
+    Among("\u{03BA}\u{03C1}\u{03B5}\u{03B1}\u{03C3}", -1, 6, None),
+    Among("\u{03BA}\u{03B1}\u{03B8}\u{03B5}\u{03C3}\u{03C4}\u{03C9}\u{03C4}\u{03BF}\u{03C3}", -1, 10, None),
+    Among("\u{03C6}\u{03C9}\u{03C4}\u{03BF}\u{03C3}", -1, 9, None),
+    Among("\u{03C0}\u{03B5}\u{03C1}\u{03B1}\u{03C4}\u{03BF}\u{03C3}", -1, 7, None),
+    Among("\u{03C4}\u{03B5}\u{03C1}\u{03B1}\u{03C4}\u{03BF}\u{03C3}", -1, 8, None),
+    Among("\u{03BA}\u{03C1}\u{03B5}\u{03B1}\u{03C4}\u{03BF}\u{03C3}", -1, 6, None),
+    Among("\u{03B3}\u{03B5}\u{03B3}\u{03BF}\u{03BD}\u{03BF}\u{03C4}\u{03BF}\u{03C3}", -1, 11, None),
+    Among("\u{03B3}\u{03B5}\u{03B3}\u{03BF}\u{03BD}\u{03BF}\u{03C3}", -1, 11, None),
+    Among("\u{03C6}\u{03B1}\u{03B3}\u{03B9}\u{03BF}\u{03C5}", -1, 1, None),
+    Among("\u{03C3}\u{03BA}\u{03B1}\u{03B3}\u{03B9}\u{03BF}\u{03C5}", -1, 2, None),
+    Among("\u{03C3}\u{03BF}\u{03B3}\u{03B9}\u{03BF}\u{03C5}", -1, 4, None),
+    Among("\u{03C4}\u{03B1}\u{03C4}\u{03BF}\u{03B3}\u{03B9}\u{03BF}\u{03C5}", -1, 5, None),
+    Among("\u{03BF}\u{03BB}\u{03BF}\u{03B3}\u{03B9}\u{03BF}\u{03C5}", -1, 3, None),
+    Among("\u{03BA}\u{03B1}\u{03B8}\u{03B5}\u{03C3}\u{03C4}\u{03C9}\u{03C4}\u{03B1}", -1, 10, None),
+    Among("\u{03C6}\u{03C9}\u{03C4}\u{03B1}", -1, 9, None),
+    Among("\u{03C0}\u{03B5}\u{03C1}\u{03B1}\u{03C4}\u{03B1}", -1, 7, None),
+    Among("\u{03C4}\u{03B5}\u{03C1}\u{03B1}\u{03C4}\u{03B1}", -1, 8, None),
+    Among("\u{03BA}\u{03C1}\u{03B5}\u{03B1}\u{03C4}\u{03B1}", -1, 6, None),
+    Among("\u{03B3}\u{03B5}\u{03B3}\u{03BF}\u{03BD}\u{03BF}\u{03C4}\u{03B1}", -1, 11, None),
+    Among("\u{03C6}\u{03B1}\u{03B3}\u{03B9}\u{03B1}", -1, 1, None),
+    Among("\u{03C3}\u{03BA}\u{03B1}\u{03B3}\u{03B9}\u{03B1}", -1, 2, None),
+    Among("\u{03C3}\u{03BF}\u{03B3}\u{03B9}\u{03B1}", -1, 4, None),
+    Among("\u{03C4}\u{03B1}\u{03C4}\u{03BF}\u{03B3}\u{03B9}\u{03B1}", -1, 5, None),
+    Among("\u{03BF}\u{03BB}\u{03BF}\u{03B3}\u{03B9}\u{03B1}", -1, 3, None),
+    Among("\u{03C0}\u{03B5}\u{03C1}\u{03B1}\u{03C4}\u{03B7}", -1, 7, None),
+    Among("\u{03BA}\u{03B1}\u{03B8}\u{03B5}\u{03C3}\u{03C4}\u{03C9}\u{03C4}\u{03C9}\u{03BD}", -1, 10, None),
+    Among("\u{03C6}\u{03C9}\u{03C4}\u{03C9}\u{03BD}", -1, 9, None),
+    Among("\u{03C0}\u{03B5}\u{03C1}\u{03B1}\u{03C4}\u{03C9}\u{03BD}", -1, 7, None),
+    Among("\u{03C4}\u{03B5}\u{03C1}\u{03B1}\u{03C4}\u{03C9}\u{03BD}", -1, 8, None),
+    Among("\u{03BA}\u{03C1}\u{03B5}\u{03B1}\u{03C4}\u{03C9}\u{03BD}", -1, 6, None),
+    Among("\u{03B3}\u{03B5}\u{03B3}\u{03BF}\u{03BD}\u{03BF}\u{03C4}\u{03C9}\u{03BD}", -1, 11, None),
+    Among("\u{03C6}\u{03B1}\u{03B3}\u{03B9}\u{03C9}\u{03BD}", -1, 1, None),
+    Among("\u{03C3}\u{03BA}\u{03B1}\u{03B3}\u{03B9}\u{03C9}\u{03BD}", -1, 2, None),
+    Among("\u{03C3}\u{03BF}\u{03B3}\u{03B9}\u{03C9}\u{03BD}", -1, 4, None),
+    Among("\u{03C4}\u{03B1}\u{03C4}\u{03BF}\u{03B3}\u{03B9}\u{03C9}\u{03BD}", -1, 5, None),
+    Among("\u{03BF}\u{03BB}\u{03BF}\u{03B3}\u{03B9}\u{03C9}\u{03BD}", -1, 3, None),
+];
+
+static A_2: &'static [Among<Context>; 9] = &[
+    Among("\u{03C0}\u{03B1}", -1, 1, None),
+    Among("\u{03BE}\u{03B1}\u{03BD}\u{03B1}\u{03C0}\u{03B1}", 0, 1, None),
+    Among("\u{03B5}\u{03C0}\u{03B1}", 0, 1, None),
+    Among("\u{03C0}\u{03B5}\u{03C1}\u{03B9}\u{03C0}\u{03B1}", 0, 1, None),
+    Among("\u{03B1}\u{03BD}\u{03B1}\u{03BC}\u{03C0}\u{03B1}", 0, 1, None),
+    Among("\u{03B5}\u{03BC}\u{03C0}\u{03B1}", 0, 1, None),
+    Among("\u{03B4}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B1}\u{03B8}\u{03C1}\u{03BF}", -1, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03BD}\u{03B1}\u{03B8}\u{03C1}\u{03BF}", 7, 1, None),
+];
+
+static A_3: &'static [Among<Context>; 22] = &[
+    Among("\u{03C0}", -1, 1, None),
+    Among("\u{03B9}\u{03BC}\u{03C0}", 0, 1, None),
+    Among("\u{03C1}", -1, 1, None),
+    Among("\u{03C0}\u{03C1}", 2, 1, None),
+    Among("\u{03BC}\u{03C0}\u{03C1}", 3, 1, None),
+    Among("\u{03B1}\u{03C1}\u{03C1}", 2, 1, None),
+    Among("\u{03B3}\u{03BB}\u{03C5}\u{03BA}\u{03C5}\u{03C1}", 2, 1, None),
+    Among("\u{03C0}\u{03BF}\u{03BB}\u{03C5}\u{03C1}", 2, 1, None),
+    Among("\u{03B1}\u{03BC}\u{03C0}\u{03B1}\u{03C1}", 2, 1, None),
+    Among("\u{03BC}\u{03B1}\u{03C1}", 2, 1, None),
+    Among("\u{03B3}\u{03BA}\u{03C1}", 2, 1, None),
+    Among("\u{03C0}\u{03B9}\u{03C0}\u{03B5}\u{03C1}\u{03BF}\u{03C1}", 2, 1, None),
+    Among("\u{03B2}\u{03BF}\u{03BB}\u{03B2}\u{03BF}\u{03C1}", 2, 1, None),
+    Among("\u{03B3}\u{03BB}\u{03C5}\u{03BA}\u{03BF}\u{03C1}", 2, 1, None),
+    Among("\u{03BB}\u{03BF}\u{03C5}", -1, 1, None),
+    Among("\u{03B2}", -1, 1, None),
+    Among("\u{03B2}\u{03B1}\u{03B8}\u{03C5}\u{03C1}\u{03B9}", -1, 1, None),
+    Among("\u{03B2}\u{03B1}\u{03C1}\u{03BA}", -1, 1, None),
+    Among("\u{03BC}\u{03B1}\u{03C1}\u{03BA}", -1, 1, None),
+    Among("\u{03BB}", -1, 1, None),
+    Among("\u{03BC}", -1, 1, None),
+    Among("\u{03BA}\u{03BF}\u{03C1}\u{03BD}", -1, 1, None),
+];
+
+static A_4: &'static [Among<Context>; 14] = &[
+    Among("\u{03B9}\u{03B6}\u{03B5}\u{03C3}", -1, 1, None),
+    Among("\u{03B9}\u{03B6}\u{03B5}\u{03B9}\u{03C3}", -1, 1, None),
+    Among("\u{03B9}\u{03B6}\u{03C9}", -1, 1, None),
+    Among("\u{03B9}\u{03B6}\u{03B1}", -1, 1, None),
+    Among("\u{03B9}\u{03B6}\u{03B1}\u{03C4}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03B6}\u{03B5}\u{03C4}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03B6}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03B6}\u{03BF}\u{03C5}\u{03BC}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03B6}\u{03B1}\u{03BC}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03B6}\u{03BF}\u{03C5}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03B6}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03B6}\u{03B5}\u{03B9}", -1, 1, None),
+    Among("\u{03B9}\u{03B6}\u{03BF}\u{03C5}\u{03BD}", -1, 1, None),
+    Among("\u{03B9}\u{03B6}\u{03B1}\u{03BD}", -1, 1, None),
+];
+
+static A_5: &'static [Among<Context>; 8] = &[
+    Among("\u{03C3}", -1, 1, None),
+    Among("\u{03C7}", -1, 1, None),
+    Among("\u{03C5}\u{03C8}", -1, 1, None),
+    Among("\u{03B6}\u{03C9}", -1, 1, None),
+    Among("\u{03B2}\u{03B9}", -1, 1, None),
+    Among("\u{03BB}\u{03B9}", -1, 1, None),
+    Among("\u{03B1}\u{03BB}", -1, 1, None),
+    Among("\u{03B5}\u{03BD}", -1, 1, None),
+];
+
+static A_6: &'static [Among<Context>; 7] = &[
+    Among("\u{03C9}\u{03B8}\u{03B7}\u{03BA}\u{03B5}\u{03C3}", -1, 1, None),
+    Among("\u{03C9}\u{03B8}\u{03B7}\u{03BA}\u{03B1}", -1, 1, None),
+    Among("\u{03C9}\u{03B8}\u{03B7}\u{03BA}\u{03B1}\u{03C4}\u{03B5}", -1, 1, None),
+    Among("\u{03C9}\u{03B8}\u{03B7}\u{03BA}\u{03B5}", -1, 1, None),
+    Among("\u{03C9}\u{03B8}\u{03B7}\u{03BA}\u{03B1}\u{03BC}\u{03B5}", -1, 1, None),
+    Among("\u{03C9}\u{03B8}\u{03B7}\u{03BA}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03C9}\u{03B8}\u{03B7}\u{03BA}\u{03B1}\u{03BD}", -1, 1, None),
+];
+
+static A_7: &'static [Among<Context>; 19] = &[
+    Among("\u{03BE}\u{03B1}\u{03BD}\u{03B1}\u{03C0}\u{03B1}", -1, 1, None),
+    Among("\u{03B5}\u{03C0}\u{03B1}", -1, 1, None),
+    Among("\u{03C0}\u{03B5}\u{03C1}\u{03B9}\u{03C0}\u{03B1}", -1, 1, None),
+    Among("\u{03B1}\u{03BD}\u{03B1}\u{03BC}\u{03C0}\u{03B1}", -1, 1, None),
+    Among("\u{03B5}\u{03BC}\u{03C0}\u{03B1}", -1, 1, None),
+    Among("\u{03C7}\u{03B1}\u{03C1}\u{03C4}\u{03BF}\u{03C0}\u{03B1}", -1, 1, None),
+    Among("\u{03B5}\u{03BE}\u{03B1}\u{03C1}\u{03C7}\u{03B1}", -1, 1, None),
+    Among("\u{03C0}\u{03B5}", -1, 1, None),
+    Among("\u{03B5}\u{03C0}\u{03B5}", 7, 1, None),
+    Among("\u{03BC}\u{03B5}\u{03C4}\u{03B5}\u{03C0}\u{03B5}", 8, 1, None),
+    Among("\u{03B5}\u{03C3}\u{03B5}", -1, 1, None),
+    Among("\u{03BA}\u{03BB}\u{03B5}", -1, 1, None),
+    Among("\u{03B5}\u{03C3}\u{03C9}\u{03BA}\u{03BB}\u{03B5}", 11, 1, None),
+    Among("\u{03B5}\u{03BA}\u{03BB}\u{03B5}", 11, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03B5}\u{03BA}\u{03BB}\u{03B5}", 13, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03BF}\u{03BA}\u{03BB}\u{03B5}", 11, 1, None),
+    Among("\u{03B4}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B1}\u{03B8}\u{03C1}\u{03BF}", -1, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03BD}\u{03B1}\u{03B8}\u{03C1}\u{03BF}", 17, 1, None),
+];
+
+static A_8: &'static [Among<Context>; 13] = &[
+    Among("\u{03C0}", -1, 1, None),
+    Among("\u{03BB}\u{03B1}\u{03C1}", -1, 1, None),
+    Among("\u{03B4}\u{03B7}\u{03BC}\u{03BF}\u{03BA}\u{03C1}\u{03B1}\u{03C4}", -1, 1, None),
+    Among("\u{03B1}\u{03C6}", -1, 1, None),
+    Among("\u{03B3}\u{03B9}\u{03B3}\u{03B1}\u{03BD}\u{03C4}\u{03BF}\u{03B1}\u{03C6}", 3, 1, None),
+    Among("\u{03B3}\u{03B5}", -1, 1, None),
+    Among("\u{03B3}\u{03BA}\u{03B5}", -1, 1, None),
+    Among("\u{03B3}\u{03BA}", -1, 1, None),
+    Among("\u{03BC}", -1, 1, None),
+    Among("\u{03C0}\u{03BF}\u{03C5}\u{03BA}\u{03B1}\u{03BC}", 8, 1, None),
+    Among("\u{03BA}\u{03BF}\u{03BC}", 8, 1, None),
+    Among("\u{03B1}\u{03BD}", -1, 1, None),
+    Among("\u{03BF}\u{03BB}\u{03BF}", -1, 1, None),
+];
+
+static A_9: &'static [Among<Context>; 7] = &[
+    Among("\u{03B9}\u{03C3}\u{03B5}\u{03C3}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03B1}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03B1}\u{03C4}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03B1}\u{03BC}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03B1}\u{03BD}", -1, 1, None),
+];
+
+static A_10: &'static [Among<Context>; 19] = &[
+    Among("\u{03BE}\u{03B1}\u{03BD}\u{03B1}\u{03C0}\u{03B1}", -1, 1, None),
+    Among("\u{03B5}\u{03C0}\u{03B1}", -1, 1, None),
+    Among("\u{03C0}\u{03B5}\u{03C1}\u{03B9}\u{03C0}\u{03B1}", -1, 1, None),
+    Among("\u{03B1}\u{03BD}\u{03B1}\u{03BC}\u{03C0}\u{03B1}", -1, 1, None),
+    Among("\u{03B5}\u{03BC}\u{03C0}\u{03B1}", -1, 1, None),
+    Among("\u{03C7}\u{03B1}\u{03C1}\u{03C4}\u{03BF}\u{03C0}\u{03B1}", -1, 1, None),
+    Among("\u{03B5}\u{03BE}\u{03B1}\u{03C1}\u{03C7}\u{03B1}", -1, 1, None),
+    Among("\u{03C0}\u{03B5}", -1, 1, None),
+    Among("\u{03B5}\u{03C0}\u{03B5}", 7, 1, None),
+    Among("\u{03BC}\u{03B5}\u{03C4}\u{03B5}\u{03C0}\u{03B5}", 8, 1, None),
+    Among("\u{03B5}\u{03C3}\u{03B5}", -1, 1, None),
+    Among("\u{03BA}\u{03BB}\u{03B5}", -1, 1, None),
+    Among("\u{03B5}\u{03C3}\u{03C9}\u{03BA}\u{03BB}\u{03B5}", 11, 1, None),
+    Among("\u{03B5}\u{03BA}\u{03BB}\u{03B5}", 11, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03B5}\u{03BA}\u{03BB}\u{03B5}", 13, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03BF}\u{03BA}\u{03BB}\u{03B5}", 11, 1, None),
+    Among("\u{03B4}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B1}\u{03B8}\u{03C1}\u{03BF}", -1, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03BD}\u{03B1}\u{03B8}\u{03C1}\u{03BF}", 17, 1, None),
+];
+
+static A_11: &'static [Among<Context>; 7] = &[
+    Among("\u{03B9}\u{03C3}\u{03B5}\u{03B9}\u{03C3}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03C9}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03B5}\u{03C4}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03BF}\u{03C5}\u{03BC}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03BF}\u{03C5}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03B5}\u{03B9}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03BF}\u{03C5}\u{03BD}", -1, 1, None),
+];
+
+static A_12: &'static [Among<Context>; 7] = &[
+    Among("\u{03C3}\u{03B5}", -1, 1, None),
+    Among("\u{03B1}\u{03C3}\u{03B5}", 0, 1, None),
+    Among("\u{03C0}\u{03BB}\u{03B5}", -1, 1, None),
+    Among("\u{03BA}\u{03BB}\u{03B5}", -1, 1, None),
+    Among("\u{03B5}\u{03C3}\u{03C9}\u{03BA}\u{03BB}\u{03B5}", 3, 1, None),
+    Among("\u{03B4}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03BD}\u{03B1}\u{03B8}\u{03C1}\u{03BF}", -1, 1, None),
+];
+
+static A_13: &'static [Among<Context>; 33] = &[
+    Among("\u{03C0}", -1, 1, None),
+    Among("\u{03B5}\u{03C5}\u{03C0}", 0, 1, None),
+    Among("\u{03B1}\u{03C0}", 0, 1, None),
+    Among("\u{03B5}\u{03BC}\u{03C0}", 0, 1, None),
+    Among("\u{03B3}\u{03C5}\u{03C1}", -1, 1, None),
+    Among("\u{03C7}\u{03C1}", -1, 1, None),
+    Among("\u{03C7}\u{03C9}\u{03C1}", -1, 1, None),
+    Among("\u{03B1}\u{03C1}", -1, 1, None),
+    Among("\u{03B1}\u{03BF}\u{03C1}", -1, 1, None),
+    Among("\u{03C7}\u{03C4}", -1, 1, None),
+    Among("\u{03B1}\u{03C7}\u{03C4}", 9, 1, None),
+    Among("\u{03BA}\u{03C4}", -1, 1, None),
+    Among("\u{03B1}\u{03BA}\u{03C4}", 11, 1, None),
+    Among("\u{03C3}\u{03C7}", -1, 1, None),
+    Among("\u{03B1}\u{03C3}\u{03C7}", 13, 1, None),
+    Among("\u{03C4}\u{03B1}\u{03C7}", -1, 1, None),
+    Among("\u{03C5}\u{03C8}", -1, 1, None),
+    Among("\u{03B1}\u{03C4}\u{03B1}", -1, 1, None),
+    Among("\u{03C6}\u{03B1}", -1, 1, None),
+    Among("\u{03B7}\u{03C6}\u{03B1}", 18, 1, None),
+    Among("\u{03BB}\u{03C5}\u{03B3}", -1, 1, None),
+    Among("\u{03BC}\u{03B5}\u{03B3}", -1, 1, None),
+    Among("\u{03B7}\u{03B4}", -1, 1, None),
+    Among("\u{03B5}\u{03C7}\u{03B8}", -1, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03B8}", -1, 1, None),
+    Among("\u{03C3}\u{03BA}", -1, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03BA}", -1, 1, None),
+    Among("\u{03BC}\u{03B1}\u{03BA}", -1, 1, None),
+    Among("\u{03BA}\u{03C5}\u{03BB}", -1, 1, None),
+    Among("\u{03C6}\u{03B9}\u{03BB}", -1, 1, None),
+    Among("\u{03BC}", -1, 1, None),
+    Among("\u{03B3}\u{03B5}\u{03BC}", 30, 1, None),
+    Among("\u{03B1}\u{03C7}\u{03BD}", -1, 1, None),
+];
+
+static A_14: &'static [Among<Context>; 11] = &[
+    Among("\u{03B9}\u{03C3}\u{03C4}\u{03BF}\u{03C5}\u{03C3}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03C4}\u{03B5}\u{03C3}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03C4}\u{03B7}\u{03C3}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03C4}\u{03BF}\u{03C3}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03C4}\u{03BF}\u{03C5}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03C4}\u{03B1}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03C4}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03C4}\u{03B7}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03C4}\u{03BF}\u{03B9}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03C4}\u{03C9}\u{03BD}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03C4}\u{03BF}", -1, 1, None),
+];
+
+static A_15: &'static [Among<Context>; 5] = &[
+    Among("\u{03C3}\u{03B5}", -1, 1, None),
+    Among("\u{03BC}\u{03B5}\u{03C4}\u{03B1}\u{03C3}\u{03B5}", 0, 1, None),
+    Among("\u{03BC}\u{03B9}\u{03BA}\u{03C1}\u{03BF}\u{03C3}\u{03B5}", 0, 1, None),
+    Among("\u{03B5}\u{03B3}\u{03BA}\u{03BB}\u{03B5}", -1, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03BF}\u{03BA}\u{03BB}\u{03B5}", -1, 1, None),
+];
+
+static A_16: &'static [Among<Context>; 2] = &[
+    Among("\u{03B4}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B1}\u{03BD}\u{03C4}\u{03B9}\u{03B4}\u{03B1}\u{03BD}\u{03B5}", 0, 1, None),
+];
+
+static A_17: &'static [Among<Context>; 10] = &[
+    Among("\u{03C4}\u{03BF}\u{03C0}\u{03B9}\u{03BA}", -1, 7, None),
+    Among("\u{03C3}\u{03BA}\u{03B5}\u{03C0}\u{03C4}\u{03B9}\u{03BA}", -1, 6, None),
+    Among("\u{03B3}\u{03BD}\u{03C9}\u{03C3}\u{03C4}\u{03B9}\u{03BA}", -1, 3, None),
+    Among("\u{03B1}\u{03B3}\u{03BD}\u{03C9}\u{03C3}\u{03C4}\u{03B9}\u{03BA}", 2, 1, None),
+    Among("\u{03B5}\u{03BA}\u{03BB}\u{03B5}\u{03BA}\u{03C4}\u{03B9}\u{03BA}", -1, 5, None),
+    Among("\u{03B1}\u{03C4}\u{03BF}\u{03BC}\u{03B9}\u{03BA}", -1, 2, None),
+    Among("\u{03B5}\u{03B8}\u{03BD}\u{03B9}\u{03BA}", -1, 4, None),
+    Among("\u{03B8}\u{03B5}\u{03B1}\u{03C4}\u{03C1}\u{03B9}\u{03BD}", -1, 10, None),
+    Among("\u{03B1}\u{03BB}\u{03B5}\u{03BE}\u{03B1}\u{03BD}\u{03B4}\u{03C1}\u{03B9}\u{03BD}", -1, 8, None),
+    Among("\u{03B2}\u{03C5}\u{03B6}\u{03B1}\u{03BD}\u{03C4}\u{03B9}\u{03BD}", -1, 9, None),
+];
+
+static A_18: &'static [Among<Context>; 6] = &[
+    Among("\u{03B9}\u{03C3}\u{03BC}\u{03BF}\u{03C5}\u{03C3}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03BC}\u{03BF}\u{03C3}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03BC}\u{03BF}\u{03C5}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03BC}\u{03BF}\u{03B9}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03BC}\u{03C9}\u{03BD}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03BC}\u{03BF}", -1, 1, None),
+];
+
+static A_19: &'static [Among<Context>; 2] = &[
+    Among("\u{03C3}", -1, 1, None),
+    Among("\u{03C7}", -1, 1, None),
+];
+
+static A_20: &'static [Among<Context>; 4] = &[
+    Among("\u{03B1}\u{03C1}\u{03B1}\u{03BA}\u{03B9}\u{03B1}", -1, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03B4}\u{03B1}\u{03BA}\u{03B9}\u{03B1}", -1, 1, None),
+    Among("\u{03B1}\u{03C1}\u{03B1}\u{03BA}\u{03B9}", -1, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03B4}\u{03B1}\u{03BA}\u{03B9}", -1, 1, None),
+];
+
+static A_21: &'static [Among<Context>; 33] = &[
+    Among("\u{03BA}\u{03B1}\u{03C4}\u{03C1}\u{03B1}\u{03C0}", -1, 1, None),
+    Among("\u{03C1}", -1, 1, None),
+    Among("\u{03B2}\u{03C1}", 1, 1, None),
+    Among("\u{03BB}\u{03B1}\u{03B2}\u{03C1}", 2, 1, None),
+    Among("\u{03B1}\u{03BC}\u{03B2}\u{03C1}", 2, 1, None),
+    Among("\u{03BC}\u{03B5}\u{03C1}", 1, 1, None),
+    Among("\u{03B1}\u{03BD}\u{03B8}\u{03C1}", 1, 1, None),
+    Among("\u{03BA}\u{03BF}\u{03C1}", 1, 1, None),
+    Among("\u{03C3}", -1, 1, None),
+    Among("\u{03BD}\u{03B1}\u{03B3}\u{03BA}\u{03B1}\u{03C3}", 8, 1, None),
+    Among("\u{03BC}\u{03BF}\u{03C5}\u{03C3}\u{03C4}", -1, 1, None),
+    Among("\u{03C1}\u{03C5}", -1, 1, None),
+    Among("\u{03C6}", -1, 1, None),
+    Among("\u{03C3}\u{03C6}", 12, 1, None),
+    Among("\u{03B1}\u{03BB}\u{03B9}\u{03C3}\u{03C6}", 13, 1, None),
+    Among("\u{03C7}", -1, 1, None),
+    Among("\u{03B2}\u{03B1}\u{03BC}\u{03B2}", -1, 1, None),
+    Among("\u{03C3}\u{03BB}\u{03BF}\u{03B2}", -1, 1, None),
+    Among("\u{03C4}\u{03C3}\u{03B5}\u{03C7}\u{03BF}\u{03C3}\u{03BB}\u{03BF}\u{03B2}", 17, 1, None),
+    Among("\u{03C4}\u{03B6}", -1, 1, None),
+    Among("\u{03BA}", -1, 1, None),
+    Among("\u{03C3}\u{03BA}", 20, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03C0}\u{03B1}\u{03BA}", 20, 1, None),
+    Among("\u{03C3}\u{03BF}\u{03BA}", 20, 1, None),
+    Among("\u{03C0}\u{03BB}", -1, 1, None),
+    Among("\u{03C6}\u{03C5}\u{03BB}", -1, 1, None),
+    Among("\u{03BB}\u{03BF}\u{03C5}\u{03BB}", -1, 1, None),
+    Among("\u{03BC}\u{03B1}\u{03BB}", -1, 1, None),
+    Among("\u{03C6}\u{03B1}\u{03C1}\u{03BC}", -1, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03B9}\u{03BC}", -1, 1, None),
+    Among("\u{03BA}\u{03BB}\u{03B9}\u{03BC}", -1, 1, None),
+    Among("\u{03C3}\u{03C0}\u{03B1}\u{03BD}", -1, 1, None),
+    Among("\u{03BA}\u{03BF}\u{03BD}", -1, 1, None),
+];
+
+static A_22: &'static [Among<Context>; 15] = &[
+    Among("\u{03C0}", -1, 1, None),
+    Among("\u{03C0}\u{03B1}\u{03C4}\u{03B5}\u{03C1}", -1, 1, None),
+    Among("\u{03C4}\u{03BF}\u{03C3}", -1, 1, None),
+    Among("\u{03BD}\u{03C5}\u{03C6}", -1, 1, None),
+    Among("\u{03B2}", -1, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03C1}\u{03B4}", -1, 1, None),
+    Among("\u{03B6}", -1, 1, None),
+    Among("\u{03C3}\u{03BA}", -1, 1, None),
+    Among("\u{03B2}\u{03B1}\u{03BB}", -1, 1, None),
+    Among("\u{03B3}\u{03BB}", -1, 1, None),
+    Among("\u{03C4}\u{03C1}\u{03B9}\u{03C0}\u{03BF}\u{03BB}", -1, 1, None),
+    Among("\u{03BC}\u{03B1}\u{03BA}\u{03C1}\u{03C5}\u{03BD}", -1, 1, None),
+    Among("\u{03B3}\u{03B9}\u{03B1}\u{03BD}", -1, 1, None),
+    Among("\u{03B7}\u{03B3}\u{03BF}\u{03C5}\u{03BC}\u{03B5}\u{03BD}", -1, 1, None),
+    Among("\u{03BA}\u{03BF}\u{03BD}", -1, 1, None),
+];
+
+static A_23: &'static [Among<Context>; 8] = &[
+    Among("\u{03B9}\u{03C4}\u{03C3}\u{03B1}\u{03C3}", -1, 1, None),
+    Among("\u{03B9}\u{03C4}\u{03C3}\u{03B5}\u{03C3}", -1, 1, None),
+    Among("\u{03B9}\u{03C4}\u{03C3}\u{03B1}", -1, 1, None),
+    Among("\u{03B1}\u{03BA}\u{03B9}\u{03B1}", -1, 1, None),
+    Among("\u{03B1}\u{03C1}\u{03B1}\u{03BA}\u{03B9}\u{03B1}", 3, 1, None),
+    Among("\u{03B1}\u{03BA}\u{03B9}", -1, 1, None),
+    Among("\u{03B1}\u{03C1}\u{03B1}\u{03BA}\u{03B9}", 5, 1, None),
+    Among("\u{03B9}\u{03C4}\u{03C3}\u{03C9}\u{03BD}", -1, 1, None),
+];
+
+static A_24: &'static [Among<Context>; 4] = &[
+    Among("\u{03B9}\u{03C1}", -1, 1, None),
+    Among("\u{03C8}\u{03B1}\u{03BB}", -1, 1, None),
+    Among("\u{03B1}\u{03B9}\u{03C6}\u{03BD}", -1, 1, None),
+    Among("\u{03BF}\u{03BB}\u{03BF}", -1, 1, None),
+];
+
+static A_25: &'static [Among<Context>; 2] = &[
+    Among("\u{03B5}", -1, 1, None),
+    Among("\u{03C0}\u{03B1}\u{03B9}\u{03C7}\u{03BD}", -1, 1, None),
+];
+
+static A_26: &'static [Among<Context>; 3] = &[
+    Among("\u{03B9}\u{03B4}\u{03B9}\u{03B1}", -1, 1, None),
+    Among("\u{03B9}\u{03B4}\u{03B9}\u{03C9}\u{03BD}", -1, 1, None),
+    Among("\u{03B9}\u{03B4}\u{03B9}\u{03BF}", -1, 1, None),
+];
+
+static A_27: &'static [Among<Context>; 7] = &[
+    Among("\u{03C1}", -1, 1, None),
+    Among("\u{03B9}\u{03B2}", -1, 1, None),
+    Among("\u{03B4}", -1, 1, None),
+    Among("\u{03BB}\u{03C5}\u{03BA}", -1, 1, None),
+    Among("\u{03C6}\u{03C1}\u{03B1}\u{03B3}\u{03BA}", -1, 1, None),
+    Among("\u{03BF}\u{03B2}\u{03B5}\u{03BB}", -1, 1, None),
+    Among("\u{03BC}\u{03B7}\u{03BD}", -1, 1, None),
+];
+
+static A_28: &'static [Among<Context>; 4] = &[
+    Among("\u{03B9}\u{03C3}\u{03BA}\u{03BF}\u{03C3}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03BA}\u{03BF}\u{03C5}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03BA}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03C3}\u{03BA}\u{03BF}", -1, 1, None),
+];
+
+static A_29: &'static [Among<Context>; 2] = &[
+    Among("\u{03B1}\u{03B4}\u{03B5}\u{03C3}", -1, 1, None),
+    Among("\u{03B1}\u{03B4}\u{03C9}\u{03BD}", -1, 1, None),
+];
+
+static A_30: &'static [Among<Context>; 10] = &[
+    Among("\u{03BC}\u{03C0}\u{03B1}\u{03BC}\u{03C0}", -1, -1, None),
+    Among("\u{03BA}\u{03C5}\u{03C1}", -1, -1, None),
+    Among("\u{03C0}\u{03B1}\u{03C4}\u{03B5}\u{03C1}", -1, -1, None),
+    Among("\u{03C0}\u{03B5}\u{03B8}\u{03B5}\u{03C1}", -1, -1, None),
+    Among("\u{03BD}\u{03C4}\u{03B1}\u{03BD}\u{03C4}", -1, -1, None),
+    Among("\u{03B3}\u{03B9}\u{03B1}\u{03B3}\u{03B9}", -1, -1, None),
+    Among("\u{03B8}\u{03B5}\u{03B9}", -1, -1, None),
+    Among("\u{03BF}\u{03BA}", -1, -1, None),
+    Among("\u{03BC}\u{03B1}\u{03BC}", -1, -1, None),
+    Among("\u{03BC}\u{03B1}\u{03BD}", -1, -1, None),
+];
+
+static A_31: &'static [Among<Context>; 2] = &[
+    Among("\u{03B5}\u{03B4}\u{03B5}\u{03C3}", -1, 1, None),
+    Among("\u{03B5}\u{03B4}\u{03C9}\u{03BD}", -1, 1, None),
+];
+
+static A_32: &'static [Among<Context>; 8] = &[
+    Among("\u{03BA}\u{03C1}\u{03B1}\u{03C3}\u{03C0}", -1, 1, None),
+    Among("\u{03C5}\u{03C0}", -1, 1, None),
+    Among("\u{03B4}\u{03B1}\u{03C0}", -1, 1, None),
+    Among("\u{03B3}\u{03B7}\u{03C0}", -1, 1, None),
+    Among("\u{03B9}\u{03C0}", -1, 1, None),
+    Among("\u{03B5}\u{03BC}\u{03C0}", -1, 1, None),
+    Among("\u{03BF}\u{03C0}", -1, 1, None),
+    Among("\u{03BC}\u{03B9}\u{03BB}", -1, 1, None),
+];
+
+static A_33: &'static [Among<Context>; 2] = &[
+    Among("\u{03BF}\u{03C5}\u{03B4}\u{03B5}\u{03C3}", -1, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03B4}\u{03C9}\u{03BD}", -1, 1, None),
+];
+
+static A_34: &'static [Among<Context>; 15] = &[
+    Among("\u{03C3}\u{03C0}", -1, 1, None),
+    Among("\u{03C6}\u{03C1}", -1, 1, None),
+    Among("\u{03C3}", -1, 1, None),
+    Among("\u{03BB}\u{03B9}\u{03C7}", -1, 1, None),
+    Among("\u{03C4}\u{03C1}\u{03B1}\u{03B3}", -1, 1, None),
+    Among("\u{03C6}\u{03B5}", -1, 1, None),
+    Among("\u{03B1}\u{03C1}\u{03BA}", -1, 1, None),
+    Among("\u{03C3}\u{03BA}", -1, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03BB}\u{03B9}\u{03B1}\u{03BA}", -1, 1, None),
+    Among("\u{03BB}\u{03BF}\u{03C5}\u{03BB}", -1, 1, None),
+    Among("\u{03C6}\u{03BB}", -1, 1, None),
+    Among("\u{03C0}\u{03B5}\u{03C4}\u{03B1}\u{03BB}", -1, 1, None),
+    Among("\u{03B2}\u{03B5}\u{03BB}", -1, 1, None),
+    Among("\u{03C7}\u{03BD}", -1, 1, None),
+    Among("\u{03C0}\u{03BB}\u{03B5}\u{03BE}", -1, 1, None),
+];
+
+static A_35: &'static [Among<Context>; 2] = &[
+    Among("\u{03B5}\u{03C9}\u{03C3}", -1, 1, None),
+    Among("\u{03B5}\u{03C9}\u{03BD}", -1, 1, None),
+];
+
+static A_36: &'static [Among<Context>; 8] = &[
+    Among("\u{03C0}", -1, 1, None),
+    Among("\u{03C0}\u{03B1}\u{03C1}", -1, 1, None),
+    Among("\u{03B4}", -1, 1, None),
+    Among("\u{03B9}\u{03B4}", 2, 1, None),
+    Among("\u{03B8}", -1, 1, None),
+    Among("\u{03B3}\u{03B1}\u{03BB}", -1, 1, None),
+    Among("\u{03B5}\u{03BB}", -1, 1, None),
+    Among("\u{03BD}", -1, 1, None),
+];
+
+static A_37: &'static [Among<Context>; 3] = &[
+    Among("\u{03B9}\u{03BF}\u{03C5}", -1, 1, None),
+    Among("\u{03B9}\u{03B1}", -1, 1, None),
+    Among("\u{03B9}\u{03C9}\u{03BD}", -1, 1, None),
+];
+
+static A_38: &'static [Among<Context>; 4] = &[
+    Among("\u{03B9}\u{03BA}\u{03BF}\u{03C5}", -1, 1, None),
+    Among("\u{03B9}\u{03BA}\u{03B1}", -1, 1, None),
+    Among("\u{03B9}\u{03BA}\u{03C9}\u{03BD}", -1, 1, None),
+    Among("\u{03B9}\u{03BA}\u{03BF}", -1, 1, None),
+];
+
+static A_39: &'static [Among<Context>; 36] = &[
+    Among("\u{03BA}\u{03B1}\u{03BB}\u{03C0}", -1, 1, None),
+    Among("\u{03B3}\u{03B5}\u{03C1}", -1, 1, None),
+    Among("\u{03C0}\u{03BB}\u{03B9}\u{03B1}\u{03C4}\u{03C3}", -1, 1, None),
+    Among("\u{03C0}\u{03B5}\u{03C4}\u{03C3}", -1, 1, None),
+    Among("\u{03C0}\u{03B9}\u{03C4}\u{03C3}", -1, 1, None),
+    Among("\u{03C6}\u{03C5}\u{03C3}", -1, 1, None),
+    Among("\u{03C7}\u{03B1}\u{03C3}", -1, 1, None),
+    Among("\u{03BC}\u{03C0}\u{03BF}\u{03C3}", -1, 1, None),
+    Among("\u{03C3}\u{03B5}\u{03C1}\u{03C4}", -1, 1, None),
+    Among("\u{03BC}\u{03C0}\u{03B1}\u{03B3}\u{03B9}\u{03B1}\u{03C4}", -1, 1, None),
+    Among("\u{03BD}\u{03B9}\u{03C4}", -1, 1, None),
+    Among("\u{03C0}\u{03B9}\u{03BA}\u{03B1}\u{03BD}\u{03C4}", -1, 1, None),
+    Among("\u{03B5}\u{03BE}\u{03C9}\u{03B4}", -1, 1, None),
+    Among("\u{03B1}\u{03B4}", -1, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03C4}\u{03B1}\u{03B4}", 13, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03BD}\u{03B1}\u{03B4}", 13, 1, None),
+    Among("\u{03B1}\u{03BD}\u{03C4}\u{03B9}\u{03B4}", -1, 1, None),
+    Among("\u{03B5}\u{03BD}\u{03B4}", -1, 1, None),
+    Among("\u{03C5}\u{03C0}\u{03BF}\u{03B4}", -1, 1, None),
+    Among("\u{03C0}\u{03C1}\u{03C9}\u{03C4}\u{03BF}\u{03B4}", -1, 1, None),
+    Among("\u{03C6}\u{03C5}\u{03BB}\u{03BF}\u{03B4}", -1, 1, None),
+    Among("\u{03B7}\u{03B8}", -1, 1, None),
+    Among("\u{03B1}\u{03BD}\u{03B7}\u{03B8}", 21, 1, None),
+    Among("\u{03BE}\u{03B9}\u{03BA}", -1, 1, None),
+    Among("\u{03BC}\u{03BF}\u{03C5}\u{03BB}", -1, 1, None),
+    Among("\u{03B1}\u{03BB}", -1, 1, None),
+    Among("\u{03B1}\u{03BC}\u{03BC}\u{03BF}\u{03C7}\u{03B1}\u{03BB}", 25, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03BD}\u{03BF}\u{03BC}\u{03B7}\u{03BB}", -1, 1, None),
+    Among("\u{03BC}\u{03C0}\u{03BF}\u{03BB}", -1, 1, None),
+    Among("\u{03B2}\u{03C1}\u{03C9}\u{03BC}", -1, 1, None),
+    Among("\u{03C4}\u{03C3}\u{03B1}\u{03BC}", -1, 1, None),
+    Among("\u{03BC}\u{03C0}\u{03B1}\u{03BD}", -1, 1, None),
+    Among("\u{03B1}\u{03BC}\u{03B1}\u{03BD}", -1, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03BB}\u{03BB}\u{03B9}\u{03BD}", -1, 1, None),
+    Among("\u{03C0}\u{03BF}\u{03C3}\u{03C4}\u{03B5}\u{03BB}\u{03BD}", -1, 1, None),
+    Among("\u{03C6}\u{03B9}\u{03BB}\u{03BF}\u{03BD}", -1, 1, None),
+];
+
+static A_40: &'static [Among<Context>; 5] = &[
+    Among("\u{03BF}\u{03C5}\u{03C3}\u{03B1}\u{03BC}\u{03B5}", -1, 1, None),
+    Among("\u{03B7}\u{03C3}\u{03B1}\u{03BC}\u{03B5}", -1, 1, None),
+    Among("\u{03B1}\u{03B3}\u{03B1}\u{03BC}\u{03B5}", -1, 1, None),
+    Among("\u{03B7}\u{03BA}\u{03B1}\u{03BC}\u{03B5}", -1, 1, None),
+    Among("\u{03B7}\u{03B8}\u{03B7}\u{03BA}\u{03B1}\u{03BC}\u{03B5}", 3, 1, None),
+];
+
+static A_41: &'static [Among<Context>; 12] = &[
+    Among("\u{03B1}\u{03BD}\u{03B1}\u{03C0}", -1, 1, None),
+    Among("\u{03C0}\u{03B9}\u{03BA}\u{03C1}", -1, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03BF}\u{03C3}\u{03C4}", -1, 1, None),
+    Among("\u{03C0}\u{03BF}\u{03C4}", -1, 1, None),
+    Among("\u{03C7}", -1, 1, None),
+    Among("\u{03C3}\u{03B9}\u{03C7}", 4, 1, None),
+    Among("\u{03B2}\u{03BF}\u{03C5}\u{03B2}", -1, 1, None),
+    Among("\u{03C0}\u{03B5}\u{03B8}", -1, 1, None),
+    Among("\u{03BE}\u{03B5}\u{03B8}", -1, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03BF}\u{03B8}", -1, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03BF}\u{03BA}", -1, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03BB}", -1, 1, None),
+];
+
+static A_42: &'static [Among<Context>; 2] = &[
+    Among("\u{03C4}\u{03C1}", -1, 1, None),
+    Among("\u{03C4}\u{03C3}", -1, 1, None),
+];
+
+static A_43: &'static [Among<Context>; 11] = &[
+    Among("\u{03BF}\u{03C5}\u{03C3}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B7}\u{03C3}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03BD}\u{03C4}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03C5}\u{03BD}\u{03C4}\u{03B1}\u{03BD}\u{03B5}", 2, 1, None),
+    Among("\u{03BF}\u{03BD}\u{03C4}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03BD}\u{03C4}\u{03B1}\u{03BD}\u{03B5}", 4, 1, None),
+    Among("\u{03BF}\u{03C4}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03C4}\u{03B1}\u{03BD}\u{03B5}", 6, 1, None),
+    Among("\u{03B1}\u{03B3}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B7}\u{03BA}\u{03B1}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B7}\u{03B8}\u{03B7}\u{03BA}\u{03B1}\u{03BD}\u{03B5}", 9, 1, None),
+];
+
+static A_44: &'static [Among<Context>; 95] = &[
+    Among("\u{03C0}", -1, 1, None),
+    Among("\u{03C3}\u{03C0}", 0, 1, None),
+    Among("\u{03C0}\u{03BF}\u{03BB}\u{03C5}\u{03B4}\u{03B1}\u{03C0}", 0, 1, None),
+    Among("\u{03B1}\u{03B4}\u{03B1}\u{03C0}", 0, 1, None),
+    Among("\u{03C7}\u{03B1}\u{03BC}\u{03B7}\u{03BB}\u{03BF}\u{03B4}\u{03B1}\u{03C0}", 0, 1, None),
+    Among("\u{03C4}\u{03C3}\u{03BF}\u{03C0}", 0, 1, None),
+    Among("\u{03BA}\u{03BF}\u{03C0}", 0, 1, None),
+    Among("\u{03C5}\u{03C0}\u{03BF}\u{03BA}\u{03BF}\u{03C0}", 6, 1, None),
+    Among("\u{03C0}\u{03B5}\u{03C1}\u{03B9}\u{03C4}\u{03C1}", -1, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03C1}", -1, 1, None),
+    Among("\u{03B5}\u{03C1}", -1, 1, None),
+    Among("\u{03B2}\u{03B5}\u{03C4}\u{03B5}\u{03C1}", 10, 1, None),
+    Among("\u{03B3}\u{03B5}\u{03C1}", 10, 1, None),
+    Among("\u{03BB}\u{03BF}\u{03C5}\u{03B8}\u{03B7}\u{03C1}", -1, 1, None),
+    Among("\u{03BA}\u{03BF}\u{03C1}\u{03BC}\u{03BF}\u{03C1}", -1, 1, None),
+    Among("\u{03C3}", -1, 1, None),
+    Among("\u{03C3}\u{03B1}\u{03C1}\u{03B1}\u{03BA}\u{03B1}\u{03C4}\u{03C3}", 15, 1, None),
+    Among("\u{03B8}\u{03C5}\u{03C3}", 15, 1, None),
+    Among("\u{03B2}\u{03B1}\u{03C3}", 15, 1, None),
+    Among("\u{03C0}\u{03BF}\u{03BB}\u{03B9}\u{03C3}", 15, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03C3}\u{03C4}", -1, 1, None),
+    Among("\u{03B4}\u{03B9}\u{03B1}\u{03C4}", -1, 1, None),
+    Among("\u{03C0}\u{03BB}\u{03B1}\u{03C4}", -1, 1, None),
+    Among("\u{03C4}\u{03C3}\u{03B1}\u{03C1}\u{03BB}\u{03B1}\u{03C4}", -1, 1, None),
+    Among("\u{03C4}\u{03B5}\u{03C4}", -1, 1, None),
+    Among("\u{03C0}\u{03BF}\u{03C5}\u{03C1}\u{03B9}\u{03C4}", -1, 1, None),
+    Among("\u{03C3}\u{03BF}\u{03C5}\u{03BB}\u{03C4}", -1, 1, None),
+    Among("\u{03B6}\u{03C9}\u{03BD}\u{03C4}", -1, 1, None),
+    Among("\u{03BC}\u{03B1}\u{03B9}\u{03BD}\u{03C4}", -1, 1, None),
+    Among("\u{03C6}", -1, 1, None),
+    Among("\u{03C0}\u{03B5}\u{03BD}\u{03C4}\u{03B1}\u{03C1}\u{03C6}", 29, 1, None),
+    Among("\u{03BA}\u{03BF}\u{03B9}\u{03BB}\u{03B1}\u{03C1}\u{03C6}", 29, 1, None),
+    Among("\u{03BF}\u{03C1}\u{03C6}", 29, 1, None),
+    Among("\u{03B4}\u{03B9}\u{03B1}\u{03C6}", 29, 1, None),
+    Among("\u{03C3}\u{03C4}\u{03B5}\u{03C6}", 29, 1, None),
+    Among("\u{03C6}\u{03C9}\u{03C4}\u{03BF}\u{03C3}\u{03C4}\u{03B5}\u{03C6}", 34, 1, None),
+    Among("\u{03C0}\u{03B5}\u{03C1}\u{03B7}\u{03C6}", 29, 1, None),
+    Among("\u{03C5}\u{03C0}\u{03B5}\u{03C1}\u{03B7}\u{03C6}", 36, 1, None),
+    Among("\u{03C7}", -1, 1, None),
+    Among("\u{03C0}\u{03BF}\u{03BB}\u{03C5}\u{03BC}\u{03B7}\u{03C7}", 38, 1, None),
+    Among("\u{03B1}\u{03BC}\u{03B7}\u{03C7}", 38, 1, None),
+    Among("\u{03B2}\u{03B9}\u{03BF}\u{03BC}\u{03B7}\u{03C7}", 38, 1, None),
+    Among("\u{03BC}\u{03B9}\u{03BA}\u{03C1}\u{03BF}\u{03B2}\u{03B9}\u{03BF}\u{03BC}\u{03B7}\u{03C7}", 41, 1, None),
+    Among("\u{03BC}\u{03B5}\u{03B3}\u{03BB}\u{03BF}\u{03B2}\u{03B9}\u{03BF}\u{03BC}\u{03B7}\u{03C7}", 41, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03C0}\u{03BD}\u{03BF}\u{03B2}\u{03B9}\u{03BF}\u{03BC}\u{03B7}\u{03C7}", 41, 1, None),
+    Among("\u{03BB}\u{03B9}\u{03C7}", 38, 1, None),
+    Among("\u{03C4}\u{03B1}\u{03B2}", -1, 1, None),
+    Among("\u{03BD}\u{03C4}\u{03B1}\u{03B2}", 46, 1, None),
+    Among("\u{03C8}\u{03B7}\u{03BB}\u{03BF}\u{03C4}\u{03B1}\u{03B2}", 46, 1, None),
+    Among("\u{03BB}\u{03B9}\u{03B2}", -1, 1, None),
+    Among("\u{03BA}\u{03BB}\u{03B9}\u{03B2}", 49, 1, None),
+    Among("\u{03BE}\u{03B7}\u{03C1}\u{03BF}\u{03BA}\u{03BB}\u{03B9}\u{03B2}", 50, 1, None),
+    Among("\u{03B3}", -1, 1, None),
+    Among("\u{03B1}\u{03BD}\u{03BF}\u{03C1}\u{03B3}", 52, 1, None),
+    Among("\u{03B5}\u{03BD}\u{03BF}\u{03C1}\u{03B3}", 52, 1, None),
+    Among("\u{03B1}\u{03B3}", 52, 1, None),
+    Among("\u{03C4}\u{03C1}\u{03B1}\u{03B3}", 55, 1, None),
+    Among("\u{03C4}\u{03C3}\u{03B1}\u{03B3}", 55, 1, None),
+    Among("\u{03C4}\u{03C3}\u{03B9}\u{03B3}\u{03B3}", 52, 1, None),
+    Among("\u{03B1}\u{03C4}\u{03C3}\u{03B9}\u{03B3}\u{03B3}", 58, 1, None),
+    Among("\u{03B1}\u{03B8}\u{03B9}\u{03B3}\u{03B3}", 52, 1, None),
+    Among("\u{03C3}\u{03C4}\u{03B5}\u{03B3}", 52, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03B7}\u{03B3}", 52, 1, None),
+    Among("\u{03C3}\u{03B9}\u{03B3}", 52, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03BB}\u{03C0}\u{03BF}\u{03C5}\u{03B6}", -1, 1, None),
+    Among("\u{03B8}", -1, 1, None),
+    Among("\u{03BC}\u{03C9}\u{03B1}\u{03BC}\u{03B5}\u{03B8}", 65, 1, None),
+    Among("\u{03C0}\u{03B9}\u{03B8}", 65, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03B9}\u{03B8}", 67, 1, None),
+    Among("\u{03B2}\u{03B1}\u{03C3}\u{03BA}", -1, 1, None),
+    Among("\u{03B2}\u{03C1}\u{03B1}\u{03C7}\u{03C5}\u{03BA}", -1, 1, None),
+    Among("\u{03B4}\u{03B5}\u{03BA}", -1, 1, None),
+    Among("\u{03C0}\u{03B5}\u{03BB}\u{03B5}\u{03BA}", -1, 1, None),
+    Among("\u{03B9}\u{03BA}", -1, 1, None),
+    Among("\u{03B1}\u{03BD}\u{03B9}\u{03BA}", 73, 1, None),
+    Among("\u{03B2}\u{03BF}\u{03C5}\u{03BB}\u{03BA}", -1, 1, None),
+    Among("\u{03C0}\u{03BB}", -1, 1, None),
+    Among("\u{03B4}\u{03B9}\u{03C0}\u{03BB}", 76, 1, None),
+    Among("\u{03C8}\u{03C5}\u{03C7}\u{03BF}\u{03C0}\u{03BB}", 76, 1, None),
+    Among("\u{03BB}\u{03B1}\u{03BF}\u{03C0}\u{03BB}", 76, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03BB}", -1, 1, None),
+    Among("\u{03B3}\u{03B1}\u{03BB}", -1, 1, None),
+    Among("\u{03B2}\u{03B1}\u{03B8}\u{03C5}\u{03B3}\u{03B1}\u{03BB}", 81, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03C4}\u{03B1}\u{03B3}\u{03B1}\u{03BB}", 81, 1, None),
+    Among("\u{03BF}\u{03BB}\u{03BF}\u{03B3}\u{03B1}\u{03BB}", 81, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03C3}\u{03C4}\u{03B5}\u{03BB}", -1, 1, None),
+    Among("\u{03BC}\u{03B5}\u{03BB}", -1, 1, None),
+    Among("\u{03C0}\u{03BF}\u{03C1}\u{03C4}\u{03BF}\u{03BB}", -1, 1, None),
+    Among("\u{03BC}", -1, 1, None),
+    Among("\u{03B4}\u{03C1}\u{03B1}\u{03B4}\u{03BF}\u{03C5}\u{03BC}", 88, 1, None),
+    Among("\u{03B2}\u{03C1}\u{03B1}\u{03C7}\u{03BC}", 88, 1, None),
+    Among("\u{03BF}\u{03BB}\u{03B9}\u{03B3}\u{03BF}\u{03B4}\u{03B1}\u{03BC}", 88, 1, None),
+    Among("\u{03BC}\u{03BF}\u{03C5}\u{03C3}\u{03BF}\u{03C5}\u{03BB}\u{03BC}", 88, 1, None),
+    Among("\u{03BD}", -1, 1, None),
+    Among("\u{03B1}\u{03BC}\u{03B5}\u{03C1}\u{03B9}\u{03BA}\u{03B1}\u{03BD}", 93, 1, None),
+];
+
+static A_45: &'static [Among<Context>; 1] = &[
+    Among("\u{03B7}\u{03C3}\u{03B5}\u{03C4}\u{03B5}", -1, 1, None),
+];
+
+static A_46: &'static [Among<Context>; 31] = &[
+    Among("\u{03C0}\u{03C5}\u{03C1}", -1, 1, None),
+    Among("\u{03B5}\u{03C5}\u{03C1}", -1, 1, None),
+    Among("\u{03C7}\u{03C9}\u{03C1}", -1, 1, None),
+    Among("\u{03B2}\u{03B1}\u{03C1}", -1, 1, None),
+    Among("\u{03B2}\u{03C1}", -1, 1, None),
+    Among("\u{03B1}\u{03B9}\u{03C1}", -1, 1, None),
+    Among("\u{03C6}\u{03BF}\u{03C1}", -1, 1, None),
+    Among("\u{03BD}\u{03B5}\u{03C4}", -1, 1, None),
+    Among("\u{03C3}\u{03C7}", -1, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03BD}\u{03B4}", -1, 1, None),
+    Among("\u{03B5}\u{03BD}\u{03B4}", -1, 1, None),
+    Among("\u{03BF}\u{03B4}", -1, 1, None),
+    Among("\u{03C5}\u{03C0}\u{03B5}\u{03C1}\u{03B8}", -1, 1, None),
+    Among("\u{03C3}\u{03B8}", -1, 1, None),
+    Among("\u{03B5}\u{03C5}\u{03B8}", -1, 1, None),
+    Among("\u{03C1}\u{03B1}\u{03B8}", -1, 1, None),
+    Among("\u{03C4}\u{03B1}\u{03B8}", -1, 1, None),
+    Among("\u{03B4}\u{03B9}\u{03B1}\u{03B8}", -1, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03B8}", -1, 1, None),
+    Among("\u{03C4}\u{03B9}\u{03B8}", -1, 1, None),
+    Among("\u{03B5}\u{03BA}\u{03B8}", -1, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03BD}\u{03B8}", -1, 1, None),
+    Among("\u{03B5}\u{03BD}\u{03B8}", -1, 1, None),
+    Among("\u{03C1}\u{03BF}\u{03B8}", -1, 1, None),
+    Among("\u{03B1}\u{03C1}\u{03BA}", -1, 1, None),
+    Among("\u{03C9}\u{03C6}\u{03B5}\u{03BB}", -1, 1, None),
+    Among("\u{03B2}\u{03BF}\u{03BB}", -1, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03BD}", -1, 1, None),
+    Among("\u{03B1}\u{03B9}\u{03BD}", -1, 1, None),
+    Among("\u{03C0}\u{03BF}\u{03BD}", -1, 1, None),
+    Among("\u{03C1}\u{03BF}\u{03BD}", -1, 1, None),
+];
+
+static A_47: &'static [Among<Context>; 25] = &[
+    Among("\u{03C3}\u{03B5}\u{03C1}\u{03C0}", -1, 1, None),
+    Among("\u{03BA}\u{03BF}\u{03C0}", -1, 1, None),
+    Among("\u{03B8}\u{03B1}\u{03C1}\u{03C1}", -1, 1, None),
+    Among("\u{03BD}\u{03C4}\u{03C1}", -1, 1, None),
+    Among("\u{03B1}\u{03B2}\u{03B1}\u{03C1}", -1, 1, None),
+    Among("\u{03B5}\u{03BD}\u{03B1}\u{03C1}", -1, 1, None),
+    Among("\u{03B1}\u{03B2}\u{03C1}", -1, 1, None),
+    Among("\u{03BC}\u{03C0}\u{03BF}\u{03C1}", -1, 1, None),
+    Among("\u{03C5}", -1, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03C1}\u{03C6}", -1, 1, None),
+    Among("\u{03BD}\u{03B9}\u{03C6}", -1, 1, None),
+    Among("\u{03C0}\u{03B1}\u{03B3}", -1, 1, None),
+    Among("\u{03B4}", -1, 1, None),
+    Among("\u{03B1}\u{03B4}", 12, 1, None),
+    Among("\u{03B8}", -1, 1, None),
+    Among("\u{03B1}\u{03B8}", 14, 1, None),
+    Among("\u{03C3}\u{03BA}", -1, 1, None),
+    Among("\u{03C4}\u{03BF}\u{03BA}", -1, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03BB}", -1, 1, None),
+    Among("\u{03C0}\u{03B1}\u{03C1}\u{03B1}\u{03BA}\u{03B1}\u{03BB}", -1, 1, None),
+    Among("\u{03C3}\u{03BA}\u{03B5}\u{03BB}", -1, 1, None),
+    Among("\u{03B5}\u{03BC}", -1, 1, None),
+    Among("\u{03B1}\u{03BD}", -1, 1, None),
+    Among("\u{03B2}\u{03B5}\u{03BD}", -1, 1, None),
+    Among("\u{03B2}\u{03B1}\u{03C1}\u{03BF}\u{03BD}", -1, 1, None),
+];
+
+static A_48: &'static [Among<Context>; 2] = &[
+    Among("\u{03C9}\u{03BD}\u{03C4}\u{03B1}\u{03C3}", -1, 1, None),
+    Among("\u{03BF}\u{03BD}\u{03C4}\u{03B1}\u{03C3}", -1, 1, None),
+];
+
+static A_49: &'static [Among<Context>; 2] = &[
+    Among("\u{03BF}\u{03BC}\u{03B1}\u{03C3}\u{03C4}\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03BC}\u{03B1}\u{03C3}\u{03C4}\u{03B5}", 0, 1, None),
+];
+
+static A_50: &'static [Among<Context>; 6] = &[
+    Among("\u{03C0}", -1, 1, None),
+    Among("\u{03B1}\u{03C0}", 0, 1, None),
+    Among("\u{03B1}\u{03BA}\u{03B1}\u{03C4}\u{03B1}\u{03C0}", 1, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03BC}\u{03C0}", 0, 1, None),
+    Among("\u{03B1}\u{03C3}\u{03C5}\u{03BC}\u{03C0}", 3, 1, None),
+    Among("\u{03B1}\u{03BC}\u{03B5}\u{03C4}\u{03B1}\u{03BC}\u{03C6}", -1, 1, None),
+];
+
+static A_51: &'static [Among<Context>; 9] = &[
+    Among("\u{03B1}\u{03C1}", -1, 1, None),
+    Among("\u{03BD}\u{03B9}\u{03C3}", -1, 1, None),
+    Among("\u{03B6}", -1, 1, None),
+    Among("\u{03B1}\u{03BB}", -1, 1, None),
+    Among("\u{03C0}\u{03B1}\u{03C1}\u{03B1}\u{03BA}\u{03B1}\u{03BB}", 3, 1, None),
+    Among("\u{03B5}\u{03BA}\u{03C4}\u{03B5}\u{03BB}", -1, 1, None),
+    Among("\u{03BC}", -1, 1, None),
+    Among("\u{03BE}", -1, 1, None),
+    Among("\u{03C0}\u{03C1}\u{03BF}", -1, 1, None),
+];
+
+static A_52: &'static [Among<Context>; 3] = &[
+    Among("\u{03B7}\u{03B8}\u{03B7}\u{03BA}\u{03B5}\u{03C3}", -1, 1, None),
+    Among("\u{03B7}\u{03B8}\u{03B7}\u{03BA}\u{03B1}", -1, 1, None),
+    Among("\u{03B7}\u{03B8}\u{03B7}\u{03BA}\u{03B5}", -1, 1, None),
+];
+
+static A_53: &'static [Among<Context>; 6] = &[
+    Among("\u{03C3}\u{03C6}", -1, 1, None),
+    Among("\u{03BD}\u{03B1}\u{03C1}\u{03B8}", -1, 1, None),
+    Among("\u{03C0}\u{03B9}\u{03B8}", -1, 1, None),
+    Among("\u{03BF}\u{03B8}", -1, 1, None),
+    Among("\u{03C3}\u{03BA}\u{03BF}\u{03C5}\u{03BB}", -1, 1, None),
+    Among("\u{03C3}\u{03BA}\u{03C9}\u{03BB}", -1, 1, None),
+];
+
+static A_54: &'static [Among<Context>; 5] = &[
+    Among("\u{03B8}", -1, 1, None),
+    Among("\u{03C0}\u{03C1}\u{03BF}\u{03C3}\u{03B8}", 0, 1, None),
+    Among("\u{03C0}\u{03B1}\u{03C1}\u{03B1}\u{03BA}\u{03B1}\u{03C4}\u{03B1}\u{03B8}", 0, 1, None),
+    Among("\u{03B4}\u{03B9}\u{03B1}\u{03B8}", 0, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03BD}\u{03B8}", 0, 1, None),
+];
+
+static A_55: &'static [Among<Context>; 3] = &[
+    Among("\u{03B7}\u{03BA}\u{03B5}\u{03C3}", -1, 1, None),
+    Among("\u{03B7}\u{03BA}\u{03B1}", -1, 1, None),
+    Among("\u{03B7}\u{03BA}\u{03B5}", -1, 1, None),
+];
+
+static A_56: &'static [Among<Context>; 12] = &[
+    Among("\u{03B2}\u{03BB}\u{03B5}\u{03C0}", -1, 1, None),
+    Among("\u{03C0}\u{03BF}\u{03B4}\u{03B1}\u{03C1}", -1, 1, None),
+    Among("\u{03C0}\u{03C1}\u{03C9}\u{03C4}", -1, 1, None),
+    Among("\u{03BA}\u{03C5}\u{03BC}\u{03B1}\u{03C4}", -1, 1, None),
+    Among("\u{03C0}\u{03B1}\u{03BD}\u{03C4}\u{03B1}\u{03C7}", -1, 1, None),
+    Among("\u{03BB}\u{03B1}\u{03C7}", -1, 1, None),
+    Among("\u{03C6}\u{03B1}\u{03B3}", -1, 1, None),
+    Among("\u{03BB}\u{03B7}\u{03B3}", -1, 1, None),
+    Among("\u{03C6}\u{03C1}\u{03C5}\u{03B4}", -1, 1, None),
+    Among("\u{03BC}\u{03B1}\u{03BD}\u{03C4}\u{03B9}\u{03BB}", -1, 1, None),
+    Among("\u{03BC}\u{03B1}\u{03BB}\u{03BB}", -1, 1, None),
+    Among("\u{03BF}\u{03BC}", -1, 1, None),
+];
+
+static A_57: &'static [Among<Context>; 25] = &[
+    Among("\u{03B5}\u{03BA}\u{03BB}\u{03B9}\u{03C0}", -1, 1, None),
+    Among("\u{03C1}", -1, 1, None),
+    Among("\u{03B1}\u{03BD}\u{03B1}\u{03C1}\u{03C1}", 1, 1, None),
+    Among("\u{03B5}\u{03BD}\u{03B4}\u{03B9}\u{03B1}\u{03C6}\u{03B5}\u{03C1}", 1, 1, None),
+    Among("\u{03C0}\u{03B1}\u{03C4}", -1, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03B8}\u{03B1}\u{03C1}\u{03B5}\u{03C5}", -1, 1, None),
+    Among("\u{03B4}\u{03B5}\u{03C5}\u{03C4}\u{03B5}\u{03C1}\u{03B5}\u{03C5}", -1, 1, None),
+    Among("\u{03BB}\u{03B5}\u{03C7}", -1, 1, None),
+    Among("\u{03C4}\u{03C3}\u{03B1}", -1, 1, None),
+    Among("\u{03C7}\u{03B1}\u{03B4}", -1, 1, None),
+    Among("\u{03BC}\u{03B5}\u{03B4}", -1, 1, None),
+    Among("\u{03BB}\u{03B1}\u{03BC}\u{03C0}\u{03B9}\u{03B4}", -1, 1, None),
+    Among("\u{03B4}\u{03B5}", -1, 1, None),
+    Among("\u{03C0}\u{03BB}\u{03B5}", -1, 1, None),
+    Among("\u{03BC}\u{03B5}\u{03C3}\u{03B1}\u{03B6}", -1, 1, None),
+    Among("\u{03B4}\u{03B5}\u{03C3}\u{03C0}\u{03BF}\u{03B6}", -1, 1, None),
+    Among("\u{03B1}\u{03B9}\u{03B8}", -1, 1, None),
+    Among("\u{03C6}\u{03B1}\u{03C1}\u{03BC}\u{03B1}\u{03BA}", -1, 1, None),
+    Among("\u{03B1}\u{03B3}\u{03BA}", -1, 1, None),
+    Among("\u{03B1}\u{03BD}\u{03B7}\u{03BA}", -1, 1, None),
+    Among("\u{03BB}", -1, 1, None),
+    Among("\u{03BC}", -1, 1, None),
+    Among("\u{03B1}\u{03BC}", 21, 1, None),
+    Among("\u{03B2}\u{03C1}\u{03BF}\u{03BC}", 21, 1, None),
+    Among("\u{03C5}\u{03C0}\u{03BF}\u{03C4}\u{03B5}\u{03B9}\u{03BD}", -1, 1, None),
+];
+
+static A_58: &'static [Among<Context>; 3] = &[
+    Among("\u{03BF}\u{03C5}\u{03C3}\u{03B5}\u{03C3}", -1, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03C3}\u{03B1}", -1, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03C3}\u{03B5}", -1, 1, None),
+];
+
+static A_59: &'static [Among<Context>; 2] = &[
+    Among("\u{03C8}\u{03BF}\u{03C6}", -1, -1, None),
+    Among("\u{03BD}\u{03B1}\u{03C5}\u{03BB}\u{03BF}\u{03C7}", -1, -1, None),
+];
+
+static A_60: &'static [Among<Context>; 10] = &[
+    Among("\u{03C1}\u{03C0}", -1, 1, None),
+    Among("\u{03C0}\u{03C1}", -1, 1, None),
+    Among("\u{03C6}\u{03C1}", -1, 1, None),
+    Among("\u{03C7}\u{03BF}\u{03C1}\u{03C4}", -1, 1, None),
+    Among("\u{03C3}\u{03C6}", -1, 1, None),
+    Among("\u{03BF}\u{03C6}", -1, 1, None),
+    Among("\u{03BB}\u{03BF}\u{03C7}", -1, 1, None),
+    Among("\u{03C0}\u{03B5}\u{03BB}", -1, 1, None),
+    Among("\u{03BB}\u{03BB}", -1, 1, None),
+    Among("\u{03C3}\u{03BC}\u{03B7}\u{03BD}", -1, 1, None),
+];
+
+static A_61: &'static [Among<Context>; 44] = &[
+    Among("\u{03C0}", -1, 1, None),
+    Among("\u{03B1}\u{03C3}\u{03C0}", 0, 1, None),
+    Among("\u{03B1}\u{03BD}\u{03C5}\u{03C0}", 0, 1, None),
+    Among("\u{03B1}\u{03C1}\u{03C4}\u{03B9}\u{03C0}", 0, 1, None),
+    Among("\u{03B1}\u{03B5}\u{03B9}\u{03C0}", 0, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03BC}\u{03C0}", 0, 1, None),
+    Among("\u{03C0}\u{03C1}\u{03BF}\u{03C3}\u{03C9}\u{03C0}\u{03BF}\u{03C0}", 0, 1, None),
+    Among("\u{03C3}\u{03B9}\u{03B4}\u{03B7}\u{03C1}\u{03BF}\u{03C0}", 0, 1, None),
+    Among("\u{03B4}\u{03C1}\u{03BF}\u{03C3}\u{03BF}\u{03C0}", 0, 1, None),
+    Among("\u{03BD}\u{03B5}\u{03BF}\u{03C0}", 0, 1, None),
+    Among("\u{03BA}\u{03C1}\u{03BF}\u{03BA}\u{03B1}\u{03BB}\u{03BF}\u{03C0}", 0, 1, None),
+    Among("\u{03BF}\u{03BB}\u{03BF}\u{03C0}", 0, 1, None),
+    Among("\u{03C1}", -1, 1, None),
+    Among("\u{03C4}\u{03C1}", 12, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03C1}", 12, 1, None),
+    Among("\u{03B1}\u{03C3}\u{03C0}\u{03B1}\u{03C1}", 12, 1, None),
+    Among("\u{03C7}\u{03B1}\u{03C1}", 12, 1, None),
+    Among("\u{03B1}\u{03C7}\u{03B1}\u{03C1}", 16, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03B5}\u{03C1}", 12, 1, None),
+    Among("\u{03C4}", -1, 1, None),
+    Among("\u{03B1}\u{03BD}\u{03C5}\u{03C3}\u{03C4}", 19, 1, None),
+    Among("\u{03B1}\u{03B2}\u{03B1}\u{03C3}\u{03C4}", 19, 1, None),
+    Among("\u{03C0}\u{03C1}\u{03BF}\u{03C3}\u{03C4}", 19, 1, None),
+    Among("\u{03B1}\u{03B9}\u{03BC}\u{03BF}\u{03C3}\u{03C4}", 19, 1, None),
+    Among("\u{03B4}\u{03B9}\u{03B1}\u{03C4}", 19, 1, None),
+    Among("\u{03B5}\u{03C0}\u{03B9}\u{03C4}", 19, 1, None),
+    Among("\u{03C3}\u{03C5}\u{03BD}\u{03C4}", 19, 1, None),
+    Among("\u{03C5}\u{03C0}\u{03BF}\u{03C4}", 19, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03BF}\u{03C4}", 19, 1, None),
+    Among("\u{03BF}\u{03BC}\u{03BF}\u{03C4}", 19, 1, None),
+    Among("\u{03BD}\u{03BF}\u{03BC}\u{03BF}\u{03C4}", 29, 1, None),
+    Among("\u{03BD}\u{03B1}\u{03C5}", -1, 1, None),
+    Among("\u{03C0}\u{03BF}\u{03BB}\u{03C5}\u{03C6}", -1, 1, None),
+    Among("\u{03B1}\u{03C6}", -1, 1, None),
+    Among("\u{03BE}\u{03B5}\u{03C6}", -1, 1, None),
+    Among("\u{03B1}\u{03B4}\u{03B7}\u{03C6}", -1, 1, None),
+    Among("\u{03C0}\u{03B1}\u{03BC}\u{03C6}", -1, 1, None),
+    Among("\u{03B1}\u{03BC}\u{03B1}\u{03BB}\u{03BB}\u{03B9}", -1, 1, None),
+    Among("\u{03BB}", -1, 1, None),
+    Among("\u{03B1}\u{03BC}\u{03B1}\u{03BB}", 38, 1, None),
+    Among("\u{03BC}", -1, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03BB}\u{03B1}\u{03BC}", 40, 1, None),
+    Among("\u{03B5}\u{03BD}", -1, 1, None),
+    Among("\u{03B4}\u{03B5}\u{03C1}\u{03B2}\u{03B5}\u{03BD}", 42, 1, None),
+];
+
+static A_62: &'static [Among<Context>; 3] = &[
+    Among("\u{03B1}\u{03B3}\u{03B5}\u{03C3}", -1, 1, None),
+    Among("\u{03B1}\u{03B3}\u{03B1}", -1, 1, None),
+    Among("\u{03B1}\u{03B3}\u{03B5}", -1, 1, None),
+];
+
+static A_63: &'static [Among<Context>; 3] = &[
+    Among("\u{03B7}\u{03C3}\u{03BF}\u{03C5}", -1, 1, None),
+    Among("\u{03B7}\u{03C3}\u{03B1}", -1, 1, None),
+    Among("\u{03B7}\u{03C3}\u{03B5}", -1, 1, None),
+];
+
+static A_64: &'static [Among<Context>; 6] = &[
+    Among("\u{03BD}", -1, 1, None),
+    Among("\u{03B5}\u{03C0}\u{03C4}\u{03B1}\u{03BD}", 0, 1, None),
+    Among("\u{03B4}\u{03C9}\u{03B4}\u{03B5}\u{03BA}\u{03B1}\u{03BD}", 0, 1, None),
+    Among("\u{03C7}\u{03B5}\u{03C1}\u{03C3}\u{03BF}\u{03BD}", 0, 1, None),
+    Among("\u{03BC}\u{03B5}\u{03B3}\u{03B1}\u{03BB}\u{03BF}\u{03BD}", 0, 1, None),
+    Among("\u{03B5}\u{03C1}\u{03B7}\u{03BC}\u{03BF}\u{03BD}", 0, 1, None),
+];
+
+static A_65: &'static [Among<Context>; 1] = &[
+    Among("\u{03B7}\u{03C3}\u{03C4}\u{03B5}", -1, 1, None),
+];
+
+static A_66: &'static [Among<Context>; 10] = &[
+    Among("\u{03C7}\u{03C1}", -1, 1, None),
+    Among("\u{03B4}\u{03C5}\u{03C3}\u{03C7}\u{03C1}", 0, 1, None),
+    Among("\u{03B5}\u{03C5}\u{03C7}\u{03C1}", 0, 1, None),
+    Among("\u{03B1}\u{03C7}\u{03C1}", 0, 1, None),
+    Among("\u{03BA}\u{03BF}\u{03B9}\u{03BD}\u{03BF}\u{03C7}\u{03C1}", 0, 1, None),
+    Among("\u{03C0}\u{03B1}\u{03BB}\u{03B9}\u{03BC}\u{03C8}", -1, 1, None),
+    Among("\u{03C3}\u{03B2}", -1, 1, None),
+    Among("\u{03B1}\u{03C3}\u{03B2}", 6, 1, None),
+    Among("\u{03B1}\u{03C0}\u{03BB}", -1, 1, None),
+    Among("\u{03B1}\u{03B5}\u{03B9}\u{03BC}\u{03BD}", -1, 1, None),
+];
+
+static A_67: &'static [Among<Context>; 3] = &[
+    Among("\u{03BF}\u{03C5}\u{03BD}\u{03B5}", -1, 1, None),
+    Among("\u{03B7}\u{03C3}\u{03BF}\u{03C5}\u{03BD}\u{03B5}", 0, 1, None),
+    Among("\u{03B7}\u{03B8}\u{03BF}\u{03C5}\u{03BD}\u{03B5}", 0, 1, None),
+];
+
+static A_68: &'static [Among<Context>; 6] = &[
+    Among("\u{03C1}", -1, 1, None),
+    Among("\u{03C3}\u{03C4}\u{03C1}\u{03B1}\u{03B2}\u{03BF}\u{03BC}\u{03BF}\u{03C5}\u{03C4}\u{03C3}", -1, 1, None),
+    Among("\u{03BA}\u{03B1}\u{03BA}\u{03BF}\u{03BC}\u{03BF}\u{03C5}\u{03C4}\u{03C3}", -1, 1, None),
+    Among("\u{03C3}\u{03C0}\u{03B9}", -1, 1, None),
+    Among("\u{03BD}", -1, 1, None),
+    Among("\u{03B5}\u{03BE}\u{03C9}\u{03BD}", 4, 1, None),
+];
+
+static A_69: &'static [Among<Context>; 3] = &[
+    Among("\u{03BF}\u{03C5}\u{03BC}\u{03B5}", -1, 1, None),
+    Among("\u{03B7}\u{03C3}\u{03BF}\u{03C5}\u{03BC}\u{03B5}", 0, 1, None),
+    Among("\u{03B7}\u{03B8}\u{03BF}\u{03C5}\u{03BC}\u{03B5}", 0, 1, None),
+];
+
+static A_70: &'static [Among<Context>; 7] = &[
+    Among("\u{03B1}\u{03C3}\u{03BF}\u{03C5}\u{03C3}", -1, 1, None),
+    Among("\u{03C0}\u{03B1}\u{03C1}\u{03B1}\u{03C3}\u{03BF}\u{03C5}\u{03C3}", 0, 1, None),
+    Among("\u{03B1}\u{03BB}\u{03BB}\u{03BF}\u{03C3}\u{03BF}\u{03C5}\u{03C3}", -1, 1, None),
+    Among("\u{03C6}", -1, 1, None),
+    Among("\u{03C7}", -1, 1, None),
+    Among("\u{03B1}\u{03B6}", -1, 1, None),
+    Among("\u{03C9}\u{03C1}\u{03B9}\u{03BF}\u{03C0}\u{03BB}", -1, 1, None),
+];
+
+static A_71: &'static [Among<Context>; 3] = &[
+    Among("\u{03BC}\u{03B1}\u{03C4}\u{03BF}\u{03C3}", -1, 1, None),
+    Among("\u{03BC}\u{03B1}\u{03C4}\u{03B1}", -1, 1, None),
+    Among("\u{03BC}\u{03B1}\u{03C4}\u{03C9}\u{03BD}", -1, 1, None),
+];
+
+static A_72: &'static [Among<Context>; 84] = &[
+    Among("\u{03C5}\u{03C3}", -1, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03C3}", 0, 1, None),
+    Among("\u{03B1}\u{03C3}", -1, 1, None),
+    Among("\u{03B5}\u{03C3}", -1, 1, None),
+    Among("\u{03B7}\u{03C3}\u{03B5}\u{03C3}", 3, 1, None),
+    Among("\u{03B7}\u{03B4}\u{03B5}\u{03C3}", 3, 1, None),
+    Among("\u{03B7}\u{03C3}", -1, 1, None),
+    Among("\u{03B5}\u{03B9}\u{03C3}", -1, 1, None),
+    Among("\u{03B7}\u{03B8}\u{03B5}\u{03B9}\u{03C3}", 7, 1, None),
+    Among("\u{03BF}\u{03C3}", -1, 1, None),
+    Among("\u{03C5}", -1, 1, None),
+    Among("\u{03BF}\u{03C5}", 10, 1, None),
+    Among("\u{03C9}", -1, 1, None),
+    Among("\u{03B7}\u{03C3}\u{03C9}", 12, 1, None),
+    Among("\u{03B1}\u{03C9}", 12, 1, None),
+    Among("\u{03B7}\u{03B8}\u{03C9}", 12, 1, None),
+    Among("\u{03B1}", -1, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03C5}\u{03BC}\u{03B1}", 16, 1, None),
+    Among("\u{03BF}\u{03C3}\u{03BF}\u{03C5}\u{03BD}\u{03B1}", 16, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03C3}\u{03BF}\u{03C5}\u{03BD}\u{03B1}", 18, 1, None),
+    Among("\u{03BF}\u{03BC}\u{03BF}\u{03C5}\u{03BD}\u{03B1}", 16, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03BC}\u{03BF}\u{03C5}\u{03BD}\u{03B1}", 20, 1, None),
+    Among("\u{03B5}", -1, 1, None),
+    Among("\u{03B9}\u{03B5}\u{03C3}\u{03B1}\u{03C3}\u{03C4}\u{03B5}", 22, 1, None),
+    Among("\u{03BF}\u{03C3}\u{03B1}\u{03C3}\u{03C4}\u{03B5}", 22, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03C3}\u{03B1}\u{03C3}\u{03C4}\u{03B5}", 24, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03BC}\u{03B1}\u{03C3}\u{03C4}\u{03B5}", 22, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03C5}\u{03BC}\u{03B1}\u{03C3}\u{03C4}\u{03B5}", 26, 1, None),
+    Among("\u{03B9}\u{03B5}\u{03BC}\u{03B1}\u{03C3}\u{03C4}\u{03B5}", 22, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03C3}\u{03B1}\u{03C4}\u{03B5}", 22, 1, None),
+    Among("\u{03B7}\u{03C3}\u{03B1}\u{03C4}\u{03B5}", 22, 1, None),
+    Among("\u{03B1}\u{03B3}\u{03B1}\u{03C4}\u{03B5}", 22, 1, None),
+    Among("\u{03B7}\u{03BA}\u{03B1}\u{03C4}\u{03B5}", 22, 1, None),
+    Among("\u{03B7}\u{03B8}\u{03B7}\u{03BA}\u{03B1}\u{03C4}\u{03B5}", 32, 1, None),
+    Among("\u{03B5}\u{03B9}\u{03C4}\u{03B5}", 22, 1, None),
+    Among("\u{03B7}\u{03B8}\u{03B5}\u{03B9}\u{03C4}\u{03B5}", 34, 1, None),
+    Among("\u{03B7}", -1, 1, None),
+    Among("\u{03B9}", -1, 1, None),
+    Among("\u{03B1}\u{03C3}\u{03B1}\u{03B9}", 37, 1, None),
+    Among("\u{03B5}\u{03C3}\u{03B1}\u{03B9}", 37, 1, None),
+    Among("\u{03B9}\u{03B5}\u{03C3}\u{03B1}\u{03B9}", 39, 1, None),
+    Among("\u{03B1}\u{03C4}\u{03B1}\u{03B9}", 37, 1, None),
+    Among("\u{03B5}\u{03C4}\u{03B1}\u{03B9}", 37, 1, None),
+    Among("\u{03B9}\u{03B5}\u{03C4}\u{03B1}\u{03B9}", 42, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03BD}\u{03C4}\u{03B1}\u{03B9}", 37, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03C5}\u{03BD}\u{03C4}\u{03B1}\u{03B9}", 44, 1, None),
+    Among("\u{03BF}\u{03BD}\u{03C4}\u{03B1}\u{03B9}", 37, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03BC}\u{03B1}\u{03B9}", 37, 1, None),
+    Among("\u{03B1}\u{03BC}\u{03B1}\u{03B9}", 37, 1, None),
+    Among("\u{03B9}\u{03B5}\u{03BC}\u{03B1}\u{03B9}", 37, 1, None),
+    Among("\u{03BF}\u{03BC}\u{03B1}\u{03B9}", 37, 1, None),
+    Among("\u{03B5}\u{03B9}", 37, 1, None),
+    Among("\u{03B7}\u{03C3}\u{03B5}\u{03B9}", 51, 1, None),
+    Among("\u{03B1}\u{03B5}\u{03B9}", 51, 1, None),
+    Among("\u{03B7}\u{03B8}\u{03B5}\u{03B9}", 51, 1, None),
+    Among("\u{03BF}\u{03B9}", 37, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03BD}", -1, 1, None),
+    Among("\u{03B7}\u{03C3}\u{03BF}\u{03C5}\u{03BD}", 56, 1, None),
+    Among("\u{03BF}\u{03C3}\u{03BF}\u{03C5}\u{03BD}", 56, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03C3}\u{03BF}\u{03C5}\u{03BD}", 58, 1, None),
+    Among("\u{03B7}\u{03B8}\u{03BF}\u{03C5}\u{03BD}", 56, 1, None),
+    Among("\u{03BF}\u{03BC}\u{03BF}\u{03C5}\u{03BD}", 56, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03BC}\u{03BF}\u{03C5}\u{03BD}", 61, 1, None),
+    Among("\u{03C9}\u{03BD}", -1, 1, None),
+    Among("\u{03B7}\u{03B4}\u{03C9}\u{03BD}", 63, 1, None),
+    Among("\u{03B1}\u{03BD}", -1, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03C3}\u{03B1}\u{03BD}", 65, 1, None),
+    Among("\u{03BF}\u{03BD}\u{03C4}\u{03BF}\u{03C5}\u{03C3}\u{03B1}\u{03BD}", 66, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03BD}\u{03C4}\u{03BF}\u{03C5}\u{03C3}\u{03B1}\u{03BD}", 67, 1, None),
+    Among("\u{03B7}\u{03C3}\u{03B1}\u{03BD}", 65, 1, None),
+    Among("\u{03BF}\u{03C3}\u{03B1}\u{03C3}\u{03C4}\u{03B1}\u{03BD}", 65, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03C3}\u{03B1}\u{03C3}\u{03C4}\u{03B1}\u{03BD}", 70, 1, None),
+    Among("\u{03BF}\u{03BC}\u{03B1}\u{03C3}\u{03C4}\u{03B1}\u{03BD}", 65, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03BC}\u{03B1}\u{03C3}\u{03C4}\u{03B1}\u{03BD}", 72, 1, None),
+    Among("\u{03BF}\u{03C5}\u{03BD}\u{03C4}\u{03B1}\u{03BD}", 65, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03C5}\u{03BD}\u{03C4}\u{03B1}\u{03BD}", 74, 1, None),
+    Among("\u{03BF}\u{03BD}\u{03C4}\u{03B1}\u{03BD}", 65, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03BD}\u{03C4}\u{03B1}\u{03BD}", 76, 1, None),
+    Among("\u{03BF}\u{03C4}\u{03B1}\u{03BD}", 65, 1, None),
+    Among("\u{03B9}\u{03BF}\u{03C4}\u{03B1}\u{03BD}", 78, 1, None),
+    Among("\u{03B1}\u{03B3}\u{03B1}\u{03BD}", 65, 1, None),
+    Among("\u{03B7}\u{03BA}\u{03B1}\u{03BD}", 65, 1, None),
+    Among("\u{03B7}\u{03B8}\u{03B7}\u{03BA}\u{03B1}\u{03BD}", 81, 1, None),
+    Among("\u{03BF}", -1, 1, None),
+];
+
+static A_73: &'static [Among<Context>; 8] = &[
+    Among("\u{03B5}\u{03C3}\u{03C4}\u{03B5}\u{03C1}", -1, 1, None),
+    Among("\u{03C5}\u{03C4}\u{03B5}\u{03C1}", -1, 1, None),
+    Among("\u{03C9}\u{03C4}\u{03B5}\u{03C1}", -1, 1, None),
+    Among("\u{03BF}\u{03C4}\u{03B5}\u{03C1}", -1, 1, None),
+    Among("\u{03B5}\u{03C3}\u{03C4}\u{03B1}\u{03C4}", -1, 1, None),
+    Among("\u{03C5}\u{03C4}\u{03B1}\u{03C4}", -1, 1, None),
+    Among("\u{03C9}\u{03C4}\u{03B1}\u{03C4}", -1, 1, None),
+    Among("\u{03BF}\u{03C4}\u{03B1}\u{03C4}", -1, 1, None),
+];
+
+static G_v: &'static [u8; 4] = &[81, 65, 16, 1];
+
+static G_v2: &'static [u8; 4] = &[81, 65, 0, 1];
+
+#[derive(Clone)]
+struct Context {
+    S_s: String,
+    b_test1: bool,
+}
+
+fn r_has_min_length(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 110
+    if !((env.current.chars().count() as i32) >= 3){
+        return false;
+    }
+    return true;
+}
+
+fn r_tolower(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 114
+    // repeat, line 115
+    'replab0: loop{
+        let v_1 = env.limit - env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 115
+            // [, line 116
+            env.ket = env.cursor;
+            // substring, line 116
+            among_var = env.find_among_b(A_0, context);
+            if among_var == 0 {
+                break 'lab1;
+            }
+            // ], line 116
+            env.bra = env.cursor;
+            if among_var == 1 {
+                // (, line 117
+                // <-, line 117
+                if !env.slice_from("\u{03B1}") {
+                    return false;
+                }
+            } else if among_var == 2 {
+                // (, line 118
+                // <-, line 118
+                if !env.slice_from("\u{03B2}") {
+                    return false;
+                }
+            } else if among_var == 3 {
+                // (, line 119
+                // <-, line 119
+                if !env.slice_from("\u{03B3}") {
+                    return false;
+                }
+            } else if among_var == 4 {
+                // (, line 120
+                // <-, line 120
+                if !env.slice_from("\u{03B4}") {
+                    return false;
+                }
+            } else if among_var == 5 {
+                // (, line 121
+                // <-, line 121
+                if !env.slice_from("\u{03B5}") {
+                    return false;
+                }
+            } else if among_var == 6 {
+                // (, line 122
+                // <-, line 122
+                if !env.slice_from("\u{03B6}") {
+                    return false;
+                }
+            } else if among_var == 7 {
+                // (, line 123
+                // <-, line 123
+                if !env.slice_from("\u{03B7}") {
+                    return false;
+                }
+            } else if among_var == 8 {
+                // (, line 124
+                // <-, line 124
+                if !env.slice_from("\u{03B8}") {
+                    return false;
+                }
+            } else if among_var == 9 {
+                // (, line 125
+                // <-, line 125
+                if !env.slice_from("\u{03B9}") {
+                    return false;
+                }
+            } else if among_var == 10 {
+                // (, line 126
+                // <-, line 126
+                if !env.slice_from("\u{03BA}") {
+                    return false;
+                }
+            } else if among_var == 11 {
+                // (, line 127
+                // <-, line 127
+                if !env.slice_from("\u{03BB}") {
+                    return false;
+                }
+            } else if among_var == 12 {
+                // (, line 128
+                // <-, line 128
+                if !env.slice_from("\u{03BC}") {
+                    return false;
+                }
+            } else if among_var == 13 {
+                // (, line 129
+                // <-, line 129
+                if !env.slice_from("\u{03BD}") {
+                    return false;
+                }
+            } else if among_var == 14 {
+                // (, line 130
+                // <-, line 130
+                if !env.slice_from("\u{03BE}") {
+                    return false;
+                }
+            } else if among_var == 15 {
+                // (, line 131
+                // <-, line 131
+                if !env.slice_from("\u{03BF}") {
+                    return false;
+                }
+            } else if among_var == 16 {
+                // (, line 132
+                // <-, line 132
+                if !env.slice_from("\u{03C0}") {
+                    return false;
+                }
+            } else if among_var == 17 {
+                // (, line 133
+                // <-, line 133
+                if !env.slice_from("\u{03C1}") {
+                    return false;
+                }
+            } else if among_var == 18 {
+                // (, line 134
+                // <-, line 134
+                if !env.slice_from("\u{03C3}") {
+                    return false;
+                }
+            } else if among_var == 19 {
+                // (, line 135
+                // <-, line 135
+                if !env.slice_from("\u{03C4}") {
+                    return false;
+                }
+            } else if among_var == 20 {
+                // (, line 136
+                // <-, line 136
+                if !env.slice_from("\u{03C5}") {
+                    return false;
+                }
+            } else if among_var == 21 {
+                // (, line 137
+                // <-, line 137
+                if !env.slice_from("\u{03C6}") {
+                    return false;
+                }
+            } else if among_var == 22 {
+                // (, line 138
+                // <-, line 138
+                if !env.slice_from("\u{03C7}") {
+                    return false;
+                }
+            } else if among_var == 23 {
+                // (, line 139
+                // <-, line 139
+                if !env.slice_from("\u{03C8}") {
+                    return false;
+                }
+            } else if among_var == 24 {
+                // (, line 140
+                // <-, line 140
+                if !env.slice_from("\u{03C9}") {
+                    return false;
+                }
+            } else if among_var == 25 {
+                // (, line 162
+                // next, line 162
+                if env.cursor <= env.limit_backward {
+                    break 'lab1;
+                }
+                env.previous_char();
+            }
+            continue 'replab0;
+        }
+        env.cursor = env.limit - v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+fn r_step1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 167
+    // [, line 168
+    env.ket = env.cursor;
+    // substring, line 168
+    among_var = env.find_among_b(A_1, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 168
+    env.bra = env.cursor;
+    if among_var == 1 {
+        // (, line 169
+        // <-, line 169
+        if !env.slice_from("\u{03C6}\u{03B1}") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 170
+        // <-, line 170
+        if !env.slice_from("\u{03C3}\u{03BA}\u{03B1}") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 171
+        // <-, line 171
+        if !env.slice_from("\u{03BF}\u{03BB}\u{03BF}") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 172
+        // <-, line 172
+        if !env.slice_from("\u{03C3}\u{03BF}") {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 173
+        // <-, line 173
+        if !env.slice_from("\u{03C4}\u{03B1}\u{03C4}\u{03BF}") {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 174
+        // <-, line 174
+        if !env.slice_from("\u{03BA}\u{03C1}\u{03B5}") {
+            return false;
+        }
+    } else if among_var == 7 {
+        // (, line 175
+        // <-, line 175
+        if !env.slice_from("\u{03C0}\u{03B5}\u{03C1}") {
+            return false;
+        }
+    } else if among_var == 8 {
+        // (, line 176
+        // <-, line 176
+        if !env.slice_from("\u{03C4}\u{03B5}\u{03C1}") {
+            return false;
+        }
+    } else if among_var == 9 {
+        // (, line 177
+        // <-, line 177
+        if !env.slice_from("\u{03C6}\u{03C9}") {
+            return false;
+        }
+    } else if among_var == 10 {
+        // (, line 178
+        // <-, line 178
+        if !env.slice_from("\u{03BA}\u{03B1}\u{03B8}\u{03B5}\u{03C3}\u{03C4}") {
+            return false;
+        }
+    } else if among_var == 11 {
+        // (, line 179
+        // <-, line 179
+        if !env.slice_from("\u{03B3}\u{03B5}\u{03B3}\u{03BF}\u{03BD}") {
+            return false;
+        }
+    }
+    // unset test1, line 181
+    context.b_test1 = false;
+    return true;
+}
+
+fn r_steps1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 184
+    // [, line 185
+    env.ket = env.cursor;
+    // substring, line 185
+    if env.find_among_b(A_4, context) == 0 {
+        return false;
+    }
+    // ], line 185
+    env.bra = env.cursor;
+    // (, line 187
+    // delete, line 188
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 189
+    context.b_test1 = false;
+    // or, line 193
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 190
+            // [, line 190
+            env.ket = env.cursor;
+            // substring, line 190
+            if env.find_among_b(A_2, context) == 0 {
+                break 'lab1;
+            }
+            // ], line 190
+            env.bra = env.cursor;
+            // atlimit, line 190
+            if env.cursor > env.limit_backward {
+                break 'lab1;
+            }
+            // (, line 192
+            // -> s, line 192
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 192
+            if !env.slice_from("\u{03B9}") {
+                return false;
+            }
+            // <+ s, line 192
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 194
+        // [, line 194
+        env.ket = env.cursor;
+        // substring, line 194
+        if env.find_among_b(A_3, context) == 0 {
+            return false;
+        }
+        // ], line 194
+        env.bra = env.cursor;
+        // atlimit, line 194
+        if env.cursor > env.limit_backward {
+            return false;
+        }
+        // (, line 198
+        // -> s, line 198
+        context.S_s = env.slice_to();
+        if context.S_s.is_empty() {
+            return false;
+        }
+        // <-, line 198
+        if !env.slice_from("\u{03B9}\u{03B6}") {
+            return false;
+        }
+        // <+ s, line 198
+        let c = env.cursor;
+        let (bra, ket) = (env.cursor, env.cursor);
+        env.insert(bra, ket, &context.S_s);
+        env.cursor = c;
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_steps2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 204
+    // [, line 205
+    env.ket = env.cursor;
+    // substring, line 205
+    if env.find_among_b(A_6, context) == 0 {
+        return false;
+    }
+    // ], line 205
+    env.bra = env.cursor;
+    // (, line 206
+    // delete, line 207
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 208
+    context.b_test1 = false;
+    // [, line 209
+    env.ket = env.cursor;
+    // substring, line 209
+    if env.find_among_b(A_5, context) == 0 {
+        return false;
+    }
+    // ], line 209
+    env.bra = env.cursor;
+    // atlimit, line 209
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 210
+    // -> s, line 210
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 210
+    if !env.slice_from("\u{03C9}\u{03BD}") {
+        return false;
+    }
+    // <+ s, line 210
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_steps3(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 216
+    // [, line 217
+    env.ket = env.cursor;
+    // substring, line 217
+    if env.find_among_b(A_9, context) == 0 {
+        return false;
+    }
+    // ], line 217
+    env.bra = env.cursor;
+    // (, line 218
+    // delete, line 219
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 220
+    context.b_test1 = false;
+    // or, line 221
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 221
+            // literal, line 221
+            if !env.eq_s_b(&"\u{03B9}\u{03C3}\u{03B1}") {
+                break 'lab1;
+            }
+            // atlimit, line 221
+            if env.cursor > env.limit_backward {
+                break 'lab1;
+            }
+            // <-, line 221
+            if !env.slice_from("\u{03B9}\u{03C3}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab2: loop {
+            // (, line 222
+            // [, line 222
+            env.ket = env.cursor;
+            // substring, line 222
+            if env.find_among_b(A_7, context) == 0 {
+                break 'lab2;
+            }
+            // ], line 222
+            env.bra = env.cursor;
+            // atlimit, line 222
+            if env.cursor > env.limit_backward {
+                break 'lab2;
+            }
+            // (, line 226
+            // -> s, line 226
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 226
+            if !env.slice_from("\u{03B9}") {
+                return false;
+            }
+            // <+ s, line 226
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 228
+        // [, line 228
+        env.ket = env.cursor;
+        // substring, line 228
+        if env.find_among_b(A_8, context) == 0 {
+            return false;
+        }
+        // ], line 228
+        env.bra = env.cursor;
+        // atlimit, line 228
+        if env.cursor > env.limit_backward {
+            return false;
+        }
+        // (, line 231
+        // -> s, line 231
+        context.S_s = env.slice_to();
+        if context.S_s.is_empty() {
+            return false;
+        }
+        // <-, line 231
+        if !env.slice_from("\u{03B9}\u{03C3}") {
+            return false;
+        }
+        // <+ s, line 231
+        let c = env.cursor;
+        let (bra, ket) = (env.cursor, env.cursor);
+        env.insert(bra, ket, &context.S_s);
+        env.cursor = c;
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_steps4(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 237
+    // [, line 238
+    env.ket = env.cursor;
+    // substring, line 238
+    if env.find_among_b(A_11, context) == 0 {
+        return false;
+    }
+    // ], line 238
+    env.bra = env.cursor;
+    // (, line 239
+    // delete, line 240
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 241
+    context.b_test1 = false;
+    // [, line 242
+    env.ket = env.cursor;
+    // substring, line 242
+    if env.find_among_b(A_10, context) == 0 {
+        return false;
+    }
+    // ], line 242
+    env.bra = env.cursor;
+    // atlimit, line 242
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 246
+    // -> s, line 246
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 246
+    if !env.slice_from("\u{03B9}") {
+        return false;
+    }
+    // <+ s, line 246
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_steps5(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 252
+    // [, line 253
+    env.ket = env.cursor;
+    // substring, line 253
+    if env.find_among_b(A_14, context) == 0 {
+        return false;
+    }
+    // ], line 253
+    env.bra = env.cursor;
+    // (, line 255
+    // delete, line 256
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 257
+    context.b_test1 = false;
+    // or, line 261
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 258
+            // [, line 258
+            env.ket = env.cursor;
+            // substring, line 258
+            if env.find_among_b(A_12, context) == 0 {
+                break 'lab1;
+            }
+            // ], line 258
+            env.bra = env.cursor;
+            // atlimit, line 258
+            if env.cursor > env.limit_backward {
+                break 'lab1;
+            }
+            // (, line 260
+            // -> s, line 260
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 260
+            if !env.slice_from("\u{03B9}") {
+                return false;
+            }
+            // <+ s, line 260
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 262
+        // [, line 262
+        env.ket = env.cursor;
+        // substring, line 262
+        if env.find_among_b(A_13, context) == 0 {
+            return false;
+        }
+        // ], line 262
+        env.bra = env.cursor;
+        // atlimit, line 262
+        if env.cursor > env.limit_backward {
+            return false;
+        }
+        // (, line 266
+        // -> s, line 266
+        context.S_s = env.slice_to();
+        if context.S_s.is_empty() {
+            return false;
+        }
+        // <-, line 266
+        if !env.slice_from("\u{03B9}\u{03C3}\u{03C4}") {
+            return false;
+        }
+        // <+ s, line 266
+        let c = env.cursor;
+        let (bra, ket) = (env.cursor, env.cursor);
+        env.insert(bra, ket, &context.S_s);
+        env.cursor = c;
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_steps6(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 272
+    // [, line 273
+    env.ket = env.cursor;
+    // substring, line 273
+    if env.find_among_b(A_18, context) == 0 {
+        return false;
+    }
+    // ], line 273
+    env.bra = env.cursor;
+    // (, line 274
+    // delete, line 275
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 276
+    context.b_test1 = false;
+    // or, line 280
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 277
+            // [, line 277
+            env.ket = env.cursor;
+            // substring, line 277
+            if env.find_among_b(A_15, context) == 0 {
+                break 'lab1;
+            }
+            // ], line 277
+            env.bra = env.cursor;
+            // atlimit, line 277
+            if env.cursor > env.limit_backward {
+                break 'lab1;
+            }
+            // (, line 279
+            // -> s, line 279
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 279
+            if !env.slice_from("\u{03B9}\u{03C3}\u{03BC}") {
+                return false;
+            }
+            // <+ s, line 279
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab2: loop {
+            // (, line 281
+            // [, line 281
+            env.ket = env.cursor;
+            // substring, line 281
+            if env.find_among_b(A_16, context) == 0 {
+                break 'lab2;
+            }
+            // ], line 281
+            env.bra = env.cursor;
+            // atlimit, line 281
+            if env.cursor > env.limit_backward {
+                break 'lab2;
+            }
+            // (, line 283
+            // -> s, line 283
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 283
+            if !env.slice_from("\u{03B9}") {
+                return false;
+            }
+            // <+ s, line 283
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 285
+        // [, line 285
+        env.ket = env.cursor;
+        // substring, line 285
+        among_var = env.find_among_b(A_17, context);
+        if among_var == 0 {
+            return false;
+        }
+        // ], line 285
+        env.bra = env.cursor;
+        if among_var == 1 {
+            // (, line 286
+            // <-, line 286
+            if !env.slice_from("\u{03B1}\u{03B3}\u{03BD}\u{03C9}\u{03C3}\u{03C4}") {
+                return false;
+            }
+        } else if among_var == 2 {
+            // (, line 287
+            // <-, line 287
+            if !env.slice_from("\u{03B1}\u{03C4}\u{03BF}\u{03BC}") {
+                return false;
+            }
+        } else if among_var == 3 {
+            // (, line 288
+            // <-, line 288
+            if !env.slice_from("\u{03B3}\u{03BD}\u{03C9}\u{03C3}\u{03C4}") {
+                return false;
+            }
+        } else if among_var == 4 {
+            // (, line 289
+            // <-, line 289
+            if !env.slice_from("\u{03B5}\u{03B8}\u{03BD}") {
+                return false;
+            }
+        } else if among_var == 5 {
+            // (, line 290
+            // <-, line 290
+            if !env.slice_from("\u{03B5}\u{03BA}\u{03BB}\u{03B5}\u{03BA}\u{03C4}") {
+                return false;
+            }
+        } else if among_var == 6 {
+            // (, line 291
+            // <-, line 291
+            if !env.slice_from("\u{03C3}\u{03BA}\u{03B5}\u{03C0}\u{03C4}") {
+                return false;
+            }
+        } else if among_var == 7 {
+            // (, line 292
+            // <-, line 292
+            if !env.slice_from("\u{03C4}\u{03BF}\u{03C0}") {
+                return false;
+            }
+        } else if among_var == 8 {
+            // (, line 293
+            // <-, line 293
+            if !env.slice_from("\u{03B1}\u{03BB}\u{03B5}\u{03BE}\u{03B1}\u{03BD}\u{03B4}\u{03C1}") {
+                return false;
+            }
+        } else if among_var == 9 {
+            // (, line 294
+            // <-, line 294
+            if !env.slice_from("\u{03B2}\u{03C5}\u{03B6}\u{03B1}\u{03BD}\u{03C4}") {
+                return false;
+            }
+        } else if among_var == 10 {
+            // (, line 295
+            // <-, line 295
+            if !env.slice_from("\u{03B8}\u{03B5}\u{03B1}\u{03C4}\u{03C1}") {
+                return false;
+            }
+        }
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_steps7(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 301
+    // [, line 302
+    env.ket = env.cursor;
+    // substring, line 302
+    if env.find_among_b(A_20, context) == 0 {
+        return false;
+    }
+    // ], line 302
+    env.bra = env.cursor;
+    // (, line 303
+    // delete, line 304
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 305
+    context.b_test1 = false;
+    // [, line 306
+    env.ket = env.cursor;
+    // substring, line 306
+    if env.find_among_b(A_19, context) == 0 {
+        return false;
+    }
+    // ], line 306
+    env.bra = env.cursor;
+    // atlimit, line 306
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 308
+    // -> s, line 308
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 308
+    if !env.slice_from("\u{03B1}\u{03C1}\u{03B1}\u{03BA}") {
+        return false;
+    }
+    // <+ s, line 308
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_steps8(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 314
+    // [, line 315
+    env.ket = env.cursor;
+    // substring, line 315
+    if env.find_among_b(A_23, context) == 0 {
+        return false;
+    }
+    // ], line 315
+    env.bra = env.cursor;
+    // (, line 316
+    // delete, line 317
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 318
+    context.b_test1 = false;
+    // or, line 325
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 319
+            // [, line 319
+            env.ket = env.cursor;
+            // substring, line 319
+            if env.find_among_b(A_21, context) == 0 {
+                break 'lab1;
+            }
+            // ], line 319
+            env.bra = env.cursor;
+            // atlimit, line 319
+            if env.cursor > env.limit_backward {
+                break 'lab1;
+            }
+            // (, line 324
+            // -> s, line 324
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 324
+            if !env.slice_from("\u{03B1}\u{03BA}") {
+                return false;
+            }
+            // <+ s, line 324
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab2: loop {
+            // (, line 326
+            // [, line 326
+            env.ket = env.cursor;
+            // substring, line 326
+            if env.find_among_b(A_22, context) == 0 {
+                break 'lab2;
+            }
+            // ], line 326
+            env.bra = env.cursor;
+            // atlimit, line 326
+            if env.cursor > env.limit_backward {
+                break 'lab2;
+            }
+            // (, line 329
+            // -> s, line 329
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 329
+            if !env.slice_from("\u{03B9}\u{03C4}\u{03C3}") {
+                return false;
+            }
+            // <+ s, line 329
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 331
+        // [, line 331
+        env.ket = env.cursor;
+        // literal, line 331
+        if !env.eq_s_b(&"\u{03BA}\u{03BF}\u{03C1}") {
+            return false;
+        }
+        // ], line 331
+        env.bra = env.cursor;
+        // -> s, line 331
+        context.S_s = env.slice_to();
+        if context.S_s.is_empty() {
+            return false;
+        }
+        // <-, line 331
+        if !env.slice_from("\u{03B9}\u{03C4}\u{03C3}") {
+            return false;
+        }
+        // <+ s, line 331
+        let c = env.cursor;
+        let (bra, ket) = (env.cursor, env.cursor);
+        env.insert(bra, ket, &context.S_s);
+        env.cursor = c;
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_steps9(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 336
+    // [, line 337
+    env.ket = env.cursor;
+    // substring, line 337
+    if env.find_among_b(A_26, context) == 0 {
+        return false;
+    }
+    // ], line 337
+    env.bra = env.cursor;
+    // (, line 338
+    // delete, line 339
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 340
+    context.b_test1 = false;
+    // or, line 343
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 341
+            // [, line 341
+            env.ket = env.cursor;
+            // substring, line 341
+            if env.find_among_b(A_24, context) == 0 {
+                break 'lab1;
+            }
+            // ], line 341
+            env.bra = env.cursor;
+            // atlimit, line 341
+            if env.cursor > env.limit_backward {
+                break 'lab1;
+            }
+            // (, line 342
+            // -> s, line 342
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 342
+            if !env.slice_from("\u{03B9}\u{03B4}") {
+                return false;
+            }
+            // <+ s, line 342
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 344
+        // [, line 344
+        env.ket = env.cursor;
+        // substring, line 344
+        if env.find_among_b(A_25, context) == 0 {
+            return false;
+        }
+        // ], line 344
+        env.bra = env.cursor;
+        // (, line 345
+        // -> s, line 345
+        context.S_s = env.slice_to();
+        if context.S_s.is_empty() {
+            return false;
+        }
+        // <-, line 345
+        if !env.slice_from("\u{03B9}\u{03B4}") {
+            return false;
+        }
+        // <+ s, line 345
+        let c = env.cursor;
+        let (bra, ket) = (env.cursor, env.cursor);
+        env.insert(bra, ket, &context.S_s);
+        env.cursor = c;
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_steps10(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 351
+    // [, line 352
+    env.ket = env.cursor;
+    // substring, line 352
+    if env.find_among_b(A_28, context) == 0 {
+        return false;
+    }
+    // ], line 352
+    env.bra = env.cursor;
+    // (, line 353
+    // delete, line 354
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 355
+    context.b_test1 = false;
+    // [, line 356
+    env.ket = env.cursor;
+    // substring, line 356
+    if env.find_among_b(A_27, context) == 0 {
+        return false;
+    }
+    // ], line 356
+    env.bra = env.cursor;
+    // atlimit, line 356
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 358
+    // -> s, line 358
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 358
+    if !env.slice_from("\u{03B9}\u{03C3}\u{03BA}") {
+        return false;
+    }
+    // <+ s, line 358
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step2a(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 364
+    // [, line 365
+    env.ket = env.cursor;
+    // substring, line 365
+    if env.find_among_b(A_29, context) == 0 {
+        return false;
+    }
+    // ], line 365
+    env.bra = env.cursor;
+    // (, line 366
+    // delete, line 366
+    if !env.slice_del() {
+        return false;
+    }
+    // not, line 368
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 368
+        // [, line 368
+        env.ket = env.cursor;
+        // substring, line 368
+        if env.find_among_b(A_30, context) == 0 {
+            break 'lab0;
+        }
+        // ], line 368
+        env.bra = env.cursor;
+        return false;
+    }
+    env.cursor = env.limit - v_1;
+    // <+, line 371
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, "\u{03B1}\u{03B4}");
+    env.cursor = c;
+    return true;
+}
+
+fn r_step2b(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 374
+    // [, line 375
+    env.ket = env.cursor;
+    // substring, line 375
+    if env.find_among_b(A_31, context) == 0 {
+        return false;
+    }
+    // ], line 375
+    env.bra = env.cursor;
+    // (, line 376
+    // delete, line 376
+    if !env.slice_del() {
+        return false;
+    }
+    // [, line 378
+    env.ket = env.cursor;
+    // substring, line 378
+    if env.find_among_b(A_32, context) == 0 {
+        return false;
+    }
+    // ], line 378
+    env.bra = env.cursor;
+    // (, line 379
+    // -> s, line 379
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 379
+    if !env.slice_from("\u{03B5}\u{03B4}") {
+        return false;
+    }
+    // <+ s, line 379
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step2c(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 383
+    // [, line 384
+    env.ket = env.cursor;
+    // substring, line 384
+    if env.find_among_b(A_33, context) == 0 {
+        return false;
+    }
+    // ], line 384
+    env.bra = env.cursor;
+    // (, line 385
+    // delete, line 385
+    if !env.slice_del() {
+        return false;
+    }
+    // [, line 387
+    env.ket = env.cursor;
+    // substring, line 387
+    if env.find_among_b(A_34, context) == 0 {
+        return false;
+    }
+    // ], line 387
+    env.bra = env.cursor;
+    // (, line 389
+    // -> s, line 389
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 389
+    if !env.slice_from("\u{03BF}\u{03C5}\u{03B4}") {
+        return false;
+    }
+    // <+ s, line 389
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step2d(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 393
+    // [, line 394
+    env.ket = env.cursor;
+    // substring, line 394
+    if env.find_among_b(A_35, context) == 0 {
+        return false;
+    }
+    // ], line 394
+    env.bra = env.cursor;
+    // (, line 395
+    // delete, line 395
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 395
+    context.b_test1 = false;
+    // [, line 397
+    env.ket = env.cursor;
+    // substring, line 397
+    if env.find_among_b(A_36, context) == 0 {
+        return false;
+    }
+    // ], line 397
+    env.bra = env.cursor;
+    // atlimit, line 397
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 398
+    // -> s, line 398
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 398
+    if !env.slice_from("\u{03B5}") {
+        return false;
+    }
+    // <+ s, line 398
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step3(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 402
+    // [, line 403
+    env.ket = env.cursor;
+    // substring, line 403
+    if env.find_among_b(A_37, context) == 0 {
+        return false;
+    }
+    // ], line 403
+    env.bra = env.cursor;
+    // (, line 404
+    // delete, line 404
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 404
+    context.b_test1 = false;
+    // (, line 406
+    // [, line 406
+    env.ket = env.cursor;
+    if !env.in_grouping_b(G_v, 945, 969) {
+        return false;
+    }
+    // ], line 406
+    env.bra = env.cursor;
+    // -> s, line 406
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 406
+    if !env.slice_from("\u{03B9}") {
+        return false;
+    }
+    // <+ s, line 406
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step4(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 409
+    // [, line 410
+    env.ket = env.cursor;
+    // substring, line 410
+    if env.find_among_b(A_38, context) == 0 {
+        return false;
+    }
+    // ], line 410
+    env.bra = env.cursor;
+    // (, line 411
+    // delete, line 411
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 411
+    context.b_test1 = false;
+    // or, line 413
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 413
+            // [, line 413
+            env.ket = env.cursor;
+            if !env.in_grouping_b(G_v, 945, 969) {
+                break 'lab1;
+            }
+            // ], line 413
+            env.bra = env.cursor;
+            // -> s, line 413
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 413
+            if !env.slice_from("\u{03B9}\u{03BA}") {
+                return false;
+            }
+            // <+ s, line 413
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // [, line 414
+        env.ket = env.cursor;
+        break 'lab0;
+    }
+    // substring, line 414
+    if env.find_among_b(A_39, context) == 0 {
+        return false;
+    }
+    // ], line 414
+    env.bra = env.cursor;
+    // atlimit, line 414
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 419
+    // -> s, line 419
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 419
+    if !env.slice_from("\u{03B9}\u{03BA}") {
+        return false;
+    }
+    // <+ s, line 419
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step5a(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 423
+    // do, line 424
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 424
+        // literal, line 424
+        if !env.eq_s_b(&"\u{03B1}\u{03B3}\u{03B1}\u{03BC}\u{03B5}") {
+            break 'lab0;
+        }
+        // atlimit, line 424
+        if env.cursor > env.limit_backward {
+            break 'lab0;
+        }
+        // <-, line 424
+        if !env.slice_from("\u{03B1}\u{03B3}\u{03B1}\u{03BC}") {
+            return false;
+        }
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    // do, line 425
+    let v_2 = env.limit - env.cursor;
+    'lab1: loop {
+        // (, line 425
+        // [, line 426
+        env.ket = env.cursor;
+        // substring, line 426
+        if env.find_among_b(A_40, context) == 0 {
+            break 'lab1;
+        }
+        // ], line 426
+        env.bra = env.cursor;
+        // (, line 427
+        // delete, line 427
+        if !env.slice_del() {
+            return false;
+        }
+        // unset test1, line 427
+        context.b_test1 = false;
+        break 'lab1;
+    }
+    env.cursor = env.limit - v_2;
+    // [, line 430
+    env.ket = env.cursor;
+    // literal, line 430
+    if !env.eq_s_b(&"\u{03B1}\u{03BC}\u{03B5}") {
+        return false;
+    }
+    // ], line 430
+    env.bra = env.cursor;
+    // delete, line 431
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 432
+    context.b_test1 = false;
+    // [, line 433
+    env.ket = env.cursor;
+    // substring, line 433
+    if env.find_among_b(A_41, context) == 0 {
+        return false;
+    }
+    // ], line 433
+    env.bra = env.cursor;
+    // atlimit, line 433
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 435
+    // -> s, line 435
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 435
+    if !env.slice_from("\u{03B1}\u{03BC}") {
+        return false;
+    }
+    // <+ s, line 435
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step5b(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 439
+    // do, line 440
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 440
+        // [, line 441
+        env.ket = env.cursor;
+        // substring, line 441
+        if env.find_among_b(A_43, context) == 0 {
+            break 'lab0;
+        }
+        // ], line 441
+        env.bra = env.cursor;
+        // (, line 443
+        // delete, line 444
+        if !env.slice_del() {
+            return false;
+        }
+        // unset test1, line 445
+        context.b_test1 = false;
+        // [, line 446
+        env.ket = env.cursor;
+        // substring, line 446
+        if env.find_among_b(A_42, context) == 0 {
+            break 'lab0;
+        }
+        // ], line 446
+        env.bra = env.cursor;
+        // atlimit, line 446
+        if env.cursor > env.limit_backward {
+            break 'lab0;
+        }
+        // (, line 447
+        // -> s, line 447
+        context.S_s = env.slice_to();
+        if context.S_s.is_empty() {
+            return false;
+        }
+        // <-, line 447
+        if !env.slice_from("\u{03B1}\u{03B3}\u{03B1}\u{03BD}") {
+            return false;
+        }
+        // <+ s, line 447
+        let c = env.cursor;
+        let (bra, ket) = (env.cursor, env.cursor);
+        env.insert(bra, ket, &context.S_s);
+        env.cursor = c;
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    // [, line 452
+    env.ket = env.cursor;
+    // literal, line 452
+    if !env.eq_s_b(&"\u{03B1}\u{03BD}\u{03B5}") {
+        return false;
+    }
+    // ], line 452
+    env.bra = env.cursor;
+    // delete, line 453
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 454
+    context.b_test1 = false;
+    // or, line 455
+    'lab1: loop {
+        let v_2 = env.limit - env.cursor;
+        'lab2: loop {
+            // (, line 455
+            // [, line 455
+            env.ket = env.cursor;
+            if !env.in_grouping_b(G_v2, 945, 969) {
+                break 'lab2;
+            }
+            // ], line 455
+            env.bra = env.cursor;
+            // -> s, line 455
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 455
+            if !env.slice_from("\u{03B1}\u{03BD}") {
+                return false;
+            }
+            // <+ s, line 455
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab1;
+        }
+        env.cursor = env.limit - v_2;
+        // [, line 456
+        env.ket = env.cursor;
+        break 'lab1;
+    }
+    // substring, line 456
+    if env.find_among_b(A_44, context) == 0 {
+        return false;
+    }
+    // ], line 456
+    env.bra = env.cursor;
+    // atlimit, line 456
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 473
+    // -> s, line 473
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 473
+    if !env.slice_from("\u{03B1}\u{03BD}") {
+        return false;
+    }
+    // <+ s, line 473
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step5c(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 477
+    // do, line 478
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 478
+        // [, line 479
+        env.ket = env.cursor;
+        // substring, line 479
+        if env.find_among_b(A_45, context) == 0 {
+            break 'lab0;
+        }
+        // ], line 479
+        env.bra = env.cursor;
+        // (, line 480
+        // delete, line 480
+        if !env.slice_del() {
+            return false;
+        }
+        // unset test1, line 480
+        context.b_test1 = false;
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    // [, line 483
+    env.ket = env.cursor;
+    // literal, line 483
+    if !env.eq_s_b(&"\u{03B5}\u{03C4}\u{03B5}") {
+        return false;
+    }
+    // ], line 483
+    env.bra = env.cursor;
+    // delete, line 484
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 485
+    context.b_test1 = false;
+    // or, line 486
+    'lab1: loop {
+        let v_2 = env.limit - env.cursor;
+        'lab2: loop {
+            // (, line 486
+            // [, line 486
+            env.ket = env.cursor;
+            if !env.in_grouping_b(G_v2, 945, 969) {
+                break 'lab2;
+            }
+            // ], line 486
+            env.bra = env.cursor;
+            // -> s, line 486
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 486
+            if !env.slice_from("\u{03B5}\u{03C4}") {
+                return false;
+            }
+            // <+ s, line 486
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab1;
+        }
+        env.cursor = env.limit - v_2;
+        'lab3: loop {
+            // (, line 487
+            // [, line 487
+            env.ket = env.cursor;
+            // substring, line 487
+            if env.find_among_b(A_46, context) == 0 {
+                break 'lab3;
+            }
+            // ], line 487
+            env.bra = env.cursor;
+            // (, line 491
+            // -> s, line 491
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 491
+            if !env.slice_from("\u{03B5}\u{03C4}") {
+                return false;
+            }
+            // <+ s, line 491
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab1;
+        }
+        env.cursor = env.limit - v_2;
+        // [, line 493
+        env.ket = env.cursor;
+        break 'lab1;
+    }
+    // substring, line 493
+    if env.find_among_b(A_47, context) == 0 {
+        return false;
+    }
+    // ], line 493
+    env.bra = env.cursor;
+    // atlimit, line 493
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 497
+    // -> s, line 497
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 497
+    if !env.slice_from("\u{03B5}\u{03C4}") {
+        return false;
+    }
+    // <+ s, line 497
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step5d(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 501
+    // [, line 502
+    env.ket = env.cursor;
+    // substring, line 502
+    if env.find_among_b(A_48, context) == 0 {
+        return false;
+    }
+    // ], line 502
+    env.bra = env.cursor;
+    // (, line 503
+    // delete, line 504
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 505
+    context.b_test1 = false;
+    // or, line 506
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 506
+            // [, line 506
+            env.ket = env.cursor;
+            // literal, line 506
+            if !env.eq_s_b(&"\u{03B1}\u{03C1}\u{03C7}") {
+                break 'lab1;
+            }
+            // ], line 506
+            env.bra = env.cursor;
+            // atlimit, line 506
+            if env.cursor > env.limit_backward {
+                break 'lab1;
+            }
+            // -> s, line 506
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 506
+            if !env.slice_from("\u{03BF}\u{03BD}\u{03C4}") {
+                return false;
+            }
+            // <+ s, line 506
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 507
+        // [, line 507
+        env.ket = env.cursor;
+        // literal, line 507
+        if !env.eq_s_b(&"\u{03BA}\u{03C1}\u{03B5}") {
+            return false;
+        }
+        // ], line 507
+        env.bra = env.cursor;
+        // -> s, line 507
+        context.S_s = env.slice_to();
+        if context.S_s.is_empty() {
+            return false;
+        }
+        // <-, line 507
+        if !env.slice_from("\u{03C9}\u{03BD}\u{03C4}") {
+            return false;
+        }
+        // <+ s, line 507
+        let c = env.cursor;
+        let (bra, ket) = (env.cursor, env.cursor);
+        env.insert(bra, ket, &context.S_s);
+        env.cursor = c;
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_step5e(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 512
+    // [, line 513
+    env.ket = env.cursor;
+    // substring, line 513
+    if env.find_among_b(A_49, context) == 0 {
+        return false;
+    }
+    // ], line 513
+    env.bra = env.cursor;
+    // (, line 514
+    // delete, line 515
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 516
+    context.b_test1 = false;
+    // (, line 517
+    // [, line 517
+    env.ket = env.cursor;
+    // literal, line 517
+    if !env.eq_s_b(&"\u{03BF}\u{03BD}") {
+        return false;
+    }
+    // ], line 517
+    env.bra = env.cursor;
+    // atlimit, line 517
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // -> s, line 517
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 517
+    if !env.slice_from("\u{03BF}\u{03BC}\u{03B1}\u{03C3}\u{03C4}") {
+        return false;
+    }
+    // <+ s, line 517
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step5f(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 522
+    // do, line 523
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 523
+        // [, line 524
+        env.ket = env.cursor;
+        // literal, line 524
+        if !env.eq_s_b(&"\u{03B9}\u{03B5}\u{03C3}\u{03C4}\u{03B5}") {
+            break 'lab0;
+        }
+        // ], line 524
+        env.bra = env.cursor;
+        // delete, line 525
+        if !env.slice_del() {
+            return false;
+        }
+        // unset test1, line 526
+        context.b_test1 = false;
+        // [, line 527
+        env.ket = env.cursor;
+        // substring, line 527
+        if env.find_among_b(A_50, context) == 0 {
+            break 'lab0;
+        }
+        // ], line 527
+        env.bra = env.cursor;
+        // atlimit, line 527
+        if env.cursor > env.limit_backward {
+            break 'lab0;
+        }
+        // (, line 528
+        // -> s, line 528
+        context.S_s = env.slice_to();
+        if context.S_s.is_empty() {
+            return false;
+        }
+        // <-, line 528
+        if !env.slice_from("\u{03B9}\u{03B5}\u{03C3}\u{03C4}") {
+            return false;
+        }
+        // <+ s, line 528
+        let c = env.cursor;
+        let (bra, ket) = (env.cursor, env.cursor);
+        env.insert(bra, ket, &context.S_s);
+        env.cursor = c;
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    // [, line 531
+    env.ket = env.cursor;
+    // literal, line 531
+    if !env.eq_s_b(&"\u{03B5}\u{03C3}\u{03C4}\u{03B5}") {
+        return false;
+    }
+    // ], line 531
+    env.bra = env.cursor;
+    // delete, line 532
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 533
+    context.b_test1 = false;
+    // [, line 534
+    env.ket = env.cursor;
+    // substring, line 534
+    if env.find_among_b(A_51, context) == 0 {
+        return false;
+    }
+    // ], line 534
+    env.bra = env.cursor;
+    // atlimit, line 534
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 536
+    // -> s, line 536
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 536
+    if !env.slice_from("\u{03B9}\u{03B5}\u{03C3}\u{03C4}") {
+        return false;
+    }
+    // <+ s, line 536
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step5g(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 540
+    // do, line 541
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 541
+        // [, line 542
+        env.ket = env.cursor;
+        // substring, line 542
+        if env.find_among_b(A_52, context) == 0 {
+            break 'lab0;
+        }
+        // ], line 542
+        env.bra = env.cursor;
+        // (, line 543
+        // delete, line 543
+        if !env.slice_del() {
+            return false;
+        }
+        // unset test1, line 543
+        context.b_test1 = false;
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    // [, line 546
+    env.ket = env.cursor;
+    // substring, line 546
+    if env.find_among_b(A_55, context) == 0 {
+        return false;
+    }
+    // ], line 546
+    env.bra = env.cursor;
+    // (, line 547
+    // delete, line 548
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 549
+    context.b_test1 = false;
+    // or, line 552
+    'lab1: loop {
+        let v_2 = env.limit - env.cursor;
+        'lab2: loop {
+            // (, line 550
+            // [, line 550
+            env.ket = env.cursor;
+            // substring, line 550
+            if env.find_among_b(A_53, context) == 0 {
+                break 'lab2;
+            }
+            // ], line 550
+            env.bra = env.cursor;
+            // (, line 551
+            // -> s, line 551
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 551
+            if !env.slice_from("\u{03B7}\u{03BA}") {
+                return false;
+            }
+            // <+ s, line 551
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab1;
+        }
+        env.cursor = env.limit - v_2;
+        // (, line 553
+        // [, line 553
+        env.ket = env.cursor;
+        // substring, line 553
+        if env.find_among_b(A_54, context) == 0 {
+            return false;
+        }
+        // ], line 553
+        env.bra = env.cursor;
+        // atlimit, line 553
+        if env.cursor > env.limit_backward {
+            return false;
+        }
+        // (, line 554
+        // -> s, line 554
+        context.S_s = env.slice_to();
+        if context.S_s.is_empty() {
+            return false;
+        }
+        // <-, line 554
+        if !env.slice_from("\u{03B7}\u{03BA}") {
+            return false;
+        }
+        // <+ s, line 554
+        let c = env.cursor;
+        let (bra, ket) = (env.cursor, env.cursor);
+        env.insert(bra, ket, &context.S_s);
+        env.cursor = c;
+        break 'lab1;
+    }
+    return true;
+}
+
+fn r_step5h(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 560
+    // [, line 561
+    env.ket = env.cursor;
+    // substring, line 561
+    if env.find_among_b(A_58, context) == 0 {
+        return false;
+    }
+    // ], line 561
+    env.bra = env.cursor;
+    // (, line 562
+    // delete, line 563
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 564
+    context.b_test1 = false;
+    // or, line 569
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 565
+            // [, line 565
+            env.ket = env.cursor;
+            // substring, line 565
+            if env.find_among_b(A_56, context) == 0 {
+                break 'lab1;
+            }
+            // ], line 565
+            env.bra = env.cursor;
+            // (, line 567
+            // -> s, line 567
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 567
+            if !env.slice_from("\u{03BF}\u{03C5}\u{03C3}") {
+                return false;
+            }
+            // <+ s, line 567
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 570
+        // [, line 570
+        env.ket = env.cursor;
+        // substring, line 570
+        if env.find_among_b(A_57, context) == 0 {
+            return false;
+        }
+        // ], line 570
+        env.bra = env.cursor;
+        // atlimit, line 570
+        if env.cursor > env.limit_backward {
+            return false;
+        }
+        // (, line 574
+        // -> s, line 574
+        context.S_s = env.slice_to();
+        if context.S_s.is_empty() {
+            return false;
+        }
+        // <-, line 574
+        if !env.slice_from("\u{03BF}\u{03C5}\u{03C3}") {
+            return false;
+        }
+        // <+ s, line 574
+        let c = env.cursor;
+        let (bra, ket) = (env.cursor, env.cursor);
+        env.insert(bra, ket, &context.S_s);
+        env.cursor = c;
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_step5i(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 580
+    // [, line 581
+    env.ket = env.cursor;
+    // substring, line 581
+    if env.find_among_b(A_62, context) == 0 {
+        return false;
+    }
+    // ], line 581
+    env.bra = env.cursor;
+    // (, line 582
+    // delete, line 583
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 584
+    context.b_test1 = false;
+    // or, line 585
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 585
+            // [, line 585
+            env.ket = env.cursor;
+            // literal, line 585
+            if !env.eq_s_b(&"\u{03BA}\u{03BF}\u{03BB}\u{03BB}") {
+                break 'lab1;
+            }
+            // ], line 585
+            env.bra = env.cursor;
+            // -> s, line 585
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 585
+            if !env.slice_from("\u{03B1}\u{03B3}") {
+                return false;
+            }
+            // <+ s, line 585
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 585
+        // not, line 586
+        let v_2 = env.limit - env.cursor;
+        'lab2: loop {
+            // (, line 586
+            // [, line 586
+            env.ket = env.cursor;
+            // substring, line 586
+            if env.find_among_b(A_59, context) == 0 {
+                break 'lab2;
+            }
+            // ], line 586
+            env.bra = env.cursor;
+            return false;
+        }
+        env.cursor = env.limit - v_2;
+        // or, line 590
+        'lab3: loop {
+            let v_3 = env.limit - env.cursor;
+            'lab4: loop {
+                // (, line 587
+                // [, line 587
+                env.ket = env.cursor;
+                // substring, line 587
+                if env.find_among_b(A_60, context) == 0 {
+                    break 'lab4;
+                }
+                // ], line 587
+                env.bra = env.cursor;
+                // (, line 589
+                // -> s, line 589
+                context.S_s = env.slice_to();
+                if context.S_s.is_empty() {
+                    return false;
+                }
+                // <-, line 589
+                if !env.slice_from("\u{03B1}\u{03B3}") {
+                    return false;
+                }
+                // <+ s, line 589
+                let c = env.cursor;
+                let (bra, ket) = (env.cursor, env.cursor);
+                env.insert(bra, ket, &context.S_s);
+                env.cursor = c;
+                break 'lab3;
+            }
+            env.cursor = env.limit - v_3;
+            // (, line 591
+            // [, line 591
+            env.ket = env.cursor;
+            // substring, line 591
+            if env.find_among_b(A_61, context) == 0 {
+                return false;
+            }
+            // ], line 591
+            env.bra = env.cursor;
+            // atlimit, line 591
+            if env.cursor > env.limit_backward {
+                return false;
+            }
+            // (, line 597
+            // -> s, line 597
+            context.S_s = env.slice_to();
+            if context.S_s.is_empty() {
+                return false;
+            }
+            // <-, line 597
+            if !env.slice_from("\u{03B1}\u{03B3}") {
+                return false;
+            }
+            // <+ s, line 597
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, &context.S_s);
+            env.cursor = c;
+            break 'lab3;
+        }
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_step5j(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 604
+    // [, line 605
+    env.ket = env.cursor;
+    // substring, line 605
+    if env.find_among_b(A_63, context) == 0 {
+        return false;
+    }
+    // ], line 605
+    env.bra = env.cursor;
+    // (, line 606
+    // delete, line 606
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 606
+    context.b_test1 = false;
+    // [, line 608
+    env.ket = env.cursor;
+    // substring, line 608
+    if env.find_among_b(A_64, context) == 0 {
+        return false;
+    }
+    // ], line 608
+    env.bra = env.cursor;
+    // atlimit, line 608
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 609
+    // -> s, line 609
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 609
+    if !env.slice_from("\u{03B7}\u{03C3}") {
+        return false;
+    }
+    // <+ s, line 609
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step5k(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 613
+    // [, line 614
+    env.ket = env.cursor;
+    // substring, line 614
+    if env.find_among_b(A_65, context) == 0 {
+        return false;
+    }
+    // ], line 614
+    env.bra = env.cursor;
+    // (, line 615
+    // delete, line 615
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 615
+    context.b_test1 = false;
+    // [, line 617
+    env.ket = env.cursor;
+    // substring, line 617
+    if env.find_among_b(A_66, context) == 0 {
+        return false;
+    }
+    // ], line 617
+    env.bra = env.cursor;
+    // atlimit, line 617
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 619
+    // -> s, line 619
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 619
+    if !env.slice_from("\u{03B7}\u{03C3}\u{03C4}") {
+        return false;
+    }
+    // <+ s, line 619
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step5l(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 623
+    // [, line 624
+    env.ket = env.cursor;
+    // substring, line 624
+    if env.find_among_b(A_67, context) == 0 {
+        return false;
+    }
+    // ], line 624
+    env.bra = env.cursor;
+    // (, line 625
+    // delete, line 625
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 625
+    context.b_test1 = false;
+    // [, line 627
+    env.ket = env.cursor;
+    // substring, line 627
+    if env.find_among_b(A_68, context) == 0 {
+        return false;
+    }
+    // ], line 627
+    env.bra = env.cursor;
+    // atlimit, line 627
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 628
+    // -> s, line 628
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 628
+    if !env.slice_from("\u{03BF}\u{03C5}\u{03BD}") {
+        return false;
+    }
+    // <+ s, line 628
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step5m(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 632
+    // [, line 633
+    env.ket = env.cursor;
+    // substring, line 633
+    if env.find_among_b(A_69, context) == 0 {
+        return false;
+    }
+    // ], line 633
+    env.bra = env.cursor;
+    // (, line 634
+    // delete, line 634
+    if !env.slice_del() {
+        return false;
+    }
+    // unset test1, line 634
+    context.b_test1 = false;
+    // [, line 636
+    env.ket = env.cursor;
+    // substring, line 636
+    if env.find_among_b(A_70, context) == 0 {
+        return false;
+    }
+    // ], line 636
+    env.bra = env.cursor;
+    // atlimit, line 636
+    if env.cursor > env.limit_backward {
+        return false;
+    }
+    // (, line 638
+    // -> s, line 638
+    context.S_s = env.slice_to();
+    if context.S_s.is_empty() {
+        return false;
+    }
+    // <-, line 638
+    if !env.slice_from("\u{03BF}\u{03C5}\u{03BC}") {
+        return false;
+    }
+    // <+ s, line 638
+    let c = env.cursor;
+    let (bra, ket) = (env.cursor, env.cursor);
+    env.insert(bra, ket, &context.S_s);
+    env.cursor = c;
+    return true;
+}
+
+fn r_step6(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 642
+    // do, line 643
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 643
+        // [, line 644
+        env.ket = env.cursor;
+        // substring, line 644
+        if env.find_among_b(A_71, context) == 0 {
+            break 'lab0;
+        }
+        // ], line 644
+        env.bra = env.cursor;
+        // (, line 645
+        // <-, line 645
+        if !env.slice_from("\u{03BC}\u{03B1}") {
+            return false;
+        }
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    // Boolean test test1, line 648
+    if !context.b_test1 {
+        return false;
+    }
+    // [, line 649
+    env.ket = env.cursor;
+    // substring, line 649
+    if env.find_among_b(A_72, context) == 0 {
+        return false;
+    }
+    // ], line 649
+    env.bra = env.cursor;
+    // (, line 659
+    // delete, line 659
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+fn r_step7(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 663
+    // [, line 664
+    env.ket = env.cursor;
+    // substring, line 664
+    if env.find_among_b(A_73, context) == 0 {
+        return false;
+    }
+    // ], line 664
+    env.bra = env.cursor;
+    // (, line 665
+    // delete, line 665
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        S_s: String::new(),
+        b_test1: false,
+    };
+    // (, line 670
+    // backwards, line 671
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 671
+    // do, line 672
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // call tolower, line 672
+        if !r_tolower(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    // call has_min_length, line 673
+    if !r_has_min_length(env, context) {
+        return false;
+    }
+    // set test1, line 674
+    context.b_test1 = true;
+    // do, line 675
+    let v_2 = env.limit - env.cursor;
+    'lab1: loop {
+        // call step1, line 675
+        if !r_step1(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = env.limit - v_2;
+    // do, line 676
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // call steps1, line 676
+        if !r_steps1(env, context) {
+            break 'lab2;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    // do, line 677
+    let v_4 = env.limit - env.cursor;
+    'lab3: loop {
+        // call steps2, line 677
+        if !r_steps2(env, context) {
+            break 'lab3;
+        }
+        break 'lab3;
+    }
+    env.cursor = env.limit - v_4;
+    // do, line 678
+    let v_5 = env.limit - env.cursor;
+    'lab4: loop {
+        // call steps3, line 678
+        if !r_steps3(env, context) {
+            break 'lab4;
+        }
+        break 'lab4;
+    }
+    env.cursor = env.limit - v_5;
+    // do, line 679
+    let v_6 = env.limit - env.cursor;
+    'lab5: loop {
+        // call steps4, line 679
+        if !r_steps4(env, context) {
+            break 'lab5;
+        }
+        break 'lab5;
+    }
+    env.cursor = env.limit - v_6;
+    // do, line 680
+    let v_7 = env.limit - env.cursor;
+    'lab6: loop {
+        // call steps5, line 680
+        if !r_steps5(env, context) {
+            break 'lab6;
+        }
+        break 'lab6;
+    }
+    env.cursor = env.limit - v_7;
+    // do, line 681
+    let v_8 = env.limit - env.cursor;
+    'lab7: loop {
+        // call steps6, line 681
+        if !r_steps6(env, context) {
+            break 'lab7;
+        }
+        break 'lab7;
+    }
+    env.cursor = env.limit - v_8;
+    // do, line 682
+    let v_9 = env.limit - env.cursor;
+    'lab8: loop {
+        // call steps7, line 682
+        if !r_steps7(env, context) {
+            break 'lab8;
+        }
+        break 'lab8;
+    }
+    env.cursor = env.limit - v_9;
+    // do, line 683
+    let v_10 = env.limit - env.cursor;
+    'lab9: loop {
+        // call steps8, line 683
+        if !r_steps8(env, context) {
+            break 'lab9;
+        }
+        break 'lab9;
+    }
+    env.cursor = env.limit - v_10;
+    // do, line 684
+    let v_11 = env.limit - env.cursor;
+    'lab10: loop {
+        // call steps9, line 684
+        if !r_steps9(env, context) {
+            break 'lab10;
+        }
+        break 'lab10;
+    }
+    env.cursor = env.limit - v_11;
+    // do, line 685
+    let v_12 = env.limit - env.cursor;
+    'lab11: loop {
+        // call steps10, line 685
+        if !r_steps10(env, context) {
+            break 'lab11;
+        }
+        break 'lab11;
+    }
+    env.cursor = env.limit - v_12;
+    // do, line 686
+    let v_13 = env.limit - env.cursor;
+    'lab12: loop {
+        // call step2a, line 686
+        if !r_step2a(env, context) {
+            break 'lab12;
+        }
+        break 'lab12;
+    }
+    env.cursor = env.limit - v_13;
+    // do, line 687
+    let v_14 = env.limit - env.cursor;
+    'lab13: loop {
+        // call step2b, line 687
+        if !r_step2b(env, context) {
+            break 'lab13;
+        }
+        break 'lab13;
+    }
+    env.cursor = env.limit - v_14;
+    // do, line 688
+    let v_15 = env.limit - env.cursor;
+    'lab14: loop {
+        // call step2c, line 688
+        if !r_step2c(env, context) {
+            break 'lab14;
+        }
+        break 'lab14;
+    }
+    env.cursor = env.limit - v_15;
+    // do, line 689
+    let v_16 = env.limit - env.cursor;
+    'lab15: loop {
+        // call step2d, line 689
+        if !r_step2d(env, context) {
+            break 'lab15;
+        }
+        break 'lab15;
+    }
+    env.cursor = env.limit - v_16;
+    // do, line 690
+    let v_17 = env.limit - env.cursor;
+    'lab16: loop {
+        // call step3, line 690
+        if !r_step3(env, context) {
+            break 'lab16;
+        }
+        break 'lab16;
+    }
+    env.cursor = env.limit - v_17;
+    // do, line 691
+    let v_18 = env.limit - env.cursor;
+    'lab17: loop {
+        // call step4, line 691
+        if !r_step4(env, context) {
+            break 'lab17;
+        }
+        break 'lab17;
+    }
+    env.cursor = env.limit - v_18;
+    // do, line 692
+    let v_19 = env.limit - env.cursor;
+    'lab18: loop {
+        // call step5a, line 692
+        if !r_step5a(env, context) {
+            break 'lab18;
+        }
+        break 'lab18;
+    }
+    env.cursor = env.limit - v_19;
+    // do, line 693
+    let v_20 = env.limit - env.cursor;
+    'lab19: loop {
+        // call step5b, line 693
+        if !r_step5b(env, context) {
+            break 'lab19;
+        }
+        break 'lab19;
+    }
+    env.cursor = env.limit - v_20;
+    // do, line 694
+    let v_21 = env.limit - env.cursor;
+    'lab20: loop {
+        // call step5c, line 694
+        if !r_step5c(env, context) {
+            break 'lab20;
+        }
+        break 'lab20;
+    }
+    env.cursor = env.limit - v_21;
+    // do, line 695
+    let v_22 = env.limit - env.cursor;
+    'lab21: loop {
+        // call step5d, line 695
+        if !r_step5d(env, context) {
+            break 'lab21;
+        }
+        break 'lab21;
+    }
+    env.cursor = env.limit - v_22;
+    // do, line 696
+    let v_23 = env.limit - env.cursor;
+    'lab22: loop {
+        // call step5e, line 696
+        if !r_step5e(env, context) {
+            break 'lab22;
+        }
+        break 'lab22;
+    }
+    env.cursor = env.limit - v_23;
+    // do, line 697
+    let v_24 = env.limit - env.cursor;
+    'lab23: loop {
+        // call step5f, line 697
+        if !r_step5f(env, context) {
+            break 'lab23;
+        }
+        break 'lab23;
+    }
+    env.cursor = env.limit - v_24;
+    // do, line 698
+    let v_25 = env.limit - env.cursor;
+    'lab24: loop {
+        // call step5g, line 698
+        if !r_step5g(env, context) {
+            break 'lab24;
+        }
+        break 'lab24;
+    }
+    env.cursor = env.limit - v_25;
+    // do, line 699
+    let v_26 = env.limit - env.cursor;
+    'lab25: loop {
+        // call step5h, line 699
+        if !r_step5h(env, context) {
+            break 'lab25;
+        }
+        break 'lab25;
+    }
+    env.cursor = env.limit - v_26;
+    // do, line 700
+    let v_27 = env.limit - env.cursor;
+    'lab26: loop {
+        // call step5j, line 700
+        if !r_step5j(env, context) {
+            break 'lab26;
+        }
+        break 'lab26;
+    }
+    env.cursor = env.limit - v_27;
+    // do, line 701
+    let v_28 = env.limit - env.cursor;
+    'lab27: loop {
+        // call step5i, line 701
+        if !r_step5i(env, context) {
+            break 'lab27;
+        }
+        break 'lab27;
+    }
+    env.cursor = env.limit - v_28;
+    // do, line 702
+    let v_29 = env.limit - env.cursor;
+    'lab28: loop {
+        // call step5k, line 702
+        if !r_step5k(env, context) {
+            break 'lab28;
+        }
+        break 'lab28;
+    }
+    env.cursor = env.limit - v_29;
+    // do, line 703
+    let v_30 = env.limit - env.cursor;
+    'lab29: loop {
+        // call step5l, line 703
+        if !r_step5l(env, context) {
+            break 'lab29;
+        }
+        break 'lab29;
+    }
+    env.cursor = env.limit - v_30;
+    // do, line 704
+    let v_31 = env.limit - env.cursor;
+    'lab30: loop {
+        // call step5m, line 704
+        if !r_step5m(env, context) {
+            break 'lab30;
+        }
+        break 'lab30;
+    }
+    env.cursor = env.limit - v_31;
+    // do, line 705
+    let v_32 = env.limit - env.cursor;
+    'lab31: loop {
+        // call step6, line 705
+        if !r_step6(env, context) {
+            break 'lab31;
+        }
+        break 'lab31;
+    }
+    env.cursor = env.limit - v_32;
+    // do, line 706
+    let v_33 = env.limit - env.cursor;
+    'lab32: loop {
+        // call step7, line 706
+        if !r_step7(env, context) {
+            break 'lab32;
+        }
+        break 'lab32;
+    }
+    env.cursor = env.limit - v_33;
+    env.cursor = env.limit_backward;
+    return true;
+}
diff --git a/src/snowball/algorithms/hungarian.rs b/src/snowball/algorithms/hungarian.rs
new file mode 100644
index 0000000..6bd683e
--- /dev/null
+++ b/src/snowball/algorithms/hungarian.rs
@@ -0,0 +1,1171 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 8] = &[
+    Among("cs", -1, -1, None),
+    Among("dzs", -1, -1, None),
+    Among("gy", -1, -1, None),
+    Among("ly", -1, -1, None),
+    Among("ny", -1, -1, None),
+    Among("sz", -1, -1, None),
+    Among("ty", -1, -1, None),
+    Among("zs", -1, -1, None),
+];
+
+static A_1: &'static [Among<Context>; 2] = &[
+    Among("\u{00E1}", -1, 1, None),
+    Among("\u{00E9}", -1, 2, None),
+];
+
+static A_2: &'static [Among<Context>; 23] = &[
+    Among("bb", -1, -1, None),
+    Among("cc", -1, -1, None),
+    Among("dd", -1, -1, None),
+    Among("ff", -1, -1, None),
+    Among("gg", -1, -1, None),
+    Among("jj", -1, -1, None),
+    Among("kk", -1, -1, None),
+    Among("ll", -1, -1, None),
+    Among("mm", -1, -1, None),
+    Among("nn", -1, -1, None),
+    Among("pp", -1, -1, None),
+    Among("rr", -1, -1, None),
+    Among("ccs", -1, -1, None),
+    Among("ss", -1, -1, None),
+    Among("zzs", -1, -1, None),
+    Among("tt", -1, -1, None),
+    Among("vv", -1, -1, None),
+    Among("ggy", -1, -1, None),
+    Among("lly", -1, -1, None),
+    Among("nny", -1, -1, None),
+    Among("tty", -1, -1, None),
+    Among("ssz", -1, -1, None),
+    Among("zz", -1, -1, None),
+];
+
+static A_3: &'static [Among<Context>; 2] = &[
+    Among("al", -1, 1, None),
+    Among("el", -1, 2, None),
+];
+
+static A_4: &'static [Among<Context>; 44] = &[
+    Among("ba", -1, -1, None),
+    Among("ra", -1, -1, None),
+    Among("be", -1, -1, None),
+    Among("re", -1, -1, None),
+    Among("ig", -1, -1, None),
+    Among("nak", -1, -1, None),
+    Among("nek", -1, -1, None),
+    Among("val", -1, -1, None),
+    Among("vel", -1, -1, None),
+    Among("ul", -1, -1, None),
+    Among("b\u{0151}l", -1, -1, None),
+    Among("r\u{0151}l", -1, -1, None),
+    Among("t\u{0151}l", -1, -1, None),
+    Among("n\u{00E1}l", -1, -1, None),
+    Among("n\u{00E9}l", -1, -1, None),
+    Among("b\u{00F3}l", -1, -1, None),
+    Among("r\u{00F3}l", -1, -1, None),
+    Among("t\u{00F3}l", -1, -1, None),
+    Among("\u{00FC}l", -1, -1, None),
+    Among("n", -1, -1, None),
+    Among("an", 19, -1, None),
+    Among("ban", 20, -1, None),
+    Among("en", 19, -1, None),
+    Among("ben", 22, -1, None),
+    Among("k\u{00E9}ppen", 22, -1, None),
+    Among("on", 19, -1, None),
+    Among("\u{00F6}n", 19, -1, None),
+    Among("k\u{00E9}pp", -1, -1, None),
+    Among("kor", -1, -1, None),
+    Among("t", -1, -1, None),
+    Among("at", 29, -1, None),
+    Among("et", 29, -1, None),
+    Among("k\u{00E9}nt", 29, -1, None),
+    Among("ank\u{00E9}nt", 32, -1, None),
+    Among("enk\u{00E9}nt", 32, -1, None),
+    Among("onk\u{00E9}nt", 32, -1, None),
+    Among("ot", 29, -1, None),
+    Among("\u{00E9}rt", 29, -1, None),
+    Among("\u{00F6}t", 29, -1, None),
+    Among("hez", -1, -1, None),
+    Among("hoz", -1, -1, None),
+    Among("h\u{00F6}z", -1, -1, None),
+    Among("v\u{00E1}", -1, -1, None),
+    Among("v\u{00E9}", -1, -1, None),
+];
+
+static A_5: &'static [Among<Context>; 3] = &[
+    Among("\u{00E1}n", -1, 2, None),
+    Among("\u{00E9}n", -1, 1, None),
+    Among("\u{00E1}nk\u{00E9}nt", -1, 3, None),
+];
+
+static A_6: &'static [Among<Context>; 6] = &[
+    Among("stul", -1, 2, None),
+    Among("astul", 0, 1, None),
+    Among("\u{00E1}stul", 0, 3, None),
+    Among("st\u{00FC}l", -1, 2, None),
+    Among("est\u{00FC}l", 3, 1, None),
+    Among("\u{00E9}st\u{00FC}l", 3, 4, None),
+];
+
+static A_7: &'static [Among<Context>; 2] = &[
+    Among("\u{00E1}", -1, 1, None),
+    Among("\u{00E9}", -1, 2, None),
+];
+
+static A_8: &'static [Among<Context>; 7] = &[
+    Among("k", -1, 7, None),
+    Among("ak", 0, 4, None),
+    Among("ek", 0, 6, None),
+    Among("ok", 0, 5, None),
+    Among("\u{00E1}k", 0, 1, None),
+    Among("\u{00E9}k", 0, 2, None),
+    Among("\u{00F6}k", 0, 3, None),
+];
+
+static A_9: &'static [Among<Context>; 12] = &[
+    Among("\u{00E9}i", -1, 7, None),
+    Among("\u{00E1}\u{00E9}i", 0, 6, None),
+    Among("\u{00E9}\u{00E9}i", 0, 5, None),
+    Among("\u{00E9}", -1, 9, None),
+    Among("k\u{00E9}", 3, 4, None),
+    Among("ak\u{00E9}", 4, 1, None),
+    Among("ek\u{00E9}", 4, 1, None),
+    Among("ok\u{00E9}", 4, 1, None),
+    Among("\u{00E1}k\u{00E9}", 4, 3, None),
+    Among("\u{00E9}k\u{00E9}", 4, 2, None),
+    Among("\u{00F6}k\u{00E9}", 4, 1, None),
+    Among("\u{00E9}\u{00E9}", 3, 8, None),
+];
+
+static A_10: &'static [Among<Context>; 31] = &[
+    Among("a", -1, 18, None),
+    Among("ja", 0, 17, None),
+    Among("d", -1, 16, None),
+    Among("ad", 2, 13, None),
+    Among("ed", 2, 13, None),
+    Among("od", 2, 13, None),
+    Among("\u{00E1}d", 2, 14, None),
+    Among("\u{00E9}d", 2, 15, None),
+    Among("\u{00F6}d", 2, 13, None),
+    Among("e", -1, 18, None),
+    Among("je", 9, 17, None),
+    Among("nk", -1, 4, None),
+    Among("unk", 11, 1, None),
+    Among("\u{00E1}nk", 11, 2, None),
+    Among("\u{00E9}nk", 11, 3, None),
+    Among("\u{00FC}nk", 11, 1, None),
+    Among("uk", -1, 8, None),
+    Among("juk", 16, 7, None),
+    Among("\u{00E1}juk", 17, 5, None),
+    Among("\u{00FC}k", -1, 8, None),
+    Among("j\u{00FC}k", 19, 7, None),
+    Among("\u{00E9}j\u{00FC}k", 20, 6, None),
+    Among("m", -1, 12, None),
+    Among("am", 22, 9, None),
+    Among("em", 22, 9, None),
+    Among("om", 22, 9, None),
+    Among("\u{00E1}m", 22, 10, None),
+    Among("\u{00E9}m", 22, 11, None),
+    Among("o", -1, 18, None),
+    Among("\u{00E1}", -1, 19, None),
+    Among("\u{00E9}", -1, 20, None),
+];
+
+static A_11: &'static [Among<Context>; 42] = &[
+    Among("id", -1, 10, None),
+    Among("aid", 0, 9, None),
+    Among("jaid", 1, 6, None),
+    Among("eid", 0, 9, None),
+    Among("jeid", 3, 6, None),
+    Among("\u{00E1}id", 0, 7, None),
+    Among("\u{00E9}id", 0, 8, None),
+    Among("i", -1, 15, None),
+    Among("ai", 7, 14, None),
+    Among("jai", 8, 11, None),
+    Among("ei", 7, 14, None),
+    Among("jei", 10, 11, None),
+    Among("\u{00E1}i", 7, 12, None),
+    Among("\u{00E9}i", 7, 13, None),
+    Among("itek", -1, 24, None),
+    Among("eitek", 14, 21, None),
+    Among("jeitek", 15, 20, None),
+    Among("\u{00E9}itek", 14, 23, None),
+    Among("ik", -1, 29, None),
+    Among("aik", 18, 26, None),
+    Among("jaik", 19, 25, None),
+    Among("eik", 18, 26, None),
+    Among("jeik", 21, 25, None),
+    Among("\u{00E1}ik", 18, 27, None),
+    Among("\u{00E9}ik", 18, 28, None),
+    Among("ink", -1, 20, None),
+    Among("aink", 25, 17, None),
+    Among("jaink", 26, 16, None),
+    Among("eink", 25, 17, None),
+    Among("jeink", 28, 16, None),
+    Among("\u{00E1}ink", 25, 18, None),
+    Among("\u{00E9}ink", 25, 19, None),
+    Among("aitok", -1, 21, None),
+    Among("jaitok", 32, 20, None),
+    Among("\u{00E1}itok", -1, 22, None),
+    Among("im", -1, 5, None),
+    Among("aim", 35, 4, None),
+    Among("jaim", 36, 1, None),
+    Among("eim", 35, 4, None),
+    Among("jeim", 38, 1, None),
+    Among("\u{00E1}im", 35, 2, None),
+    Among("\u{00E9}im", 35, 3, None),
+];
+
+static G_v: &'static [u8; 35] = &[17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 36, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1];
+
+#[derive(Clone)]
+struct Context {
+    i_p1: usize,
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 44
+    context.i_p1 = env.limit;
+    // or, line 51
+    'lab0: loop {
+        let v_1 = env.cursor;
+        'lab1: loop {
+            // (, line 48
+            if !env.in_grouping(G_v, 97, 369) {
+                break 'lab1;
+            }
+            // goto, line 48
+            'golab2: loop {
+                let v_2 = env.cursor;
+                'lab3: loop {
+                    if !env.out_grouping(G_v, 97, 369) {
+                        break 'lab3;
+                    }
+                    env.cursor = v_2;
+                    break 'golab2;
+                }
+                env.cursor = v_2;
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            // or, line 49
+            'lab4: loop {
+                let v_3 = env.cursor;
+                'lab5: loop {
+                    // among, line 49
+                    if env.find_among(A_0, context) == 0 {
+                        break 'lab5;
+                    }
+                    break 'lab4;
+                }
+                env.cursor = v_3;
+                // next, line 49
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+                break 'lab4;
+            }
+            // setmark p1, line 50
+            context.i_p1 = env.cursor;
+            break 'lab0;
+        }
+        env.cursor = v_1;
+        // (, line 53
+        if !env.out_grouping(G_v, 97, 369) {
+            return false;
+        }
+        // gopast, line 53
+        'golab6: loop {
+            'lab7: loop {
+                if !env.in_grouping(G_v, 97, 369) {
+                    break 'lab7;
+                }
+                break 'golab6;
+            }
+            if env.cursor >= env.limit {
+                return false;
+            }
+            env.next_char();
+        }
+        // setmark p1, line 53
+        context.i_p1 = env.cursor;
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_R1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p1 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_v_ending(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 60
+    // [, line 61
+    env.ket = env.cursor;
+    // substring, line 61
+    among_var = env.find_among_b(A_1, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 61
+    env.bra = env.cursor;
+    // call R1, line 61
+    if !r_R1(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 62
+        // <-, line 62
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 63
+        // <-, line 63
+        if !env.slice_from("e") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_double(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 67
+    // test, line 68
+    let v_1 = env.limit - env.cursor;
+    // among, line 68
+    if env.find_among_b(A_2, context) == 0 {
+        return false;
+    }
+    env.cursor = env.limit - v_1;
+    return true;
+}
+
+fn r_undouble(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 72
+    // next, line 73
+    if env.cursor <= env.limit_backward {
+        return false;
+    }
+    env.previous_char();
+    // [, line 73
+    env.ket = env.cursor;
+    // hop, line 73
+    let c = env.byte_index_for_hop(-1);
+    if env.limit_backward as i32 > c || c > env.limit as i32 {
+        return false;
+    }
+    env.cursor = c as usize;
+    // ], line 73
+    env.bra = env.cursor;
+    // delete, line 73
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+fn r_instrum(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 76
+    // [, line 77
+    env.ket = env.cursor;
+    // substring, line 77
+    among_var = env.find_among_b(A_3, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 77
+    env.bra = env.cursor;
+    // call R1, line 77
+    if !r_R1(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 78
+        // call double, line 78
+        if !r_double(env, context) {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 79
+        // call double, line 79
+        if !r_double(env, context) {
+            return false;
+        }
+    }
+    // delete, line 81
+    if !env.slice_del() {
+        return false;
+    }
+    // call undouble, line 82
+    if !r_undouble(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_case(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 86
+    // [, line 87
+    env.ket = env.cursor;
+    // substring, line 87
+    if env.find_among_b(A_4, context) == 0 {
+        return false;
+    }
+    // ], line 87
+    env.bra = env.cursor;
+    // call R1, line 87
+    if !r_R1(env, context) {
+        return false;
+    }
+    // delete, line 111
+    if !env.slice_del() {
+        return false;
+    }
+    // call v_ending, line 112
+    if !r_v_ending(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_case_special(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 115
+    // [, line 116
+    env.ket = env.cursor;
+    // substring, line 116
+    among_var = env.find_among_b(A_5, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 116
+    env.bra = env.cursor;
+    // call R1, line 116
+    if !r_R1(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 117
+        // <-, line 117
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 118
+        // <-, line 118
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 119
+        // <-, line 119
+        if !env.slice_from("a") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_case_other(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 123
+    // [, line 124
+    env.ket = env.cursor;
+    // substring, line 124
+    among_var = env.find_among_b(A_6, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 124
+    env.bra = env.cursor;
+    // call R1, line 124
+    if !r_R1(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 125
+        // delete, line 125
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 126
+        // delete, line 126
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 127
+        // <-, line 127
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 128
+        // <-, line 128
+        if !env.slice_from("e") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_factive(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 132
+    // [, line 133
+    env.ket = env.cursor;
+    // substring, line 133
+    among_var = env.find_among_b(A_7, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 133
+    env.bra = env.cursor;
+    // call R1, line 133
+    if !r_R1(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 134
+        // call double, line 134
+        if !r_double(env, context) {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 135
+        // call double, line 135
+        if !r_double(env, context) {
+            return false;
+        }
+    }
+    // delete, line 137
+    if !env.slice_del() {
+        return false;
+    }
+    // call undouble, line 138
+    if !r_undouble(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_plural(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 141
+    // [, line 142
+    env.ket = env.cursor;
+    // substring, line 142
+    among_var = env.find_among_b(A_8, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 142
+    env.bra = env.cursor;
+    // call R1, line 142
+    if !r_R1(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 143
+        // <-, line 143
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 144
+        // <-, line 144
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 145
+        // delete, line 145
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 146
+        // delete, line 146
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 147
+        // delete, line 147
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 148
+        // delete, line 148
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 7 {
+        // (, line 149
+        // delete, line 149
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_owned(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 153
+    // [, line 154
+    env.ket = env.cursor;
+    // substring, line 154
+    among_var = env.find_among_b(A_9, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 154
+    env.bra = env.cursor;
+    // call R1, line 154
+    if !r_R1(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 155
+        // delete, line 155
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 156
+        // <-, line 156
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 157
+        // <-, line 157
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 158
+        // delete, line 158
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 159
+        // <-, line 159
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 160
+        // <-, line 160
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 7 {
+        // (, line 161
+        // delete, line 161
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 8 {
+        // (, line 162
+        // <-, line 162
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 9 {
+        // (, line 163
+        // delete, line 163
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_sing_owner(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 167
+    // [, line 168
+    env.ket = env.cursor;
+    // substring, line 168
+    among_var = env.find_among_b(A_10, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 168
+    env.bra = env.cursor;
+    // call R1, line 168
+    if !r_R1(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 169
+        // delete, line 169
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 170
+        // <-, line 170
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 171
+        // <-, line 171
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 172
+        // delete, line 172
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 173
+        // <-, line 173
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 174
+        // <-, line 174
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 7 {
+        // (, line 175
+        // delete, line 175
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 8 {
+        // (, line 176
+        // delete, line 176
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 9 {
+        // (, line 177
+        // delete, line 177
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 10 {
+        // (, line 178
+        // <-, line 178
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 11 {
+        // (, line 179
+        // <-, line 179
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 12 {
+        // (, line 180
+        // delete, line 180
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 13 {
+        // (, line 181
+        // delete, line 181
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 14 {
+        // (, line 182
+        // <-, line 182
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 15 {
+        // (, line 183
+        // <-, line 183
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 16 {
+        // (, line 184
+        // delete, line 184
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 17 {
+        // (, line 185
+        // delete, line 185
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 18 {
+        // (, line 186
+        // delete, line 186
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 19 {
+        // (, line 187
+        // <-, line 187
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 20 {
+        // (, line 188
+        // <-, line 188
+        if !env.slice_from("e") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_plur_owner(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 192
+    // [, line 193
+    env.ket = env.cursor;
+    // substring, line 193
+    among_var = env.find_among_b(A_11, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 193
+    env.bra = env.cursor;
+    // call R1, line 193
+    if !r_R1(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 194
+        // delete, line 194
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 195
+        // <-, line 195
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 196
+        // <-, line 196
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 197
+        // delete, line 197
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 198
+        // delete, line 198
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 199
+        // delete, line 199
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 7 {
+        // (, line 200
+        // <-, line 200
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 8 {
+        // (, line 201
+        // <-, line 201
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 9 {
+        // (, line 202
+        // delete, line 202
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 10 {
+        // (, line 203
+        // delete, line 203
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 11 {
+        // (, line 204
+        // delete, line 204
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 12 {
+        // (, line 205
+        // <-, line 205
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 13 {
+        // (, line 206
+        // <-, line 206
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 14 {
+        // (, line 207
+        // delete, line 207
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 15 {
+        // (, line 208
+        // delete, line 208
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 16 {
+        // (, line 209
+        // delete, line 209
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 17 {
+        // (, line 210
+        // delete, line 210
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 18 {
+        // (, line 211
+        // <-, line 211
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 19 {
+        // (, line 212
+        // <-, line 212
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 20 {
+        // (, line 214
+        // delete, line 214
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 21 {
+        // (, line 215
+        // delete, line 215
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 22 {
+        // (, line 216
+        // <-, line 216
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 23 {
+        // (, line 217
+        // <-, line 217
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 24 {
+        // (, line 218
+        // delete, line 218
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 25 {
+        // (, line 219
+        // delete, line 219
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 26 {
+        // (, line 220
+        // delete, line 220
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 27 {
+        // (, line 221
+        // <-, line 221
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 28 {
+        // (, line 222
+        // <-, line 222
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 29 {
+        // (, line 223
+        // delete, line 223
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        i_p1: 0,
+    };
+    // (, line 228
+    // do, line 229
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call mark_regions, line 229
+        if !r_mark_regions(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // backwards, line 230
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 230
+    // do, line 231
+    let v_2 = env.limit - env.cursor;
+    'lab1: loop {
+        // call instrum, line 231
+        if !r_instrum(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = env.limit - v_2;
+    // do, line 232
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // call case, line 232
+        if !r_case(env, context) {
+            break 'lab2;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    // do, line 233
+    let v_4 = env.limit - env.cursor;
+    'lab3: loop {
+        // call case_special, line 233
+        if !r_case_special(env, context) {
+            break 'lab3;
+        }
+        break 'lab3;
+    }
+    env.cursor = env.limit - v_4;
+    // do, line 234
+    let v_5 = env.limit - env.cursor;
+    'lab4: loop {
+        // call case_other, line 234
+        if !r_case_other(env, context) {
+            break 'lab4;
+        }
+        break 'lab4;
+    }
+    env.cursor = env.limit - v_5;
+    // do, line 235
+    let v_6 = env.limit - env.cursor;
+    'lab5: loop {
+        // call factive, line 235
+        if !r_factive(env, context) {
+            break 'lab5;
+        }
+        break 'lab5;
+    }
+    env.cursor = env.limit - v_6;
+    // do, line 236
+    let v_7 = env.limit - env.cursor;
+    'lab6: loop {
+        // call owned, line 236
+        if !r_owned(env, context) {
+            break 'lab6;
+        }
+        break 'lab6;
+    }
+    env.cursor = env.limit - v_7;
+    // do, line 237
+    let v_8 = env.limit - env.cursor;
+    'lab7: loop {
+        // call sing_owner, line 237
+        if !r_sing_owner(env, context) {
+            break 'lab7;
+        }
+        break 'lab7;
+    }
+    env.cursor = env.limit - v_8;
+    // do, line 238
+    let v_9 = env.limit - env.cursor;
+    'lab8: loop {
+        // call plur_owner, line 238
+        if !r_plur_owner(env, context) {
+            break 'lab8;
+        }
+        break 'lab8;
+    }
+    env.cursor = env.limit - v_9;
+    // do, line 239
+    let v_10 = env.limit - env.cursor;
+    'lab9: loop {
+        // call plural, line 239
+        if !r_plural(env, context) {
+            break 'lab9;
+        }
+        break 'lab9;
+    }
+    env.cursor = env.limit - v_10;
+    env.cursor = env.limit_backward;
+    return true;
+}
diff --git a/src/snowball/algorithms/italian.rs b/src/snowball/algorithms/italian.rs
new file mode 100644
index 0000000..bcbfe30
--- /dev/null
+++ b/src/snowball/algorithms/italian.rs
@@ -0,0 +1,1117 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 7] = &[
+    Among("", -1, 7, None),
+    Among("qu", 0, 6, None),
+    Among("\u{00E1}", 0, 1, None),
+    Among("\u{00E9}", 0, 2, None),
+    Among("\u{00ED}", 0, 3, None),
+    Among("\u{00F3}", 0, 4, None),
+    Among("\u{00FA}", 0, 5, None),
+];
+
+static A_1: &'static [Among<Context>; 3] = &[
+    Among("", -1, 3, None),
+    Among("I", 0, 1, None),
+    Among("U", 0, 2, None),
+];
+
+static A_2: &'static [Among<Context>; 37] = &[
+    Among("la", -1, -1, None),
+    Among("cela", 0, -1, None),
+    Among("gliela", 0, -1, None),
+    Among("mela", 0, -1, None),
+    Among("tela", 0, -1, None),
+    Among("vela", 0, -1, None),
+    Among("le", -1, -1, None),
+    Among("cele", 6, -1, None),
+    Among("gliele", 6, -1, None),
+    Among("mele", 6, -1, None),
+    Among("tele", 6, -1, None),
+    Among("vele", 6, -1, None),
+    Among("ne", -1, -1, None),
+    Among("cene", 12, -1, None),
+    Among("gliene", 12, -1, None),
+    Among("mene", 12, -1, None),
+    Among("sene", 12, -1, None),
+    Among("tene", 12, -1, None),
+    Among("vene", 12, -1, None),
+    Among("ci", -1, -1, None),
+    Among("li", -1, -1, None),
+    Among("celi", 20, -1, None),
+    Among("glieli", 20, -1, None),
+    Among("meli", 20, -1, None),
+    Among("teli", 20, -1, None),
+    Among("veli", 20, -1, None),
+    Among("gli", 20, -1, None),
+    Among("mi", -1, -1, None),
+    Among("si", -1, -1, None),
+    Among("ti", -1, -1, None),
+    Among("vi", -1, -1, None),
+    Among("lo", -1, -1, None),
+    Among("celo", 31, -1, None),
+    Among("glielo", 31, -1, None),
+    Among("melo", 31, -1, None),
+    Among("telo", 31, -1, None),
+    Among("velo", 31, -1, None),
+];
+
+static A_3: &'static [Among<Context>; 5] = &[
+    Among("ando", -1, 1, None),
+    Among("endo", -1, 1, None),
+    Among("ar", -1, 2, None),
+    Among("er", -1, 2, None),
+    Among("ir", -1, 2, None),
+];
+
+static A_4: &'static [Among<Context>; 4] = &[
+    Among("ic", -1, -1, None),
+    Among("abil", -1, -1, None),
+    Among("os", -1, -1, None),
+    Among("iv", -1, 1, None),
+];
+
+static A_5: &'static [Among<Context>; 3] = &[
+    Among("ic", -1, 1, None),
+    Among("abil", -1, 1, None),
+    Among("iv", -1, 1, None),
+];
+
+static A_6: &'static [Among<Context>; 51] = &[
+    Among("ica", -1, 1, None),
+    Among("logia", -1, 3, None),
+    Among("osa", -1, 1, None),
+    Among("ista", -1, 1, None),
+    Among("iva", -1, 9, None),
+    Among("anza", -1, 1, None),
+    Among("enza", -1, 5, None),
+    Among("ice", -1, 1, None),
+    Among("atrice", 7, 1, None),
+    Among("iche", -1, 1, None),
+    Among("logie", -1, 3, None),
+    Among("abile", -1, 1, None),
+    Among("ibile", -1, 1, None),
+    Among("usione", -1, 4, None),
+    Among("azione", -1, 2, None),
+    Among("uzione", -1, 4, None),
+    Among("atore", -1, 2, None),
+    Among("ose", -1, 1, None),
+    Among("ante", -1, 1, None),
+    Among("mente", -1, 1, None),
+    Among("amente", 19, 7, None),
+    Among("iste", -1, 1, None),
+    Among("ive", -1, 9, None),
+    Among("anze", -1, 1, None),
+    Among("enze", -1, 5, None),
+    Among("ici", -1, 1, None),
+    Among("atrici", 25, 1, None),
+    Among("ichi", -1, 1, None),
+    Among("abili", -1, 1, None),
+    Among("ibili", -1, 1, None),
+    Among("ismi", -1, 1, None),
+    Among("usioni", -1, 4, None),
+    Among("azioni", -1, 2, None),
+    Among("uzioni", -1, 4, None),
+    Among("atori", -1, 2, None),
+    Among("osi", -1, 1, None),
+    Among("anti", -1, 1, None),
+    Among("amenti", -1, 6, None),
+    Among("imenti", -1, 6, None),
+    Among("isti", -1, 1, None),
+    Among("ivi", -1, 9, None),
+    Among("ico", -1, 1, None),
+    Among("ismo", -1, 1, None),
+    Among("oso", -1, 1, None),
+    Among("amento", -1, 6, None),
+    Among("imento", -1, 6, None),
+    Among("ivo", -1, 9, None),
+    Among("it\u{00E0}", -1, 8, None),
+    Among("ist\u{00E0}", -1, 1, None),
+    Among("ist\u{00E8}", -1, 1, None),
+    Among("ist\u{00EC}", -1, 1, None),
+];
+
+static A_7: &'static [Among<Context>; 87] = &[
+    Among("isca", -1, 1, None),
+    Among("enda", -1, 1, None),
+    Among("ata", -1, 1, None),
+    Among("ita", -1, 1, None),
+    Among("uta", -1, 1, None),
+    Among("ava", -1, 1, None),
+    Among("eva", -1, 1, None),
+    Among("iva", -1, 1, None),
+    Among("erebbe", -1, 1, None),
+    Among("irebbe", -1, 1, None),
+    Among("isce", -1, 1, None),
+    Among("ende", -1, 1, None),
+    Among("are", -1, 1, None),
+    Among("ere", -1, 1, None),
+    Among("ire", -1, 1, None),
+    Among("asse", -1, 1, None),
+    Among("ate", -1, 1, None),
+    Among("avate", 16, 1, None),
+    Among("evate", 16, 1, None),
+    Among("ivate", 16, 1, None),
+    Among("ete", -1, 1, None),
+    Among("erete", 20, 1, None),
+    Among("irete", 20, 1, None),
+    Among("ite", -1, 1, None),
+    Among("ereste", -1, 1, None),
+    Among("ireste", -1, 1, None),
+    Among("ute", -1, 1, None),
+    Among("erai", -1, 1, None),
+    Among("irai", -1, 1, None),
+    Among("isci", -1, 1, None),
+    Among("endi", -1, 1, None),
+    Among("erei", -1, 1, None),
+    Among("irei", -1, 1, None),
+    Among("assi", -1, 1, None),
+    Among("ati", -1, 1, None),
+    Among("iti", -1, 1, None),
+    Among("eresti", -1, 1, None),
+    Among("iresti", -1, 1, None),
+    Among("uti", -1, 1, None),
+    Among("avi", -1, 1, None),
+    Among("evi", -1, 1, None),
+    Among("ivi", -1, 1, None),
+    Among("isco", -1, 1, None),
+    Among("ando", -1, 1, None),
+    Among("endo", -1, 1, None),
+    Among("Yamo", -1, 1, None),
+    Among("iamo", -1, 1, None),
+    Among("avamo", -1, 1, None),
+    Among("evamo", -1, 1, None),
+    Among("ivamo", -1, 1, None),
+    Among("eremo", -1, 1, None),
+    Among("iremo", -1, 1, None),
+    Among("assimo", -1, 1, None),
+    Among("ammo", -1, 1, None),
+    Among("emmo", -1, 1, None),
+    Among("eremmo", 54, 1, None),
+    Among("iremmo", 54, 1, None),
+    Among("immo", -1, 1, None),
+    Among("ano", -1, 1, None),
+    Among("iscano", 58, 1, None),
+    Among("avano", 58, 1, None),
+    Among("evano", 58, 1, None),
+    Among("ivano", 58, 1, None),
+    Among("eranno", -1, 1, None),
+    Among("iranno", -1, 1, None),
+    Among("ono", -1, 1, None),
+    Among("iscono", 65, 1, None),
+    Among("arono", 65, 1, None),
+    Among("erono", 65, 1, None),
+    Among("irono", 65, 1, None),
+    Among("erebbero", -1, 1, None),
+    Among("irebbero", -1, 1, None),
+    Among("assero", -1, 1, None),
+    Among("essero", -1, 1, None),
+    Among("issero", -1, 1, None),
+    Among("ato", -1, 1, None),
+    Among("ito", -1, 1, None),
+    Among("uto", -1, 1, None),
+    Among("avo", -1, 1, None),
+    Among("evo", -1, 1, None),
+    Among("ivo", -1, 1, None),
+    Among("ar", -1, 1, None),
+    Among("ir", -1, 1, None),
+    Among("er\u{00E0}", -1, 1, None),
+    Among("ir\u{00E0}", -1, 1, None),
+    Among("er\u{00F2}", -1, 1, None),
+    Among("ir\u{00F2}", -1, 1, None),
+];
+
+static G_v: &'static [u8; 20] = &[17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2, 1];
+
+static G_AEIO: &'static [u8; 19] = &[17, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2];
+
+static G_CG: &'static [u8; 1] = &[17];
+
+#[derive(Clone)]
+struct Context {
+    i_p2: usize,
+    i_p1: usize,
+    i_pV: usize,
+}
+
+fn r_prelude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 33
+    // test, line 34
+    let v_1 = env.cursor;
+    // repeat, line 34
+    'replab0: loop{
+        let v_2 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 34
+            // [, line 35
+            env.bra = env.cursor;
+            // substring, line 35
+            among_var = env.find_among(A_0, context);
+            if among_var == 0 {
+                break 'lab1;
+            }
+            // ], line 35
+            env.ket = env.cursor;
+            if among_var == 0 {
+                break 'lab1;
+            } else if among_var == 1 {
+                // (, line 36
+                // <-, line 36
+                if !env.slice_from("\u{00E0}") {
+                    return false;
+                }
+            } else if among_var == 2 {
+                // (, line 37
+                // <-, line 37
+                if !env.slice_from("\u{00E8}") {
+                    return false;
+                }
+            } else if among_var == 3 {
+                // (, line 38
+                // <-, line 38
+                if !env.slice_from("\u{00EC}") {
+                    return false;
+                }
+            } else if among_var == 4 {
+                // (, line 39
+                // <-, line 39
+                if !env.slice_from("\u{00F2}") {
+                    return false;
+                }
+            } else if among_var == 5 {
+                // (, line 40
+                // <-, line 40
+                if !env.slice_from("\u{00F9}") {
+                    return false;
+                }
+            } else if among_var == 6 {
+                // (, line 41
+                // <-, line 41
+                if !env.slice_from("qU") {
+                    return false;
+                }
+            } else if among_var == 7 {
+                // (, line 42
+                // next, line 42
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_2;
+        break 'replab0;
+    }
+    env.cursor = v_1;
+    // repeat, line 45
+    'replab2: loop{
+        let v_3 = env.cursor;
+        'lab3: for _ in 0..1 {
+            // goto, line 45
+            'golab4: loop {
+                let v_4 = env.cursor;
+                'lab5: loop {
+                    // (, line 45
+                    if !env.in_grouping(G_v, 97, 249) {
+                        break 'lab5;
+                    }
+                    // [, line 46
+                    env.bra = env.cursor;
+                    // or, line 46
+                    'lab6: loop {
+                        let v_5 = env.cursor;
+                        'lab7: loop {
+                            // (, line 46
+                            // literal, line 46
+                            if !env.eq_s(&"u") {
+                                break 'lab7;
+                            }
+                            // ], line 46
+                            env.ket = env.cursor;
+                            if !env.in_grouping(G_v, 97, 249) {
+                                break 'lab7;
+                            }
+                            // <-, line 46
+                            if !env.slice_from("U") {
+                                return false;
+                            }
+                            break 'lab6;
+                        }
+                        env.cursor = v_5;
+                        // (, line 47
+                        // literal, line 47
+                        if !env.eq_s(&"i") {
+                            break 'lab5;
+                        }
+                        // ], line 47
+                        env.ket = env.cursor;
+                        if !env.in_grouping(G_v, 97, 249) {
+                            break 'lab5;
+                        }
+                        // <-, line 47
+                        if !env.slice_from("I") {
+                            return false;
+                        }
+                        break 'lab6;
+                    }
+                    env.cursor = v_4;
+                    break 'golab4;
+                }
+                env.cursor = v_4;
+                if env.cursor >= env.limit {
+                    break 'lab3;
+                }
+                env.next_char();
+            }
+            continue 'replab2;
+        }
+        env.cursor = v_3;
+        break 'replab2;
+    }
+    return true;
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 51
+    context.i_pV = env.limit;
+    context.i_p1 = env.limit;
+    context.i_p2 = env.limit;
+    // do, line 57
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // (, line 57
+        // or, line 59
+        'lab1: loop {
+            let v_2 = env.cursor;
+            'lab2: loop {
+                // (, line 58
+                if !env.in_grouping(G_v, 97, 249) {
+                    break 'lab2;
+                }
+                // or, line 58
+                'lab3: loop {
+                    let v_3 = env.cursor;
+                    'lab4: loop {
+                        // (, line 58
+                        if !env.out_grouping(G_v, 97, 249) {
+                            break 'lab4;
+                        }
+                        // gopast, line 58
+                        'golab5: loop {
+                            'lab6: loop {
+                                if !env.in_grouping(G_v, 97, 249) {
+                                    break 'lab6;
+                                }
+                                break 'golab5;
+                            }
+                            if env.cursor >= env.limit {
+                                break 'lab4;
+                            }
+                            env.next_char();
+                        }
+                        break 'lab3;
+                    }
+                    env.cursor = v_3;
+                    // (, line 58
+                    if !env.in_grouping(G_v, 97, 249) {
+                        break 'lab2;
+                    }
+                    // gopast, line 58
+                    'golab7: loop {
+                        'lab8: loop {
+                            if !env.out_grouping(G_v, 97, 249) {
+                                break 'lab8;
+                            }
+                            break 'golab7;
+                        }
+                        if env.cursor >= env.limit {
+                            break 'lab2;
+                        }
+                        env.next_char();
+                    }
+                    break 'lab3;
+                }
+                break 'lab1;
+            }
+            env.cursor = v_2;
+            // (, line 60
+            if !env.out_grouping(G_v, 97, 249) {
+                break 'lab0;
+            }
+            // or, line 60
+            'lab9: loop {
+                let v_6 = env.cursor;
+                'lab10: loop {
+                    // (, line 60
+                    if !env.out_grouping(G_v, 97, 249) {
+                        break 'lab10;
+                    }
+                    // gopast, line 60
+                    'golab11: loop {
+                        'lab12: loop {
+                            if !env.in_grouping(G_v, 97, 249) {
+                                break 'lab12;
+                            }
+                            break 'golab11;
+                        }
+                        if env.cursor >= env.limit {
+                            break 'lab10;
+                        }
+                        env.next_char();
+                    }
+                    break 'lab9;
+                }
+                env.cursor = v_6;
+                // (, line 60
+                if !env.in_grouping(G_v, 97, 249) {
+                    break 'lab0;
+                }
+                // next, line 60
+                if env.cursor >= env.limit {
+                    break 'lab0;
+                }
+                env.next_char();
+                break 'lab9;
+            }
+            break 'lab1;
+        }
+        // setmark pV, line 61
+        context.i_pV = env.cursor;
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 63
+    let v_8 = env.cursor;
+    'lab13: loop {
+        // (, line 63
+        // gopast, line 64
+        'golab14: loop {
+            'lab15: loop {
+                if !env.in_grouping(G_v, 97, 249) {
+                    break 'lab15;
+                }
+                break 'golab14;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // gopast, line 64
+        'golab16: loop {
+            'lab17: loop {
+                if !env.out_grouping(G_v, 97, 249) {
+                    break 'lab17;
+                }
+                break 'golab16;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // setmark p1, line 64
+        context.i_p1 = env.cursor;
+        // gopast, line 65
+        'golab18: loop {
+            'lab19: loop {
+                if !env.in_grouping(G_v, 97, 249) {
+                    break 'lab19;
+                }
+                break 'golab18;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // gopast, line 65
+        'golab20: loop {
+            'lab21: loop {
+                if !env.out_grouping(G_v, 97, 249) {
+                    break 'lab21;
+                }
+                break 'golab20;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // setmark p2, line 65
+        context.i_p2 = env.cursor;
+        break 'lab13;
+    }
+    env.cursor = v_8;
+    return true;
+}
+
+fn r_postlude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // repeat, line 69
+    'replab0: loop{
+        let v_1 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 69
+            // [, line 71
+            env.bra = env.cursor;
+            // substring, line 71
+            among_var = env.find_among(A_1, context);
+            if among_var == 0 {
+                break 'lab1;
+            }
+            // ], line 71
+            env.ket = env.cursor;
+            if among_var == 0 {
+                break 'lab1;
+            } else if among_var == 1 {
+                // (, line 72
+                // <-, line 72
+                if !env.slice_from("i") {
+                    return false;
+                }
+            } else if among_var == 2 {
+                // (, line 73
+                // <-, line 73
+                if !env.slice_from("u") {
+                    return false;
+                }
+            } else if among_var == 3 {
+                // (, line 74
+                // next, line 74
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+fn r_RV(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_pV <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_R1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p1 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_R2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p2 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_attached_pronoun(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 85
+    // [, line 86
+    env.ket = env.cursor;
+    // substring, line 86
+    if env.find_among_b(A_2, context) == 0 {
+        return false;
+    }
+    // ], line 86
+    env.bra = env.cursor;
+    // among, line 96
+    among_var = env.find_among_b(A_3, context);
+    if among_var == 0 {
+        return false;
+    }
+    // (, line 96
+    // call RV, line 96
+    if !r_RV(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 97
+        // delete, line 97
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 98
+        // <-, line 98
+        if !env.slice_from("e") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_standard_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 102
+    // [, line 103
+    env.ket = env.cursor;
+    // substring, line 103
+    among_var = env.find_among_b(A_6, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 103
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 110
+        // call R2, line 110
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 110
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 112
+        // call R2, line 112
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 112
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 113
+        let v_1 = env.limit - env.cursor;
+        'lab0: loop {
+            // (, line 113
+            // [, line 113
+            env.ket = env.cursor;
+            // literal, line 113
+            if !env.eq_s_b(&"ic") {
+                env.cursor = env.limit - v_1;
+                break 'lab0;
+            }
+            // ], line 113
+            env.bra = env.cursor;
+            // call R2, line 113
+            if !r_R2(env, context) {
+                env.cursor = env.limit - v_1;
+                break 'lab0;
+            }
+            // delete, line 113
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab0;
+        }
+    } else if among_var == 3 {
+        // (, line 116
+        // call R2, line 116
+        if !r_R2(env, context) {
+            return false;
+        }
+        // <-, line 116
+        if !env.slice_from("log") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 118
+        // call R2, line 118
+        if !r_R2(env, context) {
+            return false;
+        }
+        // <-, line 118
+        if !env.slice_from("u") {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 120
+        // call R2, line 120
+        if !r_R2(env, context) {
+            return false;
+        }
+        // <-, line 120
+        if !env.slice_from("ente") {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 122
+        // call RV, line 122
+        if !r_RV(env, context) {
+            return false;
+        }
+        // delete, line 122
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 7 {
+        // (, line 123
+        // call R1, line 124
+        if !r_R1(env, context) {
+            return false;
+        }
+        // delete, line 124
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 125
+        let v_2 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 125
+            // [, line 126
+            env.ket = env.cursor;
+            // substring, line 126
+            among_var = env.find_among_b(A_4, context);
+            if among_var == 0 {
+                env.cursor = env.limit - v_2;
+                break 'lab1;
+            }
+            // ], line 126
+            env.bra = env.cursor;
+            // call R2, line 126
+            if !r_R2(env, context) {
+                env.cursor = env.limit - v_2;
+                break 'lab1;
+            }
+            // delete, line 126
+            if !env.slice_del() {
+                return false;
+            }
+            if among_var == 0 {
+                env.cursor = env.limit - v_2;
+                break 'lab1;
+            } else if among_var == 1 {
+                // (, line 127
+                // [, line 127
+                env.ket = env.cursor;
+                // literal, line 127
+                if !env.eq_s_b(&"at") {
+                    env.cursor = env.limit - v_2;
+                    break 'lab1;
+                }
+                // ], line 127
+                env.bra = env.cursor;
+                // call R2, line 127
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_2;
+                    break 'lab1;
+                }
+                // delete, line 127
+                if !env.slice_del() {
+                    return false;
+                }
+            }
+            break 'lab1;
+        }
+    } else if among_var == 8 {
+        // (, line 132
+        // call R2, line 133
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 133
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 134
+        let v_3 = env.limit - env.cursor;
+        'lab2: loop {
+            // (, line 134
+            // [, line 135
+            env.ket = env.cursor;
+            // substring, line 135
+            among_var = env.find_among_b(A_5, context);
+            if among_var == 0 {
+                env.cursor = env.limit - v_3;
+                break 'lab2;
+            }
+            // ], line 135
+            env.bra = env.cursor;
+            if among_var == 0 {
+                env.cursor = env.limit - v_3;
+                break 'lab2;
+            } else if among_var == 1 {
+                // (, line 136
+                // call R2, line 136
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_3;
+                    break 'lab2;
+                }
+                // delete, line 136
+                if !env.slice_del() {
+                    return false;
+                }
+            }
+            break 'lab2;
+        }
+    } else if among_var == 9 {
+        // (, line 140
+        // call R2, line 141
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 141
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 142
+        let v_4 = env.limit - env.cursor;
+        'lab3: loop {
+            // (, line 142
+            // [, line 142
+            env.ket = env.cursor;
+            // literal, line 142
+            if !env.eq_s_b(&"at") {
+                env.cursor = env.limit - v_4;
+                break 'lab3;
+            }
+            // ], line 142
+            env.bra = env.cursor;
+            // call R2, line 142
+            if !r_R2(env, context) {
+                env.cursor = env.limit - v_4;
+                break 'lab3;
+            }
+            // delete, line 142
+            if !env.slice_del() {
+                return false;
+            }
+            // [, line 142
+            env.ket = env.cursor;
+            // literal, line 142
+            if !env.eq_s_b(&"ic") {
+                env.cursor = env.limit - v_4;
+                break 'lab3;
+            }
+            // ], line 142
+            env.bra = env.cursor;
+            // call R2, line 142
+            if !r_R2(env, context) {
+                env.cursor = env.limit - v_4;
+                break 'lab3;
+            }
+            // delete, line 142
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab3;
+        }
+    }
+    return true;
+}
+
+fn r_verb_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // setlimit, line 147
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 147
+    if env.cursor < context.i_pV {
+        return false;
+    }
+    env.cursor = context.i_pV;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 147
+    // [, line 148
+    env.ket = env.cursor;
+    // substring, line 148
+    among_var = env.find_among_b(A_7, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 148
+    env.bra = env.cursor;
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    } else if among_var == 1 {
+        // (, line 162
+        // delete, line 162
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    env.limit_backward = v_2;
+    return true;
+}
+
+fn r_vowel_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 169
+    // try, line 170
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 170
+        // [, line 171
+        env.ket = env.cursor;
+        if !env.in_grouping_b(G_AEIO, 97, 242) {
+            env.cursor = env.limit - v_1;
+            break 'lab0;
+        }
+        // ], line 171
+        env.bra = env.cursor;
+        // call RV, line 171
+        if !r_RV(env, context) {
+            env.cursor = env.limit - v_1;
+            break 'lab0;
+        }
+        // delete, line 171
+        if !env.slice_del() {
+            return false;
+        }
+        // [, line 172
+        env.ket = env.cursor;
+        // literal, line 172
+        if !env.eq_s_b(&"i") {
+            env.cursor = env.limit - v_1;
+            break 'lab0;
+        }
+        // ], line 172
+        env.bra = env.cursor;
+        // call RV, line 172
+        if !r_RV(env, context) {
+            env.cursor = env.limit - v_1;
+            break 'lab0;
+        }
+        // delete, line 172
+        if !env.slice_del() {
+            return false;
+        }
+        break 'lab0;
+    }
+    // try, line 174
+    let v_2 = env.limit - env.cursor;
+    'lab1: loop {
+        // (, line 174
+        // [, line 175
+        env.ket = env.cursor;
+        // literal, line 175
+        if !env.eq_s_b(&"h") {
+            env.cursor = env.limit - v_2;
+            break 'lab1;
+        }
+        // ], line 175
+        env.bra = env.cursor;
+        if !env.in_grouping_b(G_CG, 99, 103) {
+            env.cursor = env.limit - v_2;
+            break 'lab1;
+        }
+        // call RV, line 175
+        if !r_RV(env, context) {
+            env.cursor = env.limit - v_2;
+            break 'lab1;
+        }
+        // delete, line 175
+        if !env.slice_del() {
+            return false;
+        }
+        break 'lab1;
+    }
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        i_p2: 0,
+        i_p1: 0,
+        i_pV: 0,
+    };
+    // (, line 180
+    // do, line 181
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call prelude, line 181
+        if !r_prelude(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 182
+    let v_2 = env.cursor;
+    'lab1: loop {
+        // call mark_regions, line 182
+        if !r_mark_regions(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = v_2;
+    // backwards, line 183
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 183
+    // do, line 184
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // call attached_pronoun, line 184
+        if !r_attached_pronoun(env, context) {
+            break 'lab2;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    // do, line 185
+    let v_4 = env.limit - env.cursor;
+    'lab3: loop {
+        // (, line 185
+        // or, line 185
+        'lab4: loop {
+            let v_5 = env.limit - env.cursor;
+            'lab5: loop {
+                // call standard_suffix, line 185
+                if !r_standard_suffix(env, context) {
+                    break 'lab5;
+                }
+                break 'lab4;
+            }
+            env.cursor = env.limit - v_5;
+            // call verb_suffix, line 185
+            if !r_verb_suffix(env, context) {
+                break 'lab3;
+            }
+            break 'lab4;
+        }
+        break 'lab3;
+    }
+    env.cursor = env.limit - v_4;
+    // do, line 186
+    let v_6 = env.limit - env.cursor;
+    'lab6: loop {
+        // call vowel_suffix, line 186
+        if !r_vowel_suffix(env, context) {
+            break 'lab6;
+        }
+        break 'lab6;
+    }
+    env.cursor = env.limit - v_6;
+    env.cursor = env.limit_backward;
+    // do, line 188
+    let v_7 = env.cursor;
+    'lab7: loop {
+        // call postlude, line 188
+        if !r_postlude(env, context) {
+            break 'lab7;
+        }
+        break 'lab7;
+    }
+    env.cursor = v_7;
+    return true;
+}
diff --git a/src/snowball/algorithms/mod.rs b/src/snowball/algorithms/mod.rs
new file mode 100644
index 0000000..19b50c1
--- /dev/null
+++ b/src/snowball/algorithms/mod.rs
@@ -0,0 +1,18 @@
+pub mod arabic;
+pub mod danish;
+pub mod dutch;
+pub mod english;
+pub mod finnish;
+pub mod french;
+pub mod german;
+pub mod greek;
+pub mod hungarian;
+pub mod italian;
+pub mod norwegian;
+pub mod portuguese;
+pub mod romanian;
+pub mod russian;
+pub mod spanish;
+pub mod swedish;
+pub mod tamil;
+pub mod turkish;
diff --git a/src/snowball/algorithms/norwegian.rs b/src/snowball/algorithms/norwegian.rs
new file mode 100644
index 0000000..e56b9b7
--- /dev/null
+++ b/src/snowball/algorithms/norwegian.rs
@@ -0,0 +1,243 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! Snowball 2.0.0 - https://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 29] = &[
+    Among("a", -1, 1, None),
+    Among("e", -1, 1, None),
+    Among("ede", 1, 1, None),
+    Among("ande", 1, 1, None),
+    Among("ende", 1, 1, None),
+    Among("ane", 1, 1, None),
+    Among("ene", 1, 1, None),
+    Among("hetene", 6, 1, None),
+    Among("erte", 1, 3, None),
+    Among("en", -1, 1, None),
+    Among("heten", 9, 1, None),
+    Among("ar", -1, 1, None),
+    Among("er", -1, 1, None),
+    Among("heter", 12, 1, None),
+    Among("s", -1, 2, None),
+    Among("as", 14, 1, None),
+    Among("es", 14, 1, None),
+    Among("edes", 16, 1, None),
+    Among("endes", 16, 1, None),
+    Among("enes", 16, 1, None),
+    Among("hetenes", 19, 1, None),
+    Among("ens", 14, 1, None),
+    Among("hetens", 21, 1, None),
+    Among("ers", 14, 1, None),
+    Among("ets", 14, 1, None),
+    Among("et", -1, 1, None),
+    Among("het", 25, 1, None),
+    Among("ert", -1, 3, None),
+    Among("ast", -1, 1, None),
+];
+
+static A_1: &'static [Among<Context>; 2] = &[
+    Among("dt", -1, -1, None),
+    Among("vt", -1, -1, None),
+];
+
+static A_2: &'static [Among<Context>; 11] = &[
+    Among("leg", -1, 1, None),
+    Among("eleg", 0, 1, None),
+    Among("ig", -1, 1, None),
+    Among("eig", 2, 1, None),
+    Among("lig", 2, 1, None),
+    Among("elig", 4, 1, None),
+    Among("els", -1, 1, None),
+    Among("lov", -1, 1, None),
+    Among("elov", 7, 1, None),
+    Among("slov", 7, 1, None),
+    Among("hetslov", 9, 1, None),
+];
+
+static G_v: &'static [u8; 19] = &[17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128];
+
+static G_s_ending: &'static [u8; 4] = &[119, 125, 149, 1];
+
+#[derive(Clone)]
+struct Context {
+    i_x: usize,
+    i_p1: usize,
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    context.i_p1 = env.limit;
+    let v_1 = env.cursor;
+    let c = env.byte_index_for_hop(3);
+    if 0 as i32 > c || c > env.limit as i32 {
+        return false;
+    }
+    env.cursor = c as usize;
+    context.i_x = env.cursor;
+    env.cursor = v_1;
+    'golab0: loop {
+        let v_2 = env.cursor;
+        'lab1: loop {
+            if !env.in_grouping(G_v, 97, 248) {
+                break 'lab1;
+            }
+            env.cursor = v_2;
+            break 'golab0;
+        }
+        env.cursor = v_2;
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    'golab2: loop {
+        'lab3: loop {
+            if !env.out_grouping(G_v, 97, 248) {
+                break 'lab3;
+            }
+            break 'golab2;
+        }
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    context.i_p1 = env.cursor;
+    'lab4: loop {
+        if !(context.i_p1 < context.i_x){
+            break 'lab4;
+        }
+        context.i_p1 = context.i_x;
+        break 'lab4;
+    }
+    return true;
+}
+
+fn r_main_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    let v_2 = env.limit_backward;
+    env.limit_backward = context.i_p1;
+    env.ket = env.cursor;
+    among_var = env.find_among_b(A_0, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    env.bra = env.cursor;
+    env.limit_backward = v_2;
+    if among_var == 1 {
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        'lab0: loop {
+            let v_3 = env.limit - env.cursor;
+            'lab1: loop {
+                if !env.in_grouping_b(G_s_ending, 98, 122) {
+                    break 'lab1;
+                }
+                break 'lab0;
+            }
+            env.cursor = env.limit - v_3;
+            if !env.eq_s_b(&"k") {
+                return false;
+            }
+            if !env.out_grouping_b(G_v, 97, 248) {
+                return false;
+            }
+            break 'lab0;
+        }
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 3 {
+        if !env.slice_from("er") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_consonant_pair(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let v_1 = env.limit - env.cursor;
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    let v_3 = env.limit_backward;
+    env.limit_backward = context.i_p1;
+    env.ket = env.cursor;
+    if env.find_among_b(A_1, context) == 0 {
+        env.limit_backward = v_3;
+        return false;
+    }
+    env.bra = env.cursor;
+    env.limit_backward = v_3;
+    env.cursor = env.limit - v_1;
+    if env.cursor <= env.limit_backward {
+        return false;
+    }
+    env.previous_char();
+    env.bra = env.cursor;
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+fn r_other_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+
+    let v_2 = env.limit_backward;
+    env.limit_backward = context.i_p1;
+    env.ket = env.cursor;
+
+    if env.find_among_b(A_2, context) == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    env.bra = env.cursor;
+    env.limit_backward = v_2;
+
+    if !env.slice_del() {
+        return false;
+    }
+
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        i_x: 0,
+        i_p1: 0,
+    };
+
+    let v_1 = env.cursor;
+    r_mark_regions(env, context);
+    env.cursor = v_1;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+
+    let v_2 = env.limit - env.cursor;
+    r_main_suffix(env, context);
+    env.cursor = env.limit - v_2;
+
+    let v_3 = env.limit - env.cursor;
+    r_consonant_pair(env, context);
+    env.cursor = env.limit - v_3;
+
+    let v_4 = env.limit - env.cursor;
+    r_other_suffix(env, context);
+    env.cursor = env.limit - v_4;
+    env.cursor = env.limit_backward;
+
+    return true;
+}
diff --git a/src/snowball/algorithms/portuguese.rs b/src/snowball/algorithms/portuguese.rs
new file mode 100644
index 0000000..961bc49
--- /dev/null
+++ b/src/snowball/algorithms/portuguese.rs
@@ -0,0 +1,1045 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 3] = &[
+    Among("", -1, 3, None),
+    Among("\u{00E3}", 0, 1, None),
+    Among("\u{00F5}", 0, 2, None),
+];
+
+static A_1: &'static [Among<Context>; 3] = &[
+    Among("", -1, 3, None),
+    Among("a~", 0, 1, None),
+    Among("o~", 0, 2, None),
+];
+
+static A_2: &'static [Among<Context>; 4] = &[
+    Among("ic", -1, -1, None),
+    Among("ad", -1, -1, None),
+    Among("os", -1, -1, None),
+    Among("iv", -1, 1, None),
+];
+
+static A_3: &'static [Among<Context>; 3] = &[
+    Among("ante", -1, 1, None),
+    Among("avel", -1, 1, None),
+    Among("\u{00ED}vel", -1, 1, None),
+];
+
+static A_4: &'static [Among<Context>; 3] = &[
+    Among("ic", -1, 1, None),
+    Among("abil", -1, 1, None),
+    Among("iv", -1, 1, None),
+];
+
+static A_5: &'static [Among<Context>; 45] = &[
+    Among("ica", -1, 1, None),
+    Among("\u{00E2}ncia", -1, 1, None),
+    Among("\u{00EA}ncia", -1, 4, None),
+    Among("logia", -1, 2, None),
+    Among("ira", -1, 9, None),
+    Among("adora", -1, 1, None),
+    Among("osa", -1, 1, None),
+    Among("ista", -1, 1, None),
+    Among("iva", -1, 8, None),
+    Among("eza", -1, 1, None),
+    Among("idade", -1, 7, None),
+    Among("ante", -1, 1, None),
+    Among("mente", -1, 6, None),
+    Among("amente", 12, 5, None),
+    Among("\u{00E1}vel", -1, 1, None),
+    Among("\u{00ED}vel", -1, 1, None),
+    Among("ico", -1, 1, None),
+    Among("ismo", -1, 1, None),
+    Among("oso", -1, 1, None),
+    Among("amento", -1, 1, None),
+    Among("imento", -1, 1, None),
+    Among("ivo", -1, 8, None),
+    Among("a\u{00E7}a~o", -1, 1, None),
+    Among("u\u{00E7}a~o", -1, 3, None),
+    Among("ador", -1, 1, None),
+    Among("icas", -1, 1, None),
+    Among("\u{00EA}ncias", -1, 4, None),
+    Among("logias", -1, 2, None),
+    Among("iras", -1, 9, None),
+    Among("adoras", -1, 1, None),
+    Among("osas", -1, 1, None),
+    Among("istas", -1, 1, None),
+    Among("ivas", -1, 8, None),
+    Among("ezas", -1, 1, None),
+    Among("idades", -1, 7, None),
+    Among("adores", -1, 1, None),
+    Among("antes", -1, 1, None),
+    Among("a\u{00E7}o~es", -1, 1, None),
+    Among("u\u{00E7}o~es", -1, 3, None),
+    Among("icos", -1, 1, None),
+    Among("ismos", -1, 1, None),
+    Among("osos", -1, 1, None),
+    Among("amentos", -1, 1, None),
+    Among("imentos", -1, 1, None),
+    Among("ivos", -1, 8, None),
+];
+
+static A_6: &'static [Among<Context>; 120] = &[
+    Among("ada", -1, 1, None),
+    Among("ida", -1, 1, None),
+    Among("ia", -1, 1, None),
+    Among("aria", 2, 1, None),
+    Among("eria", 2, 1, None),
+    Among("iria", 2, 1, None),
+    Among("ara", -1, 1, None),
+    Among("era", -1, 1, None),
+    Among("ira", -1, 1, None),
+    Among("ava", -1, 1, None),
+    Among("asse", -1, 1, None),
+    Among("esse", -1, 1, None),
+    Among("isse", -1, 1, None),
+    Among("aste", -1, 1, None),
+    Among("este", -1, 1, None),
+    Among("iste", -1, 1, None),
+    Among("ei", -1, 1, None),
+    Among("arei", 16, 1, None),
+    Among("erei", 16, 1, None),
+    Among("irei", 16, 1, None),
+    Among("am", -1, 1, None),
+    Among("iam", 20, 1, None),
+    Among("ariam", 21, 1, None),
+    Among("eriam", 21, 1, None),
+    Among("iriam", 21, 1, None),
+    Among("aram", 20, 1, None),
+    Among("eram", 20, 1, None),
+    Among("iram", 20, 1, None),
+    Among("avam", 20, 1, None),
+    Among("em", -1, 1, None),
+    Among("arem", 29, 1, None),
+    Among("erem", 29, 1, None),
+    Among("irem", 29, 1, None),
+    Among("assem", 29, 1, None),
+    Among("essem", 29, 1, None),
+    Among("issem", 29, 1, None),
+    Among("ado", -1, 1, None),
+    Among("ido", -1, 1, None),
+    Among("ando", -1, 1, None),
+    Among("endo", -1, 1, None),
+    Among("indo", -1, 1, None),
+    Among("ara~o", -1, 1, None),
+    Among("era~o", -1, 1, None),
+    Among("ira~o", -1, 1, None),
+    Among("ar", -1, 1, None),
+    Among("er", -1, 1, None),
+    Among("ir", -1, 1, None),
+    Among("as", -1, 1, None),
+    Among("adas", 47, 1, None),
+    Among("idas", 47, 1, None),
+    Among("ias", 47, 1, None),
+    Among("arias", 50, 1, None),
+    Among("erias", 50, 1, None),
+    Among("irias", 50, 1, None),
+    Among("aras", 47, 1, None),
+    Among("eras", 47, 1, None),
+    Among("iras", 47, 1, None),
+    Among("avas", 47, 1, None),
+    Among("es", -1, 1, None),
+    Among("ardes", 58, 1, None),
+    Among("erdes", 58, 1, None),
+    Among("irdes", 58, 1, None),
+    Among("ares", 58, 1, None),
+    Among("eres", 58, 1, None),
+    Among("ires", 58, 1, None),
+    Among("asses", 58, 1, None),
+    Among("esses", 58, 1, None),
+    Among("isses", 58, 1, None),
+    Among("astes", 58, 1, None),
+    Among("estes", 58, 1, None),
+    Among("istes", 58, 1, None),
+    Among("is", -1, 1, None),
+    Among("ais", 71, 1, None),
+    Among("eis", 71, 1, None),
+    Among("areis", 73, 1, None),
+    Among("ereis", 73, 1, None),
+    Among("ireis", 73, 1, None),
+    Among("\u{00E1}reis", 73, 1, None),
+    Among("\u{00E9}reis", 73, 1, None),
+    Among("\u{00ED}reis", 73, 1, None),
+    Among("\u{00E1}sseis", 73, 1, None),
+    Among("\u{00E9}sseis", 73, 1, None),
+    Among("\u{00ED}sseis", 73, 1, None),
+    Among("\u{00E1}veis", 73, 1, None),
+    Among("\u{00ED}eis", 73, 1, None),
+    Among("ar\u{00ED}eis", 84, 1, None),
+    Among("er\u{00ED}eis", 84, 1, None),
+    Among("ir\u{00ED}eis", 84, 1, None),
+    Among("ados", -1, 1, None),
+    Among("idos", -1, 1, None),
+    Among("amos", -1, 1, None),
+    Among("\u{00E1}ramos", 90, 1, None),
+    Among("\u{00E9}ramos", 90, 1, None),
+    Among("\u{00ED}ramos", 90, 1, None),
+    Among("\u{00E1}vamos", 90, 1, None),
+    Among("\u{00ED}amos", 90, 1, None),
+    Among("ar\u{00ED}amos", 95, 1, None),
+    Among("er\u{00ED}amos", 95, 1, None),
+    Among("ir\u{00ED}amos", 95, 1, None),
+    Among("emos", -1, 1, None),
+    Among("aremos", 99, 1, None),
+    Among("eremos", 99, 1, None),
+    Among("iremos", 99, 1, None),
+    Among("\u{00E1}ssemos", 99, 1, None),
+    Among("\u{00EA}ssemos", 99, 1, None),
+    Among("\u{00ED}ssemos", 99, 1, None),
+    Among("imos", -1, 1, None),
+    Among("armos", -1, 1, None),
+    Among("ermos", -1, 1, None),
+    Among("irmos", -1, 1, None),
+    Among("\u{00E1}mos", -1, 1, None),
+    Among("ar\u{00E1}s", -1, 1, None),
+    Among("er\u{00E1}s", -1, 1, None),
+    Among("ir\u{00E1}s", -1, 1, None),
+    Among("eu", -1, 1, None),
+    Among("iu", -1, 1, None),
+    Among("ou", -1, 1, None),
+    Among("ar\u{00E1}", -1, 1, None),
+    Among("er\u{00E1}", -1, 1, None),
+    Among("ir\u{00E1}", -1, 1, None),
+];
+
+static A_7: &'static [Among<Context>; 7] = &[
+    Among("a", -1, 1, None),
+    Among("i", -1, 1, None),
+    Among("o", -1, 1, None),
+    Among("os", -1, 1, None),
+    Among("\u{00E1}", -1, 1, None),
+    Among("\u{00ED}", -1, 1, None),
+    Among("\u{00F3}", -1, 1, None),
+];
+
+static A_8: &'static [Among<Context>; 4] = &[
+    Among("e", -1, 1, None),
+    Among("\u{00E7}", -1, 2, None),
+    Among("\u{00E9}", -1, 1, None),
+    Among("\u{00EA}", -1, 1, None),
+];
+
+static G_v: &'static [u8; 20] = &[17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 19, 12, 2];
+
+#[derive(Clone)]
+struct Context {
+    i_p2: usize,
+    i_p1: usize,
+    i_pV: usize,
+}
+
+fn r_prelude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // repeat, line 36
+    'replab0: loop{
+        let v_1 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 36
+            // [, line 37
+            env.bra = env.cursor;
+            // substring, line 37
+            among_var = env.find_among(A_0, context);
+            if among_var == 0 {
+                break 'lab1;
+            }
+            // ], line 37
+            env.ket = env.cursor;
+            if among_var == 0 {
+                break 'lab1;
+            } else if among_var == 1 {
+                // (, line 38
+                // <-, line 38
+                if !env.slice_from("a~") {
+                    return false;
+                }
+            } else if among_var == 2 {
+                // (, line 39
+                // <-, line 39
+                if !env.slice_from("o~") {
+                    return false;
+                }
+            } else if among_var == 3 {
+                // (, line 40
+                // next, line 40
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 44
+    context.i_pV = env.limit;
+    context.i_p1 = env.limit;
+    context.i_p2 = env.limit;
+    // do, line 50
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // (, line 50
+        // or, line 52
+        'lab1: loop {
+            let v_2 = env.cursor;
+            'lab2: loop {
+                // (, line 51
+                if !env.in_grouping(G_v, 97, 250) {
+                    break 'lab2;
+                }
+                // or, line 51
+                'lab3: loop {
+                    let v_3 = env.cursor;
+                    'lab4: loop {
+                        // (, line 51
+                        if !env.out_grouping(G_v, 97, 250) {
+                            break 'lab4;
+                        }
+                        // gopast, line 51
+                        'golab5: loop {
+                            'lab6: loop {
+                                if !env.in_grouping(G_v, 97, 250) {
+                                    break 'lab6;
+                                }
+                                break 'golab5;
+                            }
+                            if env.cursor >= env.limit {
+                                break 'lab4;
+                            }
+                            env.next_char();
+                        }
+                        break 'lab3;
+                    }
+                    env.cursor = v_3;
+                    // (, line 51
+                    if !env.in_grouping(G_v, 97, 250) {
+                        break 'lab2;
+                    }
+                    // gopast, line 51
+                    'golab7: loop {
+                        'lab8: loop {
+                            if !env.out_grouping(G_v, 97, 250) {
+                                break 'lab8;
+                            }
+                            break 'golab7;
+                        }
+                        if env.cursor >= env.limit {
+                            break 'lab2;
+                        }
+                        env.next_char();
+                    }
+                    break 'lab3;
+                }
+                break 'lab1;
+            }
+            env.cursor = v_2;
+            // (, line 53
+            if !env.out_grouping(G_v, 97, 250) {
+                break 'lab0;
+            }
+            // or, line 53
+            'lab9: loop {
+                let v_6 = env.cursor;
+                'lab10: loop {
+                    // (, line 53
+                    if !env.out_grouping(G_v, 97, 250) {
+                        break 'lab10;
+                    }
+                    // gopast, line 53
+                    'golab11: loop {
+                        'lab12: loop {
+                            if !env.in_grouping(G_v, 97, 250) {
+                                break 'lab12;
+                            }
+                            break 'golab11;
+                        }
+                        if env.cursor >= env.limit {
+                            break 'lab10;
+                        }
+                        env.next_char();
+                    }
+                    break 'lab9;
+                }
+                env.cursor = v_6;
+                // (, line 53
+                if !env.in_grouping(G_v, 97, 250) {
+                    break 'lab0;
+                }
+                // next, line 53
+                if env.cursor >= env.limit {
+                    break 'lab0;
+                }
+                env.next_char();
+                break 'lab9;
+            }
+            break 'lab1;
+        }
+        // setmark pV, line 54
+        context.i_pV = env.cursor;
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 56
+    let v_8 = env.cursor;
+    'lab13: loop {
+        // (, line 56
+        // gopast, line 57
+        'golab14: loop {
+            'lab15: loop {
+                if !env.in_grouping(G_v, 97, 250) {
+                    break 'lab15;
+                }
+                break 'golab14;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // gopast, line 57
+        'golab16: loop {
+            'lab17: loop {
+                if !env.out_grouping(G_v, 97, 250) {
+                    break 'lab17;
+                }
+                break 'golab16;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // setmark p1, line 57
+        context.i_p1 = env.cursor;
+        // gopast, line 58
+        'golab18: loop {
+            'lab19: loop {
+                if !env.in_grouping(G_v, 97, 250) {
+                    break 'lab19;
+                }
+                break 'golab18;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // gopast, line 58
+        'golab20: loop {
+            'lab21: loop {
+                if !env.out_grouping(G_v, 97, 250) {
+                    break 'lab21;
+                }
+                break 'golab20;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // setmark p2, line 58
+        context.i_p2 = env.cursor;
+        break 'lab13;
+    }
+    env.cursor = v_8;
+    return true;
+}
+
+fn r_postlude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // repeat, line 62
+    'replab0: loop{
+        let v_1 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 62
+            // [, line 63
+            env.bra = env.cursor;
+            // substring, line 63
+            among_var = env.find_among(A_1, context);
+            if among_var == 0 {
+                break 'lab1;
+            }
+            // ], line 63
+            env.ket = env.cursor;
+            if among_var == 0 {
+                break 'lab1;
+            } else if among_var == 1 {
+                // (, line 64
+                // <-, line 64
+                if !env.slice_from("\u{00E3}") {
+                    return false;
+                }
+            } else if among_var == 2 {
+                // (, line 65
+                // <-, line 65
+                if !env.slice_from("\u{00F5}") {
+                    return false;
+                }
+            } else if among_var == 3 {
+                // (, line 66
+                // next, line 66
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+fn r_RV(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_pV <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_R1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p1 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_R2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p2 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_standard_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 76
+    // [, line 77
+    env.ket = env.cursor;
+    // substring, line 77
+    among_var = env.find_among_b(A_5, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 77
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 92
+        // call R2, line 93
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 93
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 97
+        // call R2, line 98
+        if !r_R2(env, context) {
+            return false;
+        }
+        // <-, line 98
+        if !env.slice_from("log") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 101
+        // call R2, line 102
+        if !r_R2(env, context) {
+            return false;
+        }
+        // <-, line 102
+        if !env.slice_from("u") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 105
+        // call R2, line 106
+        if !r_R2(env, context) {
+            return false;
+        }
+        // <-, line 106
+        if !env.slice_from("ente") {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 109
+        // call R1, line 110
+        if !r_R1(env, context) {
+            return false;
+        }
+        // delete, line 110
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 111
+        let v_1 = env.limit - env.cursor;
+        'lab0: loop {
+            // (, line 111
+            // [, line 112
+            env.ket = env.cursor;
+            // substring, line 112
+            among_var = env.find_among_b(A_2, context);
+            if among_var == 0 {
+                env.cursor = env.limit - v_1;
+                break 'lab0;
+            }
+            // ], line 112
+            env.bra = env.cursor;
+            // call R2, line 112
+            if !r_R2(env, context) {
+                env.cursor = env.limit - v_1;
+                break 'lab0;
+            }
+            // delete, line 112
+            if !env.slice_del() {
+                return false;
+            }
+            if among_var == 0 {
+                env.cursor = env.limit - v_1;
+                break 'lab0;
+            } else if among_var == 1 {
+                // (, line 113
+                // [, line 113
+                env.ket = env.cursor;
+                // literal, line 113
+                if !env.eq_s_b(&"at") {
+                    env.cursor = env.limit - v_1;
+                    break 'lab0;
+                }
+                // ], line 113
+                env.bra = env.cursor;
+                // call R2, line 113
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_1;
+                    break 'lab0;
+                }
+                // delete, line 113
+                if !env.slice_del() {
+                    return false;
+                }
+            }
+            break 'lab0;
+        }
+    } else if among_var == 6 {
+        // (, line 121
+        // call R2, line 122
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 122
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 123
+        let v_2 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 123
+            // [, line 124
+            env.ket = env.cursor;
+            // substring, line 124
+            among_var = env.find_among_b(A_3, context);
+            if among_var == 0 {
+                env.cursor = env.limit - v_2;
+                break 'lab1;
+            }
+            // ], line 124
+            env.bra = env.cursor;
+            if among_var == 0 {
+                env.cursor = env.limit - v_2;
+                break 'lab1;
+            } else if among_var == 1 {
+                // (, line 127
+                // call R2, line 127
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_2;
+                    break 'lab1;
+                }
+                // delete, line 127
+                if !env.slice_del() {
+                    return false;
+                }
+            }
+            break 'lab1;
+        }
+    } else if among_var == 7 {
+        // (, line 133
+        // call R2, line 134
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 134
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 135
+        let v_3 = env.limit - env.cursor;
+        'lab2: loop {
+            // (, line 135
+            // [, line 136
+            env.ket = env.cursor;
+            // substring, line 136
+            among_var = env.find_among_b(A_4, context);
+            if among_var == 0 {
+                env.cursor = env.limit - v_3;
+                break 'lab2;
+            }
+            // ], line 136
+            env.bra = env.cursor;
+            if among_var == 0 {
+                env.cursor = env.limit - v_3;
+                break 'lab2;
+            } else if among_var == 1 {
+                // (, line 139
+                // call R2, line 139
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_3;
+                    break 'lab2;
+                }
+                // delete, line 139
+                if !env.slice_del() {
+                    return false;
+                }
+            }
+            break 'lab2;
+        }
+    } else if among_var == 8 {
+        // (, line 145
+        // call R2, line 146
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 146
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 147
+        let v_4 = env.limit - env.cursor;
+        'lab3: loop {
+            // (, line 147
+            // [, line 148
+            env.ket = env.cursor;
+            // literal, line 148
+            if !env.eq_s_b(&"at") {
+                env.cursor = env.limit - v_4;
+                break 'lab3;
+            }
+            // ], line 148
+            env.bra = env.cursor;
+            // call R2, line 148
+            if !r_R2(env, context) {
+                env.cursor = env.limit - v_4;
+                break 'lab3;
+            }
+            // delete, line 148
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab3;
+        }
+    } else if among_var == 9 {
+        // (, line 152
+        // call RV, line 153
+        if !r_RV(env, context) {
+            return false;
+        }
+        // literal, line 153
+        if !env.eq_s_b(&"e") {
+            return false;
+        }
+        // <-, line 154
+        if !env.slice_from("ir") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_verb_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // setlimit, line 159
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 159
+    if env.cursor < context.i_pV {
+        return false;
+    }
+    env.cursor = context.i_pV;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 159
+    // [, line 160
+    env.ket = env.cursor;
+    // substring, line 160
+    among_var = env.find_among_b(A_6, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 160
+    env.bra = env.cursor;
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    } else if among_var == 1 {
+        // (, line 179
+        // delete, line 179
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    env.limit_backward = v_2;
+    return true;
+}
+
+fn r_residual_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 183
+    // [, line 184
+    env.ket = env.cursor;
+    // substring, line 184
+    among_var = env.find_among_b(A_7, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 184
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 187
+        // call RV, line 187
+        if !r_RV(env, context) {
+            return false;
+        }
+        // delete, line 187
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_residual_form(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 191
+    // [, line 192
+    env.ket = env.cursor;
+    // substring, line 192
+    among_var = env.find_among_b(A_8, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 192
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 194
+        // call RV, line 194
+        if !r_RV(env, context) {
+            return false;
+        }
+        // delete, line 194
+        if !env.slice_del() {
+            return false;
+        }
+        // [, line 194
+        env.ket = env.cursor;
+        // or, line 194
+        'lab0: loop {
+            let v_1 = env.limit - env.cursor;
+            'lab1: loop {
+                // (, line 194
+                // literal, line 194
+                if !env.eq_s_b(&"u") {
+                    break 'lab1;
+                }
+                // ], line 194
+                env.bra = env.cursor;
+                // test, line 194
+                let v_2 = env.limit - env.cursor;
+                // literal, line 194
+                if !env.eq_s_b(&"g") {
+                    break 'lab1;
+                }
+                env.cursor = env.limit - v_2;
+                break 'lab0;
+            }
+            env.cursor = env.limit - v_1;
+            // (, line 195
+            // literal, line 195
+            if !env.eq_s_b(&"i") {
+                return false;
+            }
+            // ], line 195
+            env.bra = env.cursor;
+            // test, line 195
+            let v_3 = env.limit - env.cursor;
+            // literal, line 195
+            if !env.eq_s_b(&"c") {
+                return false;
+            }
+            env.cursor = env.limit - v_3;
+            break 'lab0;
+        }
+        // call RV, line 195
+        if !r_RV(env, context) {
+            return false;
+        }
+        // delete, line 195
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 196
+        // <-, line 196
+        if !env.slice_from("c") {
+            return false;
+        }
+    }
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        i_p2: 0,
+        i_p1: 0,
+        i_pV: 0,
+    };
+    // (, line 201
+    // do, line 202
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call prelude, line 202
+        if !r_prelude(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 203
+    let v_2 = env.cursor;
+    'lab1: loop {
+        // call mark_regions, line 203
+        if !r_mark_regions(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = v_2;
+    // backwards, line 204
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 204
+    // do, line 205
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // (, line 205
+        // or, line 209
+        'lab3: loop {
+            let v_4 = env.limit - env.cursor;
+            'lab4: loop {
+                // (, line 206
+                // and, line 207
+                let v_5 = env.limit - env.cursor;
+                // (, line 206
+                // or, line 206
+                'lab5: loop {
+                    let v_6 = env.limit - env.cursor;
+                    'lab6: loop {
+                        // call standard_suffix, line 206
+                        if !r_standard_suffix(env, context) {
+                            break 'lab6;
+                        }
+                        break 'lab5;
+                    }
+                    env.cursor = env.limit - v_6;
+                    // call verb_suffix, line 206
+                    if !r_verb_suffix(env, context) {
+                        break 'lab4;
+                    }
+                    break 'lab5;
+                }
+                env.cursor = env.limit - v_5;
+                // do, line 207
+                let v_7 = env.limit - env.cursor;
+                'lab7: loop {
+                    // (, line 207
+                    // [, line 207
+                    env.ket = env.cursor;
+                    // literal, line 207
+                    if !env.eq_s_b(&"i") {
+                        break 'lab7;
+                    }
+                    // ], line 207
+                    env.bra = env.cursor;
+                    // test, line 207
+                    let v_8 = env.limit - env.cursor;
+                    // literal, line 207
+                    if !env.eq_s_b(&"c") {
+                        break 'lab7;
+                    }
+                    env.cursor = env.limit - v_8;
+                    // call RV, line 207
+                    if !r_RV(env, context) {
+                        break 'lab7;
+                    }
+                    // delete, line 207
+                    if !env.slice_del() {
+                        return false;
+                    }
+                    break 'lab7;
+                }
+                env.cursor = env.limit - v_7;
+                break 'lab3;
+            }
+            env.cursor = env.limit - v_4;
+            // call residual_suffix, line 209
+            if !r_residual_suffix(env, context) {
+                break 'lab2;
+            }
+            break 'lab3;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    // do, line 211
+    let v_9 = env.limit - env.cursor;
+    'lab8: loop {
+        // call residual_form, line 211
+        if !r_residual_form(env, context) {
+            break 'lab8;
+        }
+        break 'lab8;
+    }
+    env.cursor = env.limit - v_9;
+    env.cursor = env.limit_backward;
+    // do, line 213
+    let v_10 = env.cursor;
+    'lab9: loop {
+        // call postlude, line 213
+        if !r_postlude(env, context) {
+            break 'lab9;
+        }
+        break 'lab9;
+    }
+    env.cursor = v_10;
+    return true;
+}
diff --git a/src/snowball/algorithms/romanian.rs b/src/snowball/algorithms/romanian.rs
new file mode 100644
index 0000000..db4dc04
--- /dev/null
+++ b/src/snowball/algorithms/romanian.rs
@@ -0,0 +1,965 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 3] = &[
+    Among("", -1, 3, None),
+    Among("I", 0, 1, None),
+    Among("U", 0, 2, None),
+];
+
+static A_1: &'static [Among<Context>; 16] = &[
+    Among("ea", -1, 3, None),
+    Among("a\u{0163}ia", -1, 7, None),
+    Among("aua", -1, 2, None),
+    Among("iua", -1, 4, None),
+    Among("a\u{0163}ie", -1, 7, None),
+    Among("ele", -1, 3, None),
+    Among("ile", -1, 5, None),
+    Among("iile", 6, 4, None),
+    Among("iei", -1, 4, None),
+    Among("atei", -1, 6, None),
+    Among("ii", -1, 4, None),
+    Among("ului", -1, 1, None),
+    Among("ul", -1, 1, None),
+    Among("elor", -1, 3, None),
+    Among("ilor", -1, 4, None),
+    Among("iilor", 14, 4, None),
+];
+
+static A_2: &'static [Among<Context>; 46] = &[
+    Among("icala", -1, 4, None),
+    Among("iciva", -1, 4, None),
+    Among("ativa", -1, 5, None),
+    Among("itiva", -1, 6, None),
+    Among("icale", -1, 4, None),
+    Among("a\u{0163}iune", -1, 5, None),
+    Among("i\u{0163}iune", -1, 6, None),
+    Among("atoare", -1, 5, None),
+    Among("itoare", -1, 6, None),
+    Among("\u{0103}toare", -1, 5, None),
+    Among("icitate", -1, 4, None),
+    Among("abilitate", -1, 1, None),
+    Among("ibilitate", -1, 2, None),
+    Among("ivitate", -1, 3, None),
+    Among("icive", -1, 4, None),
+    Among("ative", -1, 5, None),
+    Among("itive", -1, 6, None),
+    Among("icali", -1, 4, None),
+    Among("atori", -1, 5, None),
+    Among("icatori", 18, 4, None),
+    Among("itori", -1, 6, None),
+    Among("\u{0103}tori", -1, 5, None),
+    Among("icitati", -1, 4, None),
+    Among("abilitati", -1, 1, None),
+    Among("ivitati", -1, 3, None),
+    Among("icivi", -1, 4, None),
+    Among("ativi", -1, 5, None),
+    Among("itivi", -1, 6, None),
+    Among("icit\u{0103}i", -1, 4, None),
+    Among("abilit\u{0103}i", -1, 1, None),
+    Among("ivit\u{0103}i", -1, 3, None),
+    Among("icit\u{0103}\u{0163}i", -1, 4, None),
+    Among("abilit\u{0103}\u{0163}i", -1, 1, None),
+    Among("ivit\u{0103}\u{0163}i", -1, 3, None),
+    Among("ical", -1, 4, None),
+    Among("ator", -1, 5, None),
+    Among("icator", 35, 4, None),
+    Among("itor", -1, 6, None),
+    Among("\u{0103}tor", -1, 5, None),
+    Among("iciv", -1, 4, None),
+    Among("ativ", -1, 5, None),
+    Among("itiv", -1, 6, None),
+    Among("ical\u{0103}", -1, 4, None),
+    Among("iciv\u{0103}", -1, 4, None),
+    Among("ativ\u{0103}", -1, 5, None),
+    Among("itiv\u{0103}", -1, 6, None),
+];
+
+static A_3: &'static [Among<Context>; 62] = &[
+    Among("ica", -1, 1, None),
+    Among("abila", -1, 1, None),
+    Among("ibila", -1, 1, None),
+    Among("oasa", -1, 1, None),
+    Among("ata", -1, 1, None),
+    Among("ita", -1, 1, None),
+    Among("anta", -1, 1, None),
+    Among("ista", -1, 3, None),
+    Among("uta", -1, 1, None),
+    Among("iva", -1, 1, None),
+    Among("ic", -1, 1, None),
+    Among("ice", -1, 1, None),
+    Among("abile", -1, 1, None),
+    Among("ibile", -1, 1, None),
+    Among("isme", -1, 3, None),
+    Among("iune", -1, 2, None),
+    Among("oase", -1, 1, None),
+    Among("ate", -1, 1, None),
+    Among("itate", 17, 1, None),
+    Among("ite", -1, 1, None),
+    Among("ante", -1, 1, None),
+    Among("iste", -1, 3, None),
+    Among("ute", -1, 1, None),
+    Among("ive", -1, 1, None),
+    Among("ici", -1, 1, None),
+    Among("abili", -1, 1, None),
+    Among("ibili", -1, 1, None),
+    Among("iuni", -1, 2, None),
+    Among("atori", -1, 1, None),
+    Among("osi", -1, 1, None),
+    Among("ati", -1, 1, None),
+    Among("itati", 30, 1, None),
+    Among("iti", -1, 1, None),
+    Among("anti", -1, 1, None),
+    Among("isti", -1, 3, None),
+    Among("uti", -1, 1, None),
+    Among("i\u{015F}ti", -1, 3, None),
+    Among("ivi", -1, 1, None),
+    Among("it\u{0103}i", -1, 1, None),
+    Among("o\u{015F}i", -1, 1, None),
+    Among("it\u{0103}\u{0163}i", -1, 1, None),
+    Among("abil", -1, 1, None),
+    Among("ibil", -1, 1, None),
+    Among("ism", -1, 3, None),
+    Among("ator", -1, 1, None),
+    Among("os", -1, 1, None),
+    Among("at", -1, 1, None),
+    Among("it", -1, 1, None),
+    Among("ant", -1, 1, None),
+    Among("ist", -1, 3, None),
+    Among("ut", -1, 1, None),
+    Among("iv", -1, 1, None),
+    Among("ic\u{0103}", -1, 1, None),
+    Among("abil\u{0103}", -1, 1, None),
+    Among("ibil\u{0103}", -1, 1, None),
+    Among("oas\u{0103}", -1, 1, None),
+    Among("at\u{0103}", -1, 1, None),
+    Among("it\u{0103}", -1, 1, None),
+    Among("ant\u{0103}", -1, 1, None),
+    Among("ist\u{0103}", -1, 3, None),
+    Among("ut\u{0103}", -1, 1, None),
+    Among("iv\u{0103}", -1, 1, None),
+];
+
+static A_4: &'static [Among<Context>; 94] = &[
+    Among("ea", -1, 1, None),
+    Among("ia", -1, 1, None),
+    Among("esc", -1, 1, None),
+    Among("\u{0103}sc", -1, 1, None),
+    Among("ind", -1, 1, None),
+    Among("\u{00E2}nd", -1, 1, None),
+    Among("are", -1, 1, None),
+    Among("ere", -1, 1, None),
+    Among("ire", -1, 1, None),
+    Among("\u{00E2}re", -1, 1, None),
+    Among("se", -1, 2, None),
+    Among("ase", 10, 1, None),
+    Among("sese", 10, 2, None),
+    Among("ise", 10, 1, None),
+    Among("use", 10, 1, None),
+    Among("\u{00E2}se", 10, 1, None),
+    Among("e\u{015F}te", -1, 1, None),
+    Among("\u{0103}\u{015F}te", -1, 1, None),
+    Among("eze", -1, 1, None),
+    Among("ai", -1, 1, None),
+    Among("eai", 19, 1, None),
+    Among("iai", 19, 1, None),
+    Among("sei", -1, 2, None),
+    Among("e\u{015F}ti", -1, 1, None),
+    Among("\u{0103}\u{015F}ti", -1, 1, None),
+    Among("ui", -1, 1, None),
+    Among("ezi", -1, 1, None),
+    Among("a\u{015F}i", -1, 1, None),
+    Among("se\u{015F}i", -1, 2, None),
+    Among("ase\u{015F}i", 28, 1, None),
+    Among("sese\u{015F}i", 28, 2, None),
+    Among("ise\u{015F}i", 28, 1, None),
+    Among("use\u{015F}i", 28, 1, None),
+    Among("\u{00E2}se\u{015F}i", 28, 1, None),
+    Among("i\u{015F}i", -1, 1, None),
+    Among("u\u{015F}i", -1, 1, None),
+    Among("\u{00E2}\u{015F}i", -1, 1, None),
+    Among("\u{00E2}i", -1, 1, None),
+    Among("a\u{0163}i", -1, 2, None),
+    Among("ea\u{0163}i", 38, 1, None),
+    Among("ia\u{0163}i", 38, 1, None),
+    Among("e\u{0163}i", -1, 2, None),
+    Among("i\u{0163}i", -1, 2, None),
+    Among("ar\u{0103}\u{0163}i", -1, 1, None),
+    Among("ser\u{0103}\u{0163}i", -1, 2, None),
+    Among("aser\u{0103}\u{0163}i", 44, 1, None),
+    Among("seser\u{0103}\u{0163}i", 44, 2, None),
+    Among("iser\u{0103}\u{0163}i", 44, 1, None),
+    Among("user\u{0103}\u{0163}i", 44, 1, None),
+    Among("\u{00E2}ser\u{0103}\u{0163}i", 44, 1, None),
+    Among("ir\u{0103}\u{0163}i", -1, 1, None),
+    Among("ur\u{0103}\u{0163}i", -1, 1, None),
+    Among("\u{00E2}r\u{0103}\u{0163}i", -1, 1, None),
+    Among("\u{00E2}\u{0163}i", -1, 2, None),
+    Among("am", -1, 1, None),
+    Among("eam", 54, 1, None),
+    Among("iam", 54, 1, None),
+    Among("em", -1, 2, None),
+    Among("asem", 57, 1, None),
+    Among("sesem", 57, 2, None),
+    Among("isem", 57, 1, None),
+    Among("usem", 57, 1, None),
+    Among("\u{00E2}sem", 57, 1, None),
+    Among("im", -1, 2, None),
+    Among("\u{0103}m", -1, 2, None),
+    Among("ar\u{0103}m", 64, 1, None),
+    Among("ser\u{0103}m", 64, 2, None),
+    Among("aser\u{0103}m", 66, 1, None),
+    Among("seser\u{0103}m", 66, 2, None),
+    Among("iser\u{0103}m", 66, 1, None),
+    Among("user\u{0103}m", 66, 1, None),
+    Among("\u{00E2}ser\u{0103}m", 66, 1, None),
+    Among("ir\u{0103}m", 64, 1, None),
+    Among("ur\u{0103}m", 64, 1, None),
+    Among("\u{00E2}r\u{0103}m", 64, 1, None),
+    Among("\u{00E2}m", -1, 2, None),
+    Among("au", -1, 1, None),
+    Among("eau", 76, 1, None),
+    Among("iau", 76, 1, None),
+    Among("indu", -1, 1, None),
+    Among("\u{00E2}ndu", -1, 1, None),
+    Among("ez", -1, 1, None),
+    Among("easc\u{0103}", -1, 1, None),
+    Among("ar\u{0103}", -1, 1, None),
+    Among("ser\u{0103}", -1, 2, None),
+    Among("aser\u{0103}", 84, 1, None),
+    Among("seser\u{0103}", 84, 2, None),
+    Among("iser\u{0103}", 84, 1, None),
+    Among("user\u{0103}", 84, 1, None),
+    Among("\u{00E2}ser\u{0103}", 84, 1, None),
+    Among("ir\u{0103}", -1, 1, None),
+    Among("ur\u{0103}", -1, 1, None),
+    Among("\u{00E2}r\u{0103}", -1, 1, None),
+    Among("eaz\u{0103}", -1, 1, None),
+];
+
+static A_5: &'static [Among<Context>; 5] = &[
+    Among("a", -1, 1, None),
+    Among("e", -1, 1, None),
+    Among("ie", 1, 1, None),
+    Among("i", -1, 1, None),
+    Among("\u{0103}", -1, 1, None),
+];
+
+static G_v: &'static [u8; 21] = &[17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0, 4];
+
+#[derive(Clone)]
+struct Context {
+    b_standard_suffix_removed: bool,
+    i_p2: usize,
+    i_p1: usize,
+    i_pV: usize,
+}
+
+fn r_prelude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 30
+    // repeat, line 31
+    'replab0: loop{
+        let v_1 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // goto, line 31
+            'golab2: loop {
+                let v_2 = env.cursor;
+                'lab3: loop {
+                    // (, line 31
+                    if !env.in_grouping(G_v, 97, 259) {
+                        break 'lab3;
+                    }
+                    // [, line 32
+                    env.bra = env.cursor;
+                    // or, line 32
+                    'lab4: loop {
+                        let v_3 = env.cursor;
+                        'lab5: loop {
+                            // (, line 32
+                            // literal, line 32
+                            if !env.eq_s(&"u") {
+                                break 'lab5;
+                            }
+                            // ], line 32
+                            env.ket = env.cursor;
+                            if !env.in_grouping(G_v, 97, 259) {
+                                break 'lab5;
+                            }
+                            // <-, line 32
+                            if !env.slice_from("U") {
+                                return false;
+                            }
+                            break 'lab4;
+                        }
+                        env.cursor = v_3;
+                        // (, line 33
+                        // literal, line 33
+                        if !env.eq_s(&"i") {
+                            break 'lab3;
+                        }
+                        // ], line 33
+                        env.ket = env.cursor;
+                        if !env.in_grouping(G_v, 97, 259) {
+                            break 'lab3;
+                        }
+                        // <-, line 33
+                        if !env.slice_from("I") {
+                            return false;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = v_2;
+                    break 'golab2;
+                }
+                env.cursor = v_2;
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 37
+    context.i_pV = env.limit;
+    context.i_p1 = env.limit;
+    context.i_p2 = env.limit;
+    // do, line 43
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // (, line 43
+        // or, line 45
+        'lab1: loop {
+            let v_2 = env.cursor;
+            'lab2: loop {
+                // (, line 44
+                if !env.in_grouping(G_v, 97, 259) {
+                    break 'lab2;
+                }
+                // or, line 44
+                'lab3: loop {
+                    let v_3 = env.cursor;
+                    'lab4: loop {
+                        // (, line 44
+                        if !env.out_grouping(G_v, 97, 259) {
+                            break 'lab4;
+                        }
+                        // gopast, line 44
+                        'golab5: loop {
+                            'lab6: loop {
+                                if !env.in_grouping(G_v, 97, 259) {
+                                    break 'lab6;
+                                }
+                                break 'golab5;
+                            }
+                            if env.cursor >= env.limit {
+                                break 'lab4;
+                            }
+                            env.next_char();
+                        }
+                        break 'lab3;
+                    }
+                    env.cursor = v_3;
+                    // (, line 44
+                    if !env.in_grouping(G_v, 97, 259) {
+                        break 'lab2;
+                    }
+                    // gopast, line 44
+                    'golab7: loop {
+                        'lab8: loop {
+                            if !env.out_grouping(G_v, 97, 259) {
+                                break 'lab8;
+                            }
+                            break 'golab7;
+                        }
+                        if env.cursor >= env.limit {
+                            break 'lab2;
+                        }
+                        env.next_char();
+                    }
+                    break 'lab3;
+                }
+                break 'lab1;
+            }
+            env.cursor = v_2;
+            // (, line 46
+            if !env.out_grouping(G_v, 97, 259) {
+                break 'lab0;
+            }
+            // or, line 46
+            'lab9: loop {
+                let v_6 = env.cursor;
+                'lab10: loop {
+                    // (, line 46
+                    if !env.out_grouping(G_v, 97, 259) {
+                        break 'lab10;
+                    }
+                    // gopast, line 46
+                    'golab11: loop {
+                        'lab12: loop {
+                            if !env.in_grouping(G_v, 97, 259) {
+                                break 'lab12;
+                            }
+                            break 'golab11;
+                        }
+                        if env.cursor >= env.limit {
+                            break 'lab10;
+                        }
+                        env.next_char();
+                    }
+                    break 'lab9;
+                }
+                env.cursor = v_6;
+                // (, line 46
+                if !env.in_grouping(G_v, 97, 259) {
+                    break 'lab0;
+                }
+                // next, line 46
+                if env.cursor >= env.limit {
+                    break 'lab0;
+                }
+                env.next_char();
+                break 'lab9;
+            }
+            break 'lab1;
+        }
+        // setmark pV, line 47
+        context.i_pV = env.cursor;
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 49
+    let v_8 = env.cursor;
+    'lab13: loop {
+        // (, line 49
+        // gopast, line 50
+        'golab14: loop {
+            'lab15: loop {
+                if !env.in_grouping(G_v, 97, 259) {
+                    break 'lab15;
+                }
+                break 'golab14;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // gopast, line 50
+        'golab16: loop {
+            'lab17: loop {
+                if !env.out_grouping(G_v, 97, 259) {
+                    break 'lab17;
+                }
+                break 'golab16;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // setmark p1, line 50
+        context.i_p1 = env.cursor;
+        // gopast, line 51
+        'golab18: loop {
+            'lab19: loop {
+                if !env.in_grouping(G_v, 97, 259) {
+                    break 'lab19;
+                }
+                break 'golab18;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // gopast, line 51
+        'golab20: loop {
+            'lab21: loop {
+                if !env.out_grouping(G_v, 97, 259) {
+                    break 'lab21;
+                }
+                break 'golab20;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // setmark p2, line 51
+        context.i_p2 = env.cursor;
+        break 'lab13;
+    }
+    env.cursor = v_8;
+    return true;
+}
+
+fn r_postlude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // repeat, line 55
+    'replab0: loop{
+        let v_1 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 55
+            // [, line 57
+            env.bra = env.cursor;
+            // substring, line 57
+            among_var = env.find_among(A_0, context);
+            if among_var == 0 {
+                break 'lab1;
+            }
+            // ], line 57
+            env.ket = env.cursor;
+            if among_var == 0 {
+                break 'lab1;
+            } else if among_var == 1 {
+                // (, line 58
+                // <-, line 58
+                if !env.slice_from("i") {
+                    return false;
+                }
+            } else if among_var == 2 {
+                // (, line 59
+                // <-, line 59
+                if !env.slice_from("u") {
+                    return false;
+                }
+            } else if among_var == 3 {
+                // (, line 60
+                // next, line 60
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+fn r_RV(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_pV <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_R1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p1 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_R2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p2 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_step_0(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 71
+    // [, line 72
+    env.ket = env.cursor;
+    // substring, line 72
+    among_var = env.find_among_b(A_1, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 72
+    env.bra = env.cursor;
+    // call R1, line 72
+    if !r_R1(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 74
+        // delete, line 74
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 76
+        // <-, line 76
+        if !env.slice_from("a") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 78
+        // <-, line 78
+        if !env.slice_from("e") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 80
+        // <-, line 80
+        if !env.slice_from("i") {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 82
+        // not, line 82
+        let v_1 = env.limit - env.cursor;
+        'lab0: loop {
+            // literal, line 82
+            if !env.eq_s_b(&"ab") {
+                break 'lab0;
+            }
+            return false;
+        }
+        env.cursor = env.limit - v_1;
+        // <-, line 82
+        if !env.slice_from("i") {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 84
+        // <-, line 84
+        if !env.slice_from("at") {
+            return false;
+        }
+    } else if among_var == 7 {
+        // (, line 86
+        // <-, line 86
+        if !env.slice_from("a\u{0163}i") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_combo_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // test, line 90
+    let v_1 = env.limit - env.cursor;
+    // (, line 90
+    // [, line 91
+    env.ket = env.cursor;
+    // substring, line 91
+    among_var = env.find_among_b(A_2, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 91
+    env.bra = env.cursor;
+    // call R1, line 91
+    if !r_R1(env, context) {
+        return false;
+    }
+    // (, line 91
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 99
+        // <-, line 100
+        if !env.slice_from("abil") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 102
+        // <-, line 103
+        if !env.slice_from("ibil") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 105
+        // <-, line 106
+        if !env.slice_from("iv") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 111
+        // <-, line 112
+        if !env.slice_from("ic") {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 116
+        // <-, line 117
+        if !env.slice_from("at") {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 120
+        // <-, line 121
+        if !env.slice_from("it") {
+            return false;
+        }
+    }
+    // set standard_suffix_removed, line 124
+    context.b_standard_suffix_removed = true;
+    env.cursor = env.limit - v_1;
+    return true;
+}
+
+fn r_standard_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 128
+    // unset standard_suffix_removed, line 129
+    context.b_standard_suffix_removed = false;
+    // repeat, line 130
+    'replab0: loop{
+        let v_1 = env.limit - env.cursor;
+        'lab1: for _ in 0..1 {
+            // call combo_suffix, line 130
+            if !r_combo_suffix(env, context) {
+                break 'lab1;
+            }
+            continue 'replab0;
+        }
+        env.cursor = env.limit - v_1;
+        break 'replab0;
+    }
+    // [, line 131
+    env.ket = env.cursor;
+    // substring, line 131
+    among_var = env.find_among_b(A_3, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 131
+    env.bra = env.cursor;
+    // call R2, line 131
+    if !r_R2(env, context) {
+        return false;
+    }
+    // (, line 131
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 147
+        // delete, line 148
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 150
+        // literal, line 151
+        if !env.eq_s_b(&"\u{0163}") {
+            return false;
+        }
+        // ], line 151
+        env.bra = env.cursor;
+        // <-, line 151
+        if !env.slice_from("t") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 154
+        // <-, line 155
+        if !env.slice_from("ist") {
+            return false;
+        }
+    }
+    // set standard_suffix_removed, line 159
+    context.b_standard_suffix_removed = true;
+    return true;
+}
+
+fn r_verb_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // setlimit, line 163
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 163
+    if env.cursor < context.i_pV {
+        return false;
+    }
+    env.cursor = context.i_pV;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 163
+    // [, line 164
+    env.ket = env.cursor;
+    // substring, line 164
+    among_var = env.find_among_b(A_4, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 164
+    env.bra = env.cursor;
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    } else if among_var == 1 {
+        // (, line 199
+        // or, line 199
+        'lab0: loop {
+            let v_3 = env.limit - env.cursor;
+            'lab1: loop {
+                if !env.out_grouping_b(G_v, 97, 259) {
+                    break 'lab1;
+                }
+                break 'lab0;
+            }
+            env.cursor = env.limit - v_3;
+            // literal, line 199
+            if !env.eq_s_b(&"u") {
+                env.limit_backward = v_2;
+                return false;
+            }
+            break 'lab0;
+        }
+        // delete, line 199
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 213
+        // delete, line 213
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    env.limit_backward = v_2;
+    return true;
+}
+
+fn r_vowel_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 217
+    // [, line 218
+    env.ket = env.cursor;
+    // substring, line 218
+    among_var = env.find_among_b(A_5, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 218
+    env.bra = env.cursor;
+    // call RV, line 218
+    if !r_RV(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 219
+        // delete, line 219
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        b_standard_suffix_removed: false,
+        i_p2: 0,
+        i_p1: 0,
+        i_pV: 0,
+    };
+    // (, line 224
+    // do, line 225
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call prelude, line 225
+        if !r_prelude(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 226
+    let v_2 = env.cursor;
+    'lab1: loop {
+        // call mark_regions, line 226
+        if !r_mark_regions(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = v_2;
+    // backwards, line 227
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 227
+    // do, line 228
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // call step_0, line 228
+        if !r_step_0(env, context) {
+            break 'lab2;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    // do, line 229
+    let v_4 = env.limit - env.cursor;
+    'lab3: loop {
+        // call standard_suffix, line 229
+        if !r_standard_suffix(env, context) {
+            break 'lab3;
+        }
+        break 'lab3;
+    }
+    env.cursor = env.limit - v_4;
+    // do, line 230
+    let v_5 = env.limit - env.cursor;
+    'lab4: loop {
+        // (, line 230
+        // or, line 230
+        'lab5: loop {
+            let v_6 = env.limit - env.cursor;
+            'lab6: loop {
+                // Boolean test standard_suffix_removed, line 230
+                if !context.b_standard_suffix_removed {
+                    break 'lab6;
+                }
+                break 'lab5;
+            }
+            env.cursor = env.limit - v_6;
+            // call verb_suffix, line 230
+            if !r_verb_suffix(env, context) {
+                break 'lab4;
+            }
+            break 'lab5;
+        }
+        break 'lab4;
+    }
+    env.cursor = env.limit - v_5;
+    // do, line 231
+    let v_7 = env.limit - env.cursor;
+    'lab7: loop {
+        // call vowel_suffix, line 231
+        if !r_vowel_suffix(env, context) {
+            break 'lab7;
+        }
+        break 'lab7;
+    }
+    env.cursor = env.limit - v_7;
+    env.cursor = env.limit_backward;
+    // do, line 233
+    let v_8 = env.cursor;
+    'lab8: loop {
+        // call postlude, line 233
+        if !r_postlude(env, context) {
+            break 'lab8;
+        }
+        break 'lab8;
+    }
+    env.cursor = v_8;
+    return true;
+}
diff --git a/src/snowball/algorithms/russian.rs b/src/snowball/algorithms/russian.rs
new file mode 100644
index 0000000..7677ab3
--- /dev/null
+++ b/src/snowball/algorithms/russian.rs
@@ -0,0 +1,691 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 9] = &[
+    Among("\u{0432}\u{0448}\u{0438}\u{0441}\u{044C}", -1, 1, None),
+    Among("\u{044B}\u{0432}\u{0448}\u{0438}\u{0441}\u{044C}", 0, 2, None),
+    Among("\u{0438}\u{0432}\u{0448}\u{0438}\u{0441}\u{044C}", 0, 2, None),
+    Among("\u{0432}", -1, 1, None),
+    Among("\u{044B}\u{0432}", 3, 2, None),
+    Among("\u{0438}\u{0432}", 3, 2, None),
+    Among("\u{0432}\u{0448}\u{0438}", -1, 1, None),
+    Among("\u{044B}\u{0432}\u{0448}\u{0438}", 6, 2, None),
+    Among("\u{0438}\u{0432}\u{0448}\u{0438}", 6, 2, None),
+];
+
+static A_1: &'static [Among<Context>; 26] = &[
+    Among("\u{0435}\u{043C}\u{0443}", -1, 1, None),
+    Among("\u{043E}\u{043C}\u{0443}", -1, 1, None),
+    Among("\u{044B}\u{0445}", -1, 1, None),
+    Among("\u{0438}\u{0445}", -1, 1, None),
+    Among("\u{0443}\u{044E}", -1, 1, None),
+    Among("\u{044E}\u{044E}", -1, 1, None),
+    Among("\u{0435}\u{044E}", -1, 1, None),
+    Among("\u{043E}\u{044E}", -1, 1, None),
+    Among("\u{044F}\u{044F}", -1, 1, None),
+    Among("\u{0430}\u{044F}", -1, 1, None),
+    Among("\u{044B}\u{0435}", -1, 1, None),
+    Among("\u{0435}\u{0435}", -1, 1, None),
+    Among("\u{0438}\u{0435}", -1, 1, None),
+    Among("\u{043E}\u{0435}", -1, 1, None),
+    Among("\u{044B}\u{043C}\u{0438}", -1, 1, None),
+    Among("\u{0438}\u{043C}\u{0438}", -1, 1, None),
+    Among("\u{044B}\u{0439}", -1, 1, None),
+    Among("\u{0435}\u{0439}", -1, 1, None),
+    Among("\u{0438}\u{0439}", -1, 1, None),
+    Among("\u{043E}\u{0439}", -1, 1, None),
+    Among("\u{044B}\u{043C}", -1, 1, None),
+    Among("\u{0435}\u{043C}", -1, 1, None),
+    Among("\u{0438}\u{043C}", -1, 1, None),
+    Among("\u{043E}\u{043C}", -1, 1, None),
+    Among("\u{0435}\u{0433}\u{043E}", -1, 1, None),
+    Among("\u{043E}\u{0433}\u{043E}", -1, 1, None),
+];
+
+static A_2: &'static [Among<Context>; 8] = &[
+    Among("\u{0432}\u{0448}", -1, 1, None),
+    Among("\u{044B}\u{0432}\u{0448}", 0, 2, None),
+    Among("\u{0438}\u{0432}\u{0448}", 0, 2, None),
+    Among("\u{0449}", -1, 1, None),
+    Among("\u{044E}\u{0449}", 3, 1, None),
+    Among("\u{0443}\u{044E}\u{0449}", 4, 2, None),
+    Among("\u{0435}\u{043C}", -1, 1, None),
+    Among("\u{043D}\u{043D}", -1, 1, None),
+];
+
+static A_3: &'static [Among<Context>; 2] = &[
+    Among("\u{0441}\u{044C}", -1, 1, None),
+    Among("\u{0441}\u{044F}", -1, 1, None),
+];
+
+static A_4: &'static [Among<Context>; 46] = &[
+    Among("\u{044B}\u{0442}", -1, 2, None),
+    Among("\u{044E}\u{0442}", -1, 1, None),
+    Among("\u{0443}\u{044E}\u{0442}", 1, 2, None),
+    Among("\u{044F}\u{0442}", -1, 2, None),
+    Among("\u{0435}\u{0442}", -1, 1, None),
+    Among("\u{0443}\u{0435}\u{0442}", 4, 2, None),
+    Among("\u{0438}\u{0442}", -1, 2, None),
+    Among("\u{043D}\u{044B}", -1, 1, None),
+    Among("\u{0435}\u{043D}\u{044B}", 7, 2, None),
+    Among("\u{0442}\u{044C}", -1, 1, None),
+    Among("\u{044B}\u{0442}\u{044C}", 9, 2, None),
+    Among("\u{0438}\u{0442}\u{044C}", 9, 2, None),
+    Among("\u{0435}\u{0448}\u{044C}", -1, 1, None),
+    Among("\u{0438}\u{0448}\u{044C}", -1, 2, None),
+    Among("\u{044E}", -1, 2, None),
+    Among("\u{0443}\u{044E}", 14, 2, None),
+    Among("\u{043B}\u{0430}", -1, 1, None),
+    Among("\u{044B}\u{043B}\u{0430}", 16, 2, None),
+    Among("\u{0438}\u{043B}\u{0430}", 16, 2, None),
+    Among("\u{043D}\u{0430}", -1, 1, None),
+    Among("\u{0435}\u{043D}\u{0430}", 19, 2, None),
+    Among("\u{0435}\u{0442}\u{0435}", -1, 1, None),
+    Among("\u{0438}\u{0442}\u{0435}", -1, 2, None),
+    Among("\u{0439}\u{0442}\u{0435}", -1, 1, None),
+    Among("\u{0443}\u{0439}\u{0442}\u{0435}", 23, 2, None),
+    Among("\u{0435}\u{0439}\u{0442}\u{0435}", 23, 2, None),
+    Among("\u{043B}\u{0438}", -1, 1, None),
+    Among("\u{044B}\u{043B}\u{0438}", 26, 2, None),
+    Among("\u{0438}\u{043B}\u{0438}", 26, 2, None),
+    Among("\u{0439}", -1, 1, None),
+    Among("\u{0443}\u{0439}", 29, 2, None),
+    Among("\u{0435}\u{0439}", 29, 2, None),
+    Among("\u{043B}", -1, 1, None),
+    Among("\u{044B}\u{043B}", 32, 2, None),
+    Among("\u{0438}\u{043B}", 32, 2, None),
+    Among("\u{044B}\u{043C}", -1, 2, None),
+    Among("\u{0435}\u{043C}", -1, 1, None),
+    Among("\u{0438}\u{043C}", -1, 2, None),
+    Among("\u{043D}", -1, 1, None),
+    Among("\u{0435}\u{043D}", 38, 2, None),
+    Among("\u{043B}\u{043E}", -1, 1, None),
+    Among("\u{044B}\u{043B}\u{043E}", 40, 2, None),
+    Among("\u{0438}\u{043B}\u{043E}", 40, 2, None),
+    Among("\u{043D}\u{043E}", -1, 1, None),
+    Among("\u{0435}\u{043D}\u{043E}", 43, 2, None),
+    Among("\u{043D}\u{043D}\u{043E}", 43, 1, None),
+];
+
+static A_5: &'static [Among<Context>; 36] = &[
+    Among("\u{0443}", -1, 1, None),
+    Among("\u{044F}\u{0445}", -1, 1, None),
+    Among("\u{0438}\u{044F}\u{0445}", 1, 1, None),
+    Among("\u{0430}\u{0445}", -1, 1, None),
+    Among("\u{044B}", -1, 1, None),
+    Among("\u{044C}", -1, 1, None),
+    Among("\u{044E}", -1, 1, None),
+    Among("\u{044C}\u{044E}", 6, 1, None),
+    Among("\u{0438}\u{044E}", 6, 1, None),
+    Among("\u{044F}", -1, 1, None),
+    Among("\u{044C}\u{044F}", 9, 1, None),
+    Among("\u{0438}\u{044F}", 9, 1, None),
+    Among("\u{0430}", -1, 1, None),
+    Among("\u{0435}\u{0432}", -1, 1, None),
+    Among("\u{043E}\u{0432}", -1, 1, None),
+    Among("\u{0435}", -1, 1, None),
+    Among("\u{044C}\u{0435}", 15, 1, None),
+    Among("\u{0438}\u{0435}", 15, 1, None),
+    Among("\u{0438}", -1, 1, None),
+    Among("\u{0435}\u{0438}", 18, 1, None),
+    Among("\u{0438}\u{0438}", 18, 1, None),
+    Among("\u{044F}\u{043C}\u{0438}", 18, 1, None),
+    Among("\u{0438}\u{044F}\u{043C}\u{0438}", 21, 1, None),
+    Among("\u{0430}\u{043C}\u{0438}", 18, 1, None),
+    Among("\u{0439}", -1, 1, None),
+    Among("\u{0435}\u{0439}", 24, 1, None),
+    Among("\u{0438}\u{0435}\u{0439}", 25, 1, None),
+    Among("\u{0438}\u{0439}", 24, 1, None),
+    Among("\u{043E}\u{0439}", 24, 1, None),
+    Among("\u{044F}\u{043C}", -1, 1, None),
+    Among("\u{0438}\u{044F}\u{043C}", 29, 1, None),
+    Among("\u{0430}\u{043C}", -1, 1, None),
+    Among("\u{0435}\u{043C}", -1, 1, None),
+    Among("\u{0438}\u{0435}\u{043C}", 32, 1, None),
+    Among("\u{043E}\u{043C}", -1, 1, None),
+    Among("\u{043E}", -1, 1, None),
+];
+
+static A_6: &'static [Among<Context>; 2] = &[
+    Among("\u{043E}\u{0441}\u{0442}", -1, 1, None),
+    Among("\u{043E}\u{0441}\u{0442}\u{044C}", -1, 1, None),
+];
+
+static A_7: &'static [Among<Context>; 4] = &[
+    Among("\u{0435}\u{0439}\u{0448}", -1, 1, None),
+    Among("\u{044C}", -1, 3, None),
+    Among("\u{0435}\u{0439}\u{0448}\u{0435}", -1, 1, None),
+    Among("\u{043D}", -1, 2, None),
+];
+
+static G_v: &'static [u8; 4] = &[33, 65, 8, 232];
+
+#[derive(Clone)]
+struct Context {
+    i_p2: usize,
+    i_pV: usize,
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 57
+    context.i_pV = env.limit;
+    context.i_p2 = env.limit;
+    // do, line 61
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // (, line 61
+        // gopast, line 62
+        'golab1: loop {
+            'lab2: loop {
+                if !env.in_grouping(G_v, 1072, 1103) {
+                    break 'lab2;
+                }
+                break 'golab1;
+            }
+            if env.cursor >= env.limit {
+                break 'lab0;
+            }
+            env.next_char();
+        }
+        // setmark pV, line 62
+        context.i_pV = env.cursor;
+        // gopast, line 62
+        'golab3: loop {
+            'lab4: loop {
+                if !env.out_grouping(G_v, 1072, 1103) {
+                    break 'lab4;
+                }
+                break 'golab3;
+            }
+            if env.cursor >= env.limit {
+                break 'lab0;
+            }
+            env.next_char();
+        }
+        // gopast, line 63
+        'golab5: loop {
+            'lab6: loop {
+                if !env.in_grouping(G_v, 1072, 1103) {
+                    break 'lab6;
+                }
+                break 'golab5;
+            }
+            if env.cursor >= env.limit {
+                break 'lab0;
+            }
+            env.next_char();
+        }
+        // gopast, line 63
+        'golab7: loop {
+            'lab8: loop {
+                if !env.out_grouping(G_v, 1072, 1103) {
+                    break 'lab8;
+                }
+                break 'golab7;
+            }
+            if env.cursor >= env.limit {
+                break 'lab0;
+            }
+            env.next_char();
+        }
+        // setmark p2, line 63
+        context.i_p2 = env.cursor;
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    return true;
+}
+
+fn r_R2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p2 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_perfective_gerund(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 71
+    // [, line 72
+    env.ket = env.cursor;
+    // substring, line 72
+    among_var = env.find_among_b(A_0, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 72
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 76
+        // or, line 76
+        'lab0: loop {
+            let v_1 = env.limit - env.cursor;
+            'lab1: loop {
+                // literal, line 76
+                if !env.eq_s_b(&"\u{0430}") {
+                    break 'lab1;
+                }
+                break 'lab0;
+            }
+            env.cursor = env.limit - v_1;
+            // literal, line 76
+            if !env.eq_s_b(&"\u{044F}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        // delete, line 76
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 83
+        // delete, line 83
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_adjective(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 87
+    // [, line 88
+    env.ket = env.cursor;
+    // substring, line 88
+    among_var = env.find_among_b(A_1, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 88
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 97
+        // delete, line 97
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_adjectival(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 101
+    // call adjective, line 102
+    if !r_adjective(env, context) {
+        return false;
+    }
+    // try, line 109
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 109
+        // [, line 110
+        env.ket = env.cursor;
+        // substring, line 110
+        among_var = env.find_among_b(A_2, context);
+        if among_var == 0 {
+            env.cursor = env.limit - v_1;
+            break 'lab0;
+        }
+        // ], line 110
+        env.bra = env.cursor;
+        if among_var == 0 {
+            env.cursor = env.limit - v_1;
+            break 'lab0;
+        } else if among_var == 1 {
+            // (, line 115
+            // or, line 115
+            'lab1: loop {
+                let v_2 = env.limit - env.cursor;
+                'lab2: loop {
+                    // literal, line 115
+                    if !env.eq_s_b(&"\u{0430}") {
+                        break 'lab2;
+                    }
+                    break 'lab1;
+                }
+                env.cursor = env.limit - v_2;
+                // literal, line 115
+                if !env.eq_s_b(&"\u{044F}") {
+                    env.cursor = env.limit - v_1;
+                    break 'lab0;
+                }
+                break 'lab1;
+            }
+            // delete, line 115
+            if !env.slice_del() {
+                return false;
+            }
+        } else if among_var == 2 {
+            // (, line 122
+            // delete, line 122
+            if !env.slice_del() {
+                return false;
+            }
+        }
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_reflexive(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 128
+    // [, line 129
+    env.ket = env.cursor;
+    // substring, line 129
+    among_var = env.find_among_b(A_3, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 129
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 132
+        // delete, line 132
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_verb(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 136
+    // [, line 137
+    env.ket = env.cursor;
+    // substring, line 137
+    among_var = env.find_among_b(A_4, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 137
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 143
+        // or, line 143
+        'lab0: loop {
+            let v_1 = env.limit - env.cursor;
+            'lab1: loop {
+                // literal, line 143
+                if !env.eq_s_b(&"\u{0430}") {
+                    break 'lab1;
+                }
+                break 'lab0;
+            }
+            env.cursor = env.limit - v_1;
+            // literal, line 143
+            if !env.eq_s_b(&"\u{044F}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        // delete, line 143
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 151
+        // delete, line 151
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_noun(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 159
+    // [, line 160
+    env.ket = env.cursor;
+    // substring, line 160
+    among_var = env.find_among_b(A_5, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 160
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 167
+        // delete, line 167
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_derivational(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 175
+    // [, line 176
+    env.ket = env.cursor;
+    // substring, line 176
+    among_var = env.find_among_b(A_6, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 176
+    env.bra = env.cursor;
+    // call R2, line 176
+    if !r_R2(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 179
+        // delete, line 179
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_tidy_up(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 183
+    // [, line 184
+    env.ket = env.cursor;
+    // substring, line 184
+    among_var = env.find_among_b(A_7, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 184
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 188
+        // delete, line 188
+        if !env.slice_del() {
+            return false;
+        }
+        // [, line 189
+        env.ket = env.cursor;
+        // literal, line 189
+        if !env.eq_s_b(&"\u{043D}") {
+            return false;
+        }
+        // ], line 189
+        env.bra = env.cursor;
+        // literal, line 189
+        if !env.eq_s_b(&"\u{043D}") {
+            return false;
+        }
+        // delete, line 189
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 192
+        // literal, line 192
+        if !env.eq_s_b(&"\u{043D}") {
+            return false;
+        }
+        // delete, line 192
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 194
+        // delete, line 194
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        i_p2: 0,
+        i_pV: 0,
+    };
+    // (, line 199
+    // do, line 201
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call mark_regions, line 201
+        if !r_mark_regions(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // backwards, line 202
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // setlimit, line 202
+    let v_2 = env.limit - env.cursor;
+    // tomark, line 202
+    if env.cursor < context.i_pV {
+        return false;
+    }
+    env.cursor = context.i_pV;
+    let v_3 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_2;
+    // (, line 202
+    // do, line 203
+    let v_4 = env.limit - env.cursor;
+    'lab1: loop {
+        // (, line 203
+        // or, line 204
+        'lab2: loop {
+            let v_5 = env.limit - env.cursor;
+            'lab3: loop {
+                // call perfective_gerund, line 204
+                if !r_perfective_gerund(env, context) {
+                    break 'lab3;
+                }
+                break 'lab2;
+            }
+            env.cursor = env.limit - v_5;
+            // (, line 205
+            // try, line 205
+            let v_6 = env.limit - env.cursor;
+            'lab4: loop {
+                // call reflexive, line 205
+                if !r_reflexive(env, context) {
+                    env.cursor = env.limit - v_6;
+                    break 'lab4;
+                }
+                break 'lab4;
+            }
+            // or, line 206
+            'lab5: loop {
+                let v_7 = env.limit - env.cursor;
+                'lab6: loop {
+                    // call adjectival, line 206
+                    if !r_adjectival(env, context) {
+                        break 'lab6;
+                    }
+                    break 'lab5;
+                }
+                env.cursor = env.limit - v_7;
+                'lab7: loop {
+                    // call verb, line 206
+                    if !r_verb(env, context) {
+                        break 'lab7;
+                    }
+                    break 'lab5;
+                }
+                env.cursor = env.limit - v_7;
+                // call noun, line 206
+                if !r_noun(env, context) {
+                    break 'lab1;
+                }
+                break 'lab5;
+            }
+            break 'lab2;
+        }
+        break 'lab1;
+    }
+    env.cursor = env.limit - v_4;
+    // try, line 209
+    let v_8 = env.limit - env.cursor;
+    'lab8: loop {
+        // (, line 209
+        // [, line 209
+        env.ket = env.cursor;
+        // literal, line 209
+        if !env.eq_s_b(&"\u{0438}") {
+            env.cursor = env.limit - v_8;
+            break 'lab8;
+        }
+        // ], line 209
+        env.bra = env.cursor;
+        // delete, line 209
+        if !env.slice_del() {
+            return false;
+        }
+        break 'lab8;
+    }
+    // do, line 212
+    let v_9 = env.limit - env.cursor;
+    'lab9: loop {
+        // call derivational, line 212
+        if !r_derivational(env, context) {
+            break 'lab9;
+        }
+        break 'lab9;
+    }
+    env.cursor = env.limit - v_9;
+    // do, line 213
+    let v_10 = env.limit - env.cursor;
+    'lab10: loop {
+        // call tidy_up, line 213
+        if !r_tidy_up(env, context) {
+            break 'lab10;
+        }
+        break 'lab10;
+    }
+    env.cursor = env.limit - v_10;
+    env.limit_backward = v_3;
+    env.cursor = env.limit_backward;
+    return true;
+}
diff --git a/src/snowball/algorithms/spanish.rs b/src/snowball/algorithms/spanish.rs
new file mode 100644
index 0000000..90a90b8
--- /dev/null
+++ b/src/snowball/algorithms/spanish.rs
@@ -0,0 +1,1121 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 6] = &[
+    Among("", -1, 6, None),
+    Among("\u{00E1}", 0, 1, None),
+    Among("\u{00E9}", 0, 2, None),
+    Among("\u{00ED}", 0, 3, None),
+    Among("\u{00F3}", 0, 4, None),
+    Among("\u{00FA}", 0, 5, None),
+];
+
+static A_1: &'static [Among<Context>; 13] = &[
+    Among("la", -1, -1, None),
+    Among("sela", 0, -1, None),
+    Among("le", -1, -1, None),
+    Among("me", -1, -1, None),
+    Among("se", -1, -1, None),
+    Among("lo", -1, -1, None),
+    Among("selo", 5, -1, None),
+    Among("las", -1, -1, None),
+    Among("selas", 7, -1, None),
+    Among("les", -1, -1, None),
+    Among("los", -1, -1, None),
+    Among("selos", 10, -1, None),
+    Among("nos", -1, -1, None),
+];
+
+static A_2: &'static [Among<Context>; 11] = &[
+    Among("ando", -1, 6, None),
+    Among("iendo", -1, 6, None),
+    Among("yendo", -1, 7, None),
+    Among("\u{00E1}ndo", -1, 2, None),
+    Among("i\u{00E9}ndo", -1, 1, None),
+    Among("ar", -1, 6, None),
+    Among("er", -1, 6, None),
+    Among("ir", -1, 6, None),
+    Among("\u{00E1}r", -1, 3, None),
+    Among("\u{00E9}r", -1, 4, None),
+    Among("\u{00ED}r", -1, 5, None),
+];
+
+static A_3: &'static [Among<Context>; 4] = &[
+    Among("ic", -1, -1, None),
+    Among("ad", -1, -1, None),
+    Among("os", -1, -1, None),
+    Among("iv", -1, 1, None),
+];
+
+static A_4: &'static [Among<Context>; 3] = &[
+    Among("able", -1, 1, None),
+    Among("ible", -1, 1, None),
+    Among("ante", -1, 1, None),
+];
+
+static A_5: &'static [Among<Context>; 3] = &[
+    Among("ic", -1, 1, None),
+    Among("abil", -1, 1, None),
+    Among("iv", -1, 1, None),
+];
+
+static A_6: &'static [Among<Context>; 46] = &[
+    Among("ica", -1, 1, None),
+    Among("ancia", -1, 2, None),
+    Among("encia", -1, 5, None),
+    Among("adora", -1, 2, None),
+    Among("osa", -1, 1, None),
+    Among("ista", -1, 1, None),
+    Among("iva", -1, 9, None),
+    Among("anza", -1, 1, None),
+    Among("log\u{00ED}a", -1, 3, None),
+    Among("idad", -1, 8, None),
+    Among("able", -1, 1, None),
+    Among("ible", -1, 1, None),
+    Among("ante", -1, 2, None),
+    Among("mente", -1, 7, None),
+    Among("amente", 13, 6, None),
+    Among("aci\u{00F3}n", -1, 2, None),
+    Among("uci\u{00F3}n", -1, 4, None),
+    Among("ico", -1, 1, None),
+    Among("ismo", -1, 1, None),
+    Among("oso", -1, 1, None),
+    Among("amiento", -1, 1, None),
+    Among("imiento", -1, 1, None),
+    Among("ivo", -1, 9, None),
+    Among("ador", -1, 2, None),
+    Among("icas", -1, 1, None),
+    Among("ancias", -1, 2, None),
+    Among("encias", -1, 5, None),
+    Among("adoras", -1, 2, None),
+    Among("osas", -1, 1, None),
+    Among("istas", -1, 1, None),
+    Among("ivas", -1, 9, None),
+    Among("anzas", -1, 1, None),
+    Among("log\u{00ED}as", -1, 3, None),
+    Among("idades", -1, 8, None),
+    Among("ables", -1, 1, None),
+    Among("ibles", -1, 1, None),
+    Among("aciones", -1, 2, None),
+    Among("uciones", -1, 4, None),
+    Among("adores", -1, 2, None),
+    Among("antes", -1, 2, None),
+    Among("icos", -1, 1, None),
+    Among("ismos", -1, 1, None),
+    Among("osos", -1, 1, None),
+    Among("amientos", -1, 1, None),
+    Among("imientos", -1, 1, None),
+    Among("ivos", -1, 9, None),
+];
+
+static A_7: &'static [Among<Context>; 12] = &[
+    Among("ya", -1, 1, None),
+    Among("ye", -1, 1, None),
+    Among("yan", -1, 1, None),
+    Among("yen", -1, 1, None),
+    Among("yeron", -1, 1, None),
+    Among("yendo", -1, 1, None),
+    Among("yo", -1, 1, None),
+    Among("yas", -1, 1, None),
+    Among("yes", -1, 1, None),
+    Among("yais", -1, 1, None),
+    Among("yamos", -1, 1, None),
+    Among("y\u{00F3}", -1, 1, None),
+];
+
+static A_8: &'static [Among<Context>; 96] = &[
+    Among("aba", -1, 2, None),
+    Among("ada", -1, 2, None),
+    Among("ida", -1, 2, None),
+    Among("ara", -1, 2, None),
+    Among("iera", -1, 2, None),
+    Among("\u{00ED}a", -1, 2, None),
+    Among("ar\u{00ED}a", 5, 2, None),
+    Among("er\u{00ED}a", 5, 2, None),
+    Among("ir\u{00ED}a", 5, 2, None),
+    Among("ad", -1, 2, None),
+    Among("ed", -1, 2, None),
+    Among("id", -1, 2, None),
+    Among("ase", -1, 2, None),
+    Among("iese", -1, 2, None),
+    Among("aste", -1, 2, None),
+    Among("iste", -1, 2, None),
+    Among("an", -1, 2, None),
+    Among("aban", 16, 2, None),
+    Among("aran", 16, 2, None),
+    Among("ieran", 16, 2, None),
+    Among("\u{00ED}an", 16, 2, None),
+    Among("ar\u{00ED}an", 20, 2, None),
+    Among("er\u{00ED}an", 20, 2, None),
+    Among("ir\u{00ED}an", 20, 2, None),
+    Among("en", -1, 1, None),
+    Among("asen", 24, 2, None),
+    Among("iesen", 24, 2, None),
+    Among("aron", -1, 2, None),
+    Among("ieron", -1, 2, None),
+    Among("ar\u{00E1}n", -1, 2, None),
+    Among("er\u{00E1}n", -1, 2, None),
+    Among("ir\u{00E1}n", -1, 2, None),
+    Among("ado", -1, 2, None),
+    Among("ido", -1, 2, None),
+    Among("ando", -1, 2, None),
+    Among("iendo", -1, 2, None),
+    Among("ar", -1, 2, None),
+    Among("er", -1, 2, None),
+    Among("ir", -1, 2, None),
+    Among("as", -1, 2, None),
+    Among("abas", 39, 2, None),
+    Among("adas", 39, 2, None),
+    Among("idas", 39, 2, None),
+    Among("aras", 39, 2, None),
+    Among("ieras", 39, 2, None),
+    Among("\u{00ED}as", 39, 2, None),
+    Among("ar\u{00ED}as", 45, 2, None),
+    Among("er\u{00ED}as", 45, 2, None),
+    Among("ir\u{00ED}as", 45, 2, None),
+    Among("es", -1, 1, None),
+    Among("ases", 49, 2, None),
+    Among("ieses", 49, 2, None),
+    Among("abais", -1, 2, None),
+    Among("arais", -1, 2, None),
+    Among("ierais", -1, 2, None),
+    Among("\u{00ED}ais", -1, 2, None),
+    Among("ar\u{00ED}ais", 55, 2, None),
+    Among("er\u{00ED}ais", 55, 2, None),
+    Among("ir\u{00ED}ais", 55, 2, None),
+    Among("aseis", -1, 2, None),
+    Among("ieseis", -1, 2, None),
+    Among("asteis", -1, 2, None),
+    Among("isteis", -1, 2, None),
+    Among("\u{00E1}is", -1, 2, None),
+    Among("\u{00E9}is", -1, 1, None),
+    Among("ar\u{00E9}is", 64, 2, None),
+    Among("er\u{00E9}is", 64, 2, None),
+    Among("ir\u{00E9}is", 64, 2, None),
+    Among("ados", -1, 2, None),
+    Among("idos", -1, 2, None),
+    Among("amos", -1, 2, None),
+    Among("\u{00E1}bamos", 70, 2, None),
+    Among("\u{00E1}ramos", 70, 2, None),
+    Among("i\u{00E9}ramos", 70, 2, None),
+    Among("\u{00ED}amos", 70, 2, None),
+    Among("ar\u{00ED}amos", 74, 2, None),
+    Among("er\u{00ED}amos", 74, 2, None),
+    Among("ir\u{00ED}amos", 74, 2, None),
+    Among("emos", -1, 1, None),
+    Among("aremos", 78, 2, None),
+    Among("eremos", 78, 2, None),
+    Among("iremos", 78, 2, None),
+    Among("\u{00E1}semos", 78, 2, None),
+    Among("i\u{00E9}semos", 78, 2, None),
+    Among("imos", -1, 2, None),
+    Among("ar\u{00E1}s", -1, 2, None),
+    Among("er\u{00E1}s", -1, 2, None),
+    Among("ir\u{00E1}s", -1, 2, None),
+    Among("\u{00ED}s", -1, 2, None),
+    Among("ar\u{00E1}", -1, 2, None),
+    Among("er\u{00E1}", -1, 2, None),
+    Among("ir\u{00E1}", -1, 2, None),
+    Among("ar\u{00E9}", -1, 2, None),
+    Among("er\u{00E9}", -1, 2, None),
+    Among("ir\u{00E9}", -1, 2, None),
+    Among("i\u{00F3}", -1, 2, None),
+];
+
+static A_9: &'static [Among<Context>; 8] = &[
+    Among("a", -1, 1, None),
+    Among("e", -1, 2, None),
+    Among("o", -1, 1, None),
+    Among("os", -1, 1, None),
+    Among("\u{00E1}", -1, 1, None),
+    Among("\u{00E9}", -1, 2, None),
+    Among("\u{00ED}", -1, 1, None),
+    Among("\u{00F3}", -1, 1, None),
+];
+
+static G_v: &'static [u8; 20] = &[17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 10];
+
+#[derive(Clone)]
+struct Context {
+    i_p2: usize,
+    i_p1: usize,
+    i_pV: usize,
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 31
+    context.i_pV = env.limit;
+    context.i_p1 = env.limit;
+    context.i_p2 = env.limit;
+    // do, line 37
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // (, line 37
+        // or, line 39
+        'lab1: loop {
+            let v_2 = env.cursor;
+            'lab2: loop {
+                // (, line 38
+                if !env.in_grouping(G_v, 97, 252) {
+                    break 'lab2;
+                }
+                // or, line 38
+                'lab3: loop {
+                    let v_3 = env.cursor;
+                    'lab4: loop {
+                        // (, line 38
+                        if !env.out_grouping(G_v, 97, 252) {
+                            break 'lab4;
+                        }
+                        // gopast, line 38
+                        'golab5: loop {
+                            'lab6: loop {
+                                if !env.in_grouping(G_v, 97, 252) {
+                                    break 'lab6;
+                                }
+                                break 'golab5;
+                            }
+                            if env.cursor >= env.limit {
+                                break 'lab4;
+                            }
+                            env.next_char();
+                        }
+                        break 'lab3;
+                    }
+                    env.cursor = v_3;
+                    // (, line 38
+                    if !env.in_grouping(G_v, 97, 252) {
+                        break 'lab2;
+                    }
+                    // gopast, line 38
+                    'golab7: loop {
+                        'lab8: loop {
+                            if !env.out_grouping(G_v, 97, 252) {
+                                break 'lab8;
+                            }
+                            break 'golab7;
+                        }
+                        if env.cursor >= env.limit {
+                            break 'lab2;
+                        }
+                        env.next_char();
+                    }
+                    break 'lab3;
+                }
+                break 'lab1;
+            }
+            env.cursor = v_2;
+            // (, line 40
+            if !env.out_grouping(G_v, 97, 252) {
+                break 'lab0;
+            }
+            // or, line 40
+            'lab9: loop {
+                let v_6 = env.cursor;
+                'lab10: loop {
+                    // (, line 40
+                    if !env.out_grouping(G_v, 97, 252) {
+                        break 'lab10;
+                    }
+                    // gopast, line 40
+                    'golab11: loop {
+                        'lab12: loop {
+                            if !env.in_grouping(G_v, 97, 252) {
+                                break 'lab12;
+                            }
+                            break 'golab11;
+                        }
+                        if env.cursor >= env.limit {
+                            break 'lab10;
+                        }
+                        env.next_char();
+                    }
+                    break 'lab9;
+                }
+                env.cursor = v_6;
+                // (, line 40
+                if !env.in_grouping(G_v, 97, 252) {
+                    break 'lab0;
+                }
+                // next, line 40
+                if env.cursor >= env.limit {
+                    break 'lab0;
+                }
+                env.next_char();
+                break 'lab9;
+            }
+            break 'lab1;
+        }
+        // setmark pV, line 41
+        context.i_pV = env.cursor;
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // do, line 43
+    let v_8 = env.cursor;
+    'lab13: loop {
+        // (, line 43
+        // gopast, line 44
+        'golab14: loop {
+            'lab15: loop {
+                if !env.in_grouping(G_v, 97, 252) {
+                    break 'lab15;
+                }
+                break 'golab14;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // gopast, line 44
+        'golab16: loop {
+            'lab17: loop {
+                if !env.out_grouping(G_v, 97, 252) {
+                    break 'lab17;
+                }
+                break 'golab16;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // setmark p1, line 44
+        context.i_p1 = env.cursor;
+        // gopast, line 45
+        'golab18: loop {
+            'lab19: loop {
+                if !env.in_grouping(G_v, 97, 252) {
+                    break 'lab19;
+                }
+                break 'golab18;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // gopast, line 45
+        'golab20: loop {
+            'lab21: loop {
+                if !env.out_grouping(G_v, 97, 252) {
+                    break 'lab21;
+                }
+                break 'golab20;
+            }
+            if env.cursor >= env.limit {
+                break 'lab13;
+            }
+            env.next_char();
+        }
+        // setmark p2, line 45
+        context.i_p2 = env.cursor;
+        break 'lab13;
+    }
+    env.cursor = v_8;
+    return true;
+}
+
+fn r_postlude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // repeat, line 49
+    'replab0: loop{
+        let v_1 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 49
+            // [, line 50
+            env.bra = env.cursor;
+            // substring, line 50
+            among_var = env.find_among(A_0, context);
+            if among_var == 0 {
+                break 'lab1;
+            }
+            // ], line 50
+            env.ket = env.cursor;
+            if among_var == 0 {
+                break 'lab1;
+            } else if among_var == 1 {
+                // (, line 51
+                // <-, line 51
+                if !env.slice_from("a") {
+                    return false;
+                }
+            } else if among_var == 2 {
+                // (, line 52
+                // <-, line 52
+                if !env.slice_from("e") {
+                    return false;
+                }
+            } else if among_var == 3 {
+                // (, line 53
+                // <-, line 53
+                if !env.slice_from("i") {
+                    return false;
+                }
+            } else if among_var == 4 {
+                // (, line 54
+                // <-, line 54
+                if !env.slice_from("o") {
+                    return false;
+                }
+            } else if among_var == 5 {
+                // (, line 55
+                // <-, line 55
+                if !env.slice_from("u") {
+                    return false;
+                }
+            } else if among_var == 6 {
+                // (, line 57
+                // next, line 57
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            continue 'replab0;
+        }
+        env.cursor = v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+fn r_RV(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_pV <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_R1(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p1 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_R2(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    if !(context.i_p2 <= env.cursor){
+        return false;
+    }
+    return true;
+}
+
+fn r_attached_pronoun(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 67
+    // [, line 68
+    env.ket = env.cursor;
+    // substring, line 68
+    if env.find_among_b(A_1, context) == 0 {
+        return false;
+    }
+    // ], line 68
+    env.bra = env.cursor;
+    // substring, line 72
+    among_var = env.find_among_b(A_2, context);
+    if among_var == 0 {
+        return false;
+    }
+    // call RV, line 72
+    if !r_RV(env, context) {
+        return false;
+    }
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 73
+        // ], line 73
+        env.bra = env.cursor;
+        // <-, line 73
+        if !env.slice_from("iendo") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 74
+        // ], line 74
+        env.bra = env.cursor;
+        // <-, line 74
+        if !env.slice_from("ando") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 75
+        // ], line 75
+        env.bra = env.cursor;
+        // <-, line 75
+        if !env.slice_from("ar") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 76
+        // ], line 76
+        env.bra = env.cursor;
+        // <-, line 76
+        if !env.slice_from("er") {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 77
+        // ], line 77
+        env.bra = env.cursor;
+        // <-, line 77
+        if !env.slice_from("ir") {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 81
+        // delete, line 81
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 7 {
+        // (, line 82
+        // literal, line 82
+        if !env.eq_s_b(&"u") {
+            return false;
+        }
+        // delete, line 82
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_standard_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 86
+    // [, line 87
+    env.ket = env.cursor;
+    // substring, line 87
+    among_var = env.find_among_b(A_6, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 87
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 98
+        // call R2, line 99
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 99
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 104
+        // call R2, line 105
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 105
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 106
+        let v_1 = env.limit - env.cursor;
+        'lab0: loop {
+            // (, line 106
+            // [, line 106
+            env.ket = env.cursor;
+            // literal, line 106
+            if !env.eq_s_b(&"ic") {
+                env.cursor = env.limit - v_1;
+                break 'lab0;
+            }
+            // ], line 106
+            env.bra = env.cursor;
+            // call R2, line 106
+            if !r_R2(env, context) {
+                env.cursor = env.limit - v_1;
+                break 'lab0;
+            }
+            // delete, line 106
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab0;
+        }
+    } else if among_var == 3 {
+        // (, line 110
+        // call R2, line 111
+        if !r_R2(env, context) {
+            return false;
+        }
+        // <-, line 111
+        if !env.slice_from("log") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 114
+        // call R2, line 115
+        if !r_R2(env, context) {
+            return false;
+        }
+        // <-, line 115
+        if !env.slice_from("u") {
+            return false;
+        }
+    } else if among_var == 5 {
+        // (, line 118
+        // call R2, line 119
+        if !r_R2(env, context) {
+            return false;
+        }
+        // <-, line 119
+        if !env.slice_from("ente") {
+            return false;
+        }
+    } else if among_var == 6 {
+        // (, line 122
+        // call R1, line 123
+        if !r_R1(env, context) {
+            return false;
+        }
+        // delete, line 123
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 124
+        let v_2 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 124
+            // [, line 125
+            env.ket = env.cursor;
+            // substring, line 125
+            among_var = env.find_among_b(A_3, context);
+            if among_var == 0 {
+                env.cursor = env.limit - v_2;
+                break 'lab1;
+            }
+            // ], line 125
+            env.bra = env.cursor;
+            // call R2, line 125
+            if !r_R2(env, context) {
+                env.cursor = env.limit - v_2;
+                break 'lab1;
+            }
+            // delete, line 125
+            if !env.slice_del() {
+                return false;
+            }
+            if among_var == 0 {
+                env.cursor = env.limit - v_2;
+                break 'lab1;
+            } else if among_var == 1 {
+                // (, line 126
+                // [, line 126
+                env.ket = env.cursor;
+                // literal, line 126
+                if !env.eq_s_b(&"at") {
+                    env.cursor = env.limit - v_2;
+                    break 'lab1;
+                }
+                // ], line 126
+                env.bra = env.cursor;
+                // call R2, line 126
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_2;
+                    break 'lab1;
+                }
+                // delete, line 126
+                if !env.slice_del() {
+                    return false;
+                }
+            }
+            break 'lab1;
+        }
+    } else if among_var == 7 {
+        // (, line 134
+        // call R2, line 135
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 135
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 136
+        let v_3 = env.limit - env.cursor;
+        'lab2: loop {
+            // (, line 136
+            // [, line 137
+            env.ket = env.cursor;
+            // substring, line 137
+            among_var = env.find_among_b(A_4, context);
+            if among_var == 0 {
+                env.cursor = env.limit - v_3;
+                break 'lab2;
+            }
+            // ], line 137
+            env.bra = env.cursor;
+            if among_var == 0 {
+                env.cursor = env.limit - v_3;
+                break 'lab2;
+            } else if among_var == 1 {
+                // (, line 140
+                // call R2, line 140
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_3;
+                    break 'lab2;
+                }
+                // delete, line 140
+                if !env.slice_del() {
+                    return false;
+                }
+            }
+            break 'lab2;
+        }
+    } else if among_var == 8 {
+        // (, line 146
+        // call R2, line 147
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 147
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 148
+        let v_4 = env.limit - env.cursor;
+        'lab3: loop {
+            // (, line 148
+            // [, line 149
+            env.ket = env.cursor;
+            // substring, line 149
+            among_var = env.find_among_b(A_5, context);
+            if among_var == 0 {
+                env.cursor = env.limit - v_4;
+                break 'lab3;
+            }
+            // ], line 149
+            env.bra = env.cursor;
+            if among_var == 0 {
+                env.cursor = env.limit - v_4;
+                break 'lab3;
+            } else if among_var == 1 {
+                // (, line 152
+                // call R2, line 152
+                if !r_R2(env, context) {
+                    env.cursor = env.limit - v_4;
+                    break 'lab3;
+                }
+                // delete, line 152
+                if !env.slice_del() {
+                    return false;
+                }
+            }
+            break 'lab3;
+        }
+    } else if among_var == 9 {
+        // (, line 158
+        // call R2, line 159
+        if !r_R2(env, context) {
+            return false;
+        }
+        // delete, line 159
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 160
+        let v_5 = env.limit - env.cursor;
+        'lab4: loop {
+            // (, line 160
+            // [, line 161
+            env.ket = env.cursor;
+            // literal, line 161
+            if !env.eq_s_b(&"at") {
+                env.cursor = env.limit - v_5;
+                break 'lab4;
+            }
+            // ], line 161
+            env.bra = env.cursor;
+            // call R2, line 161
+            if !r_R2(env, context) {
+                env.cursor = env.limit - v_5;
+                break 'lab4;
+            }
+            // delete, line 161
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab4;
+        }
+    }
+    return true;
+}
+
+fn r_y_verb_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 167
+    // setlimit, line 168
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 168
+    if env.cursor < context.i_pV {
+        return false;
+    }
+    env.cursor = context.i_pV;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 168
+    // [, line 168
+    env.ket = env.cursor;
+    // substring, line 168
+    among_var = env.find_among_b(A_7, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 168
+    env.bra = env.cursor;
+    env.limit_backward = v_2;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 171
+        // literal, line 171
+        if !env.eq_s_b(&"u") {
+            return false;
+        }
+        // delete, line 171
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_verb_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 175
+    // setlimit, line 176
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 176
+    if env.cursor < context.i_pV {
+        return false;
+    }
+    env.cursor = context.i_pV;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 176
+    // [, line 176
+    env.ket = env.cursor;
+    // substring, line 176
+    among_var = env.find_among_b(A_8, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 176
+    env.bra = env.cursor;
+    env.limit_backward = v_2;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 179
+        // try, line 179
+        let v_3 = env.limit - env.cursor;
+        'lab0: loop {
+            // (, line 179
+            // literal, line 179
+            if !env.eq_s_b(&"u") {
+                env.cursor = env.limit - v_3;
+                break 'lab0;
+            }
+            // test, line 179
+            let v_4 = env.limit - env.cursor;
+            // literal, line 179
+            if !env.eq_s_b(&"g") {
+                env.cursor = env.limit - v_3;
+                break 'lab0;
+            }
+            env.cursor = env.limit - v_4;
+            break 'lab0;
+        }
+        // ], line 179
+        env.bra = env.cursor;
+        // delete, line 179
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 200
+        // delete, line 200
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_residual_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 204
+    // [, line 205
+    env.ket = env.cursor;
+    // substring, line 205
+    among_var = env.find_among_b(A_9, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 205
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 208
+        // call RV, line 208
+        if !r_RV(env, context) {
+            return false;
+        }
+        // delete, line 208
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 210
+        // call RV, line 210
+        if !r_RV(env, context) {
+            return false;
+        }
+        // delete, line 210
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 210
+        let v_1 = env.limit - env.cursor;
+        'lab0: loop {
+            // (, line 210
+            // [, line 210
+            env.ket = env.cursor;
+            // literal, line 210
+            if !env.eq_s_b(&"u") {
+                env.cursor = env.limit - v_1;
+                break 'lab0;
+            }
+            // ], line 210
+            env.bra = env.cursor;
+            // test, line 210
+            let v_2 = env.limit - env.cursor;
+            // literal, line 210
+            if !env.eq_s_b(&"g") {
+                env.cursor = env.limit - v_1;
+                break 'lab0;
+            }
+            env.cursor = env.limit - v_2;
+            // call RV, line 210
+            if !r_RV(env, context) {
+                env.cursor = env.limit - v_1;
+                break 'lab0;
+            }
+            // delete, line 210
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab0;
+        }
+    }
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        i_p2: 0,
+        i_p1: 0,
+        i_pV: 0,
+    };
+    // (, line 215
+    // do, line 216
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call mark_regions, line 216
+        if !r_mark_regions(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // backwards, line 217
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 217
+    // do, line 218
+    let v_2 = env.limit - env.cursor;
+    'lab1: loop {
+        // call attached_pronoun, line 218
+        if !r_attached_pronoun(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = env.limit - v_2;
+    // do, line 219
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // (, line 219
+        // or, line 219
+        'lab3: loop {
+            let v_4 = env.limit - env.cursor;
+            'lab4: loop {
+                // call standard_suffix, line 219
+                if !r_standard_suffix(env, context) {
+                    break 'lab4;
+                }
+                break 'lab3;
+            }
+            env.cursor = env.limit - v_4;
+            'lab5: loop {
+                // call y_verb_suffix, line 220
+                if !r_y_verb_suffix(env, context) {
+                    break 'lab5;
+                }
+                break 'lab3;
+            }
+            env.cursor = env.limit - v_4;
+            // call verb_suffix, line 221
+            if !r_verb_suffix(env, context) {
+                break 'lab2;
+            }
+            break 'lab3;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    // do, line 223
+    let v_5 = env.limit - env.cursor;
+    'lab6: loop {
+        // call residual_suffix, line 223
+        if !r_residual_suffix(env, context) {
+            break 'lab6;
+        }
+        break 'lab6;
+    }
+    env.cursor = env.limit - v_5;
+    env.cursor = env.limit_backward;
+    // do, line 225
+    let v_6 = env.cursor;
+    'lab7: loop {
+        // call postlude, line 225
+        if !r_postlude(env, context) {
+            break 'lab7;
+        }
+        break 'lab7;
+    }
+    env.cursor = v_6;
+    return true;
+}
diff --git a/src/snowball/algorithms/swedish.rs b/src/snowball/algorithms/swedish.rs
new file mode 100644
index 0000000..08744d8
--- /dev/null
+++ b/src/snowball/algorithms/swedish.rs
@@ -0,0 +1,323 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 37] = &[
+    Among("a", -1, 1, None),
+    Among("arna", 0, 1, None),
+    Among("erna", 0, 1, None),
+    Among("heterna", 2, 1, None),
+    Among("orna", 0, 1, None),
+    Among("ad", -1, 1, None),
+    Among("e", -1, 1, None),
+    Among("ade", 6, 1, None),
+    Among("ande", 6, 1, None),
+    Among("arne", 6, 1, None),
+    Among("are", 6, 1, None),
+    Among("aste", 6, 1, None),
+    Among("en", -1, 1, None),
+    Among("anden", 12, 1, None),
+    Among("aren", 12, 1, None),
+    Among("heten", 12, 1, None),
+    Among("ern", -1, 1, None),
+    Among("ar", -1, 1, None),
+    Among("er", -1, 1, None),
+    Among("heter", 18, 1, None),
+    Among("or", -1, 1, None),
+    Among("s", -1, 2, None),
+    Among("as", 21, 1, None),
+    Among("arnas", 22, 1, None),
+    Among("ernas", 22, 1, None),
+    Among("ornas", 22, 1, None),
+    Among("es", 21, 1, None),
+    Among("ades", 26, 1, None),
+    Among("andes", 26, 1, None),
+    Among("ens", 21, 1, None),
+    Among("arens", 29, 1, None),
+    Among("hetens", 29, 1, None),
+    Among("erns", 21, 1, None),
+    Among("at", -1, 1, None),
+    Among("andet", -1, 1, None),
+    Among("het", -1, 1, None),
+    Among("ast", -1, 1, None),
+];
+
+static A_1: &'static [Among<Context>; 7] = &[
+    Among("dd", -1, -1, None),
+    Among("gd", -1, -1, None),
+    Among("nn", -1, -1, None),
+    Among("dt", -1, -1, None),
+    Among("gt", -1, -1, None),
+    Among("kt", -1, -1, None),
+    Among("tt", -1, -1, None),
+];
+
+static A_2: &'static [Among<Context>; 5] = &[
+    Among("ig", -1, 1, None),
+    Among("lig", 0, 1, None),
+    Among("els", -1, 1, None),
+    Among("fullt", -1, 3, None),
+    Among("l\u{00F6}st", -1, 2, None),
+];
+
+static G_v: &'static [u8; 19] = &[17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 32];
+
+static G_s_ending: &'static [u8; 3] = &[119, 127, 149];
+
+#[derive(Clone)]
+struct Context {
+    i_x: usize,
+    i_p1: usize,
+}
+
+fn r_mark_regions(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 26
+    context.i_p1 = env.limit;
+    // test, line 29
+    let v_1 = env.cursor;
+    // (, line 29
+    // hop, line 29
+    let c = env.byte_index_for_hop(3);
+    if 0 as i32 > c || c > env.limit as i32 {
+        return false;
+    }
+    env.cursor = c as usize;
+    // setmark x, line 29
+    context.i_x = env.cursor;
+    env.cursor = v_1;
+    // goto, line 30
+    'golab0: loop {
+        let v_2 = env.cursor;
+        'lab1: loop {
+            if !env.in_grouping(G_v, 97, 246) {
+                break 'lab1;
+            }
+            env.cursor = v_2;
+            break 'golab0;
+        }
+        env.cursor = v_2;
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // gopast, line 30
+    'golab2: loop {
+        'lab3: loop {
+            if !env.out_grouping(G_v, 97, 246) {
+                break 'lab3;
+            }
+            break 'golab2;
+        }
+        if env.cursor >= env.limit {
+            return false;
+        }
+        env.next_char();
+    }
+    // setmark p1, line 30
+    context.i_p1 = env.cursor;
+    // try, line 31
+    'lab4: loop {
+        // (, line 31
+        if !(context.i_p1 < context.i_x){
+            break 'lab4;
+        }
+        context.i_p1 = context.i_x;
+        break 'lab4;
+    }
+    return true;
+}
+
+fn r_main_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 36
+    // setlimit, line 37
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 37
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    env.cursor = context.i_p1;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 37
+    // [, line 37
+    env.ket = env.cursor;
+    // substring, line 37
+    among_var = env.find_among_b(A_0, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 37
+    env.bra = env.cursor;
+    env.limit_backward = v_2;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 44
+        // delete, line 44
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 46
+        if !env.in_grouping_b(G_s_ending, 98, 121) {
+            return false;
+        }
+        // delete, line 46
+        if !env.slice_del() {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_consonant_pair(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // setlimit, line 50
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 50
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    env.cursor = context.i_p1;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 50
+    // and, line 52
+    let v_3 = env.limit - env.cursor;
+    // among, line 51
+    if env.find_among_b(A_1, context) == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    env.cursor = env.limit - v_3;
+    // (, line 52
+    // [, line 52
+    env.ket = env.cursor;
+    // next, line 52
+    if env.cursor <= env.limit_backward {
+        env.limit_backward = v_2;
+        return false;
+    }
+    env.previous_char();
+    // ], line 52
+    env.bra = env.cursor;
+    // delete, line 52
+    if !env.slice_del() {
+        return false;
+    }
+    env.limit_backward = v_2;
+    return true;
+}
+
+fn r_other_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // setlimit, line 55
+    let v_1 = env.limit - env.cursor;
+    // tomark, line 55
+    if env.cursor < context.i_p1 {
+        return false;
+    }
+    env.cursor = context.i_p1;
+    let v_2 = env.limit_backward;
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit - v_1;
+    // (, line 55
+    // [, line 56
+    env.ket = env.cursor;
+    // substring, line 56
+    among_var = env.find_among_b(A_2, context);
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    }
+    // ], line 56
+    env.bra = env.cursor;
+    if among_var == 0 {
+        env.limit_backward = v_2;
+        return false;
+    } else if among_var == 1 {
+        // (, line 57
+        // delete, line 57
+        if !env.slice_del() {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 58
+        // <-, line 58
+        if !env.slice_from("l\u{00F6}s") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 59
+        // <-, line 59
+        if !env.slice_from("full") {
+            return false;
+        }
+    }
+    env.limit_backward = v_2;
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        i_x: 0,
+        i_p1: 0,
+    };
+    // (, line 64
+    // do, line 66
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call mark_regions, line 66
+        if !r_mark_regions(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // backwards, line 67
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 67
+    // do, line 68
+    let v_2 = env.limit - env.cursor;
+    'lab1: loop {
+        // call main_suffix, line 68
+        if !r_main_suffix(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = env.limit - v_2;
+    // do, line 69
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // call consonant_pair, line 69
+        if !r_consonant_pair(env, context) {
+            break 'lab2;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    // do, line 70
+    let v_4 = env.limit - env.cursor;
+    'lab3: loop {
+        // call other_suffix, line 70
+        if !r_other_suffix(env, context) {
+            break 'lab3;
+        }
+        break 'lab3;
+    }
+    env.cursor = env.limit - v_4;
+    env.cursor = env.limit_backward;
+    return true;
+}
diff --git a/src/snowball/algorithms/tamil.rs b/src/snowball/algorithms/tamil.rs
new file mode 100644
index 0000000..4fcec0f
--- /dev/null
+++ b/src/snowball/algorithms/tamil.rs
@@ -0,0 +1,2523 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 10] = &[
+    Among("\u{0B95}", -1, -1, None),
+    Among("\u{0B99}", -1, -1, None),
+    Among("\u{0B9A}", -1, -1, None),
+    Among("\u{0B9E}", -1, -1, None),
+    Among("\u{0BA4}", -1, -1, None),
+    Among("\u{0BA8}", -1, -1, None),
+    Among("\u{0BAA}", -1, -1, None),
+    Among("\u{0BAE}", -1, -1, None),
+    Among("\u{0BAF}", -1, -1, None),
+    Among("\u{0BB5}", -1, -1, None),
+];
+
+static A_1: &'static [Among<Context>; 3] = &[
+    Among("\u{0BA8}\u{0BCD}\u{0BA4}\u{0BCD}", -1, -1, None),
+    Among("\u{0BA8}\u{0BCD}", -1, -1, None),
+    Among("\u{0BA8}\u{0BCD}\u{0BA4}", -1, -1, None),
+];
+
+static A_2: &'static [Among<Context>; 3] = &[
+    Among("\u{0BC0}", -1, -1, None),
+    Among("\u{0BC8}", -1, -1, None),
+    Among("\u{0BBF}", -1, -1, None),
+];
+
+static A_3: &'static [Among<Context>; 6] = &[
+    Among("\u{0B95}", -1, -1, None),
+    Among("\u{0B9A}", -1, -1, None),
+    Among("\u{0B9F}", -1, -1, None),
+    Among("\u{0BA4}", -1, -1, None),
+    Among("\u{0BAA}", -1, -1, None),
+    Among("\u{0BB1}", -1, -1, None),
+];
+
+static A_4: &'static [Among<Context>; 6] = &[
+    Among("\u{0B95}", -1, -1, None),
+    Among("\u{0B9A}", -1, -1, None),
+    Among("\u{0B9F}", -1, -1, None),
+    Among("\u{0BA4}", -1, -1, None),
+    Among("\u{0BAA}", -1, -1, None),
+    Among("\u{0BB1}", -1, -1, None),
+];
+
+static A_5: &'static [Among<Context>; 6] = &[
+    Among("\u{0B95}", -1, -1, None),
+    Among("\u{0B9A}", -1, -1, None),
+    Among("\u{0B9F}", -1, -1, None),
+    Among("\u{0BA4}", -1, -1, None),
+    Among("\u{0BAA}", -1, -1, None),
+    Among("\u{0BB1}", -1, -1, None),
+];
+
+static A_6: &'static [Among<Context>; 6] = &[
+    Among("\u{0BAF}", -1, -1, None),
+    Among("\u{0BB0}", -1, -1, None),
+    Among("\u{0BB2}", -1, -1, None),
+    Among("\u{0BB3}", -1, -1, None),
+    Among("\u{0BB4}", -1, -1, None),
+    Among("\u{0BB5}", -1, -1, None),
+];
+
+static A_7: &'static [Among<Context>; 6] = &[
+    Among("\u{0B99}", -1, -1, None),
+    Among("\u{0B9E}", -1, -1, None),
+    Among("\u{0BA3}", -1, -1, None),
+    Among("\u{0BA8}", -1, -1, None),
+    Among("\u{0BA9}", -1, -1, None),
+    Among("\u{0BAE}", -1, -1, None),
+];
+
+static A_8: &'static [Among<Context>; 3] = &[
+    Among("\u{0BB5}\u{0BCD}", -1, -1, None),
+    Among("\u{0BAF}", -1, -1, None),
+    Among("\u{0BB5}", -1, -1, None),
+];
+
+static A_9: &'static [Among<Context>; 8] = &[
+    Among("\u{0BC0}", -1, -1, None),
+    Among("\u{0BC1}", -1, -1, None),
+    Among("\u{0BC2}", -1, -1, None),
+    Among("\u{0BC6}", -1, -1, None),
+    Among("\u{0BC7}", -1, -1, None),
+    Among("\u{0BC8}", -1, -1, None),
+    Among("\u{0BBE}", -1, -1, None),
+    Among("\u{0BBF}", -1, -1, None),
+];
+
+static A_10: &'static [Among<Context>; 8] = &[
+    Among("\u{0BC0}", -1, -1, None),
+    Among("\u{0BC1}", -1, -1, None),
+    Among("\u{0BC2}", -1, -1, None),
+    Among("\u{0BC6}", -1, -1, None),
+    Among("\u{0BC7}", -1, -1, None),
+    Among("\u{0BC8}", -1, -1, None),
+    Among("\u{0BBE}", -1, -1, None),
+    Among("\u{0BBF}", -1, -1, None),
+];
+
+static A_11: &'static [Among<Context>; 3] = &[
+    Among("\u{0B85}", -1, -1, None),
+    Among("\u{0B87}", -1, -1, None),
+    Among("\u{0B89}", -1, -1, None),
+];
+
+static A_12: &'static [Among<Context>; 10] = &[
+    Among("\u{0B95}", -1, -1, None),
+    Among("\u{0B99}", -1, -1, None),
+    Among("\u{0B9A}", -1, -1, None),
+    Among("\u{0B9E}", -1, -1, None),
+    Among("\u{0BA4}", -1, -1, None),
+    Among("\u{0BA8}", -1, -1, None),
+    Among("\u{0BAA}", -1, -1, None),
+    Among("\u{0BAE}", -1, -1, None),
+    Among("\u{0BAF}", -1, -1, None),
+    Among("\u{0BB5}", -1, -1, None),
+];
+
+static A_13: &'static [Among<Context>; 6] = &[
+    Among("\u{0B95}", -1, -1, None),
+    Among("\u{0B9A}", -1, -1, None),
+    Among("\u{0B9F}", -1, -1, None),
+    Among("\u{0BA4}", -1, -1, None),
+    Among("\u{0BAA}", -1, -1, None),
+    Among("\u{0BB1}", -1, -1, None),
+];
+
+static A_14: &'static [Among<Context>; 3] = &[
+    Among("\u{0BC7}", -1, -1, None),
+    Among("\u{0BCB}", -1, -1, None),
+    Among("\u{0BBE}", -1, -1, None),
+];
+
+static A_15: &'static [Among<Context>; 2] = &[
+    Among("\u{0BAA}\u{0BBF}", -1, -1, None),
+    Among("\u{0BB5}\u{0BBF}", -1, -1, None),
+];
+
+static A_16: &'static [Among<Context>; 8] = &[
+    Among("\u{0BC0}", -1, -1, None),
+    Among("\u{0BC1}", -1, -1, None),
+    Among("\u{0BC2}", -1, -1, None),
+    Among("\u{0BC6}", -1, -1, None),
+    Among("\u{0BC7}", -1, -1, None),
+    Among("\u{0BC8}", -1, -1, None),
+    Among("\u{0BBE}", -1, -1, None),
+    Among("\u{0BBF}", -1, -1, None),
+];
+
+static A_17: &'static [Among<Context>; 13] = &[
+    Among("\u{0BAA}\u{0B9F}\u{0BCD}\u{0B9F}\u{0BC1}", -1, -1, None),
+    Among("\u{0BB5}\u{0BBF}\u{0B9F}\u{0BCD}\u{0B9F}\u{0BC1}", -1, -1, None),
+    Among("\u{0BAA}\u{0B9F}\u{0BC1}", -1, -1, None),
+    Among("\u{0BB5}\u{0BBF}\u{0B9F}\u{0BC1}", -1, -1, None),
+    Among("\u{0BAA}\u{0B9F}\u{0BCD}\u{0B9F}\u{0BA4}\u{0BC1}", -1, -1, None),
+    Among("\u{0BC6}\u{0BB2}\u{0BCD}\u{0BB2}\u{0BBE}\u{0BAE}\u{0BCD}", -1, -1, None),
+    Among("\u{0BAA}\u{0B9F}\u{0BCD}\u{0B9F}", -1, -1, None),
+    Among("\u{0BAA}\u{0B9F}\u{0BCD}\u{0B9F}\u{0BA3}", -1, -1, None),
+    Among("\u{0BA4}\u{0BBE}\u{0BA9}", -1, -1, None),
+    Among("\u{0BAA}\u{0B9F}\u{0BBF}\u{0BA4}\u{0BBE}\u{0BA9}", 8, -1, None),
+    Among("\u{0B95}\u{0BC1}\u{0BB0}\u{0BBF}\u{0BAF}", -1, -1, None),
+    Among("\u{0BAA}\u{0B9F}\u{0BBF}", -1, -1, None),
+    Among("\u{0BAA}\u{0BB1}\u{0BCD}\u{0BB1}\u{0BBF}", -1, -1, None),
+];
+
+static A_18: &'static [Among<Context>; 6] = &[
+    Among("\u{0B95}", -1, -1, None),
+    Among("\u{0B9A}", -1, -1, None),
+    Among("\u{0B9F}", -1, -1, None),
+    Among("\u{0BA4}", -1, -1, None),
+    Among("\u{0BAA}", -1, -1, None),
+    Among("\u{0BB1}", -1, -1, None),
+];
+
+static A_19: &'static [Among<Context>; 6] = &[
+    Among("\u{0B95}", -1, -1, None),
+    Among("\u{0B9A}", -1, -1, None),
+    Among("\u{0B9F}", -1, -1, None),
+    Among("\u{0BA4}", -1, -1, None),
+    Among("\u{0BAA}", -1, -1, None),
+    Among("\u{0BB1}", -1, -1, None),
+];
+
+static A_20: &'static [Among<Context>; 8] = &[
+    Among("\u{0BC0}", -1, -1, None),
+    Among("\u{0BC1}", -1, -1, None),
+    Among("\u{0BC2}", -1, -1, None),
+    Among("\u{0BC6}", -1, -1, None),
+    Among("\u{0BC7}", -1, -1, None),
+    Among("\u{0BC8}", -1, -1, None),
+    Among("\u{0BBE}", -1, -1, None),
+    Among("\u{0BBF}", -1, -1, None),
+];
+
+static A_21: &'static [Among<Context>; 8] = &[
+    Among("\u{0BC0}", -1, -1, None),
+    Among("\u{0BC1}", -1, -1, None),
+    Among("\u{0BC2}", -1, -1, None),
+    Among("\u{0BC6}", -1, -1, None),
+    Among("\u{0BC7}", -1, -1, None),
+    Among("\u{0BC8}", -1, -1, None),
+    Among("\u{0BBE}", -1, -1, None),
+    Among("\u{0BBF}", -1, -1, None),
+];
+
+static A_22: &'static [Among<Context>; 2] = &[
+    Among("\u{0BAA}\u{0B9F}\u{0BC1}", -1, -1, None),
+    Among("\u{0B95}\u{0BCA}\u{0BA3}\u{0BCD}\u{0B9F}\u{0BBF}\u{0BB0}\u{0BCD}", -1, -1, None),
+];
+
+static A_23: &'static [Among<Context>; 12] = &[
+    Among("\u{0B85}", -1, -1, None),
+    Among("\u{0B86}", -1, -1, None),
+    Among("\u{0B87}", -1, -1, None),
+    Among("\u{0B88}", -1, -1, None),
+    Among("\u{0B89}", -1, -1, None),
+    Among("\u{0B8A}", -1, -1, None),
+    Among("\u{0B8E}", -1, -1, None),
+    Among("\u{0B8F}", -1, -1, None),
+    Among("\u{0B90}", -1, -1, None),
+    Among("\u{0B92}", -1, -1, None),
+    Among("\u{0B93}", -1, -1, None),
+    Among("\u{0B94}", -1, -1, None),
+];
+
+static A_24: &'static [Among<Context>; 8] = &[
+    Among("\u{0BC0}", -1, -1, None),
+    Among("\u{0BC1}", -1, -1, None),
+    Among("\u{0BC2}", -1, -1, None),
+    Among("\u{0BC6}", -1, -1, None),
+    Among("\u{0BC7}", -1, -1, None),
+    Among("\u{0BC8}", -1, -1, None),
+    Among("\u{0BBE}", -1, -1, None),
+    Among("\u{0BBF}", -1, -1, None),
+];
+
+static A_25: &'static [Among<Context>; 6] = &[
+    Among("\u{0B95}\u{0BBF}\u{0BA9}\u{0BCD}\u{0BB1}\u{0BCD}", -1, -1, None),
+    Among("\u{0BBE}\u{0BA8}\u{0BBF}\u{0BA9}\u{0BCD}\u{0BB1}\u{0BCD}", -1, -1, None),
+    Among("\u{0B95}\u{0BBF}\u{0BB1}\u{0BCD}", -1, -1, None),
+    Among("\u{0B95}\u{0BBF}\u{0BA9}\u{0BCD}\u{0BB1}", -1, -1, None),
+    Among("\u{0BBE}\u{0BA8}\u{0BBF}\u{0BA9}\u{0BCD}\u{0BB1}", -1, -1, None),
+    Among("\u{0B95}\u{0BBF}\u{0BB1}", -1, -1, None),
+];
+
+#[derive(Clone)]
+struct Context {
+    i_length: usize,
+    b_found_wrong_ending: bool,
+    b_found_vetrumai_urupu: bool,
+    b_found_a_match: bool,
+}
+
+fn r_has_min_length(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 104
+    context.i_length = env.current.chars().count();
+    if !(context.i_length > 4){
+        return false;
+    }
+    return true;
+}
+
+fn r_fix_va_start(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 109
+    // or, line 110
+    'lab0: loop {
+        let v_1 = env.cursor;
+        'lab1: loop {
+            // (, line 110
+            // and, line 110
+            let v_2 = env.cursor;
+            // try, line 110
+            let v_3 = env.cursor;
+            'lab2: loop {
+                // literal, line 110
+                if !env.eq_s(&"\u{0BB5}\u{0BCB}") {
+                    env.cursor = v_3;
+                    break 'lab2;
+                }
+                break 'lab2;
+            }
+            env.cursor = v_2;
+            // [, line 110
+            env.bra = env.cursor;
+            // literal, line 110
+            if !env.eq_s(&"\u{0BB5}\u{0BCB}") {
+                break 'lab1;
+            }
+            // ], line 110
+            env.ket = env.cursor;
+            // <-, line 110
+            if !env.slice_from("\u{0B93}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = v_1;
+        'lab3: loop {
+            // (, line 111
+            // and, line 111
+            let v_4 = env.cursor;
+            // try, line 111
+            let v_5 = env.cursor;
+            'lab4: loop {
+                // literal, line 111
+                if !env.eq_s(&"\u{0BB5}\u{0BCA}") {
+                    env.cursor = v_5;
+                    break 'lab4;
+                }
+                break 'lab4;
+            }
+            env.cursor = v_4;
+            // [, line 111
+            env.bra = env.cursor;
+            // literal, line 111
+            if !env.eq_s(&"\u{0BB5}\u{0BCA}") {
+                break 'lab3;
+            }
+            // ], line 111
+            env.ket = env.cursor;
+            // <-, line 111
+            if !env.slice_from("\u{0B92}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = v_1;
+        'lab5: loop {
+            // (, line 112
+            // and, line 112
+            let v_6 = env.cursor;
+            // try, line 112
+            let v_7 = env.cursor;
+            'lab6: loop {
+                // literal, line 112
+                if !env.eq_s(&"\u{0BB5}\u{0BC1}") {
+                    env.cursor = v_7;
+                    break 'lab6;
+                }
+                break 'lab6;
+            }
+            env.cursor = v_6;
+            // [, line 112
+            env.bra = env.cursor;
+            // literal, line 112
+            if !env.eq_s(&"\u{0BB5}\u{0BC1}") {
+                break 'lab5;
+            }
+            // ], line 112
+            env.ket = env.cursor;
+            // <-, line 112
+            if !env.slice_from("\u{0B89}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = v_1;
+        // (, line 113
+        // and, line 113
+        let v_8 = env.cursor;
+        // try, line 113
+        let v_9 = env.cursor;
+        'lab7: loop {
+            // literal, line 113
+            if !env.eq_s(&"\u{0BB5}\u{0BC2}") {
+                env.cursor = v_9;
+                break 'lab7;
+            }
+            break 'lab7;
+        }
+        env.cursor = v_8;
+        // [, line 113
+        env.bra = env.cursor;
+        // literal, line 113
+        if !env.eq_s(&"\u{0BB5}\u{0BC2}") {
+            return false;
+        }
+        // ], line 113
+        env.ket = env.cursor;
+        // <-, line 113
+        if !env.slice_from("\u{0B8A}") {
+            return false;
+        }
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_fix_endings(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 116
+    // set found_wrong_ending, line 117
+    context.b_found_wrong_ending = true;
+    // repeat, line 118
+    'replab0: loop{
+        let v_1 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 118
+            // Boolean test found_wrong_ending, line 118
+            if !context.b_found_wrong_ending {
+                break 'lab1;
+            }
+            // (, line 118
+            // do, line 118
+            let v_2 = env.cursor;
+            'lab2: loop {
+                // call fix_ending, line 118
+                if !r_fix_ending(env, context) {
+                    break 'lab2;
+                }
+                break 'lab2;
+            }
+            env.cursor = v_2;
+            continue 'replab0;
+        }
+        env.cursor = v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+fn r_remove_question_prefixes(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 121
+    // [, line 122
+    env.bra = env.cursor;
+    // (, line 122
+    // literal, line 122
+    if !env.eq_s(&"\u{0B8E}") {
+        return false;
+    }
+    // among, line 122
+    if env.find_among(A_0, context) == 0 {
+        return false;
+    }
+    // literal, line 122
+    if !env.eq_s(&"\u{0BCD}") {
+        return false;
+    }
+    // ], line 122
+    env.ket = env.cursor;
+    // delete, line 122
+    if !env.slice_del() {
+        return false;
+    }
+    // do, line 123
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call fix_va_start, line 123
+        if !r_fix_va_start(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    return true;
+}
+
+fn r_fix_ending(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 126
+    // unset found_wrong_ending, line 127
+    context.b_found_wrong_ending = false;
+    context.i_length = env.current.chars().count();
+    if !(context.i_length > 3){
+        return false;
+    }
+    // backwards, line 130
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 130
+    // or, line 132
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 131
+            // [, line 131
+            env.ket = env.cursor;
+            // among, line 131
+            if env.find_among_b(A_1, context) == 0 {
+                break 'lab1;
+            }
+            // ], line 131
+            env.bra = env.cursor;
+            // delete, line 131
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab2: loop {
+            // (, line 133
+            // [, line 133
+            env.ket = env.cursor;
+            // literal, line 133
+            if !env.eq_s_b(&"\u{0BAF}\u{0BCD}") {
+                break 'lab2;
+            }
+            // test, line 133
+            let v_2 = env.limit - env.cursor;
+            // among, line 133
+            if env.find_among_b(A_2, context) == 0 {
+                break 'lab2;
+            }
+            env.cursor = env.limit - v_2;
+            // ], line 133
+            env.bra = env.cursor;
+            // delete, line 133
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab3: loop {
+            // (, line 135
+            // [, line 135
+            env.ket = env.cursor;
+            // or, line 135
+            'lab4: loop {
+                let v_3 = env.limit - env.cursor;
+                'lab5: loop {
+                    // literal, line 135
+                    if !env.eq_s_b(&"\u{0B9F}\u{0BCD}\u{0BAA}\u{0BCD}") {
+                        break 'lab5;
+                    }
+                    break 'lab4;
+                }
+                env.cursor = env.limit - v_3;
+                // literal, line 135
+                if !env.eq_s_b(&"\u{0B9F}\u{0BCD}\u{0B95}\u{0BCD}") {
+                    break 'lab3;
+                }
+                break 'lab4;
+            }
+            // ], line 135
+            env.bra = env.cursor;
+            // <-, line 135
+            if !env.slice_from("\u{0BB3}\u{0BCD}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab6: loop {
+            // (, line 137
+            // [, line 137
+            env.ket = env.cursor;
+            // literal, line 137
+            if !env.eq_s_b(&"\u{0BA9}\u{0BCD}\u{0BB1}\u{0BCD}") {
+                break 'lab6;
+            }
+            // ], line 137
+            env.bra = env.cursor;
+            // <-, line 137
+            if !env.slice_from("\u{0BB2}\u{0BCD}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab7: loop {
+            // (, line 140
+            // [, line 140
+            env.ket = env.cursor;
+            // literal, line 140
+            if !env.eq_s_b(&"\u{0BB1}\u{0BCD}\u{0B95}\u{0BCD}") {
+                break 'lab7;
+            }
+            // ], line 140
+            env.bra = env.cursor;
+            // <-, line 140
+            if !env.slice_from("\u{0BB2}\u{0BCD}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab8: loop {
+            // (, line 142
+            // [, line 142
+            env.ket = env.cursor;
+            // literal, line 142
+            if !env.eq_s_b(&"\u{0B9F}\u{0BCD}\u{0B9F}\u{0BCD}") {
+                break 'lab8;
+            }
+            // ], line 142
+            env.bra = env.cursor;
+            // <-, line 142
+            if !env.slice_from("\u{0B9F}\u{0BC1}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab9: loop {
+            // (, line 144
+            // Boolean test found_vetrumai_urupu, line 144
+            if !context.b_found_vetrumai_urupu {
+                break 'lab9;
+            }
+            // [, line 144
+            env.ket = env.cursor;
+            // literal, line 144
+            if !env.eq_s_b(&"\u{0BA4}\u{0BCD}\u{0BA4}\u{0BCD}") {
+                break 'lab9;
+            }
+            // (, line 144
+            // test, line 144
+            let v_4 = env.limit - env.cursor;
+            // not, line 144
+            let v_5 = env.limit - env.cursor;
+            'lab10: loop {
+                // literal, line 144
+                if !env.eq_s_b(&"\u{0BC8}") {
+                    break 'lab10;
+                }
+                break 'lab9;
+            }
+            env.cursor = env.limit - v_5;
+            env.cursor = env.limit - v_4;
+            // ], line 144
+            env.bra = env.cursor;
+            // <-, line 144
+            if !env.slice_from("\u{0BAE}\u{0BCD}") {
+                return false;
+            }
+            // ], line 144
+            env.bra = env.cursor;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab11: loop {
+            // (, line 146
+            // [, line 146
+            env.ket = env.cursor;
+            // or, line 146
+            'lab12: loop {
+                let v_6 = env.limit - env.cursor;
+                'lab13: loop {
+                    // literal, line 146
+                    if !env.eq_s_b(&"\u{0BC1}\u{0B95}\u{0BCD}") {
+                        break 'lab13;
+                    }
+                    break 'lab12;
+                }
+                env.cursor = env.limit - v_6;
+                // literal, line 146
+                if !env.eq_s_b(&"\u{0BC1}\u{0B95}\u{0BCD}\u{0B95}\u{0BCD}") {
+                    break 'lab11;
+                }
+                break 'lab12;
+            }
+            // ], line 146
+            env.bra = env.cursor;
+            // <-, line 146
+            if !env.slice_from("\u{0BCD}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab14: loop {
+            // (, line 148
+            // [, line 148
+            env.ket = env.cursor;
+            // literal, line 148
+            if !env.eq_s_b(&"\u{0BCD}") {
+                break 'lab14;
+            }
+            // among, line 148
+            if env.find_among_b(A_3, context) == 0 {
+                break 'lab14;
+            }
+            // literal, line 148
+            if !env.eq_s_b(&"\u{0BCD}") {
+                break 'lab14;
+            }
+            // among, line 148
+            if env.find_among_b(A_4, context) == 0 {
+                break 'lab14;
+            }
+            // ], line 148
+            env.bra = env.cursor;
+            // delete, line 148
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab15: loop {
+            // (, line 150
+            // [, line 150
+            env.ket = env.cursor;
+            // literal, line 150
+            if !env.eq_s_b(&"\u{0BC1}\u{0B95}\u{0BCD}") {
+                break 'lab15;
+            }
+            // ], line 150
+            env.bra = env.cursor;
+            // <-, line 150
+            if !env.slice_from("\u{0BCD}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab16: loop {
+            // (, line 152
+            // [, line 152
+            env.ket = env.cursor;
+            // literal, line 152
+            if !env.eq_s_b(&"\u{0BCD}") {
+                break 'lab16;
+            }
+            // among, line 152
+            if env.find_among_b(A_5, context) == 0 {
+                break 'lab16;
+            }
+            // ], line 152
+            env.bra = env.cursor;
+            // delete, line 152
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab17: loop {
+            // (, line 154
+            // [, line 154
+            env.ket = env.cursor;
+            // literal, line 154
+            if !env.eq_s_b(&"\u{0BCD}") {
+                break 'lab17;
+            }
+            // (, line 154
+            // or, line 154
+            'lab18: loop {
+                let v_7 = env.limit - env.cursor;
+                'lab19: loop {
+                    // among, line 154
+                    if env.find_among_b(A_6, context) == 0 {
+                        break 'lab19;
+                    }
+                    break 'lab18;
+                }
+                env.cursor = env.limit - v_7;
+                // among, line 154
+                if env.find_among_b(A_7, context) == 0 {
+                    break 'lab17;
+                }
+                break 'lab18;
+            }
+            // literal, line 154
+            if !env.eq_s_b(&"\u{0BCD}") {
+                break 'lab17;
+            }
+            // ], line 154
+            env.bra = env.cursor;
+            // <-, line 154
+            if !env.slice_from("\u{0BCD}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab20: loop {
+            // (, line 156
+            // [, line 156
+            env.ket = env.cursor;
+            // among, line 156
+            if env.find_among_b(A_8, context) == 0 {
+                break 'lab20;
+            }
+            // ], line 156
+            env.bra = env.cursor;
+            // delete, line 156
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab21: loop {
+            // (, line 158
+            // [, line 158
+            env.ket = env.cursor;
+            // literal, line 158
+            if !env.eq_s_b(&"\u{0BA9}\u{0BC1}") {
+                break 'lab21;
+            }
+            // (, line 158
+            // test, line 158
+            let v_8 = env.limit - env.cursor;
+            // not, line 158
+            let v_9 = env.limit - env.cursor;
+            'lab22: loop {
+                // among, line 158
+                if env.find_among_b(A_9, context) == 0 {
+                    break 'lab22;
+                }
+                break 'lab21;
+            }
+            env.cursor = env.limit - v_9;
+            env.cursor = env.limit - v_8;
+            // ], line 158
+            env.bra = env.cursor;
+            // delete, line 158
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab23: loop {
+            // (, line 160
+            // [, line 160
+            env.ket = env.cursor;
+            // literal, line 160
+            if !env.eq_s_b(&"\u{0B99}\u{0BCD}") {
+                break 'lab23;
+            }
+            // (, line 160
+            // test, line 160
+            let v_10 = env.limit - env.cursor;
+            // not, line 160
+            let v_11 = env.limit - env.cursor;
+            'lab24: loop {
+                // literal, line 160
+                if !env.eq_s_b(&"\u{0BC8}") {
+                    break 'lab24;
+                }
+                break 'lab23;
+            }
+            env.cursor = env.limit - v_11;
+            env.cursor = env.limit - v_10;
+            // ], line 160
+            env.bra = env.cursor;
+            // <-, line 160
+            if !env.slice_from("\u{0BAE}\u{0BCD}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab25: loop {
+            // (, line 162
+            // [, line 162
+            env.ket = env.cursor;
+            // literal, line 162
+            if !env.eq_s_b(&"\u{0B99}\u{0BCD}") {
+                break 'lab25;
+            }
+            // ], line 162
+            env.bra = env.cursor;
+            // delete, line 162
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 164
+        // [, line 164
+        env.ket = env.cursor;
+        // literal, line 164
+        if !env.eq_s_b(&"\u{0BCD}") {
+            return false;
+        }
+        // (, line 164
+        // test, line 164
+        let v_12 = env.limit - env.cursor;
+        // (, line 164
+        // or, line 164
+        'lab26: loop {
+            let v_13 = env.limit - env.cursor;
+            'lab27: loop {
+                // among, line 164
+                if env.find_among_b(A_10, context) == 0 {
+                    break 'lab27;
+                }
+                break 'lab26;
+            }
+            env.cursor = env.limit - v_13;
+            // literal, line 164
+            if !env.eq_s_b(&"\u{0BCD}") {
+                return false;
+            }
+            break 'lab26;
+        }
+        env.cursor = env.limit - v_12;
+        // ], line 164
+        env.bra = env.cursor;
+        // delete, line 164
+        if !env.slice_del() {
+            return false;
+        }
+        break 'lab0;
+    }
+    env.cursor = env.limit_backward;
+    // set found_wrong_ending, line 167
+    context.b_found_wrong_ending = true;
+    return true;
+}
+
+fn r_remove_pronoun_prefixes(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 170
+    // unset found_a_match, line 171
+    context.b_found_a_match = false;
+    // [, line 172
+    env.bra = env.cursor;
+    // among, line 172
+    if env.find_among(A_11, context) == 0 {
+        return false;
+    }
+    // among, line 172
+    if env.find_among(A_12, context) == 0 {
+        return false;
+    }
+    // literal, line 172
+    if !env.eq_s(&"\u{0BCD}") {
+        return false;
+    }
+    // ], line 172
+    env.ket = env.cursor;
+    // delete, line 172
+    if !env.slice_del() {
+        return false;
+    }
+    // (, line 173
+    // set found_a_match, line 173
+    context.b_found_a_match = true;
+    // do, line 174
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call fix_va_start, line 174
+        if !r_fix_va_start(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    return true;
+}
+
+fn r_remove_plural_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 177
+    // unset found_a_match, line 178
+    context.b_found_a_match = false;
+    // backwards, line 179
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 179
+    // or, line 180
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 180
+            // [, line 180
+            env.ket = env.cursor;
+            // literal, line 180
+            if !env.eq_s_b(&"\u{0BC1}\u{0B99}\u{0BCD}\u{0B95}\u{0BB3}\u{0BCD}") {
+                break 'lab1;
+            }
+            // (, line 180
+            // test, line 180
+            let v_2 = env.limit - env.cursor;
+            // not, line 180
+            let v_3 = env.limit - env.cursor;
+            'lab2: loop {
+                // among, line 180
+                if env.find_among_b(A_13, context) == 0 {
+                    break 'lab2;
+                }
+                break 'lab1;
+            }
+            env.cursor = env.limit - v_3;
+            env.cursor = env.limit - v_2;
+            // ], line 180
+            env.bra = env.cursor;
+            // <-, line 180
+            if !env.slice_from("\u{0BCD}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab3: loop {
+            // (, line 181
+            // [, line 181
+            env.ket = env.cursor;
+            // literal, line 181
+            if !env.eq_s_b(&"\u{0BB1}\u{0BCD}\u{0B95}\u{0BB3}\u{0BCD}") {
+                break 'lab3;
+            }
+            // ], line 181
+            env.bra = env.cursor;
+            // <-, line 181
+            if !env.slice_from("\u{0BB2}\u{0BCD}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab4: loop {
+            // (, line 182
+            // [, line 182
+            env.ket = env.cursor;
+            // literal, line 182
+            if !env.eq_s_b(&"\u{0B9F}\u{0BCD}\u{0B95}\u{0BB3}\u{0BCD}") {
+                break 'lab4;
+            }
+            // ], line 182
+            env.bra = env.cursor;
+            // <-, line 182
+            if !env.slice_from("\u{0BB3}\u{0BCD}") {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 183
+        // [, line 183
+        env.ket = env.cursor;
+        // literal, line 183
+        if !env.eq_s_b(&"\u{0B95}\u{0BB3}\u{0BCD}") {
+            return false;
+        }
+        // ], line 183
+        env.bra = env.cursor;
+        // delete, line 183
+        if !env.slice_del() {
+            return false;
+        }
+        break 'lab0;
+    }
+    // (, line 184
+    // set found_a_match, line 184
+    context.b_found_a_match = true;
+    env.cursor = env.limit_backward;
+    return true;
+}
+
+fn r_remove_question_suffixes(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 188
+    // call has_min_length, line 189
+    if !r_has_min_length(env, context) {
+        return false;
+    }
+    // unset found_a_match, line 190
+    context.b_found_a_match = false;
+    // backwards, line 191
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 191
+    // do, line 192
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 192
+        // [, line 193
+        env.ket = env.cursor;
+        // among, line 193
+        if env.find_among_b(A_14, context) == 0 {
+            break 'lab0;
+        }
+        // ], line 193
+        env.bra = env.cursor;
+        // <-, line 193
+        if !env.slice_from("\u{0BCD}") {
+            return false;
+        }
+        // (, line 194
+        // set found_a_match, line 194
+        context.b_found_a_match = true;
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    env.cursor = env.limit_backward;
+    // do, line 197
+    let v_2 = env.cursor;
+    'lab1: loop {
+        // call fix_endings, line 197
+        if !r_fix_endings(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = v_2;
+    return true;
+}
+
+fn r_remove_command_suffixes(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 200
+    // call has_min_length, line 201
+    if !r_has_min_length(env, context) {
+        return false;
+    }
+    // unset found_a_match, line 202
+    context.b_found_a_match = false;
+    // backwards, line 203
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 203
+    // [, line 204
+    env.ket = env.cursor;
+    // among, line 204
+    if env.find_among_b(A_15, context) == 0 {
+        return false;
+    }
+    // ], line 204
+    env.bra = env.cursor;
+    // delete, line 204
+    if !env.slice_del() {
+        return false;
+    }
+    // (, line 205
+    // set found_a_match, line 205
+    context.b_found_a_match = true;
+    env.cursor = env.limit_backward;
+    return true;
+}
+
+fn r_remove_um(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 209
+    // unset found_a_match, line 210
+    context.b_found_a_match = false;
+    // call has_min_length, line 211
+    if !r_has_min_length(env, context) {
+        return false;
+    }
+    // backwards, line 212
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 212
+    // [, line 212
+    env.ket = env.cursor;
+    // literal, line 212
+    if !env.eq_s_b(&"\u{0BC1}\u{0BAE}\u{0BCD}") {
+        return false;
+    }
+    // ], line 212
+    env.bra = env.cursor;
+    // <-, line 212
+    if !env.slice_from("\u{0BCD}") {
+        return false;
+    }
+    // (, line 213
+    // set found_a_match, line 213
+    context.b_found_a_match = true;
+    env.cursor = env.limit_backward;
+    // do, line 215
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call fix_ending, line 215
+        if !r_fix_ending(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    return true;
+}
+
+fn r_remove_common_word_endings(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 218
+    // unset found_a_match, line 222
+    context.b_found_a_match = false;
+    // call has_min_length, line 223
+    if !r_has_min_length(env, context) {
+        return false;
+    }
+    // backwards, line 224
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 224
+    // or, line 241
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // test, line 225
+            let v_2 = env.limit - env.cursor;
+            // (, line 225
+            // [, line 225
+            env.ket = env.cursor;
+            // or, line 225
+            'lab2: loop {
+                let v_3 = env.limit - env.cursor;
+                'lab3: loop {
+                    // literal, line 225
+                    if !env.eq_s_b(&"\u{0BC1}\u{0B9F}\u{0BA9}\u{0BCD}") {
+                        break 'lab3;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_3;
+                'lab4: loop {
+                    // literal, line 226
+                    if !env.eq_s_b(&"\u{0BBF}\u{0BB2}\u{0BCD}\u{0BB2}\u{0BC8}") {
+                        break 'lab4;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_3;
+                'lab5: loop {
+                    // literal, line 227
+                    if !env.eq_s_b(&"\u{0BBF}\u{0B9F}\u{0BAE}\u{0BCD}") {
+                        break 'lab5;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_3;
+                'lab6: loop {
+                    // literal, line 228
+                    if !env.eq_s_b(&"\u{0BBF}\u{0BA9}\u{0BCD}\u{0BB1}\u{0BBF}") {
+                        break 'lab6;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_3;
+                'lab7: loop {
+                    // literal, line 229
+                    if !env.eq_s_b(&"\u{0BBE}\u{0B95}\u{0BBF}") {
+                        break 'lab7;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_3;
+                'lab8: loop {
+                    // literal, line 230
+                    if !env.eq_s_b(&"\u{0BBE}\u{0B95}\u{0BBF}\u{0BAF}") {
+                        break 'lab8;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_3;
+                'lab9: loop {
+                    // literal, line 231
+                    if !env.eq_s_b(&"\u{0BC6}\u{0BA9}\u{0BCD}\u{0BB1}\u{0BC1}") {
+                        break 'lab9;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_3;
+                'lab10: loop {
+                    // literal, line 232
+                    if !env.eq_s_b(&"\u{0BC1}\u{0BB3}\u{0BCD}\u{0BB3}") {
+                        break 'lab10;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_3;
+                'lab11: loop {
+                    // literal, line 233
+                    if !env.eq_s_b(&"\u{0BC1}\u{0B9F}\u{0BC8}\u{0BAF}") {
+                        break 'lab11;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_3;
+                'lab12: loop {
+                    // literal, line 234
+                    if !env.eq_s_b(&"\u{0BC1}\u{0B9F}\u{0BC8}") {
+                        break 'lab12;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_3;
+                'lab13: loop {
+                    // literal, line 235
+                    if !env.eq_s_b(&"\u{0BC6}\u{0BA9}\u{0BC1}\u{0BAE}\u{0BCD}") {
+                        break 'lab13;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_3;
+                'lab14: loop {
+                    // (, line 236
+                    // literal, line 236
+                    if !env.eq_s_b(&"\u{0BB2}\u{0BCD}\u{0BB2}") {
+                        break 'lab14;
+                    }
+                    // test, line 236
+                    let v_4 = env.limit - env.cursor;
+                    // (, line 236
+                    // not, line 236
+                    let v_5 = env.limit - env.cursor;
+                    'lab15: loop {
+                        // among, line 236
+                        if env.find_among_b(A_16, context) == 0 {
+                            break 'lab15;
+                        }
+                        break 'lab14;
+                    }
+                    env.cursor = env.limit - v_5;
+                    env.cursor = env.limit - v_4;
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_3;
+                'lab16: loop {
+                    // literal, line 237
+                    if !env.eq_s_b(&"\u{0BC6}\u{0BA9}") {
+                        break 'lab16;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_3;
+                // literal, line 238
+                if !env.eq_s_b(&"\u{0BBE}\u{0B95}\u{0BBF}") {
+                    break 'lab1;
+                }
+                break 'lab2;
+            }
+            // ], line 238
+            env.bra = env.cursor;
+            // <-, line 238
+            if !env.slice_from("\u{0BCD}") {
+                return false;
+            }
+            // (, line 239
+            // set found_a_match, line 239
+            context.b_found_a_match = true;
+            env.cursor = env.limit - v_2;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // test, line 242
+        let v_6 = env.limit - env.cursor;
+        // (, line 242
+        // [, line 242
+        env.ket = env.cursor;
+        // among, line 242
+        if env.find_among_b(A_17, context) == 0 {
+            return false;
+        }
+        // ], line 255
+        env.bra = env.cursor;
+        // delete, line 255
+        if !env.slice_del() {
+            return false;
+        }
+        // (, line 256
+        // set found_a_match, line 256
+        context.b_found_a_match = true;
+        env.cursor = env.limit - v_6;
+        break 'lab0;
+    }
+    env.cursor = env.limit_backward;
+    // do, line 259
+    let v_7 = env.cursor;
+    'lab17: loop {
+        // call fix_endings, line 259
+        if !r_fix_endings(env, context) {
+            break 'lab17;
+        }
+        break 'lab17;
+    }
+    env.cursor = v_7;
+    return true;
+}
+
+fn r_remove_vetrumai_urupukal(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 262
+    // unset found_a_match, line 263
+    context.b_found_a_match = false;
+    // unset found_vetrumai_urupu, line 264
+    context.b_found_vetrumai_urupu = false;
+    // call has_min_length, line 265
+    if !r_has_min_length(env, context) {
+        return false;
+    }
+    // backwards, line 266
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 266
+    // (, line 267
+    // or, line 269
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // test, line 268
+            let v_2 = env.limit - env.cursor;
+            // (, line 268
+            // [, line 268
+            env.ket = env.cursor;
+            // literal, line 268
+            if !env.eq_s_b(&"\u{0BA9}\u{0BC8}") {
+                break 'lab1;
+            }
+            // ], line 268
+            env.bra = env.cursor;
+            // delete, line 268
+            if !env.slice_del() {
+                return false;
+            }
+            env.cursor = env.limit - v_2;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab2: loop {
+            // test, line 270
+            let v_3 = env.limit - env.cursor;
+            // (, line 270
+            // [, line 270
+            env.ket = env.cursor;
+            // or, line 271
+            'lab3: loop {
+                let v_4 = env.limit - env.cursor;
+                'lab4: loop {
+                    // (, line 270
+                    // or, line 270
+                    'lab5: loop {
+                        let v_5 = env.limit - env.cursor;
+                        'lab6: loop {
+                            // literal, line 270
+                            if !env.eq_s_b(&"\u{0BBF}\u{0BA9}\u{0BC8}") {
+                                break 'lab6;
+                            }
+                            break 'lab5;
+                        }
+                        env.cursor = env.limit - v_5;
+                        // literal, line 271
+                        if !env.eq_s_b(&"\u{0BC8}") {
+                            break 'lab4;
+                        }
+                        break 'lab5;
+                    }
+                    // (, line 271
+                    // test, line 271
+                    let v_6 = env.limit - env.cursor;
+                    // not, line 271
+                    let v_7 = env.limit - env.cursor;
+                    'lab7: loop {
+                        // among, line 271
+                        if env.find_among_b(A_18, context) == 0 {
+                            break 'lab7;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_7;
+                    env.cursor = env.limit - v_6;
+                    break 'lab3;
+                }
+                env.cursor = env.limit - v_4;
+                // (, line 272
+                // literal, line 272
+                if !env.eq_s_b(&"\u{0BC8}") {
+                    break 'lab2;
+                }
+                // (, line 272
+                // test, line 272
+                let v_8 = env.limit - env.cursor;
+                // (, line 272
+                // among, line 272
+                if env.find_among_b(A_19, context) == 0 {
+                    break 'lab2;
+                }
+                // literal, line 272
+                if !env.eq_s_b(&"\u{0BCD}") {
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_8;
+                break 'lab3;
+            }
+            // ], line 273
+            env.bra = env.cursor;
+            // <-, line 273
+            if !env.slice_from("\u{0BCD}") {
+                return false;
+            }
+            env.cursor = env.limit - v_3;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab8: loop {
+            // test, line 276
+            let v_9 = env.limit - env.cursor;
+            // (, line 276
+            // [, line 276
+            env.ket = env.cursor;
+            // or, line 277
+            'lab9: loop {
+                let v_10 = env.limit - env.cursor;
+                'lab10: loop {
+                    // literal, line 277
+                    if !env.eq_s_b(&"\u{0BCA}\u{0B9F}\u{0BC1}") {
+                        break 'lab10;
+                    }
+                    break 'lab9;
+                }
+                env.cursor = env.limit - v_10;
+                'lab11: loop {
+                    // literal, line 278
+                    if !env.eq_s_b(&"\u{0BCB}\u{0B9F}\u{0BC1}") {
+                        break 'lab11;
+                    }
+                    break 'lab9;
+                }
+                env.cursor = env.limit - v_10;
+                'lab12: loop {
+                    // literal, line 279
+                    if !env.eq_s_b(&"\u{0BBF}\u{0BB2}\u{0BCD}") {
+                        break 'lab12;
+                    }
+                    break 'lab9;
+                }
+                env.cursor = env.limit - v_10;
+                'lab13: loop {
+                    // literal, line 280
+                    if !env.eq_s_b(&"\u{0BBF}\u{0BB1}\u{0BCD}") {
+                        break 'lab13;
+                    }
+                    break 'lab9;
+                }
+                env.cursor = env.limit - v_10;
+                'lab14: loop {
+                    // (, line 281
+                    // literal, line 281
+                    if !env.eq_s_b(&"\u{0BBF}\u{0BA9}\u{0BCD}") {
+                        break 'lab14;
+                    }
+                    // (, line 281
+                    // test, line 281
+                    let v_11 = env.limit - env.cursor;
+                    // not, line 281
+                    let v_12 = env.limit - env.cursor;
+                    'lab15: loop {
+                        // literal, line 281
+                        if !env.eq_s_b(&"\u{0BAE}") {
+                            break 'lab15;
+                        }
+                        break 'lab14;
+                    }
+                    env.cursor = env.limit - v_12;
+                    env.cursor = env.limit - v_11;
+                    break 'lab9;
+                }
+                env.cursor = env.limit - v_10;
+                'lab16: loop {
+                    // literal, line 282
+                    if !env.eq_s_b(&"\u{0BBF}\u{0BA9}\u{0BCD}\u{0BB1}\u{0BC1}") {
+                        break 'lab16;
+                    }
+                    break 'lab9;
+                }
+                env.cursor = env.limit - v_10;
+                'lab17: loop {
+                    // literal, line 283
+                    if !env.eq_s_b(&"\u{0BBF}\u{0BB0}\u{0BC1}\u{0BA8}\u{0BCD}\u{0BA4}\u{0BC1}") {
+                        break 'lab17;
+                    }
+                    break 'lab9;
+                }
+                env.cursor = env.limit - v_10;
+                'lab18: loop {
+                    // literal, line 284
+                    if !env.eq_s_b(&"\u{0BB5}\u{0BBF}\u{0B9F}") {
+                        break 'lab18;
+                    }
+                    break 'lab9;
+                }
+                env.cursor = env.limit - v_10;
+                'lab19: loop {
+                    // (, line 285
+                    if !(context.i_length >= 7){
+                        break 'lab19;
+                    }
+                    // literal, line 285
+                    if !env.eq_s_b(&"\u{0BBF}\u{0B9F}\u{0BAE}\u{0BCD}") {
+                        break 'lab19;
+                    }
+                    break 'lab9;
+                }
+                env.cursor = env.limit - v_10;
+                'lab20: loop {
+                    // literal, line 286
+                    if !env.eq_s_b(&"\u{0BBE}\u{0BB2}\u{0BCD}") {
+                        break 'lab20;
+                    }
+                    break 'lab9;
+                }
+                env.cursor = env.limit - v_10;
+                'lab21: loop {
+                    // literal, line 287
+                    if !env.eq_s_b(&"\u{0BC1}\u{0B9F}\u{0BC8}") {
+                        break 'lab21;
+                    }
+                    break 'lab9;
+                }
+                env.cursor = env.limit - v_10;
+                'lab22: loop {
+                    // literal, line 288
+                    if !env.eq_s_b(&"\u{0BBE}\u{0BAE}\u{0BB2}\u{0BCD}") {
+                        break 'lab22;
+                    }
+                    break 'lab9;
+                }
+                env.cursor = env.limit - v_10;
+                'lab23: loop {
+                    // (, line 289
+                    // literal, line 289
+                    if !env.eq_s_b(&"\u{0BB2}\u{0BCD}") {
+                        break 'lab23;
+                    }
+                    // (, line 289
+                    // test, line 289
+                    let v_13 = env.limit - env.cursor;
+                    // not, line 289
+                    let v_14 = env.limit - env.cursor;
+                    'lab24: loop {
+                        // among, line 289
+                        if env.find_among_b(A_20, context) == 0 {
+                            break 'lab24;
+                        }
+                        break 'lab23;
+                    }
+                    env.cursor = env.limit - v_14;
+                    env.cursor = env.limit - v_13;
+                    break 'lab9;
+                }
+                env.cursor = env.limit - v_10;
+                // literal, line 290
+                if !env.eq_s_b(&"\u{0BC1}\u{0BB3}\u{0BCD}") {
+                    break 'lab8;
+                }
+                break 'lab9;
+            }
+            // ], line 291
+            env.bra = env.cursor;
+            // <-, line 291
+            if !env.slice_from("\u{0BCD}") {
+                return false;
+            }
+            env.cursor = env.limit - v_9;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab25: loop {
+            // test, line 294
+            let v_15 = env.limit - env.cursor;
+            // (, line 294
+            // [, line 294
+            env.ket = env.cursor;
+            // or, line 295
+            'lab26: loop {
+                let v_16 = env.limit - env.cursor;
+                'lab27: loop {
+                    // literal, line 295
+                    if !env.eq_s_b(&"\u{0B95}\u{0BA3}\u{0BCD}") {
+                        break 'lab27;
+                    }
+                    break 'lab26;
+                }
+                env.cursor = env.limit - v_16;
+                'lab28: loop {
+                    // literal, line 296
+                    if !env.eq_s_b(&"\u{0BAE}\u{0BC1}\u{0BA9}\u{0BCD}") {
+                        break 'lab28;
+                    }
+                    break 'lab26;
+                }
+                env.cursor = env.limit - v_16;
+                'lab29: loop {
+                    // literal, line 297
+                    if !env.eq_s_b(&"\u{0BAE}\u{0BC7}\u{0BB2}\u{0BCD}") {
+                        break 'lab29;
+                    }
+                    break 'lab26;
+                }
+                env.cursor = env.limit - v_16;
+                'lab30: loop {
+                    // literal, line 298
+                    if !env.eq_s_b(&"\u{0BAE}\u{0BC7}\u{0BB1}\u{0BCD}") {
+                        break 'lab30;
+                    }
+                    break 'lab26;
+                }
+                env.cursor = env.limit - v_16;
+                'lab31: loop {
+                    // literal, line 299
+                    if !env.eq_s_b(&"\u{0B95}\u{0BC0}\u{0BB4}\u{0BCD}") {
+                        break 'lab31;
+                    }
+                    break 'lab26;
+                }
+                env.cursor = env.limit - v_16;
+                'lab32: loop {
+                    // literal, line 300
+                    if !env.eq_s_b(&"\u{0BAA}\u{0BBF}\u{0BA9}\u{0BCD}") {
+                        break 'lab32;
+                    }
+                    break 'lab26;
+                }
+                env.cursor = env.limit - v_16;
+                // (, line 301
+                // literal, line 301
+                if !env.eq_s_b(&"\u{0BA4}\u{0BC1}") {
+                    break 'lab25;
+                }
+                // (, line 301
+                // test, line 301
+                let v_17 = env.limit - env.cursor;
+                // not, line 301
+                let v_18 = env.limit - env.cursor;
+                'lab33: loop {
+                    // among, line 301
+                    if env.find_among_b(A_21, context) == 0 {
+                        break 'lab33;
+                    }
+                    break 'lab25;
+                }
+                env.cursor = env.limit - v_18;
+                env.cursor = env.limit - v_17;
+                break 'lab26;
+            }
+            // ], line 302
+            env.bra = env.cursor;
+            // delete, line 302
+            if !env.slice_del() {
+                return false;
+            }
+            env.cursor = env.limit - v_15;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // test, line 305
+        let v_19 = env.limit - env.cursor;
+        // (, line 305
+        // [, line 305
+        env.ket = env.cursor;
+        // literal, line 305
+        if !env.eq_s_b(&"\u{0BC0}") {
+            return false;
+        }
+        // ], line 305
+        env.bra = env.cursor;
+        // <-, line 305
+        if !env.slice_from("\u{0BBF}") {
+            return false;
+        }
+        env.cursor = env.limit - v_19;
+        break 'lab0;
+    }
+    // (, line 307
+    // set found_a_match, line 307
+    context.b_found_a_match = true;
+    // (, line 308
+    // set found_vetrumai_urupu, line 308
+    context.b_found_vetrumai_urupu = true;
+    // do, line 309
+    let v_20 = env.limit - env.cursor;
+    'lab34: loop {
+        // (, line 309
+        // [, line 309
+        env.ket = env.cursor;
+        // literal, line 309
+        if !env.eq_s_b(&"\u{0BBF}\u{0BA9}\u{0BCD}") {
+            break 'lab34;
+        }
+        // ], line 309
+        env.bra = env.cursor;
+        // <-, line 309
+        if !env.slice_from("\u{0BCD}") {
+            return false;
+        }
+        break 'lab34;
+    }
+    env.cursor = env.limit - v_20;
+    env.cursor = env.limit_backward;
+    // do, line 311
+    let v_21 = env.cursor;
+    'lab35: loop {
+        // call fix_endings, line 311
+        if !r_fix_endings(env, context) {
+            break 'lab35;
+        }
+        break 'lab35;
+    }
+    env.cursor = v_21;
+    return true;
+}
+
+fn r_remove_tense_suffixes(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 314
+    // set found_a_match, line 315
+    context.b_found_a_match = true;
+    // repeat, line 316
+    'replab0: loop{
+        let v_1 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 316
+            // Boolean test found_a_match, line 316
+            if !context.b_found_a_match {
+                break 'lab1;
+            }
+            // (, line 316
+            // do, line 316
+            let v_2 = env.cursor;
+            'lab2: loop {
+                // call remove_tense_suffix, line 316
+                if !r_remove_tense_suffix(env, context) {
+                    break 'lab2;
+                }
+                break 'lab2;
+            }
+            env.cursor = v_2;
+            continue 'replab0;
+        }
+        env.cursor = v_1;
+        break 'replab0;
+    }
+    return true;
+}
+
+fn r_remove_tense_suffix(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 319
+    // unset found_a_match, line 320
+    context.b_found_a_match = false;
+    // call has_min_length, line 321
+    if !r_has_min_length(env, context) {
+        return false;
+    }
+    // backwards, line 322
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 322
+    // do, line 323
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // (, line 323
+        // or, line 330
+        'lab1: loop {
+            let v_2 = env.limit - env.cursor;
+            'lab2: loop {
+                // test, line 324
+                let v_3 = env.limit - env.cursor;
+                // (, line 324
+                // [, line 324
+                env.ket = env.cursor;
+                // among, line 324
+                if env.find_among_b(A_22, context) == 0 {
+                    break 'lab2;
+                }
+                // ], line 327
+                env.bra = env.cursor;
+                // delete, line 327
+                if !env.slice_del() {
+                    return false;
+                }
+                // (, line 328
+                // set found_a_match, line 328
+                context.b_found_a_match = true;
+                env.cursor = env.limit - v_3;
+                break 'lab1;
+            }
+            env.cursor = env.limit - v_2;
+            'lab3: loop {
+                // test, line 331
+                let v_4 = env.limit - env.cursor;
+                // (, line 331
+                // [, line 331
+                env.ket = env.cursor;
+                // or, line 332
+                'lab4: loop {
+                    let v_5 = env.limit - env.cursor;
+                    'lab5: loop {
+                        // literal, line 332
+                        if !env.eq_s_b(&"\u{0BAE}\u{0BBE}\u{0BB0}\u{0BCD}") {
+                            break 'lab5;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab6: loop {
+                        // literal, line 333
+                        if !env.eq_s_b(&"\u{0BAE}\u{0BBF}\u{0BA9}\u{0BCD}") {
+                            break 'lab6;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab7: loop {
+                        // literal, line 334
+                        if !env.eq_s_b(&"\u{0BA9}\u{0BA9}\u{0BCD}") {
+                            break 'lab7;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab8: loop {
+                        // literal, line 335
+                        if !env.eq_s_b(&"\u{0BA9}\u{0BBE}\u{0BA9}\u{0BCD}") {
+                            break 'lab8;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab9: loop {
+                        // literal, line 336
+                        if !env.eq_s_b(&"\u{0BA9}\u{0BBE}\u{0BB3}\u{0BCD}") {
+                            break 'lab9;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab10: loop {
+                        // literal, line 337
+                        if !env.eq_s_b(&"\u{0BA9}\u{0BBE}\u{0BB0}\u{0BCD}") {
+                            break 'lab10;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab11: loop {
+                        // (, line 338
+                        // literal, line 338
+                        if !env.eq_s_b(&"\u{0BB5}\u{0BA9}\u{0BCD}") {
+                            break 'lab11;
+                        }
+                        // test, line 338
+                        let v_6 = env.limit - env.cursor;
+                        // (, line 338
+                        // not, line 338
+                        let v_7 = env.limit - env.cursor;
+                        'lab12: loop {
+                            // among, line 338
+                            if env.find_among_b(A_23, context) == 0 {
+                                break 'lab12;
+                            }
+                            break 'lab11;
+                        }
+                        env.cursor = env.limit - v_7;
+                        env.cursor = env.limit - v_6;
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab13: loop {
+                        // literal, line 339
+                        if !env.eq_s_b(&"\u{0BA9}\u{0BB3}\u{0BCD}") {
+                            break 'lab13;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab14: loop {
+                        // literal, line 340
+                        if !env.eq_s_b(&"\u{0BB5}\u{0BB3}\u{0BCD}") {
+                            break 'lab14;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab15: loop {
+                        // literal, line 341
+                        if !env.eq_s_b(&"\u{0BA9}\u{0BB0}\u{0BCD}") {
+                            break 'lab15;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab16: loop {
+                        // literal, line 342
+                        if !env.eq_s_b(&"\u{0BB5}\u{0BB0}\u{0BCD}") {
+                            break 'lab16;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab17: loop {
+                        // literal, line 343
+                        if !env.eq_s_b(&"\u{0BA9}") {
+                            break 'lab17;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab18: loop {
+                        // literal, line 343
+                        if !env.eq_s_b(&"\u{0BAA}") {
+                            break 'lab18;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab19: loop {
+                        // literal, line 343
+                        if !env.eq_s_b(&"\u{0B95}") {
+                            break 'lab19;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab20: loop {
+                        // literal, line 343
+                        if !env.eq_s_b(&"\u{0BA4}") {
+                            break 'lab20;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab21: loop {
+                        // literal, line 343
+                        if !env.eq_s_b(&"\u{0BAF}") {
+                            break 'lab21;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab22: loop {
+                        // literal, line 344
+                        if !env.eq_s_b(&"\u{0BAA}\u{0BA9}\u{0BCD}") {
+                            break 'lab22;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab23: loop {
+                        // literal, line 345
+                        if !env.eq_s_b(&"\u{0BAA}\u{0BB3}\u{0BCD}") {
+                            break 'lab23;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab24: loop {
+                        // literal, line 346
+                        if !env.eq_s_b(&"\u{0BAA}\u{0BB0}\u{0BCD}") {
+                            break 'lab24;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab25: loop {
+                        // (, line 347
+                        // literal, line 347
+                        if !env.eq_s_b(&"\u{0BA4}\u{0BC1}") {
+                            break 'lab25;
+                        }
+                        // (, line 347
+                        // test, line 347
+                        let v_8 = env.limit - env.cursor;
+                        // not, line 347
+                        let v_9 = env.limit - env.cursor;
+                        'lab26: loop {
+                            // among, line 347
+                            if env.find_among_b(A_24, context) == 0 {
+                                break 'lab26;
+                            }
+                            break 'lab25;
+                        }
+                        env.cursor = env.limit - v_9;
+                        env.cursor = env.limit - v_8;
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab27: loop {
+                        // literal, line 348
+                        if !env.eq_s_b(&"\u{0BBF}\u{0BB1}\u{0BCD}\u{0BB1}\u{0BC1}") {
+                            break 'lab27;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab28: loop {
+                        // literal, line 349
+                        if !env.eq_s_b(&"\u{0BAA}\u{0BAE}\u{0BCD}") {
+                            break 'lab28;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab29: loop {
+                        // literal, line 350
+                        if !env.eq_s_b(&"\u{0BA9}\u{0BAE}\u{0BCD}") {
+                            break 'lab29;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab30: loop {
+                        // literal, line 351
+                        if !env.eq_s_b(&"\u{0BA4}\u{0BC1}\u{0BAE}\u{0BCD}") {
+                            break 'lab30;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab31: loop {
+                        // literal, line 352
+                        if !env.eq_s_b(&"\u{0BB1}\u{0BC1}\u{0BAE}\u{0BCD}") {
+                            break 'lab31;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab32: loop {
+                        // literal, line 353
+                        if !env.eq_s_b(&"\u{0B95}\u{0BC1}\u{0BAE}\u{0BCD}") {
+                            break 'lab32;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab33: loop {
+                        // literal, line 354
+                        if !env.eq_s_b(&"\u{0BA9}\u{0BC6}\u{0BA9}\u{0BCD}") {
+                            break 'lab33;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab34: loop {
+                        // literal, line 355
+                        if !env.eq_s_b(&"\u{0BA9}\u{0BC8}") {
+                            break 'lab34;
+                        }
+                        break 'lab4;
+                    }
+                    env.cursor = env.limit - v_5;
+                    // literal, line 356
+                    if !env.eq_s_b(&"\u{0BB5}\u{0BC8}") {
+                        break 'lab3;
+                    }
+                    break 'lab4;
+                }
+                // ], line 357
+                env.bra = env.cursor;
+                // delete, line 357
+                if !env.slice_del() {
+                    return false;
+                }
+                // (, line 358
+                // set found_a_match, line 358
+                context.b_found_a_match = true;
+                env.cursor = env.limit - v_4;
+                break 'lab1;
+            }
+            env.cursor = env.limit - v_2;
+            'lab35: loop {
+                // test, line 361
+                let v_10 = env.limit - env.cursor;
+                // (, line 361
+                // [, line 361
+                env.ket = env.cursor;
+                // or, line 362
+                'lab36: loop {
+                    let v_11 = env.limit - env.cursor;
+                    'lab37: loop {
+                        // (, line 362
+                        // literal, line 362
+                        if !env.eq_s_b(&"\u{0BBE}\u{0BA9}\u{0BCD}") {
+                            break 'lab37;
+                        }
+                        // test, line 362
+                        let v_12 = env.limit - env.cursor;
+                        // (, line 362
+                        // not, line 362
+                        let v_13 = env.limit - env.cursor;
+                        'lab38: loop {
+                            // literal, line 362
+                            if !env.eq_s_b(&"\u{0B9A}") {
+                                break 'lab38;
+                            }
+                            break 'lab37;
+                        }
+                        env.cursor = env.limit - v_13;
+                        env.cursor = env.limit - v_12;
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab39: loop {
+                        // literal, line 363
+                        if !env.eq_s_b(&"\u{0BBE}\u{0BB3}\u{0BCD}") {
+                            break 'lab39;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab40: loop {
+                        // literal, line 364
+                        if !env.eq_s_b(&"\u{0BBE}\u{0BB0}\u{0BCD}") {
+                            break 'lab40;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab41: loop {
+                        // literal, line 365
+                        if !env.eq_s_b(&"\u{0BC7}\u{0BA9}\u{0BCD}") {
+                            break 'lab41;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab42: loop {
+                        // literal, line 366
+                        if !env.eq_s_b(&"\u{0BBE}") {
+                            break 'lab42;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab43: loop {
+                        // literal, line 367
+                        if !env.eq_s_b(&"\u{0BBE}\u{0BAE}\u{0BCD}") {
+                            break 'lab43;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab44: loop {
+                        // literal, line 368
+                        if !env.eq_s_b(&"\u{0BC6}\u{0BAE}\u{0BCD}") {
+                            break 'lab44;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab45: loop {
+                        // literal, line 369
+                        if !env.eq_s_b(&"\u{0BC7}\u{0BAE}\u{0BCD}") {
+                            break 'lab45;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab46: loop {
+                        // literal, line 370
+                        if !env.eq_s_b(&"\u{0BCB}\u{0BAE}\u{0BCD}") {
+                            break 'lab46;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab47: loop {
+                        // literal, line 371
+                        if !env.eq_s_b(&"\u{0B95}\u{0BC1}\u{0BAE}\u{0BCD}") {
+                            break 'lab47;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab48: loop {
+                        // literal, line 372
+                        if !env.eq_s_b(&"\u{0BA4}\u{0BC1}\u{0BAE}\u{0BCD}") {
+                            break 'lab48;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab49: loop {
+                        // literal, line 373
+                        if !env.eq_s_b(&"\u{0B9F}\u{0BC1}\u{0BAE}\u{0BCD}") {
+                            break 'lab49;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab50: loop {
+                        // literal, line 374
+                        if !env.eq_s_b(&"\u{0BB1}\u{0BC1}\u{0BAE}\u{0BCD}") {
+                            break 'lab50;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab51: loop {
+                        // literal, line 375
+                        if !env.eq_s_b(&"\u{0BBE}\u{0BAF}\u{0BCD}") {
+                            break 'lab51;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab52: loop {
+                        // literal, line 376
+                        if !env.eq_s_b(&"\u{0BA9}\u{0BC6}\u{0BA9}\u{0BCD}") {
+                            break 'lab52;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab53: loop {
+                        // literal, line 377
+                        if !env.eq_s_b(&"\u{0BA9}\u{0BBF}\u{0BB0}\u{0BCD}") {
+                            break 'lab53;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    'lab54: loop {
+                        // literal, line 378
+                        if !env.eq_s_b(&"\u{0BC0}\u{0BB0}\u{0BCD}") {
+                            break 'lab54;
+                        }
+                        break 'lab36;
+                    }
+                    env.cursor = env.limit - v_11;
+                    // literal, line 379
+                    if !env.eq_s_b(&"\u{0BC0}\u{0BAF}\u{0BB0}\u{0BCD}") {
+                        break 'lab35;
+                    }
+                    break 'lab36;
+                }
+                // ], line 380
+                env.bra = env.cursor;
+                // <-, line 380
+                if !env.slice_from("\u{0BCD}") {
+                    return false;
+                }
+                // (, line 381
+                // set found_a_match, line 381
+                context.b_found_a_match = true;
+                env.cursor = env.limit - v_10;
+                break 'lab1;
+            }
+            env.cursor = env.limit - v_2;
+            // test, line 384
+            let v_14 = env.limit - env.cursor;
+            // (, line 384
+            // (, line 384
+            // [, line 384
+            env.ket = env.cursor;
+            // or, line 384
+            'lab55: loop {
+                let v_15 = env.limit - env.cursor;
+                'lab56: loop {
+                    // literal, line 384
+                    if !env.eq_s_b(&"\u{0B95}\u{0BC1}") {
+                        break 'lab56;
+                    }
+                    break 'lab55;
+                }
+                env.cursor = env.limit - v_15;
+                // literal, line 384
+                if !env.eq_s_b(&"\u{0BA4}\u{0BC1}") {
+                    break 'lab0;
+                }
+                break 'lab55;
+            }
+            // (, line 384
+            // test, line 384
+            let v_16 = env.limit - env.cursor;
+            // literal, line 384
+            if !env.eq_s_b(&"\u{0BCD}") {
+                break 'lab0;
+            }
+            env.cursor = env.limit - v_16;
+            // ], line 384
+            env.bra = env.cursor;
+            // delete, line 384
+            if !env.slice_del() {
+                return false;
+            }
+            // (, line 385
+            // set found_a_match, line 385
+            context.b_found_a_match = true;
+            env.cursor = env.limit - v_14;
+            break 'lab1;
+        }
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    // do, line 388
+    let v_17 = env.limit - env.cursor;
+    'lab57: loop {
+        // (, line 388
+        // [, line 388
+        env.ket = env.cursor;
+        // among, line 388
+        if env.find_among_b(A_25, context) == 0 {
+            break 'lab57;
+        }
+        // ], line 395
+        env.bra = env.cursor;
+        // delete, line 395
+        if !env.slice_del() {
+            return false;
+        }
+        // (, line 396
+        // set found_a_match, line 396
+        context.b_found_a_match = true;
+        break 'lab57;
+    }
+    env.cursor = env.limit - v_17;
+    env.cursor = env.limit_backward;
+    // do, line 399
+    let v_18 = env.cursor;
+    'lab58: loop {
+        // call fix_endings, line 399
+        if !r_fix_endings(env, context) {
+            break 'lab58;
+        }
+        break 'lab58;
+    }
+    env.cursor = v_18;
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        i_length: 0,
+        b_found_wrong_ending: false,
+        b_found_vetrumai_urupu: false,
+        b_found_a_match: false,
+    };
+    // (, line 402
+    // unset found_vetrumai_urupu, line 403
+    context.b_found_vetrumai_urupu = false;
+    // do, line 404
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // call fix_ending, line 404
+        if !r_fix_ending(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = v_1;
+    // call has_min_length, line 405
+    if !r_has_min_length(env, context) {
+        return false;
+    }
+    // do, line 406
+    let v_2 = env.cursor;
+    'lab1: loop {
+        // call remove_question_prefixes, line 406
+        if !r_remove_question_prefixes(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = v_2;
+    // do, line 407
+    let v_3 = env.cursor;
+    'lab2: loop {
+        // call remove_pronoun_prefixes, line 407
+        if !r_remove_pronoun_prefixes(env, context) {
+            break 'lab2;
+        }
+        break 'lab2;
+    }
+    env.cursor = v_3;
+    // do, line 408
+    let v_4 = env.cursor;
+    'lab3: loop {
+        // call remove_question_suffixes, line 408
+        if !r_remove_question_suffixes(env, context) {
+            break 'lab3;
+        }
+        break 'lab3;
+    }
+    env.cursor = v_4;
+    // do, line 409
+    let v_5 = env.cursor;
+    'lab4: loop {
+        // call remove_um, line 409
+        if !r_remove_um(env, context) {
+            break 'lab4;
+        }
+        break 'lab4;
+    }
+    env.cursor = v_5;
+    // do, line 410
+    let v_6 = env.cursor;
+    'lab5: loop {
+        // call remove_common_word_endings, line 410
+        if !r_remove_common_word_endings(env, context) {
+            break 'lab5;
+        }
+        break 'lab5;
+    }
+    env.cursor = v_6;
+    // do, line 411
+    let v_7 = env.cursor;
+    'lab6: loop {
+        // call remove_vetrumai_urupukal, line 411
+        if !r_remove_vetrumai_urupukal(env, context) {
+            break 'lab6;
+        }
+        break 'lab6;
+    }
+    env.cursor = v_7;
+    // do, line 412
+    let v_8 = env.cursor;
+    'lab7: loop {
+        // call remove_plural_suffix, line 412
+        if !r_remove_plural_suffix(env, context) {
+            break 'lab7;
+        }
+        break 'lab7;
+    }
+    env.cursor = v_8;
+    // do, line 413
+    let v_9 = env.cursor;
+    'lab8: loop {
+        // call remove_command_suffixes, line 413
+        if !r_remove_command_suffixes(env, context) {
+            break 'lab8;
+        }
+        break 'lab8;
+    }
+    env.cursor = v_9;
+    // do, line 414
+    let v_10 = env.cursor;
+    'lab9: loop {
+        // call remove_tense_suffixes, line 414
+        if !r_remove_tense_suffixes(env, context) {
+            break 'lab9;
+        }
+        break 'lab9;
+    }
+    env.cursor = v_10;
+    return true;
+}
diff --git a/src/snowball/algorithms/turkish.rs b/src/snowball/algorithms/turkish.rs
new file mode 100644
index 0000000..ef73f51
--- /dev/null
+++ b/src/snowball/algorithms/turkish.rs
@@ -0,0 +1,2832 @@
+//! This file was generated automatically by the Snowball to Rust compiler
+//! http://snowballstem.org/
+
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use snowball::SnowballEnv;
+use snowball::Among;
+
+static A_0: &'static [Among<Context>; 10] = &[
+    Among("m", -1, -1, None),
+    Among("n", -1, -1, None),
+    Among("miz", -1, -1, None),
+    Among("niz", -1, -1, None),
+    Among("muz", -1, -1, None),
+    Among("nuz", -1, -1, None),
+    Among("m\u{0131}z", -1, -1, None),
+    Among("n\u{0131}z", -1, -1, None),
+    Among("m\u{00FC}z", -1, -1, None),
+    Among("n\u{00FC}z", -1, -1, None),
+];
+
+static A_1: &'static [Among<Context>; 2] = &[
+    Among("leri", -1, -1, None),
+    Among("lar\u{0131}", -1, -1, None),
+];
+
+static A_2: &'static [Among<Context>; 4] = &[
+    Among("ni", -1, -1, None),
+    Among("nu", -1, -1, None),
+    Among("n\u{0131}", -1, -1, None),
+    Among("n\u{00FC}", -1, -1, None),
+];
+
+static A_3: &'static [Among<Context>; 4] = &[
+    Among("in", -1, -1, None),
+    Among("un", -1, -1, None),
+    Among("\u{0131}n", -1, -1, None),
+    Among("\u{00FC}n", -1, -1, None),
+];
+
+static A_4: &'static [Among<Context>; 2] = &[
+    Among("a", -1, -1, None),
+    Among("e", -1, -1, None),
+];
+
+static A_5: &'static [Among<Context>; 2] = &[
+    Among("na", -1, -1, None),
+    Among("ne", -1, -1, None),
+];
+
+static A_6: &'static [Among<Context>; 4] = &[
+    Among("da", -1, -1, None),
+    Among("ta", -1, -1, None),
+    Among("de", -1, -1, None),
+    Among("te", -1, -1, None),
+];
+
+static A_7: &'static [Among<Context>; 2] = &[
+    Among("nda", -1, -1, None),
+    Among("nde", -1, -1, None),
+];
+
+static A_8: &'static [Among<Context>; 4] = &[
+    Among("dan", -1, -1, None),
+    Among("tan", -1, -1, None),
+    Among("den", -1, -1, None),
+    Among("ten", -1, -1, None),
+];
+
+static A_9: &'static [Among<Context>; 2] = &[
+    Among("ndan", -1, -1, None),
+    Among("nden", -1, -1, None),
+];
+
+static A_10: &'static [Among<Context>; 2] = &[
+    Among("la", -1, -1, None),
+    Among("le", -1, -1, None),
+];
+
+static A_11: &'static [Among<Context>; 2] = &[
+    Among("ca", -1, -1, None),
+    Among("ce", -1, -1, None),
+];
+
+static A_12: &'static [Among<Context>; 4] = &[
+    Among("im", -1, -1, None),
+    Among("um", -1, -1, None),
+    Among("\u{0131}m", -1, -1, None),
+    Among("\u{00FC}m", -1, -1, None),
+];
+
+static A_13: &'static [Among<Context>; 4] = &[
+    Among("sin", -1, -1, None),
+    Among("sun", -1, -1, None),
+    Among("s\u{0131}n", -1, -1, None),
+    Among("s\u{00FC}n", -1, -1, None),
+];
+
+static A_14: &'static [Among<Context>; 4] = &[
+    Among("iz", -1, -1, None),
+    Among("uz", -1, -1, None),
+    Among("\u{0131}z", -1, -1, None),
+    Among("\u{00FC}z", -1, -1, None),
+];
+
+static A_15: &'static [Among<Context>; 4] = &[
+    Among("siniz", -1, -1, None),
+    Among("sunuz", -1, -1, None),
+    Among("s\u{0131}n\u{0131}z", -1, -1, None),
+    Among("s\u{00FC}n\u{00FC}z", -1, -1, None),
+];
+
+static A_16: &'static [Among<Context>; 2] = &[
+    Among("lar", -1, -1, None),
+    Among("ler", -1, -1, None),
+];
+
+static A_17: &'static [Among<Context>; 4] = &[
+    Among("niz", -1, -1, None),
+    Among("nuz", -1, -1, None),
+    Among("n\u{0131}z", -1, -1, None),
+    Among("n\u{00FC}z", -1, -1, None),
+];
+
+static A_18: &'static [Among<Context>; 8] = &[
+    Among("dir", -1, -1, None),
+    Among("tir", -1, -1, None),
+    Among("dur", -1, -1, None),
+    Among("tur", -1, -1, None),
+    Among("d\u{0131}r", -1, -1, None),
+    Among("t\u{0131}r", -1, -1, None),
+    Among("d\u{00FC}r", -1, -1, None),
+    Among("t\u{00FC}r", -1, -1, None),
+];
+
+static A_19: &'static [Among<Context>; 2] = &[
+    Among("cas\u{0131}na", -1, -1, None),
+    Among("cesine", -1, -1, None),
+];
+
+static A_20: &'static [Among<Context>; 32] = &[
+    Among("di", -1, -1, None),
+    Among("ti", -1, -1, None),
+    Among("dik", -1, -1, None),
+    Among("tik", -1, -1, None),
+    Among("duk", -1, -1, None),
+    Among("tuk", -1, -1, None),
+    Among("d\u{0131}k", -1, -1, None),
+    Among("t\u{0131}k", -1, -1, None),
+    Among("d\u{00FC}k", -1, -1, None),
+    Among("t\u{00FC}k", -1, -1, None),
+    Among("dim", -1, -1, None),
+    Among("tim", -1, -1, None),
+    Among("dum", -1, -1, None),
+    Among("tum", -1, -1, None),
+    Among("d\u{0131}m", -1, -1, None),
+    Among("t\u{0131}m", -1, -1, None),
+    Among("d\u{00FC}m", -1, -1, None),
+    Among("t\u{00FC}m", -1, -1, None),
+    Among("din", -1, -1, None),
+    Among("tin", -1, -1, None),
+    Among("dun", -1, -1, None),
+    Among("tun", -1, -1, None),
+    Among("d\u{0131}n", -1, -1, None),
+    Among("t\u{0131}n", -1, -1, None),
+    Among("d\u{00FC}n", -1, -1, None),
+    Among("t\u{00FC}n", -1, -1, None),
+    Among("du", -1, -1, None),
+    Among("tu", -1, -1, None),
+    Among("d\u{0131}", -1, -1, None),
+    Among("t\u{0131}", -1, -1, None),
+    Among("d\u{00FC}", -1, -1, None),
+    Among("t\u{00FC}", -1, -1, None),
+];
+
+static A_21: &'static [Among<Context>; 8] = &[
+    Among("sa", -1, -1, None),
+    Among("se", -1, -1, None),
+    Among("sak", -1, -1, None),
+    Among("sek", -1, -1, None),
+    Among("sam", -1, -1, None),
+    Among("sem", -1, -1, None),
+    Among("san", -1, -1, None),
+    Among("sen", -1, -1, None),
+];
+
+static A_22: &'static [Among<Context>; 4] = &[
+    Among("mi\u{015F}", -1, -1, None),
+    Among("mu\u{015F}", -1, -1, None),
+    Among("m\u{0131}\u{015F}", -1, -1, None),
+    Among("m\u{00FC}\u{015F}", -1, -1, None),
+];
+
+static A_23: &'static [Among<Context>; 4] = &[
+    Among("b", -1, 1, None),
+    Among("c", -1, 2, None),
+    Among("d", -1, 3, None),
+    Among("\u{011F}", -1, 4, None),
+];
+
+static G_vowel: &'static [u8; 27] = &[17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 8, 0, 0, 0, 0, 0, 0, 1];
+
+static G_U: &'static [u8; 26] = &[1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1];
+
+static G_vowel1: &'static [u8; 27] = &[1, 64, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
+
+static G_vowel2: &'static [u8; 19] = &[17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130];
+
+static G_vowel3: &'static [u8; 27] = &[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
+
+static G_vowel4: &'static [u8; 1] = &[17];
+
+static G_vowel5: &'static [u8; 1] = &[65];
+
+static G_vowel6: &'static [u8; 1] = &[65];
+
+#[derive(Clone)]
+struct Context {
+    b_continue_stemming_noun_suffixes: bool,
+    i_strlen: usize,
+}
+
+fn r_check_vowel_harmony(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 111
+    // test, line 112
+    let v_1 = env.limit - env.cursor;
+    // (, line 113
+    // (, line 114
+    // goto, line 114
+    'golab0: loop {
+        let v_2 = env.limit - env.cursor;
+        'lab1: loop {
+            if !env.in_grouping_b(G_vowel, 97, 305) {
+                break 'lab1;
+            }
+            env.cursor = env.limit - v_2;
+            break 'golab0;
+        }
+        env.cursor = env.limit - v_2;
+        if env.cursor <= env.limit_backward {
+            return false;
+        }
+        env.previous_char();
+    }
+    // (, line 115
+    // or, line 116
+    'lab2: loop {
+        let v_3 = env.limit - env.cursor;
+        'lab3: loop {
+            // (, line 116
+            // literal, line 116
+            if !env.eq_s_b(&"a") {
+                break 'lab3;
+            }
+            // goto, line 116
+            'golab4: loop {
+                let v_4 = env.limit - env.cursor;
+                'lab5: loop {
+                    if !env.in_grouping_b(G_vowel1, 97, 305) {
+                        break 'lab5;
+                    }
+                    env.cursor = env.limit - v_4;
+                    break 'golab4;
+                }
+                env.cursor = env.limit - v_4;
+                if env.cursor <= env.limit_backward {
+                    break 'lab3;
+                }
+                env.previous_char();
+            }
+            break 'lab2;
+        }
+        env.cursor = env.limit - v_3;
+        'lab6: loop {
+            // (, line 117
+            // literal, line 117
+            if !env.eq_s_b(&"e") {
+                break 'lab6;
+            }
+            // goto, line 117
+            'golab7: loop {
+                let v_5 = env.limit - env.cursor;
+                'lab8: loop {
+                    if !env.in_grouping_b(G_vowel2, 101, 252) {
+                        break 'lab8;
+                    }
+                    env.cursor = env.limit - v_5;
+                    break 'golab7;
+                }
+                env.cursor = env.limit - v_5;
+                if env.cursor <= env.limit_backward {
+                    break 'lab6;
+                }
+                env.previous_char();
+            }
+            break 'lab2;
+        }
+        env.cursor = env.limit - v_3;
+        'lab9: loop {
+            // (, line 118
+            // literal, line 118
+            if !env.eq_s_b(&"\u{0131}") {
+                break 'lab9;
+            }
+            // goto, line 118
+            'golab10: loop {
+                let v_6 = env.limit - env.cursor;
+                'lab11: loop {
+                    if !env.in_grouping_b(G_vowel3, 97, 305) {
+                        break 'lab11;
+                    }
+                    env.cursor = env.limit - v_6;
+                    break 'golab10;
+                }
+                env.cursor = env.limit - v_6;
+                if env.cursor <= env.limit_backward {
+                    break 'lab9;
+                }
+                env.previous_char();
+            }
+            break 'lab2;
+        }
+        env.cursor = env.limit - v_3;
+        'lab12: loop {
+            // (, line 119
+            // literal, line 119
+            if !env.eq_s_b(&"i") {
+                break 'lab12;
+            }
+            // goto, line 119
+            'golab13: loop {
+                let v_7 = env.limit - env.cursor;
+                'lab14: loop {
+                    if !env.in_grouping_b(G_vowel4, 101, 105) {
+                        break 'lab14;
+                    }
+                    env.cursor = env.limit - v_7;
+                    break 'golab13;
+                }
+                env.cursor = env.limit - v_7;
+                if env.cursor <= env.limit_backward {
+                    break 'lab12;
+                }
+                env.previous_char();
+            }
+            break 'lab2;
+        }
+        env.cursor = env.limit - v_3;
+        'lab15: loop {
+            // (, line 120
+            // literal, line 120
+            if !env.eq_s_b(&"o") {
+                break 'lab15;
+            }
+            // goto, line 120
+            'golab16: loop {
+                let v_8 = env.limit - env.cursor;
+                'lab17: loop {
+                    if !env.in_grouping_b(G_vowel5, 111, 117) {
+                        break 'lab17;
+                    }
+                    env.cursor = env.limit - v_8;
+                    break 'golab16;
+                }
+                env.cursor = env.limit - v_8;
+                if env.cursor <= env.limit_backward {
+                    break 'lab15;
+                }
+                env.previous_char();
+            }
+            break 'lab2;
+        }
+        env.cursor = env.limit - v_3;
+        'lab18: loop {
+            // (, line 121
+            // literal, line 121
+            if !env.eq_s_b(&"\u{00F6}") {
+                break 'lab18;
+            }
+            // goto, line 121
+            'golab19: loop {
+                let v_9 = env.limit - env.cursor;
+                'lab20: loop {
+                    if !env.in_grouping_b(G_vowel6, 246, 252) {
+                        break 'lab20;
+                    }
+                    env.cursor = env.limit - v_9;
+                    break 'golab19;
+                }
+                env.cursor = env.limit - v_9;
+                if env.cursor <= env.limit_backward {
+                    break 'lab18;
+                }
+                env.previous_char();
+            }
+            break 'lab2;
+        }
+        env.cursor = env.limit - v_3;
+        'lab21: loop {
+            // (, line 122
+            // literal, line 122
+            if !env.eq_s_b(&"u") {
+                break 'lab21;
+            }
+            // goto, line 122
+            'golab22: loop {
+                let v_10 = env.limit - env.cursor;
+                'lab23: loop {
+                    if !env.in_grouping_b(G_vowel5, 111, 117) {
+                        break 'lab23;
+                    }
+                    env.cursor = env.limit - v_10;
+                    break 'golab22;
+                }
+                env.cursor = env.limit - v_10;
+                if env.cursor <= env.limit_backward {
+                    break 'lab21;
+                }
+                env.previous_char();
+            }
+            break 'lab2;
+        }
+        env.cursor = env.limit - v_3;
+        // (, line 123
+        // literal, line 123
+        if !env.eq_s_b(&"\u{00FC}") {
+            return false;
+        }
+        // goto, line 123
+        'golab24: loop {
+            let v_11 = env.limit - env.cursor;
+            'lab25: loop {
+                if !env.in_grouping_b(G_vowel6, 246, 252) {
+                    break 'lab25;
+                }
+                env.cursor = env.limit - v_11;
+                break 'golab24;
+            }
+            env.cursor = env.limit - v_11;
+            if env.cursor <= env.limit_backward {
+                return false;
+            }
+            env.previous_char();
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_1;
+    return true;
+}
+
+fn r_mark_suffix_with_optional_n_consonant(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 132
+    // or, line 134
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 133
+            // literal, line 133
+            if !env.eq_s_b(&"n") {
+                break 'lab1;
+            }
+            // (, line 133
+            // test, line 133
+            let v_2 = env.limit - env.cursor;
+            if !env.in_grouping_b(G_vowel, 97, 305) {
+                break 'lab1;
+            }
+            env.cursor = env.limit - v_2;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 135
+        // (, line 135
+        // not, line 135
+        let v_3 = env.limit - env.cursor;
+        'lab2: loop {
+            // (, line 135
+            // test, line 135
+            let v_4 = env.limit - env.cursor;
+            // literal, line 135
+            if !env.eq_s_b(&"n") {
+                break 'lab2;
+            }
+            env.cursor = env.limit - v_4;
+            return false;
+        }
+        env.cursor = env.limit - v_3;
+        // test, line 135
+        let v_5 = env.limit - env.cursor;
+        // (, line 135
+        // next, line 135
+        if env.cursor <= env.limit_backward {
+            return false;
+        }
+        env.previous_char();
+        if !env.in_grouping_b(G_vowel, 97, 305) {
+            return false;
+        }
+        env.cursor = env.limit - v_5;
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_mark_suffix_with_optional_s_consonant(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 143
+    // or, line 145
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 144
+            // literal, line 144
+            if !env.eq_s_b(&"s") {
+                break 'lab1;
+            }
+            // (, line 144
+            // test, line 144
+            let v_2 = env.limit - env.cursor;
+            if !env.in_grouping_b(G_vowel, 97, 305) {
+                break 'lab1;
+            }
+            env.cursor = env.limit - v_2;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 146
+        // (, line 146
+        // not, line 146
+        let v_3 = env.limit - env.cursor;
+        'lab2: loop {
+            // (, line 146
+            // test, line 146
+            let v_4 = env.limit - env.cursor;
+            // literal, line 146
+            if !env.eq_s_b(&"s") {
+                break 'lab2;
+            }
+            env.cursor = env.limit - v_4;
+            return false;
+        }
+        env.cursor = env.limit - v_3;
+        // test, line 146
+        let v_5 = env.limit - env.cursor;
+        // (, line 146
+        // next, line 146
+        if env.cursor <= env.limit_backward {
+            return false;
+        }
+        env.previous_char();
+        if !env.in_grouping_b(G_vowel, 97, 305) {
+            return false;
+        }
+        env.cursor = env.limit - v_5;
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_mark_suffix_with_optional_y_consonant(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 153
+    // or, line 155
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 154
+            // literal, line 154
+            if !env.eq_s_b(&"y") {
+                break 'lab1;
+            }
+            // (, line 154
+            // test, line 154
+            let v_2 = env.limit - env.cursor;
+            if !env.in_grouping_b(G_vowel, 97, 305) {
+                break 'lab1;
+            }
+            env.cursor = env.limit - v_2;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 156
+        // (, line 156
+        // not, line 156
+        let v_3 = env.limit - env.cursor;
+        'lab2: loop {
+            // (, line 156
+            // test, line 156
+            let v_4 = env.limit - env.cursor;
+            // literal, line 156
+            if !env.eq_s_b(&"y") {
+                break 'lab2;
+            }
+            env.cursor = env.limit - v_4;
+            return false;
+        }
+        env.cursor = env.limit - v_3;
+        // test, line 156
+        let v_5 = env.limit - env.cursor;
+        // (, line 156
+        // next, line 156
+        if env.cursor <= env.limit_backward {
+            return false;
+        }
+        env.previous_char();
+        if !env.in_grouping_b(G_vowel, 97, 305) {
+            return false;
+        }
+        env.cursor = env.limit - v_5;
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_mark_suffix_with_optional_U_vowel(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 159
+    // or, line 161
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 160
+            if !env.in_grouping_b(G_U, 105, 305) {
+                break 'lab1;
+            }
+            // (, line 160
+            // test, line 160
+            let v_2 = env.limit - env.cursor;
+            if !env.out_grouping_b(G_vowel, 97, 305) {
+                break 'lab1;
+            }
+            env.cursor = env.limit - v_2;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 162
+        // (, line 162
+        // not, line 162
+        let v_3 = env.limit - env.cursor;
+        'lab2: loop {
+            // (, line 162
+            // test, line 162
+            let v_4 = env.limit - env.cursor;
+            if !env.in_grouping_b(G_U, 105, 305) {
+                break 'lab2;
+            }
+            env.cursor = env.limit - v_4;
+            return false;
+        }
+        env.cursor = env.limit - v_3;
+        // test, line 162
+        let v_5 = env.limit - env.cursor;
+        // (, line 162
+        // next, line 162
+        if env.cursor <= env.limit_backward {
+            return false;
+        }
+        env.previous_char();
+        if !env.out_grouping_b(G_vowel, 97, 305) {
+            return false;
+        }
+        env.cursor = env.limit - v_5;
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_mark_possessives(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 166
+    // among, line 167
+    if env.find_among_b(A_0, context) == 0 {
+        return false;
+    }
+    // (, line 169
+    // call mark_suffix_with_optional_U_vowel, line 169
+    if !r_mark_suffix_with_optional_U_vowel(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_sU(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 172
+    // call check_vowel_harmony, line 173
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    if !env.in_grouping_b(G_U, 105, 305) {
+        return false;
+    }
+    // (, line 175
+    // call mark_suffix_with_optional_s_consonant, line 175
+    if !r_mark_suffix_with_optional_s_consonant(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_lArI(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 178
+    // among, line 179
+    if env.find_among_b(A_1, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_yU(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 182
+    // call check_vowel_harmony, line 183
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    if !env.in_grouping_b(G_U, 105, 305) {
+        return false;
+    }
+    // (, line 185
+    // call mark_suffix_with_optional_y_consonant, line 185
+    if !r_mark_suffix_with_optional_y_consonant(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_nU(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 188
+    // call check_vowel_harmony, line 189
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 190
+    if env.find_among_b(A_2, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_nUn(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 193
+    // call check_vowel_harmony, line 194
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 195
+    if env.find_among_b(A_3, context) == 0 {
+        return false;
+    }
+    // (, line 196
+    // call mark_suffix_with_optional_n_consonant, line 196
+    if !r_mark_suffix_with_optional_n_consonant(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_yA(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 199
+    // call check_vowel_harmony, line 200
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 201
+    if env.find_among_b(A_4, context) == 0 {
+        return false;
+    }
+    // (, line 202
+    // call mark_suffix_with_optional_y_consonant, line 202
+    if !r_mark_suffix_with_optional_y_consonant(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_nA(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 205
+    // call check_vowel_harmony, line 206
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 207
+    if env.find_among_b(A_5, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_DA(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 210
+    // call check_vowel_harmony, line 211
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 212
+    if env.find_among_b(A_6, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_ndA(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 215
+    // call check_vowel_harmony, line 216
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 217
+    if env.find_among_b(A_7, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_DAn(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 220
+    // call check_vowel_harmony, line 221
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 222
+    if env.find_among_b(A_8, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_ndAn(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 225
+    // call check_vowel_harmony, line 226
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 227
+    if env.find_among_b(A_9, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_ylA(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 230
+    // call check_vowel_harmony, line 231
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 232
+    if env.find_among_b(A_10, context) == 0 {
+        return false;
+    }
+    // (, line 233
+    // call mark_suffix_with_optional_y_consonant, line 233
+    if !r_mark_suffix_with_optional_y_consonant(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_ki(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 236
+    // literal, line 237
+    if !env.eq_s_b(&"ki") {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_ncA(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 240
+    // call check_vowel_harmony, line 241
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 242
+    if env.find_among_b(A_11, context) == 0 {
+        return false;
+    }
+    // (, line 243
+    // call mark_suffix_with_optional_n_consonant, line 243
+    if !r_mark_suffix_with_optional_n_consonant(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_yUm(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 246
+    // call check_vowel_harmony, line 247
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 248
+    if env.find_among_b(A_12, context) == 0 {
+        return false;
+    }
+    // (, line 249
+    // call mark_suffix_with_optional_y_consonant, line 249
+    if !r_mark_suffix_with_optional_y_consonant(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_sUn(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 252
+    // call check_vowel_harmony, line 253
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 254
+    if env.find_among_b(A_13, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_yUz(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 257
+    // call check_vowel_harmony, line 258
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 259
+    if env.find_among_b(A_14, context) == 0 {
+        return false;
+    }
+    // (, line 260
+    // call mark_suffix_with_optional_y_consonant, line 260
+    if !r_mark_suffix_with_optional_y_consonant(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_sUnUz(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 263
+    // among, line 264
+    if env.find_among_b(A_15, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_lAr(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 267
+    // call check_vowel_harmony, line 268
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 269
+    if env.find_among_b(A_16, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_nUz(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 272
+    // call check_vowel_harmony, line 273
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 274
+    if env.find_among_b(A_17, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_DUr(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 277
+    // call check_vowel_harmony, line 278
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 279
+    if env.find_among_b(A_18, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_cAsInA(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 282
+    // among, line 283
+    if env.find_among_b(A_19, context) == 0 {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_yDU(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 286
+    // call check_vowel_harmony, line 287
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 288
+    if env.find_among_b(A_20, context) == 0 {
+        return false;
+    }
+    // (, line 292
+    // call mark_suffix_with_optional_y_consonant, line 292
+    if !r_mark_suffix_with_optional_y_consonant(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_ysA(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 296
+    // among, line 297
+    if env.find_among_b(A_21, context) == 0 {
+        return false;
+    }
+    // (, line 298
+    // call mark_suffix_with_optional_y_consonant, line 298
+    if !r_mark_suffix_with_optional_y_consonant(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_ymUs_(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 301
+    // call check_vowel_harmony, line 302
+    if !r_check_vowel_harmony(env, context) {
+        return false;
+    }
+    // among, line 303
+    if env.find_among_b(A_22, context) == 0 {
+        return false;
+    }
+    // (, line 304
+    // call mark_suffix_with_optional_y_consonant, line 304
+    if !r_mark_suffix_with_optional_y_consonant(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_mark_yken(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 307
+    // literal, line 308
+    if !env.eq_s_b(&"ken") {
+        return false;
+    }
+    // (, line 308
+    // call mark_suffix_with_optional_y_consonant, line 308
+    if !r_mark_suffix_with_optional_y_consonant(env, context) {
+        return false;
+    }
+    return true;
+}
+
+fn r_stem_nominal_verb_suffixes(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 311
+    // [, line 312
+    env.ket = env.cursor;
+    // set continue_stemming_noun_suffixes, line 313
+    context.b_continue_stemming_noun_suffixes = true;
+    // or, line 315
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 314
+            // or, line 314
+            'lab2: loop {
+                let v_2 = env.limit - env.cursor;
+                'lab3: loop {
+                    // call mark_ymUs_, line 314
+                    if !r_mark_ymUs_(env, context) {
+                        break 'lab3;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_2;
+                'lab4: loop {
+                    // call mark_yDU, line 314
+                    if !r_mark_yDU(env, context) {
+                        break 'lab4;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_2;
+                'lab5: loop {
+                    // call mark_ysA, line 314
+                    if !r_mark_ysA(env, context) {
+                        break 'lab5;
+                    }
+                    break 'lab2;
+                }
+                env.cursor = env.limit - v_2;
+                // call mark_yken, line 314
+                if !r_mark_yken(env, context) {
+                    break 'lab1;
+                }
+                break 'lab2;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab6: loop {
+            // (, line 316
+            // call mark_cAsInA, line 316
+            if !r_mark_cAsInA(env, context) {
+                break 'lab6;
+            }
+            // (, line 316
+            // or, line 316
+            'lab7: loop {
+                let v_3 = env.limit - env.cursor;
+                'lab8: loop {
+                    // call mark_sUnUz, line 316
+                    if !r_mark_sUnUz(env, context) {
+                        break 'lab8;
+                    }
+                    break 'lab7;
+                }
+                env.cursor = env.limit - v_3;
+                'lab9: loop {
+                    // call mark_lAr, line 316
+                    if !r_mark_lAr(env, context) {
+                        break 'lab9;
+                    }
+                    break 'lab7;
+                }
+                env.cursor = env.limit - v_3;
+                'lab10: loop {
+                    // call mark_yUm, line 316
+                    if !r_mark_yUm(env, context) {
+                        break 'lab10;
+                    }
+                    break 'lab7;
+                }
+                env.cursor = env.limit - v_3;
+                'lab11: loop {
+                    // call mark_sUn, line 316
+                    if !r_mark_sUn(env, context) {
+                        break 'lab11;
+                    }
+                    break 'lab7;
+                }
+                env.cursor = env.limit - v_3;
+                'lab12: loop {
+                    // call mark_yUz, line 316
+                    if !r_mark_yUz(env, context) {
+                        break 'lab12;
+                    }
+                    break 'lab7;
+                }
+                env.cursor = env.limit - v_3;
+                break 'lab7;
+            }
+            // call mark_ymUs_, line 316
+            if !r_mark_ymUs_(env, context) {
+                break 'lab6;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab13: loop {
+            // (, line 318
+            // call mark_lAr, line 319
+            if !r_mark_lAr(env, context) {
+                break 'lab13;
+            }
+            // ], line 319
+            env.bra = env.cursor;
+            // delete, line 319
+            if !env.slice_del() {
+                return false;
+            }
+            // try, line 319
+            let v_4 = env.limit - env.cursor;
+            'lab14: loop {
+                // (, line 319
+                // [, line 319
+                env.ket = env.cursor;
+                // (, line 319
+                // or, line 319
+                'lab15: loop {
+                    let v_5 = env.limit - env.cursor;
+                    'lab16: loop {
+                        // call mark_DUr, line 319
+                        if !r_mark_DUr(env, context) {
+                            break 'lab16;
+                        }
+                        break 'lab15;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab17: loop {
+                        // call mark_yDU, line 319
+                        if !r_mark_yDU(env, context) {
+                            break 'lab17;
+                        }
+                        break 'lab15;
+                    }
+                    env.cursor = env.limit - v_5;
+                    'lab18: loop {
+                        // call mark_ysA, line 319
+                        if !r_mark_ysA(env, context) {
+                            break 'lab18;
+                        }
+                        break 'lab15;
+                    }
+                    env.cursor = env.limit - v_5;
+                    // call mark_ymUs_, line 319
+                    if !r_mark_ymUs_(env, context) {
+                        env.cursor = env.limit - v_4;
+                        break 'lab14;
+                    }
+                    break 'lab15;
+                }
+                break 'lab14;
+            }
+            // unset continue_stemming_noun_suffixes, line 320
+            context.b_continue_stemming_noun_suffixes = false;
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab19: loop {
+            // (, line 323
+            // call mark_nUz, line 323
+            if !r_mark_nUz(env, context) {
+                break 'lab19;
+            }
+            // (, line 323
+            // or, line 323
+            'lab20: loop {
+                let v_6 = env.limit - env.cursor;
+                'lab21: loop {
+                    // call mark_yDU, line 323
+                    if !r_mark_yDU(env, context) {
+                        break 'lab21;
+                    }
+                    break 'lab20;
+                }
+                env.cursor = env.limit - v_6;
+                // call mark_ysA, line 323
+                if !r_mark_ysA(env, context) {
+                    break 'lab19;
+                }
+                break 'lab20;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab22: loop {
+            // (, line 325
+            // (, line 325
+            // or, line 325
+            'lab23: loop {
+                let v_7 = env.limit - env.cursor;
+                'lab24: loop {
+                    // call mark_sUnUz, line 325
+                    if !r_mark_sUnUz(env, context) {
+                        break 'lab24;
+                    }
+                    break 'lab23;
+                }
+                env.cursor = env.limit - v_7;
+                'lab25: loop {
+                    // call mark_yUz, line 325
+                    if !r_mark_yUz(env, context) {
+                        break 'lab25;
+                    }
+                    break 'lab23;
+                }
+                env.cursor = env.limit - v_7;
+                'lab26: loop {
+                    // call mark_sUn, line 325
+                    if !r_mark_sUn(env, context) {
+                        break 'lab26;
+                    }
+                    break 'lab23;
+                }
+                env.cursor = env.limit - v_7;
+                // call mark_yUm, line 325
+                if !r_mark_yUm(env, context) {
+                    break 'lab22;
+                }
+                break 'lab23;
+            }
+            // ], line 325
+            env.bra = env.cursor;
+            // delete, line 325
+            if !env.slice_del() {
+                return false;
+            }
+            // try, line 325
+            let v_8 = env.limit - env.cursor;
+            'lab27: loop {
+                // (, line 325
+                // [, line 325
+                env.ket = env.cursor;
+                // call mark_ymUs_, line 325
+                if !r_mark_ymUs_(env, context) {
+                    env.cursor = env.limit - v_8;
+                    break 'lab27;
+                }
+                break 'lab27;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 327
+        // call mark_DUr, line 327
+        if !r_mark_DUr(env, context) {
+            return false;
+        }
+        // ], line 327
+        env.bra = env.cursor;
+        // delete, line 327
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 327
+        let v_9 = env.limit - env.cursor;
+        'lab28: loop {
+            // (, line 327
+            // [, line 327
+            env.ket = env.cursor;
+            // (, line 327
+            // or, line 327
+            'lab29: loop {
+                let v_10 = env.limit - env.cursor;
+                'lab30: loop {
+                    // call mark_sUnUz, line 327
+                    if !r_mark_sUnUz(env, context) {
+                        break 'lab30;
+                    }
+                    break 'lab29;
+                }
+                env.cursor = env.limit - v_10;
+                'lab31: loop {
+                    // call mark_lAr, line 327
+                    if !r_mark_lAr(env, context) {
+                        break 'lab31;
+                    }
+                    break 'lab29;
+                }
+                env.cursor = env.limit - v_10;
+                'lab32: loop {
+                    // call mark_yUm, line 327
+                    if !r_mark_yUm(env, context) {
+                        break 'lab32;
+                    }
+                    break 'lab29;
+                }
+                env.cursor = env.limit - v_10;
+                'lab33: loop {
+                    // call mark_sUn, line 327
+                    if !r_mark_sUn(env, context) {
+                        break 'lab33;
+                    }
+                    break 'lab29;
+                }
+                env.cursor = env.limit - v_10;
+                'lab34: loop {
+                    // call mark_yUz, line 327
+                    if !r_mark_yUz(env, context) {
+                        break 'lab34;
+                    }
+                    break 'lab29;
+                }
+                env.cursor = env.limit - v_10;
+                break 'lab29;
+            }
+            // call mark_ymUs_, line 327
+            if !r_mark_ymUs_(env, context) {
+                env.cursor = env.limit - v_9;
+                break 'lab28;
+            }
+            break 'lab28;
+        }
+        break 'lab0;
+    }
+    // ], line 328
+    env.bra = env.cursor;
+    // delete, line 328
+    if !env.slice_del() {
+        return false;
+    }
+    return true;
+}
+
+fn r_stem_suffix_chain_before_ki(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 332
+    // [, line 333
+    env.ket = env.cursor;
+    // call mark_ki, line 334
+    if !r_mark_ki(env, context) {
+        return false;
+    }
+    // (, line 335
+    // or, line 342
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 336
+            // call mark_DA, line 336
+            if !r_mark_DA(env, context) {
+                break 'lab1;
+            }
+            // ], line 336
+            env.bra = env.cursor;
+            // delete, line 336
+            if !env.slice_del() {
+                return false;
+            }
+            // try, line 336
+            let v_2 = env.limit - env.cursor;
+            'lab2: loop {
+                // (, line 336
+                // [, line 336
+                env.ket = env.cursor;
+                // or, line 338
+                'lab3: loop {
+                    let v_3 = env.limit - env.cursor;
+                    'lab4: loop {
+                        // (, line 337
+                        // call mark_lAr, line 337
+                        if !r_mark_lAr(env, context) {
+                            break 'lab4;
+                        }
+                        // ], line 337
+                        env.bra = env.cursor;
+                        // delete, line 337
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        // try, line 337
+                        let v_4 = env.limit - env.cursor;
+                        'lab5: loop {
+                            // (, line 337
+                            // call stem_suffix_chain_before_ki, line 337
+                            if !r_stem_suffix_chain_before_ki(env, context) {
+                                env.cursor = env.limit - v_4;
+                                break 'lab5;
+                            }
+                            break 'lab5;
+                        }
+                        break 'lab3;
+                    }
+                    env.cursor = env.limit - v_3;
+                    // (, line 339
+                    // call mark_possessives, line 339
+                    if !r_mark_possessives(env, context) {
+                        env.cursor = env.limit - v_2;
+                        break 'lab2;
+                    }
+                    // ], line 339
+                    env.bra = env.cursor;
+                    // delete, line 339
+                    if !env.slice_del() {
+                        return false;
+                    }
+                    // try, line 339
+                    let v_5 = env.limit - env.cursor;
+                    'lab6: loop {
+                        // (, line 339
+                        // [, line 339
+                        env.ket = env.cursor;
+                        // call mark_lAr, line 339
+                        if !r_mark_lAr(env, context) {
+                            env.cursor = env.limit - v_5;
+                            break 'lab6;
+                        }
+                        // ], line 339
+                        env.bra = env.cursor;
+                        // delete, line 339
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        // call stem_suffix_chain_before_ki, line 339
+                        if !r_stem_suffix_chain_before_ki(env, context) {
+                            env.cursor = env.limit - v_5;
+                            break 'lab6;
+                        }
+                        break 'lab6;
+                    }
+                    break 'lab3;
+                }
+                break 'lab2;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab7: loop {
+            // (, line 343
+            // call mark_nUn, line 343
+            if !r_mark_nUn(env, context) {
+                break 'lab7;
+            }
+            // ], line 343
+            env.bra = env.cursor;
+            // delete, line 343
+            if !env.slice_del() {
+                return false;
+            }
+            // try, line 343
+            let v_6 = env.limit - env.cursor;
+            'lab8: loop {
+                // (, line 343
+                // [, line 343
+                env.ket = env.cursor;
+                // or, line 345
+                'lab9: loop {
+                    let v_7 = env.limit - env.cursor;
+                    'lab10: loop {
+                        // (, line 344
+                        // call mark_lArI, line 344
+                        if !r_mark_lArI(env, context) {
+                            break 'lab10;
+                        }
+                        // ], line 344
+                        env.bra = env.cursor;
+                        // delete, line 344
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        break 'lab9;
+                    }
+                    env.cursor = env.limit - v_7;
+                    'lab11: loop {
+                        // (, line 346
+                        // [, line 346
+                        env.ket = env.cursor;
+                        // or, line 346
+                        'lab12: loop {
+                            let v_8 = env.limit - env.cursor;
+                            'lab13: loop {
+                                // call mark_possessives, line 346
+                                if !r_mark_possessives(env, context) {
+                                    break 'lab13;
+                                }
+                                break 'lab12;
+                            }
+                            env.cursor = env.limit - v_8;
+                            // call mark_sU, line 346
+                            if !r_mark_sU(env, context) {
+                                break 'lab11;
+                            }
+                            break 'lab12;
+                        }
+                        // ], line 346
+                        env.bra = env.cursor;
+                        // delete, line 346
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        // try, line 346
+                        let v_9 = env.limit - env.cursor;
+                        'lab14: loop {
+                            // (, line 346
+                            // [, line 346
+                            env.ket = env.cursor;
+                            // call mark_lAr, line 346
+                            if !r_mark_lAr(env, context) {
+                                env.cursor = env.limit - v_9;
+                                break 'lab14;
+                            }
+                            // ], line 346
+                            env.bra = env.cursor;
+                            // delete, line 346
+                            if !env.slice_del() {
+                                return false;
+                            }
+                            // call stem_suffix_chain_before_ki, line 346
+                            if !r_stem_suffix_chain_before_ki(env, context) {
+                                env.cursor = env.limit - v_9;
+                                break 'lab14;
+                            }
+                            break 'lab14;
+                        }
+                        break 'lab9;
+                    }
+                    env.cursor = env.limit - v_7;
+                    // (, line 348
+                    // call stem_suffix_chain_before_ki, line 348
+                    if !r_stem_suffix_chain_before_ki(env, context) {
+                        env.cursor = env.limit - v_6;
+                        break 'lab8;
+                    }
+                    break 'lab9;
+                }
+                break 'lab8;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 351
+        // call mark_ndA, line 351
+        if !r_mark_ndA(env, context) {
+            return false;
+        }
+        // (, line 351
+        // or, line 353
+        'lab15: loop {
+            let v_10 = env.limit - env.cursor;
+            'lab16: loop {
+                // (, line 352
+                // call mark_lArI, line 352
+                if !r_mark_lArI(env, context) {
+                    break 'lab16;
+                }
+                // ], line 352
+                env.bra = env.cursor;
+                // delete, line 352
+                if !env.slice_del() {
+                    return false;
+                }
+                break 'lab15;
+            }
+            env.cursor = env.limit - v_10;
+            'lab17: loop {
+                // (, line 354
+                // (, line 354
+                // call mark_sU, line 354
+                if !r_mark_sU(env, context) {
+                    break 'lab17;
+                }
+                // ], line 354
+                env.bra = env.cursor;
+                // delete, line 354
+                if !env.slice_del() {
+                    return false;
+                }
+                // try, line 354
+                let v_11 = env.limit - env.cursor;
+                'lab18: loop {
+                    // (, line 354
+                    // [, line 354
+                    env.ket = env.cursor;
+                    // call mark_lAr, line 354
+                    if !r_mark_lAr(env, context) {
+                        env.cursor = env.limit - v_11;
+                        break 'lab18;
+                    }
+                    // ], line 354
+                    env.bra = env.cursor;
+                    // delete, line 354
+                    if !env.slice_del() {
+                        return false;
+                    }
+                    // call stem_suffix_chain_before_ki, line 354
+                    if !r_stem_suffix_chain_before_ki(env, context) {
+                        env.cursor = env.limit - v_11;
+                        break 'lab18;
+                    }
+                    break 'lab18;
+                }
+                break 'lab15;
+            }
+            env.cursor = env.limit - v_10;
+            // (, line 356
+            // call stem_suffix_chain_before_ki, line 356
+            if !r_stem_suffix_chain_before_ki(env, context) {
+                return false;
+            }
+            break 'lab15;
+        }
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_stem_noun_suffixes(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 361
+    // or, line 363
+    'lab0: loop {
+        let v_1 = env.limit - env.cursor;
+        'lab1: loop {
+            // (, line 362
+            // [, line 362
+            env.ket = env.cursor;
+            // call mark_lAr, line 362
+            if !r_mark_lAr(env, context) {
+                break 'lab1;
+            }
+            // ], line 362
+            env.bra = env.cursor;
+            // delete, line 362
+            if !env.slice_del() {
+                return false;
+            }
+            // try, line 362
+            let v_2 = env.limit - env.cursor;
+            'lab2: loop {
+                // (, line 362
+                // call stem_suffix_chain_before_ki, line 362
+                if !r_stem_suffix_chain_before_ki(env, context) {
+                    env.cursor = env.limit - v_2;
+                    break 'lab2;
+                }
+                break 'lab2;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab3: loop {
+            // (, line 364
+            // [, line 364
+            env.ket = env.cursor;
+            // call mark_ncA, line 364
+            if !r_mark_ncA(env, context) {
+                break 'lab3;
+            }
+            // ], line 364
+            env.bra = env.cursor;
+            // delete, line 364
+            if !env.slice_del() {
+                return false;
+            }
+            // try, line 365
+            let v_3 = env.limit - env.cursor;
+            'lab4: loop {
+                // (, line 365
+                // or, line 367
+                'lab5: loop {
+                    let v_4 = env.limit - env.cursor;
+                    'lab6: loop {
+                        // (, line 366
+                        // [, line 366
+                        env.ket = env.cursor;
+                        // call mark_lArI, line 366
+                        if !r_mark_lArI(env, context) {
+                            break 'lab6;
+                        }
+                        // ], line 366
+                        env.bra = env.cursor;
+                        // delete, line 366
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        break 'lab5;
+                    }
+                    env.cursor = env.limit - v_4;
+                    'lab7: loop {
+                        // (, line 368
+                        // [, line 368
+                        env.ket = env.cursor;
+                        // or, line 368
+                        'lab8: loop {
+                            let v_5 = env.limit - env.cursor;
+                            'lab9: loop {
+                                // call mark_possessives, line 368
+                                if !r_mark_possessives(env, context) {
+                                    break 'lab9;
+                                }
+                                break 'lab8;
+                            }
+                            env.cursor = env.limit - v_5;
+                            // call mark_sU, line 368
+                            if !r_mark_sU(env, context) {
+                                break 'lab7;
+                            }
+                            break 'lab8;
+                        }
+                        // ], line 368
+                        env.bra = env.cursor;
+                        // delete, line 368
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        // try, line 368
+                        let v_6 = env.limit - env.cursor;
+                        'lab10: loop {
+                            // (, line 368
+                            // [, line 368
+                            env.ket = env.cursor;
+                            // call mark_lAr, line 368
+                            if !r_mark_lAr(env, context) {
+                                env.cursor = env.limit - v_6;
+                                break 'lab10;
+                            }
+                            // ], line 368
+                            env.bra = env.cursor;
+                            // delete, line 368
+                            if !env.slice_del() {
+                                return false;
+                            }
+                            // call stem_suffix_chain_before_ki, line 368
+                            if !r_stem_suffix_chain_before_ki(env, context) {
+                                env.cursor = env.limit - v_6;
+                                break 'lab10;
+                            }
+                            break 'lab10;
+                        }
+                        break 'lab5;
+                    }
+                    env.cursor = env.limit - v_4;
+                    // (, line 370
+                    // [, line 370
+                    env.ket = env.cursor;
+                    // call mark_lAr, line 370
+                    if !r_mark_lAr(env, context) {
+                        env.cursor = env.limit - v_3;
+                        break 'lab4;
+                    }
+                    // ], line 370
+                    env.bra = env.cursor;
+                    // delete, line 370
+                    if !env.slice_del() {
+                        return false;
+                    }
+                    // call stem_suffix_chain_before_ki, line 370
+                    if !r_stem_suffix_chain_before_ki(env, context) {
+                        env.cursor = env.limit - v_3;
+                        break 'lab4;
+                    }
+                    break 'lab5;
+                }
+                break 'lab4;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab11: loop {
+            // (, line 374
+            // [, line 374
+            env.ket = env.cursor;
+            // (, line 374
+            // or, line 374
+            'lab12: loop {
+                let v_7 = env.limit - env.cursor;
+                'lab13: loop {
+                    // call mark_ndA, line 374
+                    if !r_mark_ndA(env, context) {
+                        break 'lab13;
+                    }
+                    break 'lab12;
+                }
+                env.cursor = env.limit - v_7;
+                // call mark_nA, line 374
+                if !r_mark_nA(env, context) {
+                    break 'lab11;
+                }
+                break 'lab12;
+            }
+            // (, line 375
+            // or, line 377
+            'lab14: loop {
+                let v_8 = env.limit - env.cursor;
+                'lab15: loop {
+                    // (, line 376
+                    // call mark_lArI, line 376
+                    if !r_mark_lArI(env, context) {
+                        break 'lab15;
+                    }
+                    // ], line 376
+                    env.bra = env.cursor;
+                    // delete, line 376
+                    if !env.slice_del() {
+                        return false;
+                    }
+                    break 'lab14;
+                }
+                env.cursor = env.limit - v_8;
+                'lab16: loop {
+                    // (, line 378
+                    // call mark_sU, line 378
+                    if !r_mark_sU(env, context) {
+                        break 'lab16;
+                    }
+                    // ], line 378
+                    env.bra = env.cursor;
+                    // delete, line 378
+                    if !env.slice_del() {
+                        return false;
+                    }
+                    // try, line 378
+                    let v_9 = env.limit - env.cursor;
+                    'lab17: loop {
+                        // (, line 378
+                        // [, line 378
+                        env.ket = env.cursor;
+                        // call mark_lAr, line 378
+                        if !r_mark_lAr(env, context) {
+                            env.cursor = env.limit - v_9;
+                            break 'lab17;
+                        }
+                        // ], line 378
+                        env.bra = env.cursor;
+                        // delete, line 378
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        // call stem_suffix_chain_before_ki, line 378
+                        if !r_stem_suffix_chain_before_ki(env, context) {
+                            env.cursor = env.limit - v_9;
+                            break 'lab17;
+                        }
+                        break 'lab17;
+                    }
+                    break 'lab14;
+                }
+                env.cursor = env.limit - v_8;
+                // (, line 380
+                // call stem_suffix_chain_before_ki, line 380
+                if !r_stem_suffix_chain_before_ki(env, context) {
+                    break 'lab11;
+                }
+                break 'lab14;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab18: loop {
+            // (, line 384
+            // [, line 384
+            env.ket = env.cursor;
+            // (, line 384
+            // or, line 384
+            'lab19: loop {
+                let v_10 = env.limit - env.cursor;
+                'lab20: loop {
+                    // call mark_ndAn, line 384
+                    if !r_mark_ndAn(env, context) {
+                        break 'lab20;
+                    }
+                    break 'lab19;
+                }
+                env.cursor = env.limit - v_10;
+                // call mark_nU, line 384
+                if !r_mark_nU(env, context) {
+                    break 'lab18;
+                }
+                break 'lab19;
+            }
+            // (, line 384
+            // or, line 384
+            'lab21: loop {
+                let v_11 = env.limit - env.cursor;
+                'lab22: loop {
+                    // (, line 384
+                    // call mark_sU, line 384
+                    if !r_mark_sU(env, context) {
+                        break 'lab22;
+                    }
+                    // ], line 384
+                    env.bra = env.cursor;
+                    // delete, line 384
+                    if !env.slice_del() {
+                        return false;
+                    }
+                    // try, line 384
+                    let v_12 = env.limit - env.cursor;
+                    'lab23: loop {
+                        // (, line 384
+                        // [, line 384
+                        env.ket = env.cursor;
+                        // call mark_lAr, line 384
+                        if !r_mark_lAr(env, context) {
+                            env.cursor = env.limit - v_12;
+                            break 'lab23;
+                        }
+                        // ], line 384
+                        env.bra = env.cursor;
+                        // delete, line 384
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        // call stem_suffix_chain_before_ki, line 384
+                        if !r_stem_suffix_chain_before_ki(env, context) {
+                            env.cursor = env.limit - v_12;
+                            break 'lab23;
+                        }
+                        break 'lab23;
+                    }
+                    break 'lab21;
+                }
+                env.cursor = env.limit - v_11;
+                // (, line 384
+                // call mark_lArI, line 384
+                if !r_mark_lArI(env, context) {
+                    break 'lab18;
+                }
+                break 'lab21;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab24: loop {
+            // (, line 386
+            // [, line 386
+            env.ket = env.cursor;
+            // call mark_DAn, line 386
+            if !r_mark_DAn(env, context) {
+                break 'lab24;
+            }
+            // ], line 386
+            env.bra = env.cursor;
+            // delete, line 386
+            if !env.slice_del() {
+                return false;
+            }
+            // try, line 386
+            let v_13 = env.limit - env.cursor;
+            'lab25: loop {
+                // (, line 386
+                // [, line 386
+                env.ket = env.cursor;
+                // (, line 387
+                // or, line 389
+                'lab26: loop {
+                    let v_14 = env.limit - env.cursor;
+                    'lab27: loop {
+                        // (, line 388
+                        // call mark_possessives, line 388
+                        if !r_mark_possessives(env, context) {
+                            break 'lab27;
+                        }
+                        // ], line 388
+                        env.bra = env.cursor;
+                        // delete, line 388
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        // try, line 388
+                        let v_15 = env.limit - env.cursor;
+                        'lab28: loop {
+                            // (, line 388
+                            // [, line 388
+                            env.ket = env.cursor;
+                            // call mark_lAr, line 388
+                            if !r_mark_lAr(env, context) {
+                                env.cursor = env.limit - v_15;
+                                break 'lab28;
+                            }
+                            // ], line 388
+                            env.bra = env.cursor;
+                            // delete, line 388
+                            if !env.slice_del() {
+                                return false;
+                            }
+                            // call stem_suffix_chain_before_ki, line 388
+                            if !r_stem_suffix_chain_before_ki(env, context) {
+                                env.cursor = env.limit - v_15;
+                                break 'lab28;
+                            }
+                            break 'lab28;
+                        }
+                        break 'lab26;
+                    }
+                    env.cursor = env.limit - v_14;
+                    'lab29: loop {
+                        // (, line 390
+                        // call mark_lAr, line 390
+                        if !r_mark_lAr(env, context) {
+                            break 'lab29;
+                        }
+                        // ], line 390
+                        env.bra = env.cursor;
+                        // delete, line 390
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        // try, line 390
+                        let v_16 = env.limit - env.cursor;
+                        'lab30: loop {
+                            // (, line 390
+                            // call stem_suffix_chain_before_ki, line 390
+                            if !r_stem_suffix_chain_before_ki(env, context) {
+                                env.cursor = env.limit - v_16;
+                                break 'lab30;
+                            }
+                            break 'lab30;
+                        }
+                        break 'lab26;
+                    }
+                    env.cursor = env.limit - v_14;
+                    // (, line 392
+                    // call stem_suffix_chain_before_ki, line 392
+                    if !r_stem_suffix_chain_before_ki(env, context) {
+                        env.cursor = env.limit - v_13;
+                        break 'lab25;
+                    }
+                    break 'lab26;
+                }
+                break 'lab25;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab31: loop {
+            // (, line 396
+            // [, line 396
+            env.ket = env.cursor;
+            // or, line 396
+            'lab32: loop {
+                let v_17 = env.limit - env.cursor;
+                'lab33: loop {
+                    // call mark_nUn, line 396
+                    if !r_mark_nUn(env, context) {
+                        break 'lab33;
+                    }
+                    break 'lab32;
+                }
+                env.cursor = env.limit - v_17;
+                // call mark_ylA, line 396
+                if !r_mark_ylA(env, context) {
+                    break 'lab31;
+                }
+                break 'lab32;
+            }
+            // ], line 396
+            env.bra = env.cursor;
+            // delete, line 396
+            if !env.slice_del() {
+                return false;
+            }
+            // try, line 397
+            let v_18 = env.limit - env.cursor;
+            'lab34: loop {
+                // (, line 397
+                // or, line 399
+                'lab35: loop {
+                    let v_19 = env.limit - env.cursor;
+                    'lab36: loop {
+                        // (, line 398
+                        // [, line 398
+                        env.ket = env.cursor;
+                        // call mark_lAr, line 398
+                        if !r_mark_lAr(env, context) {
+                            break 'lab36;
+                        }
+                        // ], line 398
+                        env.bra = env.cursor;
+                        // delete, line 398
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        // call stem_suffix_chain_before_ki, line 398
+                        if !r_stem_suffix_chain_before_ki(env, context) {
+                            break 'lab36;
+                        }
+                        break 'lab35;
+                    }
+                    env.cursor = env.limit - v_19;
+                    'lab37: loop {
+                        // (, line 400
+                        // [, line 400
+                        env.ket = env.cursor;
+                        // or, line 400
+                        'lab38: loop {
+                            let v_20 = env.limit - env.cursor;
+                            'lab39: loop {
+                                // call mark_possessives, line 400
+                                if !r_mark_possessives(env, context) {
+                                    break 'lab39;
+                                }
+                                break 'lab38;
+                            }
+                            env.cursor = env.limit - v_20;
+                            // call mark_sU, line 400
+                            if !r_mark_sU(env, context) {
+                                break 'lab37;
+                            }
+                            break 'lab38;
+                        }
+                        // ], line 400
+                        env.bra = env.cursor;
+                        // delete, line 400
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        // try, line 400
+                        let v_21 = env.limit - env.cursor;
+                        'lab40: loop {
+                            // (, line 400
+                            // [, line 400
+                            env.ket = env.cursor;
+                            // call mark_lAr, line 400
+                            if !r_mark_lAr(env, context) {
+                                env.cursor = env.limit - v_21;
+                                break 'lab40;
+                            }
+                            // ], line 400
+                            env.bra = env.cursor;
+                            // delete, line 400
+                            if !env.slice_del() {
+                                return false;
+                            }
+                            // call stem_suffix_chain_before_ki, line 400
+                            if !r_stem_suffix_chain_before_ki(env, context) {
+                                env.cursor = env.limit - v_21;
+                                break 'lab40;
+                            }
+                            break 'lab40;
+                        }
+                        break 'lab35;
+                    }
+                    env.cursor = env.limit - v_19;
+                    // call stem_suffix_chain_before_ki, line 402
+                    if !r_stem_suffix_chain_before_ki(env, context) {
+                        env.cursor = env.limit - v_18;
+                        break 'lab34;
+                    }
+                    break 'lab35;
+                }
+                break 'lab34;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab41: loop {
+            // (, line 406
+            // [, line 406
+            env.ket = env.cursor;
+            // call mark_lArI, line 406
+            if !r_mark_lArI(env, context) {
+                break 'lab41;
+            }
+            // ], line 406
+            env.bra = env.cursor;
+            // delete, line 406
+            if !env.slice_del() {
+                return false;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab42: loop {
+            // (, line 408
+            // call stem_suffix_chain_before_ki, line 408
+            if !r_stem_suffix_chain_before_ki(env, context) {
+                break 'lab42;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        'lab43: loop {
+            // (, line 410
+            // [, line 410
+            env.ket = env.cursor;
+            // or, line 410
+            'lab44: loop {
+                let v_22 = env.limit - env.cursor;
+                'lab45: loop {
+                    // call mark_DA, line 410
+                    if !r_mark_DA(env, context) {
+                        break 'lab45;
+                    }
+                    break 'lab44;
+                }
+                env.cursor = env.limit - v_22;
+                'lab46: loop {
+                    // call mark_yU, line 410
+                    if !r_mark_yU(env, context) {
+                        break 'lab46;
+                    }
+                    break 'lab44;
+                }
+                env.cursor = env.limit - v_22;
+                // call mark_yA, line 410
+                if !r_mark_yA(env, context) {
+                    break 'lab43;
+                }
+                break 'lab44;
+            }
+            // ], line 410
+            env.bra = env.cursor;
+            // delete, line 410
+            if !env.slice_del() {
+                return false;
+            }
+            // try, line 410
+            let v_23 = env.limit - env.cursor;
+            'lab47: loop {
+                // (, line 410
+                // [, line 410
+                env.ket = env.cursor;
+                // (, line 410
+                // or, line 410
+                'lab48: loop {
+                    let v_24 = env.limit - env.cursor;
+                    'lab49: loop {
+                        // (, line 410
+                        // call mark_possessives, line 410
+                        if !r_mark_possessives(env, context) {
+                            break 'lab49;
+                        }
+                        // ], line 410
+                        env.bra = env.cursor;
+                        // delete, line 410
+                        if !env.slice_del() {
+                            return false;
+                        }
+                        // try, line 410
+                        let v_25 = env.limit - env.cursor;
+                        'lab50: loop {
+                            // (, line 410
+                            // [, line 410
+                            env.ket = env.cursor;
+                            // call mark_lAr, line 410
+                            if !r_mark_lAr(env, context) {
+                                env.cursor = env.limit - v_25;
+                                break 'lab50;
+                            }
+                            break 'lab50;
+                        }
+                        break 'lab48;
+                    }
+                    env.cursor = env.limit - v_24;
+                    // call mark_lAr, line 410
+                    if !r_mark_lAr(env, context) {
+                        env.cursor = env.limit - v_23;
+                        break 'lab47;
+                    }
+                    break 'lab48;
+                }
+                // ], line 410
+                env.bra = env.cursor;
+                // delete, line 410
+                if !env.slice_del() {
+                    return false;
+                }
+                // [, line 410
+                env.ket = env.cursor;
+                // call stem_suffix_chain_before_ki, line 410
+                if !r_stem_suffix_chain_before_ki(env, context) {
+                    env.cursor = env.limit - v_23;
+                    break 'lab47;
+                }
+                break 'lab47;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_1;
+        // (, line 412
+        // [, line 412
+        env.ket = env.cursor;
+        // or, line 412
+        'lab51: loop {
+            let v_26 = env.limit - env.cursor;
+            'lab52: loop {
+                // call mark_possessives, line 412
+                if !r_mark_possessives(env, context) {
+                    break 'lab52;
+                }
+                break 'lab51;
+            }
+            env.cursor = env.limit - v_26;
+            // call mark_sU, line 412
+            if !r_mark_sU(env, context) {
+                return false;
+            }
+            break 'lab51;
+        }
+        // ], line 412
+        env.bra = env.cursor;
+        // delete, line 412
+        if !env.slice_del() {
+            return false;
+        }
+        // try, line 412
+        let v_27 = env.limit - env.cursor;
+        'lab53: loop {
+            // (, line 412
+            // [, line 412
+            env.ket = env.cursor;
+            // call mark_lAr, line 412
+            if !r_mark_lAr(env, context) {
+                env.cursor = env.limit - v_27;
+                break 'lab53;
+            }
+            // ], line 412
+            env.bra = env.cursor;
+            // delete, line 412
+            if !env.slice_del() {
+                return false;
+            }
+            // call stem_suffix_chain_before_ki, line 412
+            if !r_stem_suffix_chain_before_ki(env, context) {
+                env.cursor = env.limit - v_27;
+                break 'lab53;
+            }
+            break 'lab53;
+        }
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_post_process_last_consonants(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    let mut among_var;
+    // (, line 415
+    // [, line 416
+    env.ket = env.cursor;
+    // substring, line 416
+    among_var = env.find_among_b(A_23, context);
+    if among_var == 0 {
+        return false;
+    }
+    // ], line 416
+    env.bra = env.cursor;
+    if among_var == 0 {
+        return false;
+    } else if among_var == 1 {
+        // (, line 417
+        // <-, line 417
+        if !env.slice_from("p") {
+            return false;
+        }
+    } else if among_var == 2 {
+        // (, line 418
+        // <-, line 418
+        if !env.slice_from("\u{00E7}") {
+            return false;
+        }
+    } else if among_var == 3 {
+        // (, line 419
+        // <-, line 419
+        if !env.slice_from("t") {
+            return false;
+        }
+    } else if among_var == 4 {
+        // (, line 420
+        // <-, line 420
+        if !env.slice_from("k") {
+            return false;
+        }
+    }
+    return true;
+}
+
+fn r_append_U_to_stems_ending_with_d_or_g(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 430
+    // test, line 431
+    let v_1 = env.limit - env.cursor;
+    // (, line 431
+    // or, line 431
+    'lab0: loop {
+        let v_2 = env.limit - env.cursor;
+        'lab1: loop {
+            // literal, line 431
+            if !env.eq_s_b(&"d") {
+                break 'lab1;
+            }
+            break 'lab0;
+        }
+        env.cursor = env.limit - v_2;
+        // literal, line 431
+        if !env.eq_s_b(&"g") {
+            return false;
+        }
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    // or, line 433
+    'lab2: loop {
+        let v_3 = env.limit - env.cursor;
+        'lab3: loop {
+            // (, line 432
+            // test, line 432
+            let v_4 = env.limit - env.cursor;
+            // (, line 432
+            // (, line 432
+            // goto, line 432
+            'golab4: loop {
+                let v_5 = env.limit - env.cursor;
+                'lab5: loop {
+                    if !env.in_grouping_b(G_vowel, 97, 305) {
+                        break 'lab5;
+                    }
+                    env.cursor = env.limit - v_5;
+                    break 'golab4;
+                }
+                env.cursor = env.limit - v_5;
+                if env.cursor <= env.limit_backward {
+                    break 'lab3;
+                }
+                env.previous_char();
+            }
+            // or, line 432
+            'lab6: loop {
+                let v_6 = env.limit - env.cursor;
+                'lab7: loop {
+                    // literal, line 432
+                    if !env.eq_s_b(&"a") {
+                        break 'lab7;
+                    }
+                    break 'lab6;
+                }
+                env.cursor = env.limit - v_6;
+                // literal, line 432
+                if !env.eq_s_b(&"\u{0131}") {
+                    break 'lab3;
+                }
+                break 'lab6;
+            }
+            env.cursor = env.limit - v_4;
+            // <+, line 432
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, "\u{0131}");
+            env.cursor = c;
+            break 'lab2;
+        }
+        env.cursor = env.limit - v_3;
+        'lab8: loop {
+            // (, line 434
+            // test, line 434
+            let v_7 = env.limit - env.cursor;
+            // (, line 434
+            // (, line 434
+            // goto, line 434
+            'golab9: loop {
+                let v_8 = env.limit - env.cursor;
+                'lab10: loop {
+                    if !env.in_grouping_b(G_vowel, 97, 305) {
+                        break 'lab10;
+                    }
+                    env.cursor = env.limit - v_8;
+                    break 'golab9;
+                }
+                env.cursor = env.limit - v_8;
+                if env.cursor <= env.limit_backward {
+                    break 'lab8;
+                }
+                env.previous_char();
+            }
+            // or, line 434
+            'lab11: loop {
+                let v_9 = env.limit - env.cursor;
+                'lab12: loop {
+                    // literal, line 434
+                    if !env.eq_s_b(&"e") {
+                        break 'lab12;
+                    }
+                    break 'lab11;
+                }
+                env.cursor = env.limit - v_9;
+                // literal, line 434
+                if !env.eq_s_b(&"i") {
+                    break 'lab8;
+                }
+                break 'lab11;
+            }
+            env.cursor = env.limit - v_7;
+            // <+, line 434
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, "i");
+            env.cursor = c;
+            break 'lab2;
+        }
+        env.cursor = env.limit - v_3;
+        'lab13: loop {
+            // (, line 436
+            // test, line 436
+            let v_10 = env.limit - env.cursor;
+            // (, line 436
+            // (, line 436
+            // goto, line 436
+            'golab14: loop {
+                let v_11 = env.limit - env.cursor;
+                'lab15: loop {
+                    if !env.in_grouping_b(G_vowel, 97, 305) {
+                        break 'lab15;
+                    }
+                    env.cursor = env.limit - v_11;
+                    break 'golab14;
+                }
+                env.cursor = env.limit - v_11;
+                if env.cursor <= env.limit_backward {
+                    break 'lab13;
+                }
+                env.previous_char();
+            }
+            // or, line 436
+            'lab16: loop {
+                let v_12 = env.limit - env.cursor;
+                'lab17: loop {
+                    // literal, line 436
+                    if !env.eq_s_b(&"o") {
+                        break 'lab17;
+                    }
+                    break 'lab16;
+                }
+                env.cursor = env.limit - v_12;
+                // literal, line 436
+                if !env.eq_s_b(&"u") {
+                    break 'lab13;
+                }
+                break 'lab16;
+            }
+            env.cursor = env.limit - v_10;
+            // <+, line 436
+            let c = env.cursor;
+            let (bra, ket) = (env.cursor, env.cursor);
+            env.insert(bra, ket, "u");
+            env.cursor = c;
+            break 'lab2;
+        }
+        env.cursor = env.limit - v_3;
+        // (, line 438
+        // test, line 438
+        let v_13 = env.limit - env.cursor;
+        // (, line 438
+        // (, line 438
+        // goto, line 438
+        'golab18: loop {
+            let v_14 = env.limit - env.cursor;
+            'lab19: loop {
+                if !env.in_grouping_b(G_vowel, 97, 305) {
+                    break 'lab19;
+                }
+                env.cursor = env.limit - v_14;
+                break 'golab18;
+            }
+            env.cursor = env.limit - v_14;
+            if env.cursor <= env.limit_backward {
+                return false;
+            }
+            env.previous_char();
+        }
+        // or, line 438
+        'lab20: loop {
+            let v_15 = env.limit - env.cursor;
+            'lab21: loop {
+                // literal, line 438
+                if !env.eq_s_b(&"\u{00F6}") {
+                    break 'lab21;
+                }
+                break 'lab20;
+            }
+            env.cursor = env.limit - v_15;
+            // literal, line 438
+            if !env.eq_s_b(&"\u{00FC}") {
+                return false;
+            }
+            break 'lab20;
+        }
+        env.cursor = env.limit - v_13;
+        // <+, line 438
+        let c = env.cursor;
+        let (bra, ket) = (env.cursor, env.cursor);
+        env.insert(bra, ket, "\u{00FC}");
+        env.cursor = c;
+        break 'lab2;
+    }
+    return true;
+}
+
+fn r_more_than_one_syllable_word(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 445
+    // test, line 446
+    let v_1 = env.cursor;
+    // (, line 446
+    // atleast, line 446
+    let mut v_2 = 2;
+    // atleast, line 446
+    'replab0: loop{
+        let v_3 = env.cursor;
+        'lab1: for _ in 0..1 {
+            // (, line 446
+            // gopast, line 446
+            'golab2: loop {
+                'lab3: loop {
+                    if !env.in_grouping(G_vowel, 97, 305) {
+                        break 'lab3;
+                    }
+                    break 'golab2;
+                }
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            v_2 -= 1;
+            continue 'replab0;
+        }
+        env.cursor = v_3;
+        break 'replab0;
+    }
+    if v_2 > 0 {
+        return false;
+    }
+    env.cursor = v_1;
+    return true;
+}
+
+fn r_is_reserved_word(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 449
+    // or, line 451
+    'lab0: loop {
+        let v_1 = env.cursor;
+        'lab1: loop {
+            // test, line 450
+            let v_2 = env.cursor;
+            // (, line 450
+            // gopast, line 450
+            'golab2: loop {
+                'lab3: loop {
+                    // literal, line 450
+                    if !env.eq_s(&"ad") {
+                        break 'lab3;
+                    }
+                    break 'golab2;
+                }
+                if env.cursor >= env.limit {
+                    break 'lab1;
+                }
+                env.next_char();
+            }
+            // (, line 450
+            context.i_strlen = 2;
+            // (, line 450
+            if !(context.i_strlen == env.limit){
+                break 'lab1;
+            }
+            env.cursor = v_2;
+            break 'lab0;
+        }
+        env.cursor = v_1;
+        // test, line 452
+        let v_4 = env.cursor;
+        // (, line 452
+        // gopast, line 452
+        'golab4: loop {
+            'lab5: loop {
+                // literal, line 452
+                if !env.eq_s(&"soyad") {
+                    break 'lab5;
+                }
+                break 'golab4;
+            }
+            if env.cursor >= env.limit {
+                return false;
+            }
+            env.next_char();
+        }
+        // (, line 452
+        context.i_strlen = 5;
+        // (, line 452
+        if !(context.i_strlen == env.limit){
+            return false;
+        }
+        env.cursor = v_4;
+        break 'lab0;
+    }
+    return true;
+}
+
+fn r_postlude(env: &mut SnowballEnv, context: &mut Context) -> bool {
+    // (, line 455
+    // not, line 456
+    let v_1 = env.cursor;
+    'lab0: loop {
+        // (, line 456
+        // call is_reserved_word, line 456
+        if !r_is_reserved_word(env, context) {
+            break 'lab0;
+        }
+        return false;
+    }
+    env.cursor = v_1;
+    // backwards, line 457
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 457
+    // do, line 458
+    let v_2 = env.limit - env.cursor;
+    'lab1: loop {
+        // call append_U_to_stems_ending_with_d_or_g, line 458
+        if !r_append_U_to_stems_ending_with_d_or_g(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = env.limit - v_2;
+    // do, line 459
+    let v_3 = env.limit - env.cursor;
+    'lab2: loop {
+        // call post_process_last_consonants, line 459
+        if !r_post_process_last_consonants(env, context) {
+            break 'lab2;
+        }
+        break 'lab2;
+    }
+    env.cursor = env.limit - v_3;
+    env.cursor = env.limit_backward;
+    return true;
+}
+
+pub fn stem(env: &mut SnowballEnv) -> bool {
+    let mut context = &mut Context {
+        b_continue_stemming_noun_suffixes: false,
+        i_strlen: 0,
+    };
+    // (, line 464
+    // (, line 465
+    // call more_than_one_syllable_word, line 465
+    if !r_more_than_one_syllable_word(env, context) {
+        return false;
+    }
+    // (, line 466
+    // backwards, line 467
+    env.limit_backward = env.cursor;
+    env.cursor = env.limit;
+    // (, line 467
+    // do, line 468
+    let v_1 = env.limit - env.cursor;
+    'lab0: loop {
+        // call stem_nominal_verb_suffixes, line 468
+        if !r_stem_nominal_verb_suffixes(env, context) {
+            break 'lab0;
+        }
+        break 'lab0;
+    }
+    env.cursor = env.limit - v_1;
+    // Boolean test continue_stemming_noun_suffixes, line 469
+    if !context.b_continue_stemming_noun_suffixes {
+        return false;
+    }
+    // do, line 470
+    let v_2 = env.limit - env.cursor;
+    'lab1: loop {
+        // call stem_noun_suffixes, line 470
+        if !r_stem_noun_suffixes(env, context) {
+            break 'lab1;
+        }
+        break 'lab1;
+    }
+    env.cursor = env.limit - v_2;
+    env.cursor = env.limit_backward;
+    // call postlude, line 473
+    if !r_postlude(env, context) {
+        return false;
+    }
+    return true;
+}
diff --git a/src/snowball/among.rs b/src/snowball/among.rs
new file mode 100644
index 0000000..57fc8ba
--- /dev/null
+++ b/src/snowball/among.rs
@@ -0,0 +1,6 @@
+use snowball::SnowballEnv;
+
+pub struct Among<T: 'static>(pub &'static str,
+                             pub i32,
+                             pub i32,
+                             pub Option<&'static (dyn Fn(&mut SnowballEnv, &mut T) -> bool + Sync)>);
diff --git a/src/snowball/mod.rs b/src/snowball/mod.rs
new file mode 100644
index 0000000..f664723
--- /dev/null
+++ b/src/snowball/mod.rs
@@ -0,0 +1,6 @@
+pub mod algorithms;
+mod among;
+mod snowball_env;
+
+pub use snowball::among::Among;
+pub use snowball::snowball_env::SnowballEnv;
diff --git a/src/snowball/snowball_env.rs b/src/snowball/snowball_env.rs
new file mode 100644
index 0000000..0535b71
--- /dev/null
+++ b/src/snowball/snowball_env.rs
@@ -0,0 +1,394 @@
+use std::borrow::Cow;
+use snowball::Among;
+
+#[derive(Debug, Clone)]
+pub struct SnowballEnv<'a> {
+    pub current: Cow<'a, str>,
+    pub cursor: usize,
+    pub limit: usize,
+    pub limit_backward: usize,
+    pub bra: usize,
+    pub ket: usize,
+}
+
+
+impl<'a> SnowballEnv<'a> {
+    pub fn create(value: &'a str) -> Self {
+        let len = value.len();
+        SnowballEnv {
+            current: Cow::from(value),
+            cursor: 0,
+            limit: len,
+            limit_backward: 0,
+            bra: 0,
+            ket: len,
+        }
+    }
+
+    pub fn get_current(self) -> Cow<'a, str> {
+        self.current
+    }
+
+    fn replace_s(&mut self, bra: usize, ket: usize, s: &str) -> i32 {
+        let adjustment = s.len() as i32 - (ket as i32 - bra as i32);
+        let mut result = String::with_capacity(self.current.len());
+        {
+            let (lhs, _) = self.current.split_at(bra);
+            let (_, rhs) = self.current.split_at(ket);
+            result.push_str(lhs);
+            result.push_str(s);
+            result.push_str(rhs);
+        }
+        // ... not very nice...
+        let new_lim = self.limit as i32 + adjustment;
+        self.limit = new_lim as usize;
+        if self.cursor >= ket {
+            let new_cur = self.cursor as i32 + adjustment;
+            self.cursor = new_cur as usize;
+        } else if self.cursor > bra {
+            self.cursor = bra
+        }
+        self.current = Cow::from(result);
+        adjustment
+    }
+
+    /// Check if s is after cursor.
+    /// If so, move cursor to the end of s
+    pub fn eq_s(&mut self, s: &str) -> bool {
+        if self.cursor >= self.limit {
+            return false;
+        }
+        if self.current[self.cursor..].starts_with(s) {
+            self.cursor += s.len();
+            while !self.current.is_char_boundary(self.cursor) {
+                self.cursor += 1;
+            }
+            true
+        } else {
+            false
+        }
+    }
+
+    /// Check if 's' is before cursor
+    /// If so, move cursor to the beginning of s
+    pub fn eq_s_b(&mut self, s: &str) -> bool {
+        if (self.cursor as i32 - self.limit_backward as i32) < s.len() as i32 {
+            false
+            // Check if cursor -s.len is a char boundry. if not well... return false obv
+        } else if !self.current.is_char_boundary(self.cursor - s.len()) ||
+                  !self.current[self.cursor - s.len()..].starts_with(s) {
+            false
+        } else {
+            self.cursor -= s.len();
+            true
+        }
+    }
+
+    /// Replace string between `bra` and `ket` with s
+    pub fn slice_from(&mut self, s: &str) -> bool {
+        let (bra, ket) = (self.bra, self.ket);
+        self.replace_s(bra, ket, s);
+        true
+    }
+
+    /// Move cursor to next charater
+    pub fn next_char(&mut self) {
+        self.cursor += 1;
+        while !self.current.is_char_boundary(self.cursor) {
+            self.cursor += 1;
+        }
+    }
+
+    /// Move cursor to previous character
+    pub fn previous_char(&mut self) {
+        self.cursor -= 1;
+        while !self.current.is_char_boundary(self.cursor) {
+            self.cursor -= 1;
+        }
+    }
+
+    pub fn byte_index_for_hop(&self, mut delta: i32) -> i32 {
+        if delta > 0 {
+            let mut res = self.cursor;
+            while delta > 0 {
+                res += 1;
+                delta -= 1;
+                while res <= self.current.len() && !self.current.is_char_boundary(res) {
+                    res += 1;
+                }
+            }
+            return res as i32;
+        } else if delta < 0 {
+            let mut res: i32 = self.cursor as i32;
+            while delta < 0 {
+                res -= 1;
+                delta += 1;
+                while res >= 0 && !self.current.is_char_boundary(res as usize) {
+                    res -= 1;
+                }
+            }
+            return res as i32;
+        } else {
+            return self.cursor as i32;
+        }
+    }
+
+    // A grouping is represented by a minimum code point, a maximum code point,
+    // and a bitfield of which code points in that range are in the grouping.
+    // For example, in english.sbl, valid_LI is 'cdeghkmnrt'.
+    // The minimum and maximum code points are 99 and 116,
+    // so every time one of these grouping functions is called for g_valid_LI,
+    // min must be 99 and max must be 116. There are 18 code points within that
+    // range (inclusive) so the grouping is represented with 18 bits, plus 6 bits of padding:
+    //
+    // cdefghij klmnopqr st
+    // 11101100 10110001 01000000
+    //
+    // The first bit is the least significant.
+    // Those three bytes become &[0b00110111, 0b10001101, 0b00000010],
+    // which is &[55, 141, 2], which is how g_valid_LI is defined in english.rs.
+    /// Check if the char the cursor points to is in the grouping
+    pub fn in_grouping(&mut self, chars: &[u8], min: u32, max: u32) -> bool {
+        if self.cursor >= self.limit {
+            return false;
+        }
+        if let Some(chr) = self.current[self.cursor..].chars().next() {
+            let mut ch = chr as u32; //codepoint as integer
+            if ch > max || ch < min {
+                return false;
+            }
+            ch -= min;
+            if (chars[(ch >> 3) as usize] & (0x1 << (ch & 0x7))) == 0 {
+                return false;
+            }
+            self.next_char();
+            return true;
+        }
+        return false;
+    }
+
+    pub fn in_grouping_b(&mut self, chars: &[u8], min: u32, max: u32) -> bool {
+        if self.cursor <= self.limit_backward {
+            return false;
+        }
+        self.previous_char();
+        if let Some(chr) = self.current[self.cursor..].chars().next() {
+            let mut ch = chr as u32; //codepoint as integer
+            self.next_char();
+            if ch > max || ch < min {
+                return false;
+            }
+            ch -= min;
+            if (chars[(ch >> 3) as usize] & (0x1 << (ch & 0x7))) == 0 {
+                return false;
+            }
+            self.previous_char();
+            return true;
+        }
+        return false;
+    }
+
+    pub fn out_grouping(&mut self, chars: &[u8], min: u32, max: u32) -> bool {
+        if self.cursor >= self.limit {
+            return false;
+        }
+        if let Some(chr) = self.current[self.cursor..].chars().next() {
+            let mut ch = chr as u32; //codepoint as integer
+            if ch > max || ch < min {
+                self.next_char();
+                return true;
+            }
+            ch -= min;
+            if (chars[(ch >> 3) as usize] & (0x1 << (ch & 0x7))) == 0 {
+                self.next_char();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    pub fn out_grouping_b(&mut self, chars: &[u8], min: u32, max: u32) -> bool {
+        if self.cursor <= self.limit_backward {
+            return false;
+        }
+        self.previous_char();
+        if let Some(chr) = self.current[self.cursor..].chars().next() {
+            let mut ch = chr as u32; //codepoint as integer
+            self.next_char();
+            if ch > max || ch < min {
+                self.previous_char();
+                return true;
+            }
+            ch -= min;
+            if (chars[(ch >> 3) as usize] & (0x1 << (ch & 0x7))) == 0 {
+                self.previous_char();
+                return true;
+            }
+        }
+        return false;
+
+    }
+
+
+    /// Helper function that removes the string slice between `bra` and `ket`
+    pub fn slice_del(&mut self) -> bool {
+        self.slice_from("")
+    }
+
+    pub fn insert(&mut self, bra: usize, ket: usize, s: &str) {
+        let adjustment = self.replace_s(bra, ket, s);
+        if bra <= self.bra {
+            self.bra = (self.bra as i32 + adjustment) as usize;
+        }
+        if bra <= self.ket {
+            self.ket = (self.ket as i32 + adjustment) as usize;
+        }
+    }
+
+    pub fn slice_to(&mut self) -> String {
+        self.current[self.bra..self.ket].to_string()
+    }
+
+    pub fn find_among<T>(&mut self, amongs: &[Among<T>], context: &mut T) -> i32 {
+        use std::cmp::min;
+        let mut i: i32 = 0;
+        let mut j: i32 = amongs.len() as i32;
+
+        let c = self.cursor;
+        let l = self.limit;
+
+        let mut common_i = 0;
+        let mut common_j = 0;
+
+        let mut first_key_inspected = false;
+        loop {
+            let k = i + ((j - i) >> 1);
+            let mut diff: i32 = 0;
+            let mut common = min(common_i, common_j);
+            let w = &amongs[k as usize];
+            for lvar in common..w.0.len() {
+                if c + common == l {
+                    diff = -1;
+                    break;
+                }
+                diff = self.current.as_bytes()[c + common] as i32 - w.0.as_bytes()[lvar] as i32;
+                if diff != 0 {
+                    break;
+                }
+                common += 1;
+            }
+            if diff < 0 {
+                j = k;
+                common_j = common;
+            } else {
+                i = k;
+                common_i = common;
+            }
+            if j - i <= 1 {
+                if i > 0 {
+                    break;
+                }
+                if j == i {
+                    break;
+                }
+                if first_key_inspected {
+                    break;
+                }
+                first_key_inspected = true;
+            }
+        }
+
+        loop {
+            let w = &amongs[i as usize];
+            if common_i >= w.0.len() {
+                self.cursor = c + w.0.len();
+                if let Some(ref method) = w.3 {
+                    let res = method(self, context);
+                    self.cursor = c + w.0.len();
+                    if res {
+                        return w.2;
+                    }
+                } else {
+                    return w.2;
+                }
+            }
+            i = w.1;
+            if i < 0 {
+                return 0;
+            }
+        }
+    }
+
+    pub fn find_among_b<T>(&mut self, amongs: &[Among<T>], context: &mut T) -> i32 {
+        let mut i: i32 = 0;
+        let mut j: i32 = amongs.len() as i32;
+
+        let c = self.cursor;
+        let lb = self.limit_backward;
+
+        let mut common_i = 0;
+        let mut common_j = 0;
+
+        let mut first_key_inspected = false;
+
+        loop {
+            let k = i + ((j - i) >> 1);
+            let mut diff: i32 = 0;
+            let mut common = if common_i < common_j {
+                common_i
+            } else {
+                common_j
+            };
+            let w = &amongs[k as usize];
+            for lvar in (0..w.0.len() - common).rev() {
+                if c - common == lb {
+                    diff = -1;
+                    break;
+                }
+                diff = self.current.as_bytes()[c - common - 1] as i32 - w.0.as_bytes()[lvar] as i32;
+                if diff != 0 {
+                    break;
+                }
+                common += 1;
+            }
+            if diff < 0 {
+                j = k;
+                common_j = common;
+            } else {
+                i = k;
+                common_i = common;
+            }
+            if j - i <= 1 {
+                if i > 0 {
+                    break;
+                }
+                if j == i {
+                    break;
+                }
+                if first_key_inspected {
+                    break;
+                }
+                first_key_inspected = true;
+            }
+        }
+        loop {
+            let w = &amongs[i as usize];
+            if common_i >= w.0.len() {
+                self.cursor = c - w.0.len();
+                if let Some(ref method) = w.3 {
+                    let res = method(self, context);
+                    self.cursor = c - w.0.len();
+                    if res {
+                        return w.2;
+                    }
+                } else {
+                    return w.2;
+                }
+            }
+            i = w.1;
+            if i < 0 {
+                return 0;
+            }
+        }
+    }
+}