/.*かった(ら|り)?/ { /* remove plain past, conditional, and alternative */
	switch ($tail) {
		case "":
			$state->add(V_PAST); break;
		case "ら":
			$state->add(V_PLAIN, V_CONDITIONAL); break;
		case "り":
			$state->add(V_PLAIN, V_ALTERNATIVE); break;
			}
	return head($word, 3 + strlen($tail)) . "い";
	}
--
/.*(たい|たくない)/ { /* desiderative */
	switch ($tail) {
		case "たい":
			$state->add(V_DESIDERATIVE); break;
		case "たくない":
			$state->add(V_DESIDERATIVE, V_NEGATIVE); break;
			}
	return make_plain(head($word, strlen($tail)));
	}
--
/.*(ましょう|まい)/ { /* easily detectable voltional forms - wait, the masu in neg-polite-volitional doesnt matter */
	switch ($tail) {
		case "ましょう":
			$state->add(V_VOLITIONAL, V_POLITE); break;
		case "まい":
			$state->add(V_NEGATIVE, V_VOLITIONAL); break;
			}
	return make_plain(head($word, strlen($tail)));
	}
--
/.*(だろう|でしょう)/ { /* conjectural */
	$state->add(V_CONJECTURAL);
	switch ($tail) {
		case "だろう":
			$state->add(V_PLAIN); break;
		case "でしょう":
			$state->add(V_POLITE); break; 
			}
	/* negative */
	$head = head($word, strlen($tail));
	if (transform($head, i) == $head) return head($word, strlen($tail));
	/* not */
	return make_plain(head($word, strlen($tail)));
	}
--
/.*う/ { /* plain volitional - blocking on だろう/でしょう */
	if (transform(head($word), o) == head($word) or tail($word, 2) == "よう" and tail($word, 3) != "だろう") { 
		$state->add(V_VOLITIONAL);
		if (tail(head($word)) == "よ") return make_plain(head($word, 2));
		return transform(head($word), u); }
	$_unchanged = true; 
	return $word;
	}
--
/.*(ならば|なら|ければ)/ { /* provisional - this seemed like a good place to put it - ARGHHH */
	$state->add(V_PROVISIONAL);
	switch ($tail) {
		case "なら":
		case "ならば":
			return head($word, strlen($tail));
		case "ければ":
			$state->add(V_PLAIN);
			return head($word, strlen($tail)) . "い";
		}
	}
--
/.*でした(り|ら)/ { /* special negative polite alternative and conditional */
	/* We have to hard code this in to avoid it being tagged as non-past */
	switch ($tail) {
		case "り":
			$state->add(V_ALTERNATIVE); break;
		case "ら":
			$state->add(V_CONDITIONAL); break;
			}
	$state->add(V_POLITE, V_NEGATIVE);
	return make_plain(head($word, 7));
	}
--
/.*(て|で|たら|だら|たり|だり|た|だ)/ { /* te-forms */

	function try_unconj ($word, $stem_array) {
		foreach ($stem_array as $stem) {
			if (in_edict($word . $stem)) return $word . $stem;
			}
		die ($word . " (stem): could not deconjugate");
		}
	
	switch ($tail) {
		case "て": case "で":
			$state->add(V_TE_FORM);	break;
		case "たら": case "だら":
			$state->add(V_CONDITIONAL); break;
		case "たり": case "だり":
			$state->add(V_ALTERNATIVE); break;
		case "た": case "だ":
			$state->add(V_PAST); break;
		}
		
	/* Easy te-forms */
	if (tail(head($word, strlen($tail)), 2) == "まし") return make_plain(head($word, strlen($tail))); /* polite */
	elseif (tail(head($word, strlen($tail)), 3) == "ません") return head($word, strlen($tail)); /* polite negative */
	elseif (tail(head($word, strlen($tail)), 2) == "ない") {
		$state->add(V_PLAIN);
		return head($word, strlen($tail)); /* plain negative (2) */
		}
	elseif (tail(head($word, strlen($tail)), 2) == "なく") {
		$state->add(V_PLAIN);
		return head($word, strlen($tail) + 1) . "い"; /* plain negative (1) */
		}
		
	$word = head($word, strlen($tail));
	$conj = tail($word);
	$cut = head($word);
	switch ($conj) {
		case "っ":
			$stem_array = array("う", "つ", "る");
			return try_unconj ($cut, $stem_array);
		case "ん": 
			$stem_array = array("む", "ぬ", "ぶ");
			return try_unconj ($cut, $stem_array);
		case "い":
			$stem_array = array("く", "ぐ");
			return try_unconj ($cut, $stem_array);
		default:
			echo "hi";
			echo $word;
			return make_plain($word);
			}
	}
--
/.*(ます|ませんでした|ません|ました|なさい|なさるな)/ { /* formal and stem forms, have to put ませんでした first because of regex laziness */
	/* These have to come after the て-entry because it was shadowing ましたら */
	switch ($tail) {
		case "ます":
			$state->add(V_POLITE); break;
		case "ません":
			$state->add(V_POLITE, V_NEGATIVE); break;
		case "ました":
			$state->add(V_PAST, V_POLITE); break;
		case "ませんでした":
			$state->add(V_PAST, V_POLITE, V_NEGATIVE); break;
		case "なさい":
			$state->add(V_IMPERATIVE, V_POLITE); break;
		case "なさるな":
			$state->add(V_IMPERATIVE, V_POLITE, V_NEGATIVE); break;
		}
	return make_plain(head($word, strlen($tail)));
	}
--
/.*(ない|ず|ぬ)/ { /* negatives - gotta put this here because its blocking - moved, blocking on なさい */
	$state->add(V_NEGATIVE);
	$word = head($word, strlen($tail));
	return make_plain($word);
	}
--
/.*な/ { /* negative plain imperative */
	$state->add(V_PLAIN, V_NEGATIVE, V_IMPERATIVE);
	return head($word, 1);
	}
--
/.*る$/ { /* general verb handler */
	/* maybe its already good? */
	if (in_edict($word)) {
		/* we are unnecessarily adding plain to all verbs that go all the way */
		if (!in_array(V_POLITE, $state->state) and !in_array(V_PLAIN, $state->state)) $state->add(V_PLAIN); /* dont quite know if thats necessary. */
		return $word;
		}
	/* type-2 and normal verbs - causpass (normal) */
	/* We have to move this up to the front to match before ir-rare */
	if (tail(head($word), 4) == "させられ") {	/* type-2 */
		$state->add(V_CAUSPASS); 
		return make_plain(head($word, 5)); 
		}
	elseif (tail(head($word), 3) == "せられ") { /* normal */
		$state->add(V_CAUSPASS);
		return transform(head($word, 4), u);
		}

	
	/* handle type-2 verbs first */
	$last_two = tail(head($word), 2);
	switch ($last_two) {
		case "られ":
			$state->add(V_POTENTIAL_PASSIVE);
			return make_plain(head($word, 3));
		case "させ":
			$state->add(V_CAUSATIVE);
			return make_plain(head($word, 3));
		}
	
	
	
	/* normal verbs - passive and causative */
	$tail = tail($last_two);
	switch ($tail) {
		case "れ":
			$state->add(V_PASSIVE);
			return transform(head($word, 2), u);
		case "せ":
			$state->add(V_CAUSATIVE);
			return transform(head($word, 2), u);
		}
	
	/* normal verbs - causpass (informal style) */
	if (tail(head($word), 2) == "され") {
		$state->add(V_CAUSPASS);
		return transform(head($word, 2), u);
		}
	
	/* normal verbs - potential */
	/* if it works, just go for it */
	$reduced = transform(head($word), u);
	
	if (in_edict($reduced)) {
		$state->add(V_POTENTIAL);
		return $reduced;
		}
	}
--
/.*ろ/ { /* imperative type-2 */
	$r = make_plain(head($word));
	if (in_edict($r)) {$state->add(V_IMPERATIVE); return $r; }
	$_unchanged = true;
	return $word;
	}
--
/.*ば/ { /* provisional part 2 */
	$state->add(V_PROVISIONAL, V_PLAIN);
	return transform(head($word), u);
	}
--
/.*(.)/ { /* for imperative only OR good as is */
	if (in_edict($word)) {
		/* we are unnecessarily adding plain to all verbs that go all the way */
		if (!in_array(V_POLITE, $state->state) and !in_array(V_PLAIN, $state->state)) $state->add(V_PLAIN); /* dont quite know if thats necessary. */
		$_unchanged = true;
		return $word;
		}
	elseif (transform($tail, e) != $tail) { $_unchanged = true; return $word; }; /* Everyone else */
	$state->add(V_IMPERATIVE);
	return transform($word, u);
	}