summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrej Shadura <andrewsh@debian.org>2018-12-26 20:22:35 +0100
committerAndrej Shadura <andrewsh@debian.org>2018-12-26 20:22:35 +0100
commit0abd94bb0cc3d7cc07da074acccffcfbc27b0352 (patch)
tree86dba5c6a4bc4f99bcfa731ee71f2bbd7fb7470c
parent781e1fe64337af4712341611a88654670c43a67d (diff)
Import Upstream version 1.5.0
-rw-r--r--.classpath21
-rw-r--r--.gitignore3
-rw-r--r--ACKNOWLEDGMENT6
-rw-r--r--CHANGES90
-rw-r--r--LICENSE2
-rw-r--r--README11
-rw-r--r--TODO16
-rw-r--r--build.xml331
-rw-r--r--doc/api/allclasses-frame.html48
-rw-r--r--doc/api/allclasses-noframe.html48
-rw-r--r--doc/api/constant-values.html212
-rw-r--r--doc/api/deprecated-list.html4
-rw-r--r--doc/api/help-doc.html4
-rw-r--r--doc/api/index-all.html938
-rw-r--r--doc/api/index.html2
-rw-r--r--doc/api/morfologik/fsa/CFSA.html871
-rw-r--r--doc/api/morfologik/fsa/CFSA2.html (renamed from doc/api/morfologik/fsa/FSAVer5Impl.html)473
-rw-r--r--doc/api/morfologik/fsa/CFSA2Serializer.html414
-rw-r--r--doc/api/morfologik/fsa/ConstantArcSizeFSA.html654
-rw-r--r--doc/api/morfologik/fsa/FSA.html668
-rw-r--r--doc/api/morfologik/fsa/FSA5.html887
-rw-r--r--doc/api/morfologik/fsa/FSA5Serializer.html468
-rw-r--r--doc/api/morfologik/fsa/FSABuilder.InfoEntry.html431
-rw-r--r--doc/api/morfologik/fsa/FSABuilder.html450
-rw-r--r--doc/api/morfologik/fsa/FSAFinalStatesIterator.html65
-rw-r--r--doc/api/morfologik/fsa/FSAFlags.html87
-rw-r--r--doc/api/morfologik/fsa/FSAInfo.html399
-rw-r--r--doc/api/morfologik/fsa/FSASerializer.html335
-rw-r--r--doc/api/morfologik/fsa/FSATraversal.html394
-rw-r--r--doc/api/morfologik/fsa/FSATraversalHelper.html358
-rw-r--r--doc/api/morfologik/fsa/FSAUtils.IntIntHolder.html (renamed from doc/api/morfologik/fsa/FSAMatch.html)165
-rw-r--r--doc/api/morfologik/fsa/FSAUtils.html379
-rw-r--r--doc/api/morfologik/fsa/MatchResult.html397
-rw-r--r--doc/api/morfologik/fsa/StateVisitor.html211
-rw-r--r--doc/api/morfologik/fsa/package-frame.html45
-rw-r--r--doc/api/morfologik/fsa/package-summary.html95
-rw-r--r--doc/api/morfologik/fsa/package-tree.html19
-rw-r--r--doc/api/morfologik/stemming/Dictionary.html4
-rw-r--r--doc/api/morfologik/stemming/DictionaryIterator.html7
-rw-r--r--doc/api/morfologik/stemming/DictionaryLookup.html15
-rw-r--r--doc/api/morfologik/stemming/DictionaryMetadata.html4
-rw-r--r--doc/api/morfologik/stemming/IStemmer.html4
-rw-r--r--doc/api/morfologik/stemming/PolishStemmer.html4
-rw-r--r--doc/api/morfologik/stemming/WordData.html20
-rw-r--r--doc/api/morfologik/stemming/package-frame.html4
-rw-r--r--doc/api/morfologik/stemming/package-summary.html4
-rw-r--r--doc/api/morfologik/stemming/package-tree.html4
-rw-r--r--doc/api/morfologik/tools/FSABuildTool.Format.html (renamed from doc/api/morfologik/fsa/FSAMatchType.html)165
-rw-r--r--doc/api/morfologik/tools/FSABuildTool.html522
-rw-r--r--doc/api/morfologik/tools/FSADumpTool.html (renamed from doc/api/morfologik/tools/DumpTool.html)75
-rw-r--r--doc/api/morfologik/tools/IMessageLogger.html (renamed from doc/api/morfologik/fsa/FSAHelpers.html)114
-rw-r--r--doc/api/morfologik/tools/InflectionFramesTool.html8
-rw-r--r--doc/api/morfologik/tools/Launcher.html8
-rw-r--r--doc/api/morfologik/tools/MorphEncoder.html584
-rw-r--r--doc/api/morfologik/tools/WriterMessageLogger.html (renamed from doc/api/morfologik/util/PerformanceTimer.html)128
-rw-r--r--doc/api/morfologik/tools/package-frame.html36
-rw-r--r--doc/api/morfologik/tools/package-summary.html47
-rw-r--r--doc/api/morfologik/tools/package-tree.html22
-rw-r--r--doc/api/morfologik/util/Arrays.html139
-rw-r--r--doc/api/morfologik/util/BufferUtils.html25
-rw-r--r--doc/api/morfologik/util/FileUtils.html181
-rw-r--r--doc/api/morfologik/util/ResourceUtils.html10
-rw-r--r--doc/api/morfologik/util/package-frame.html6
-rw-r--r--doc/api/morfologik/util/package-summary.html8
-rw-r--r--doc/api/morfologik/util/package-tree.html6
-rw-r--r--doc/api/overview-frame.html4
-rw-r--r--doc/api/overview-summary.html4
-rw-r--r--doc/api/overview-tree.html21
-rw-r--r--lib/commons-cli-1.2.LICENSE202
-rw-r--r--lib/commons-cli-1.2.jarbin0 -> 41123 bytes
-rw-r--r--lib/hppc-0.3.2.jarbin0 -> 981375 bytes
-rw-r--r--lib/hppc.LICENSE202
-rw-r--r--lib/junit-4.7.jarbin0 -> 232354 bytes
-rw-r--r--lib/junit-benchmarks-0.1.0.jarbin0 -> 54998 bytes
-rw-r--r--lib/junit-benchmarks.LICENSE202
-rw-r--r--lib/junit.LICENSE88
-rw-r--r--lib/thirdparty.LICENSE5
-rw-r--r--src-test/morfologik/fsa/CFSA2SerializerTest.java27
-rw-r--r--src-test/morfologik/fsa/FSA5SerializerTest.java10
-rw-r--r--src-test/morfologik/fsa/FSA5Test.java117
-rw-r--r--src-test/morfologik/fsa/FSABuilderTest.java112
-rw-r--r--src-test/morfologik/fsa/FSATestUtils.java179
-rw-r--r--src-test/morfologik/fsa/FSATraversalTest.java160
-rw-r--r--src-test/morfologik/fsa/SerializerTestBase.java256
-rw-r--r--src-test/morfologik/fsa/abc-numbers.fsabin0 -> 29 bytes
-rw-r--r--src-test/morfologik/fsa/abc.fsabin0 -> 24 bytes
-rw-r--r--src-test/morfologik/fsa/abc.in6
-rw-r--r--src-test/morfologik/fsa/en_tst.dictbin0 -> 1070678 bytes
-rw-r--r--src-test/morfologik/fsa/minimal.fsabin0 -> 24 bytes
-rw-r--r--src-test/morfologik/fsa/minimal.in3
-rw-r--r--src-test/morfologik/fsa/minimal2.fsabin0 -> 194 bytes
-rw-r--r--src-test/morfologik/fsa/minimal2.in24
-rw-r--r--src-test/morfologik/stemming/DictionaryLookupTest.java250
-rw-r--r--src-test/morfologik/stemming/PerformanceTest.java73
-rw-r--r--src-test/morfologik/stemming/PolishStemmerTest.java54
-rw-r--r--src-test/morfologik/stemming/StringDecoderBenchmarkTest.java62
-rw-r--r--src-test/morfologik/stemming/test-diacritics-utf8.dictbin0 -> 136 bytes
-rw-r--r--src-test/morfologik/stemming/test-diacritics-utf8.info10
-rw-r--r--src-test/morfologik/stemming/test-infix.dictbin0 -> 1859 bytes
-rw-r--r--src-test/morfologik/stemming/test-infix.info9
-rw-r--r--src-test/morfologik/stemming/test-prefix.dictbin0 -> 1776 bytes
-rw-r--r--src-test/morfologik/stemming/test-prefix.info9
-rw-r--r--src-test/morfologik/stemming/test-separators.dictbin0 -> 155 bytes
-rw-r--r--src-test/morfologik/stemming/test-separators.info9
-rw-r--r--src-test/morfologik/stemming/test-separators.txt8
-rw-r--r--src-test/morfologik/stemming/test-synth.dictbin0 -> 1354192 bytes
-rw-r--r--src-test/morfologik/stemming/test-synth.info6
-rw-r--r--src-test/morfologik/tools/LauncherTest.java26
-rw-r--r--src-test/morfologik/tools/MorphEncoderTest.java125
-rw-r--r--src-test/morfologik/tools/MorphEncodingToolTest.java110
-rw-r--r--src-test/morfologik/tools/Text2FSA5Test.java37
-rw-r--r--src-test/morfologik/util/MinMax.java21
-rw-r--r--src/morfologik/dictionaries/pl.LICENSE8
-rw-r--r--src/morfologik/dictionaries/pl.dictbin0 -> 1806661 bytes
-rw-r--r--src/morfologik/dictionaries/pl.info13
-rw-r--r--src/morfologik/fsa/CFSA.java364
-rw-r--r--src/morfologik/fsa/CFSA2.java404
-rw-r--r--src/morfologik/fsa/CFSA2Serializer.java536
-rw-r--r--src/morfologik/fsa/ConstantArcSizeFSA.java134
-rw-r--r--src/morfologik/fsa/FSA.java467
-rw-r--r--src/morfologik/fsa/FSA5.java323
-rw-r--r--src/morfologik/fsa/FSA5Serializer.java334
-rw-r--r--src/morfologik/fsa/FSABuilder.java486
-rw-r--r--src/morfologik/fsa/FSAFinalStatesIterator.java174
-rw-r--r--src/morfologik/fsa/FSAFlags.java81
-rw-r--r--src/morfologik/fsa/FSAHeader.java52
-rw-r--r--src/morfologik/fsa/FSAHelpers.java110
-rw-r--r--src/morfologik/fsa/FSAInfo.java157
-rw-r--r--src/morfologik/fsa/FSAMatch.java76
-rw-r--r--src/morfologik/fsa/FSAMatchType.java43
-rw-r--r--src/morfologik/fsa/FSASerializer.java45
-rw-r--r--src/morfologik/fsa/FSATraversal.java169
-rw-r--r--src/morfologik/fsa/FSATraversalHelper.java136
-rw-r--r--src/morfologik/fsa/FSAUtils.java202
-rw-r--r--src/morfologik/fsa/FSAVer5Impl.java272
-rw-r--r--src/morfologik/fsa/MatchResult.java86
-rw-r--r--src/morfologik/fsa/NullMessageLogger.java24
-rw-r--r--src/morfologik/fsa/StateVisitor.java11
-rw-r--r--src/morfologik/stemming/ArrayViewList.java132
-rw-r--r--src/morfologik/stemming/Dictionary.java279
-rw-r--r--src/morfologik/stemming/DictionaryIterator.java236
-rw-r--r--src/morfologik/stemming/DictionaryLookup.java617
-rw-r--r--src/morfologik/stemming/DictionaryMetadata.java212
-rw-r--r--src/morfologik/stemming/IStemmer.java22
-rw-r--r--src/morfologik/stemming/PolishStemmer.java51
-rw-r--r--src/morfologik/stemming/WordData.java402
-rw-r--r--src/morfologik/tools/DumpTool.java241
-rw-r--r--src/morfologik/tools/FSABuildTool.java486
-rw-r--r--src/morfologik/tools/FSADumpTool.java286
-rw-r--r--src/morfologik/tools/IMessageLogger.java25
-rw-r--r--src/morfologik/tools/InflectionFramesTool.java191
-rw-r--r--src/morfologik/tools/Launcher.java190
-rw-r--r--src/morfologik/tools/MorphEncoder.java399
-rw-r--r--src/morfologik/tools/MorphEncodingTool.java213
-rw-r--r--src/morfologik/tools/PolishStemmingTool.java287
-rw-r--r--src/morfologik/tools/SharedOptions.java203
-rw-r--r--src/morfologik/tools/Tool.java122
-rw-r--r--src/morfologik/tools/WriterMessageLogger.java123
-rw-r--r--src/morfologik/util/Arrays.java81
-rw-r--r--src/morfologik/util/BufferUtils.java73
-rw-r--r--src/morfologik/util/FileUtils.java149
-rw-r--r--src/morfologik/util/PerformanceTimer.java77
-rw-r--r--src/morfologik/util/ResourceUtils.java83
163 files changed, 19759 insertions, 4714 deletions
diff --git a/.classpath b/.classpath
index 38c404c..df7d164 100644
--- a/.classpath
+++ b/.classpath
@@ -1,10 +1,11 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry kind="src" path="src-test"/>
- <classpathentry kind="lib" path="lib/commons-cli-1.2.jar"/>
- <classpathentry kind="lib" path="lib/junit-4.3.1.jar"/>
- <classpathentry kind="lib" path="lib/junitext-0.2.4.jar"/>
- <classpathentry kind="output" path="tmp/eclipse"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="src" path="src-test"/>
+ <classpathentry kind="lib" path="lib/commons-cli-1.2.jar"/>
+ <classpathentry kind="lib" path="lib/junit-benchmarks-0.1.0.jar"/>
+ <classpathentry kind="lib" path="lib/junit-4.7.jar"/>
+ <classpathentry kind="lib" path="lib/hppc-0.3.2.jar"/>
+ <classpathentry kind="output" path="tmp/eclipse"/>
+</classpath>
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fa137ce
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+tmp/
+dist/
+*.patch \ No newline at end of file
diff --git a/ACKNOWLEDGMENT b/ACKNOWLEDGMENT
index eab1c39..c68b089 100644
--- a/ACKNOWLEDGMENT
+++ b/ACKNOWLEDGMENT
@@ -1,2 +1,6 @@
Polish stemming data comes from Polish ispell/myspell dictionary hosted at
-http://sjp.pl/ and licensed under LGPL. \ No newline at end of file
+http://sjp.pl/. It was corrected and enriched with part-of-speech tags in
+Morfologik project. The resulting data set is licensed on the terms
+of LGPL and/or Creative Commons ShareAlike (pick the suitable license).
+
+See http://morfologik.blogspot.com \ No newline at end of file
diff --git a/CHANGES b/CHANGES
index bbd5588..65243fe 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,90 @@
+1.5.0
+ Major size saving improvements in CFSA2. Built in Polish dictionary size decreased from
+ 2,811,345 to 1,806,661 (CFSA2 format).
+
+ FSABuilder returns a ready-to-be-used FSA (ConstantArcSizeFSA). Construction overhead
+ for this automaton is a round zero (it is immediately serialized in-memory).
+
+ Polish dictionary updated to Morfologik 1.7. [19.11.2010]
+
+ Added an option to serialize automaton to CFSA2 or FSA5 directly from fsa_build.
+
+ CFSA is now deprecated for serialization (the code still reads CFSA automata, but will
+ no be able to serialize them). Use CFSA2.
+
+ Added immediate state interning.
+ Speedup in automaton construction by about 30%, memory use
+ decreased significantly (did not perform exact measurements, but incremental
+ construction from presorted data should consume way less memory).
+
+ Added an option to build FSA from already sorted data (--sorted). Avoids in-memory sorting.
+ Pipe the input through shell sort if building FSA from large data.
+
+ Changed the default ordering from Java signed-byte to C-like unsigned byte value.
+ This lets one use GNU sort to sort the input using 'export LC_ALL=C; sort input'.
+
+ Added traversal routines to calculate perfect hashing based on FSA with NUMBERS.
+
+ Changed the order of serialized arcs in the binary serializer for FSA5 to lexicographic
+ (consistent with the input). Depth-first traversal recreates the input, in other words.
+
+ Removed character-based automata.
+
+ Incompatible API changes to FSA builders (moved to morfologik.fsa).
+
+ Incompatible API changes to FSATraversalHelper. Cleaned up match types, added
+ unit tests.
+
+ ################################################################
+ - Incompatible API changes have been made in release 1.5.0. See above.
+ - An external dependency HPPC (high performance primitive collections) is now required
+ for compiling FSAs (it is optional for traversals).
+ ################################################################
+
+1.4.1
+ Upgrade of the built-in Morfologik dictionary for Polish (in CFSA format).
+
+ Added options to define custom FILLER and ANNOT_SEPARATOR bytes in the fsa_build
+ tool.
+
+ Corrected an inconsistency with the C fsa package -- FILLER and ANNOT_SEPARATOR
+ characters are now identical with the C version.
+
+ Cleanups to the tools' launcher -- will complain about missing JARs, if any.
+
+1.4.0
+ Added FSA5 construction in Java (on byte sequences). Added preliminary support for
+ character sequences. Added a command line tool for FSA5
+ construction from unsorted data (sorting is done in-memory).
+
+ Added a tool to encode tab-delimited dictionaries to the format accepted by
+ fsa_build and FSA5 construction tool.
+
+ Added a new version of Morfologik dictionary for Polish (in CFSA format).
+
+1.3.0
+ Added runtime checking for tools availability so that unavailable
+ tools don't show up in the list.
+
+ Recompressed the built-in Polish dictionary to CFSA.
+
+ Cleaned up FSA/Dictionary separation. FSAs don't store encoding any more (because
+ it does not make sense for them to do so). The FSA is a purely abstract class
+ pushing functionality to sub-classes. Input stream reading cleaned up.
+
+ Added initial code for CFSA (compressed FSA). Reduces automata size about 10%.
+
+ Changes in the public API. Implementation classes renamed
+ (FSAVer5Impl into FSA5). Major tweaks and tunes to the API.
+
+ Added support for version 5 automata built with NUMBERS flag (an extra field
+ stored for each node).
+
+ ################################################################
+ Incompatible API changes have been made in release 1.3.0.
+ ################################################################
+
1.2.2 License switch to plain BSD (removed the patent clause which did not make much sense
anyway).
@@ -25,8 +111,8 @@
Tools updated. Dumping existing FSAs is much, much faster now.
################################################################
- WARNING: Incompatible API changes have been made in release 1.2.
- WARNING: Java 1.5 or later is required from this version on.
+ Incompatible API changes have been made in release 1.2.
+ Java 1.5 or later is required from this version on.
################################################################
1.1.4 * Fixed a bug that caused UTF-8 dictionaries to be garbled. Now it should be relatively
diff --git a/LICENSE b/LICENSE
index 2891db8..9074aac 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
Copyright (c) 2006 Dawid Weiss
-Copyright (c) 2007-2009 Dawid Weiss, Marcin Miłkowski
+Copyright (c) 2007-2011 Dawid Weiss, Marcin Miłkowski
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
diff --git a/README b/README
index 505d0f2..4ce3038 100644
--- a/README
+++ b/README
@@ -5,8 +5,12 @@ CONTENTS
This project provides:
- Finite state automaton traversal routines for Jan Daciuk's FSA package.
+
+ - Creation of byte-based, efficient finite state automata in Java, including
+ custom, efficient data storage formats (not compatible with Daciuk's FSA package).
- - A stemming engine for the Polish language built on top of FSA traversal.
+ - A stemming engine for the Polish language built on top of a large dictionary
+ of inflected forms, stems and grammatical annotations.
There are a few command-line tools you may find useful. Type:
@@ -18,8 +22,9 @@ for an up-to-date list of all tools.
AUTHORS
=======
-Marcin Miłkowski (http://marcinmilkowski.pl)
-Dawid Weiss (http://www.dawidweiss.com)
+Marcin Miłkowski (http://marcinmilkowski.pl) [linguistic data lead]
+Dawid Weiss (http://www.dawidweiss.com) [fsa lead]
+Grzegorz SÅ‚owikowski [maven bundles maintenance]
QUESTIONS, COMMENTS
diff --git a/TODO b/TODO
index 20f3ef3..eed30fd 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,19 @@
-PLANS FOR VERSION 1.3
+BUGS?
+
+
+NEXT MAJOR VERSION
+
+- New binary automaton format;
+ - allow direct arc lookup on highly fanning nodes, especially root nodes
+ - allow direct perf. hashing number on arcs of highly fanning nodes, especially root nodes
+ - variable coding for state numbers
+ - state flags to encode single-arc-final tails in a compact form (no arcs at all?).
+
+
+NOT EVEN SCHEDULED
+
+- Add arc reuse (optimisation).
- Add a set of utility classes for parsing morphological tags. This could be similar
(or even compatible?) with Morfeusz-Java.
diff --git a/build.xml b/build.xml
index 8353ba5..5961525 100644
--- a/build.xml
+++ b/build.xml
@@ -1,187 +1,196 @@
-<project name="Stempelator" default="build">
- <property name="build.name" value="morfologik-stemming" />
- <property name="build.ver" value="1.2.2" />
+<project name="morfologik-stemming" default="build">
+ <property name="build.name" value="morfologik-stemming" />
+ <property name="build.ver" value="1.5.0" />
+
+ <property name="tmp.dir" value="tmp" />
+ <property name="build.dir" value="${tmp.dir}/build" />
+ <property name="build.test.dir" value="${tmp.dir}/test" />
+ <property name="dist.dir" value="dist" />
+
+ <property name="jarfile-nodict" value="${tmp.dir}/bin/${build.name}-nodict-${build.ver}.jar" />
+ <property name="jarfile" value="${tmp.dir}/bin/${build.name}-${build.ver}.jar" />
+
+ <property name="srczip" value="${dist.dir}/${build.name}-${build.ver}-src.zip" />
+ <property name="binzip" value="${dist.dir}/${build.name}-${build.ver}.zip" />
+
+ <presetdef name="javac">
+ <javac deprecation="false" debug="true" target="1.6" source="1.6"
+ encoding="UTF-8" includeantruntime="false" />
+ </presetdef>
+
+ <path id="compile.classpath">
+ <fileset dir="lib">
+ <include name="**/*.jar" />
+ </fileset>
+ </path>
+
+ <fileset dir="lib" id="runtime.dependencies">
+ <include name="**/*.jar" />
+ <exclude name="junit*.jar" />
+ </fileset>
+
+
+ <target name="init">
+ <tstamp />
+ <mkdir dir="${build.dir}" />
+ <mkdir dir="${build.test.dir}" />
+ </target>
+
- <property name="tmp.dir" value="tmp" />
- <property name="build.dir" value="${tmp.dir}/build" />
- <property name="build.test.dir" value="${tmp.dir}/test" />
- <property name="dist.dir" value="dist" />
- <property name="jarfile-nodict" value="${tmp.dir}/bin/${build.name}-nodict-${build.ver}.jar" />
- <property name="jarfile" value="${tmp.dir}/bin/${build.name}-${build.ver}.jar" />
+ <target name="clean">
+ <delete dir="${build.dir}" failonerror="false" />
+ <delete dir="${dist.dir}" failonerror="false" />
+ <delete dir="target" failonerror="false" />
+ <delete dir="${tmp.dir}" failonerror="false">
+ <exclude name="eclipse/**" />
+ </delete>
+ </target>
+
- <property name="srczip" value="${dist.dir}/${build.name}-${build.ver}-src.zip" />
- <property name="binzip" value="${dist.dir}/${build.name}-${build.ver}.zip" />
+ <target name="compile" depends="init">
+ <javac classpath="${classpath}" destdir="${build.dir}">
+ <classpath refid="compile.classpath" />
+ <include name="**/*.java" />
+ <src location="src" />
+ </javac>
- <path id="compile.classpath">
- <fileset dir="lib">
- <include name="**/*.jar" />
- </fileset>
- </path>
+ <!-- Copy additional resources to the build folder. -->
+ <copy todir="${build.dir}">
+ <fileset dir="src">
+ <exclude name="**/*.java" />
+ </fileset>
+ </copy>
+ </target>
- <fileset dir="lib" id="runtime.dependencies">
- <include name="**/*.jar" />
- <exclude name="junit*.jar" />
- </fileset>
- <target name="init">
- <tstamp />
- <mkdir dir="${build.dir}" />
- <mkdir dir="${build.test.dir}" />
- <mkdir dir="${dist.dir}" />
- </target>
+ <target name="compile.test" depends="init,compile">
+ <javac classpath="${classpath}" destdir="${build.test.dir}">
+ <classpath refid="compile.classpath" />
+ <classpath location="${build.dir}" />
+ <src location="src-test" />
+ </javac>
+ <!-- Copy additional resources to the build folder. -->
+ <copy todir="${build.test.dir}">
+ <fileset dir="src-test">
+ <exclude name="**/*.java" />
+ </fileset>
+ </copy>
+ </target>
- <target name="clean">
- <delete dir="${build.dir}" failonerror="false" />
- <delete dir="${dist.dir}" failonerror="false" />
- <delete dir="${tmp.dir}" failonerror="false">
- <exclude name="eclipse/**" />
- </delete>
- </target>
+ <target name="test" depends="compile, compile.test">
+ <mkdir dir="${tmp.dir}/tests" />
+ <junit printsummary="yes" haltonfailure="yes" maxmemory="256m" forkmode="once" fork="true">
+ <classpath refid="compile.classpath" />
+ <classpath location="${build.dir}" />
+ <classpath location="${build.test.dir}" />
- <target name="compile" depends="init">
- <javac classpath="${classpath}" destdir="${build.dir}" encoding="UTF-8"
- source="1.5" target="1.5">
- <classpath refid="compile.classpath" />
- <include name="**/*.java" />
- <src location="src" />
- </javac>
-
- <!-- Copy additional resources to the build folder. -->
- <copy todir="${build.dir}">
- <fileset dir="src">
- <exclude name="**/*.java" />
- </fileset>
- </copy>
- </target>
-
-
-
- <target name="compile.test" depends="init,compile">
- <javac classpath="${classpath}" destdir="${build.test.dir}" encoding="UTF-8">
- <classpath refid="compile.classpath" />
- <classpath location="${build.dir}" />
-
- <src location="src-test" />
- </javac>
-
- <!-- Copy additional resources to the build folder. -->
- <copy todir="${build.test.dir}">
- <fileset dir="src-test">
- <exclude name="**/*.java" />
- </fileset>
- </copy>
- </target>
-
-
-
- <target name="test" depends="compile, compile.test">
- <mkdir dir="${tmp.dir}/tests" />
- <junit printsummary="yes" haltonfailure="yes">
- <classpath refid="compile.classpath" />
- <classpath location="${build.dir}" />
- <classpath location="${build.test.dir}" />
-
- <formatter type="plain" />
-
- <batchtest todir="${tmp.dir}/tests">
- <fileset dir="src-test">
- <include name="**/*Test.java" />
- </fileset>
- </batchtest>
- </junit>
- </target>
-
+ <jvmarg value="-ea" />
+ <formatter type="plain" />
- <target name="javadoc" depends="init">
- <javadoc sourcepath="src" packagenames="morfologik.*" destdir="${tmp.dir}/javadoc">
- <classpath refid="compile.classpath" />
- </javadoc>
- </target>
+ <batchtest todir="${tmp.dir}/tests">
+ <fileset dir="src-test">
+ <include name="**/*Test.java" />
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
- <target name="jar" depends="clean, compile">
- <mkdir dir="${tmp.dir}/bin" />
-
- <property name="main.class" value="morfologik.tools.Launcher" />
-
- <pathconvert property="manifest.classpath" pathsep=" ">
- <flattenmapper />
- <path>
- <fileset refid="runtime.dependencies" />
- </path>
- </pathconvert>
+ <target name="javadoc" depends="init">
+ <javadoc sourcepath="src" packagenames="morfologik.*" destdir="${tmp.dir}/javadoc">
+ <classpath refid="compile.classpath" />
+ </javadoc>
+ </target>
- <jar jarfile="${jarfile}">
- <fileset dir="${build.dir}" />
- <zipfileset file="LICENSE" fullpath="META-INF/Morfologik.LICENSE" />
- <manifest>
- <attribute name="Main-Class" value="${main.class}" />
- <attribute name="Class-Path" value="${manifest.classpath}" />
- </manifest>
- </jar>
-
- <jar jarfile="${jarfile-nodict}">
- <fileset dir="${build.dir}">
- <exclude name="morfologik/dictionaries/**" />
- </fileset>
- <zipfileset file="LICENSE" fullpath="META-INF/Morfologik.LICENSE" />
- <manifest>
- <attribute name="Main-Class" value="${main.class}" />
- <attribute name="Class-Path" value="${manifest.classpath}" />
- </manifest>
- </jar>
- </target>
-
-
-
- <target name="build" depends="jar">
- <copy todir="${tmp.dir}/bin">
- <fileset refid="runtime.dependencies" />
- <fileset dir=".">
- <include name="LICENSE*.txt" />
- <include name="README.txt" />
- <include name="version.txt" />
- </fileset>
- </copy>
- </target>
-
-
-
- <target name="dist" depends="clean, test, build, javadoc, licenses">
- <!-- Package source distribution -->
- <fileset dir="." id="srcdistfiles">
- <exclude name="tmp/**" />
- <exclude name="dist/**" />
- <exclude name=".settings/**" />
- <exclude name="${srczip}" />
- </fileset>
-
- <zip destfile="${srczip}">
- <fileset refid="srcdistfiles" />
- <zipfileset prefix="doc/api" dir="${tmp.dir}/javadoc" />
- </zip>
-
- <zip destfile="${binzip}">
- <fileset dir="${tmp.dir}/bin" />
- <zipfileset prefix="api" dir="${tmp.dir}/javadoc" />
+
+
+ <target name="jar" depends="clean, compile, licenses">
+ <mkdir dir="${tmp.dir}/bin" />
+
+ <property name="main.class" value="morfologik.tools.Launcher" />
+
+ <pathconvert property="manifest.classpath" pathsep=" ">
+ <flattenmapper />
+ <path>
+ <fileset refid="runtime.dependencies" />
+ </path>
+ </pathconvert>
+
+ <jar jarfile="${jarfile}">
+ <fileset dir="${build.dir}" />
+ <zipfileset file="${tmp.dir}/licenses/morfologik-stemming.LICENSE" fullpath="META-INF/Morfologik.LICENSE" />
+ <manifest>
+ <attribute name="Main-Class" value="${main.class}" />
+ <attribute name="Class-Path" value="${manifest.classpath}" />
+ </manifest>
+ </jar>
+
+ <jar jarfile="${jarfile-nodict}">
+ <fileset dir="${build.dir}">
+ <exclude name="morfologik/dictionaries/**" />
+ </fileset>
+ <zipfileset file="${tmp.dir}/licenses/morfologik-stemming-nodict.LICENSE" fullpath="META-INF/Morfologik.LICENSE" />
+ <manifest>
+ <attribute name="Main-Class" value="${main.class}" />
+ <attribute name="Class-Path" value="${manifest.classpath}" />
+ </manifest>
+ </jar>
+ </target>
+
+
+
+ <target name="build" depends="jar">
+ <copy todir="${tmp.dir}/bin">
+ <fileset refid="runtime.dependencies" />
+ <fileset dir="lib" includes="*.LICENSE" excludes="junit*" />
+ <fileset dir=".">
+ <include name="LICENSE*.txt" />
+ <include name="README.txt" />
+ <include name="version.txt" />
+ </fileset>
+ </copy>
+ </target>
+
+
+
+ <target name="dist" depends="clean, test, build, javadoc, licenses">
+ <mkdir dir="${dist.dir}" />
+
+ <!-- Package source distribution -->
+ <fileset dir="." id="srcdistfiles">
+ <exclude name="tmp/**" />
+ <exclude name="dist/**" />
+ <exclude name=".settings/**" />
+ <exclude name=".git/**" />
+ <exclude name="${srczip}" />
+ </fileset>
+
+ <zip destfile="${srczip}">
+ <fileset refid="srcdistfiles" />
+ <zipfileset prefix="doc/api" dir="${tmp.dir}/javadoc" />
+ </zip>
+
+ <zip destfile="${binzip}">
+ <fileset dir="${tmp.dir}/bin" />
+ <zipfileset prefix="api" dir="${tmp.dir}/javadoc" />
<!-- Include licenses. -->
<zipfileset dir="${tmp.dir}/licenses" />
- </zip>
- </target>
-
-
-
- <target name="licenses">
+ </zip>
+ </target>
+
+
+
+ <target name="licenses">
<delete dir="${tmp.dir}/licenses" />
<mkdir dir="${tmp.dir}/licenses" />
diff --git a/doc/api/allclasses-frame.html b/doc/api/allclasses-frame.html
index 4ac4f4a..876e191 100644
--- a/doc/api/allclasses-frame.html
+++ b/doc/api/allclasses-frame.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
All Classes
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
@@ -25,6 +25,14 @@ All Classes
<BR>
<A HREF="morfologik/util/BufferUtils.html" title="class in morfologik.util" target="classFrame">BufferUtils</A>
<BR>
+<A HREF="morfologik/fsa/CFSA.html" title="class in morfologik.fsa" target="classFrame">CFSA</A>
+<BR>
+<A HREF="morfologik/fsa/CFSA2.html" title="class in morfologik.fsa" target="classFrame">CFSA2</A>
+<BR>
+<A HREF="morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa" target="classFrame">CFSA2Serializer</A>
+<BR>
+<A HREF="morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa" target="classFrame">ConstantArcSizeFSA</A>
+<BR>
<A HREF="morfologik/stemming/Dictionary.html" title="class in morfologik.stemming" target="classFrame">Dictionary</A>
<BR>
<A HREF="morfologik/stemming/DictionaryIterator.html" title="class in morfologik.stemming" target="classFrame">DictionaryIterator</A>
@@ -33,25 +41,39 @@ All Classes
<BR>
<A HREF="morfologik/stemming/DictionaryMetadata.html" title="class in morfologik.stemming" target="classFrame">DictionaryMetadata</A>
<BR>
-<A HREF="morfologik/tools/DumpTool.html" title="class in morfologik.tools" target="classFrame">DumpTool</A>
-<BR>
<A HREF="morfologik/util/FileUtils.html" title="class in morfologik.util" target="classFrame">FileUtils</A>
<BR>
<A HREF="morfologik/fsa/FSA.html" title="class in morfologik.fsa" target="classFrame">FSA</A>
<BR>
+<A HREF="morfologik/fsa/FSA5.html" title="class in morfologik.fsa" target="classFrame">FSA5</A>
+<BR>
+<A HREF="morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa" target="classFrame">FSA5Serializer</A>
+<BR>
+<A HREF="morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa" target="classFrame">FSABuilder</A>
+<BR>
+<A HREF="morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa" target="classFrame">FSABuilder.InfoEntry</A>
+<BR>
+<A HREF="morfologik/tools/FSABuildTool.html" title="class in morfologik.tools" target="classFrame">FSABuildTool</A>
+<BR>
+<A HREF="morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools" target="classFrame">FSABuildTool.Format</A>
+<BR>
+<A HREF="morfologik/tools/FSADumpTool.html" title="class in morfologik.tools" target="classFrame">FSADumpTool</A>
+<BR>
<A HREF="morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa" target="classFrame">FSAFinalStatesIterator</A>
<BR>
<A HREF="morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa" target="classFrame">FSAFlags</A>
<BR>
-<A HREF="morfologik/fsa/FSAHelpers.html" title="class in morfologik.fsa" target="classFrame">FSAHelpers</A>
+<A HREF="morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa" target="classFrame">FSAInfo</A>
<BR>
-<A HREF="morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa" target="classFrame">FSAMatch</A>
+<A HREF="morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa" target="classFrame"><I>FSASerializer</I></A>
<BR>
-<A HREF="morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa" target="classFrame">FSAMatchType</A>
+<A HREF="morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa" target="classFrame">FSATraversal</A>
<BR>
-<A HREF="morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa" target="classFrame">FSATraversalHelper</A>
+<A HREF="morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa" target="classFrame">FSAUtils</A>
<BR>
-<A HREF="morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa" target="classFrame">FSAVer5Impl</A>
+<A HREF="morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa" target="classFrame">FSAUtils.IntIntHolder</A>
+<BR>
+<A HREF="morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools" target="classFrame"><I>IMessageLogger</I></A>
<BR>
<A HREF="morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools" target="classFrame">InflectionFramesTool</A>
<BR>
@@ -59,14 +81,20 @@ All Classes
<BR>
<A HREF="morfologik/tools/Launcher.html" title="class in morfologik.tools" target="classFrame">Launcher</A>
<BR>
-<A HREF="morfologik/util/PerformanceTimer.html" title="class in morfologik.util" target="classFrame">PerformanceTimer</A>
+<A HREF="morfologik/fsa/MatchResult.html" title="class in morfologik.fsa" target="classFrame">MatchResult</A>
+<BR>
+<A HREF="morfologik/tools/MorphEncoder.html" title="class in morfologik.tools" target="classFrame">MorphEncoder</A>
<BR>
<A HREF="morfologik/stemming/PolishStemmer.html" title="class in morfologik.stemming" target="classFrame">PolishStemmer</A>
<BR>
<A HREF="morfologik/util/ResourceUtils.html" title="class in morfologik.util" target="classFrame">ResourceUtils</A>
<BR>
+<A HREF="morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa" target="classFrame"><I>StateVisitor</I></A>
+<BR>
<A HREF="morfologik/stemming/WordData.html" title="class in morfologik.stemming" target="classFrame">WordData</A>
<BR>
+<A HREF="morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools" target="classFrame">WriterMessageLogger</A>
+<BR>
</FONT></TD>
</TR>
</TABLE>
diff --git a/doc/api/allclasses-noframe.html b/doc/api/allclasses-noframe.html
index c879a3a..50dcd62 100644
--- a/doc/api/allclasses-noframe.html
+++ b/doc/api/allclasses-noframe.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
All Classes
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
@@ -25,6 +25,14 @@ All Classes
<BR>
<A HREF="morfologik/util/BufferUtils.html" title="class in morfologik.util">BufferUtils</A>
<BR>
+<A HREF="morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<BR>
+<A HREF="morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<BR>
+<A HREF="morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A>
+<BR>
+<A HREF="morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<BR>
<A HREF="morfologik/stemming/Dictionary.html" title="class in morfologik.stemming">Dictionary</A>
<BR>
<A HREF="morfologik/stemming/DictionaryIterator.html" title="class in morfologik.stemming">DictionaryIterator</A>
@@ -33,25 +41,39 @@ All Classes
<BR>
<A HREF="morfologik/stemming/DictionaryMetadata.html" title="class in morfologik.stemming">DictionaryMetadata</A>
<BR>
-<A HREF="morfologik/tools/DumpTool.html" title="class in morfologik.tools">DumpTool</A>
-<BR>
<A HREF="morfologik/util/FileUtils.html" title="class in morfologik.util">FileUtils</A>
<BR>
<A HREF="morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
<BR>
+<A HREF="morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<BR>
+<A HREF="morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A>
+<BR>
+<A HREF="morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa">FSABuilder</A>
+<BR>
+<A HREF="morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A>
+<BR>
+<A HREF="morfologik/tools/FSABuildTool.html" title="class in morfologik.tools">FSABuildTool</A>
+<BR>
+<A HREF="morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A>
+<BR>
+<A HREF="morfologik/tools/FSADumpTool.html" title="class in morfologik.tools">FSADumpTool</A>
+<BR>
<A HREF="morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa">FSAFinalStatesIterator</A>
<BR>
<A HREF="morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>
<BR>
-<A HREF="morfologik/fsa/FSAHelpers.html" title="class in morfologik.fsa">FSAHelpers</A>
+<A HREF="morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa">FSAInfo</A>
<BR>
-<A HREF="morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A>
+<A HREF="morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa"><I>FSASerializer</I></A>
<BR>
-<A HREF="morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A>
+<A HREF="morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa">FSATraversal</A>
<BR>
-<A HREF="morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa">FSATraversalHelper</A>
+<A HREF="morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa">FSAUtils</A>
<BR>
-<A HREF="morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
+<A HREF="morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa">FSAUtils.IntIntHolder</A>
+<BR>
+<A HREF="morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools"><I>IMessageLogger</I></A>
<BR>
<A HREF="morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools">InflectionFramesTool</A>
<BR>
@@ -59,14 +81,20 @@ All Classes
<BR>
<A HREF="morfologik/tools/Launcher.html" title="class in morfologik.tools">Launcher</A>
<BR>
-<A HREF="morfologik/util/PerformanceTimer.html" title="class in morfologik.util">PerformanceTimer</A>
+<A HREF="morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A>
+<BR>
+<A HREF="morfologik/tools/MorphEncoder.html" title="class in morfologik.tools">MorphEncoder</A>
<BR>
<A HREF="morfologik/stemming/PolishStemmer.html" title="class in morfologik.stemming">PolishStemmer</A>
<BR>
<A HREF="morfologik/util/ResourceUtils.html" title="class in morfologik.util">ResourceUtils</A>
<BR>
+<A HREF="morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa"><I>StateVisitor</I></A>
+<BR>
<A HREF="morfologik/stemming/WordData.html" title="class in morfologik.stemming">WordData</A>
<BR>
+<A HREF="morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools">WriterMessageLogger</A>
+<BR>
</FONT></TD>
</TR>
</TABLE>
diff --git a/doc/api/constant-values.html b/doc/api/constant-values.html
index fe96491..e296aa0 100644
--- a/doc/api/constant-values.html
+++ b/doc/api/constant-values.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
Constant Field Values
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
@@ -100,13 +100,31 @@ morfologik.fsa.*</FONT></TH>
<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
-<TH ALIGN="left" COLSPAN="3">morfologik.fsa.<A HREF="morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></TH>
+<TH ALIGN="left" COLSPAN="3">morfologik.fsa.<A HREF="morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<A NAME="morfologik.fsa.FSA.VERSION_5"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<A NAME="morfologik.fsa.CFSA.BIT_FINAL_ARC"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/CFSA.html#BIT_FINAL_ARC">BIT_FINAL_ARC</A></CODE></TD>
+<TD ALIGN="right"><CODE>1</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.CFSA.BIT_LAST_ARC"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/CFSA.html#BIT_LAST_ARC">BIT_LAST_ARC</A></CODE></TD>
+<TD ALIGN="right"><CODE>2</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.CFSA.BIT_TARGET_NEXT"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/CFSA.html#BIT_TARGET_NEXT">BIT_TARGET_NEXT</A></CODE></TD>
+<TD ALIGN="right"><CODE>4</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.CFSA.VERSION"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
<CODE>public&nbsp;static&nbsp;final&nbsp;byte</CODE></FONT></TD>
-<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/FSA.html#VERSION_5">VERSION_5</A></CODE></TD>
-<TD ALIGN="right"><CODE>5</CODE></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/CFSA.html#VERSION">VERSION</A></CODE></TD>
+<TD ALIGN="right"><CODE>-59</CODE></TD>
</TR>
</FONT></TD>
</TR>
@@ -118,14 +136,188 @@ morfologik.fsa.*</FONT></TH>
<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
-<TH ALIGN="left" COLSPAN="3">morfologik.fsa.<A HREF="morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A></TH>
+<TH ALIGN="left" COLSPAN="3">morfologik.fsa.<A HREF="morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.CFSA2.BIT_FINAL_ARC"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/CFSA2.html#BIT_FINAL_ARC">BIT_FINAL_ARC</A></CODE></TD>
+<TD ALIGN="right"><CODE>32</CODE></TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<A NAME="morfologik.fsa.FSAVer5Impl.gotoOffset"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
-<CODE>protected&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
-<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/FSAVer5Impl.html#gotoOffset">gotoOffset</A></CODE></TD>
+<A NAME="morfologik.fsa.CFSA2.BIT_LAST_ARC"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/CFSA2.html#BIT_LAST_ARC">BIT_LAST_ARC</A></CODE></TD>
+<TD ALIGN="right"><CODE>64</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.CFSA2.BIT_TARGET_NEXT"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/CFSA2.html#BIT_TARGET_NEXT">BIT_TARGET_NEXT</A></CODE></TD>
+<TD ALIGN="right"><CODE>128</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.CFSA2.VERSION"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;byte</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/CFSA2.html#VERSION">VERSION</A></CODE></TD>
+<TD ALIGN="right"><CODE>-58</CODE></TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="3">morfologik.fsa.<A HREF="morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.ConstantArcSizeFSA.ADDRESS_OFFSET"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/ConstantArcSizeFSA.html#ADDRESS_OFFSET">ADDRESS_OFFSET</A></CODE></TD>
+<TD ALIGN="right"><CODE>2</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.ConstantArcSizeFSA.ARC_SIZE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/ConstantArcSizeFSA.html#ARC_SIZE">ARC_SIZE</A></CODE></TD>
+<TD ALIGN="right"><CODE>6</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.ConstantArcSizeFSA.BIT_ARC_FINAL"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/ConstantArcSizeFSA.html#BIT_ARC_FINAL">BIT_ARC_FINAL</A></CODE></TD>
+<TD ALIGN="right"><CODE>2</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.ConstantArcSizeFSA.BIT_ARC_LAST"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/ConstantArcSizeFSA.html#BIT_ARC_LAST">BIT_ARC_LAST</A></CODE></TD>
+<TD ALIGN="right"><CODE>1</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.ConstantArcSizeFSA.FLAGS_OFFSET"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/ConstantArcSizeFSA.html#FLAGS_OFFSET">FLAGS_OFFSET</A></CODE></TD>
+<TD ALIGN="right"><CODE>0</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.ConstantArcSizeFSA.FLAGS_SIZE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/ConstantArcSizeFSA.html#FLAGS_SIZE">FLAGS_SIZE</A></CODE></TD>
+<TD ALIGN="right"><CODE>1</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.ConstantArcSizeFSA.LABEL_OFFSET"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/ConstantArcSizeFSA.html#LABEL_OFFSET">LABEL_OFFSET</A></CODE></TD>
+<TD ALIGN="right"><CODE>1</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.ConstantArcSizeFSA.LABEL_SIZE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/ConstantArcSizeFSA.html#LABEL_SIZE">LABEL_SIZE</A></CODE></TD>
<TD ALIGN="right"><CODE>1</CODE></TD>
</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.ConstantArcSizeFSA.TARGET_ADDRESS_SIZE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/ConstantArcSizeFSA.html#TARGET_ADDRESS_SIZE">TARGET_ADDRESS_SIZE</A></CODE></TD>
+<TD ALIGN="right"><CODE>4</CODE></TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="3">morfologik.fsa.<A HREF="morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.FSA5.ADDRESS_OFFSET"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/FSA5.html#ADDRESS_OFFSET">ADDRESS_OFFSET</A></CODE></TD>
+<TD ALIGN="right"><CODE>1</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.FSA5.BIT_FINAL_ARC"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/FSA5.html#BIT_FINAL_ARC">BIT_FINAL_ARC</A></CODE></TD>
+<TD ALIGN="right"><CODE>1</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.FSA5.BIT_LAST_ARC"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/FSA5.html#BIT_LAST_ARC">BIT_LAST_ARC</A></CODE></TD>
+<TD ALIGN="right"><CODE>2</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.FSA5.BIT_TARGET_NEXT"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/FSA5.html#BIT_TARGET_NEXT">BIT_TARGET_NEXT</A></CODE></TD>
+<TD ALIGN="right"><CODE>4</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.FSA5.DEFAULT_ANNOTATION"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;byte</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/FSA5.html#DEFAULT_ANNOTATION">DEFAULT_ANNOTATION</A></CODE></TD>
+<TD ALIGN="right"><CODE>43</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.FSA5.DEFAULT_FILLER"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;byte</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/FSA5.html#DEFAULT_FILLER">DEFAULT_FILLER</A></CODE></TD>
+<TD ALIGN="right"><CODE>95</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.FSA5.VERSION"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;byte</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/FSA5.html#VERSION">VERSION</A></CODE></TD>
+<TD ALIGN="right"><CODE>5</CODE></TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="3">morfologik.fsa.<A HREF="morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.MatchResult.AUTOMATON_HAS_PREFIX"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/MatchResult.html#AUTOMATON_HAS_PREFIX">AUTOMATON_HAS_PREFIX</A></CODE></TD>
+<TD ALIGN="right"><CODE>-3</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.MatchResult.EXACT_MATCH"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/MatchResult.html#EXACT_MATCH">EXACT_MATCH</A></CODE></TD>
+<TD ALIGN="right"><CODE>0</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.MatchResult.NO_MATCH"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/MatchResult.html#NO_MATCH">NO_MATCH</A></CODE></TD>
+<TD ALIGN="right"><CODE>-1</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="morfologik.fsa.MatchResult.SEQUENCE_IS_A_PREFIX"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="morfologik/fsa/MatchResult.html#SEQUENCE_IS_A_PREFIX">SEQUENCE_IS_A_PREFIX</A></CODE></TD>
+<TD ALIGN="right"><CODE>-4</CODE></TD>
+</TR>
</FONT></TD>
</TR>
</TABLE>
diff --git a/doc/api/deprecated-list.html b/doc/api/deprecated-list.html
index 5501a3f..2b4b8b8 100644
--- a/doc/api/deprecated-list.html
+++ b/doc/api/deprecated-list.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
Deprecated List
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
diff --git a/doc/api/help-doc.html b/doc/api/help-doc.html
index 3ccffe9..16c5ae3 100644
--- a/doc/api/help-doc.html
+++ b/doc/api/help-doc.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
API Help
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
diff --git a/doc/api/index-all.html b/doc/api/index-all.html
index 5f5403a..6ae27f4 100644
--- a/doc/api/index-all.html
+++ b/doc/api/index-all.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
Index
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="./stylesheet.css" TITLE="Style">
@@ -77,19 +77,60 @@ function windowTitle()
<A NAME="skip-navbar_top"></A>
<!-- ========= END OF TOP NAVBAR ========= -->
-<A HREF="#_A_">A</A> <A HREF="#_B_">B</A> <A HREF="#_C_">C</A> <A HREF="#_D_">D</A> <A HREF="#_E_">E</A> <A HREF="#_F_">F</A> <A HREF="#_G_">G</A> <A HREF="#_H_">H</A> <A HREF="#_I_">I</A> <A HREF="#_L_">L</A> <A HREF="#_M_">M</A> <A HREF="#_N_">N</A> <A HREF="#_O_">O</A> <A HREF="#_P_">P</A> <A HREF="#_R_">R</A> <A HREF="#_S_">S</A> <A HREF="#_T_">T</A> <A HREF="#_U_">U</A> <A HREF="#_V_">V</A> <A HREF="#_W_">W</A> <HR>
+<A HREF="#_A_">A</A> <A HREF="#_B_">B</A> <A HREF="#_C_">C</A> <A HREF="#_D_">D</A> <A HREF="#_E_">E</A> <A HREF="#_F_">F</A> <A HREF="#_G_">G</A> <A HREF="#_H_">H</A> <A HREF="#_I_">I</A> <A HREF="#_K_">K</A> <A HREF="#_L_">L</A> <A HREF="#_M_">M</A> <A HREF="#_N_">N</A> <A HREF="#_O_">O</A> <A HREF="#_P_">P</A> <A HREF="#_R_">R</A> <A HREF="#_S_">S</A> <A HREF="#_T_">T</A> <A HREF="#_U_">U</A> <A HREF="#_V_">V</A> <A HREF="#_W_">W</A> <HR>
<A NAME="_A_"><!-- --></A><H2>
<B>A</B></H2>
<DL>
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#arcs"><B>arcs</B></A> -
-Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
+<DT><A HREF="./morfologik/fsa/FSAUtils.IntIntHolder.html#a"><B>a</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa">FSAUtils.IntIntHolder</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/StateVisitor.html#accept(int)"><B>accept(int)</B></A> -
+Method in interface morfologik.fsa.<A HREF="./morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa">StateVisitor</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSABuilder.html#add(byte[], int, int)"><B>add(byte[], int, int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa">FSABuilder</A>
+<DD>Add a single sequence of bytes to the FSA.
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#ADDRESS_OFFSET"><B>ADDRESS_OFFSET</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>Offset of the address field inside an arc.
+<DT><A HREF="./morfologik/fsa/FSA5.html#ADDRESS_OFFSET"><B>ADDRESS_OFFSET</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>An offset in the arc structure, where the address and flags field begins.
+<DT><A HREF="./morfologik/fsa/FSA5.html#annotation"><B>annotation</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Annotation character.
+<DT><A HREF="./morfologik/fsa/FSA5Serializer.html#annotationByte"><B>annotationByte</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#ARC_SIZE"><B>ARC_SIZE</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>Size of a single arc structure.
+<DT><A HREF="./morfologik/fsa/CFSA.html#arcs"><B>arcs</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>An array of bytes with the internal representation of the automaton.
+<DT><A HREF="./morfologik/fsa/CFSA2.html#arcs"><B>arcs</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
<DD>An array of bytes with the internal representation of the automaton.
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#arcSize"><B>arcSize</B></A> -
-Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
-<DD>Size of a single arc (in bytes).
+<DT><A HREF="./morfologik/fsa/FSA5.html#arcs"><B>arcs</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>An array of bytes with the internal representation of the automaton.
+<DT><A HREF="./morfologik/fsa/FSAInfo.html#arcsCount"><B>arcsCount</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa">FSAInfo</A>
+<DD>Number of arcs in the automaton, excluding an arcs from the zero node
+ (initial) and an arc from the start node to the root node.
+<DT><A HREF="./morfologik/fsa/FSAInfo.html#arcsCountTotal"><B>arcsCountTotal</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa">FSAInfo</A>
+<DD>Total number of arcs, counting arcs that physically overlap due to
+ merging.
<DT><A HREF="./morfologik/util/Arrays.html" title="class in morfologik.util"><B>Arrays</B></A> - Class in <A HREF="./morfologik/util/package-summary.html">morfologik.util</A><DD>Compatibility layer for JVM 1.5.<DT><A HREF="./morfologik/util/FileUtils.html#assertExists(java.io.File, boolean, boolean)"><B>assertExists(File, boolean, boolean)</B></A> -
Static method in class morfologik.util.<A HREF="./morfologik/util/FileUtils.html" title="class in morfologik.util">FileUtils</A>
<DD>Checks if the given file exists.
+<DT><A HREF="./morfologik/fsa/FSAFlags.html#asShort(java.util.Set)"><B>asShort(Set&lt;FSAFlags&gt;)</B></A> -
+Static method in enum morfologik.fsa.<A HREF="./morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>
+<DD>Returns the set of flags encoded in a single short.
+<DT><A HREF="./morfologik/tools/MorphEncoder.html#asString(byte[], java.lang.String)"><B>asString(byte[], String)</B></A> -
+Static method in class morfologik.tools.<A HREF="./morfologik/tools/MorphEncoder.html" title="class in morfologik.tools">MorphEncoder</A>
+<DD>Converts a byte array to a given encoding.
<DT><A HREF="./morfologik/stemming/DictionaryMetadata.html#ATTR_NAME_ENCODING"><B>ATTR_NAME_ENCODING</B></A> -
Static variable in class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryMetadata.html" title="class in morfologik.stemming">DictionaryMetadata</A>
<DD>Attribute name for <A HREF="./morfologik/stemming/DictionaryMetadata.html#encoding"><CODE>DictionaryMetadata.encoding</CODE></A>.
@@ -102,39 +143,109 @@ Static variable in class morfologik.stemming.<A HREF="./morfologik/stemming/Dict
<DT><A HREF="./morfologik/stemming/DictionaryMetadata.html#ATTR_NAME_USES_PREFIXES"><B>ATTR_NAME_USES_PREFIXES</B></A> -
Static variable in class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryMetadata.html" title="class in morfologik.stemming">DictionaryMetadata</A>
<DD>Attribute name for <A HREF="./morfologik/stemming/DictionaryMetadata.html#usesPrefixes"><CODE>DictionaryMetadata.usesPrefixes</CODE></A>.
+<DT><A HREF="./morfologik/fsa/MatchResult.html#AUTOMATON_HAS_PREFIX"><B>AUTOMATON_HAS_PREFIX</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A>
+<DD>The automaton contains a prefix of the input sequence.
</DL>
<HR>
<A NAME="_B_"><!-- --></A><H2>
<B>B</B></H2>
<DL>
+<DT><A HREF="./morfologik/fsa/FSAUtils.IntIntHolder.html#b"><B>b</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa">FSAUtils.IntIntHolder</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#BIT_ARC_FINAL"><B>BIT_ARC_FINAL</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>An arc flag indicating the target node of an arc corresponds to a final
+ state.
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#BIT_ARC_LAST"><B>BIT_ARC_LAST</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>An arc flag indicating the arc is last within its state.
+<DT><A HREF="./morfologik/fsa/CFSA.html#BIT_FINAL_ARC"><B>BIT_FINAL_ARC</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Bitmask indicating that an arc corresponds to the last character of a
+ sequence available when building the automaton.
+<DT><A HREF="./morfologik/fsa/CFSA2.html#BIT_FINAL_ARC"><B>BIT_FINAL_ARC</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>The arc corresponds to the last character of a sequence
+ available when building the automaton (acceptor transition).
+<DT><A HREF="./morfologik/fsa/FSA5.html#BIT_FINAL_ARC"><B>BIT_FINAL_ARC</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Bit indicating that an arc corresponds to the last character of a
+ sequence available when building the automaton.
+<DT><A HREF="./morfologik/fsa/CFSA.html#BIT_LAST_ARC"><B>BIT_LAST_ARC</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Bitmask indicating that an arc is the last one of the node's list and the
+ following one belongs to another node.
+<DT><A HREF="./morfologik/fsa/CFSA2.html#BIT_LAST_ARC"><B>BIT_LAST_ARC</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>The arc is the last one from the current node's arcs list.
+<DT><A HREF="./morfologik/fsa/FSA5.html#BIT_LAST_ARC"><B>BIT_LAST_ARC</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Bit indicating that an arc is the last one of the node's list and the
+ following one belongs to another node.
+<DT><A HREF="./morfologik/fsa/CFSA.html#BIT_TARGET_NEXT"><B>BIT_TARGET_NEXT</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Bitmask indicating that the target node of this arc follows it in the
+ compressed automaton structure (no goto field).
+<DT><A HREF="./morfologik/fsa/CFSA2.html#BIT_TARGET_NEXT"><B>BIT_TARGET_NEXT</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>The target node of this arc follows the last arc of the current state
+ (no goto field).
+<DT><A HREF="./morfologik/fsa/FSA5.html#BIT_TARGET_NEXT"><B>BIT_TARGET_NEXT</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Bit indicating that the target node of this arc follows it in the
+ compressed automaton structure (no goto field).
<DT><A HREF="./morfologik/fsa/FSAFlags.html#bits"><B>bits</B></A> -
Variable in enum morfologik.fsa.<A HREF="./morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>
<DD>Bit mask for the corresponding flag.
-<DT><A HREF="./morfologik/util/BufferUtils.html" title="class in morfologik.util"><B>BufferUtils</B></A> - Class in <A HREF="./morfologik/util/package-summary.html">morfologik.util</A><DD>Utility functions for buffers.</DL>
+<DT><A HREF="./morfologik/util/BufferUtils.html" title="class in morfologik.util"><B>BufferUtils</B></A> - Class in <A HREF="./morfologik/util/package-summary.html">morfologik.util</A><DD>Utility functions for buffers.<DT><A HREF="./morfologik/fsa/FSABuilder.html#build(byte[][])"><B>build(byte[][])</B></A> -
+Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa">FSABuilder</A>
+<DD>Build a minimal, deterministic automaton from a sorted list of byte sequences.
+<DT><A HREF="./morfologik/fsa/FSABuilder.html#build(java.lang.Iterable)"><B>build(Iterable&lt;byte[]&gt;)</B></A> -
+Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa">FSABuilder</A>
+<DD>Build a minimal, deterministic automaton from an iterable list of byte sequences.
+</DL>
<HR>
<A NAME="_C_"><!-- --></A><H2>
<B>C</B></H2>
<DL>
+<DT><A HREF="./morfologik/fsa/FSAUtils.html#calculateFanOuts(morfologik.fsa.FSA, int)"><B>calculateFanOuts(FSA, int)</B></A> -
+Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa">FSAUtils</A>
+<DD>Calculate fan-out ratio.
+<DT><A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa"><B>CFSA</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>CFSA (Compact Finite State Automaton) binary format implementation.<DT><A HREF="./morfologik/fsa/CFSA.html#CFSA(java.io.InputStream)"><B>CFSA(InputStream)</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Creates a new automaton, reading it from a file in FSA format, version 5.
+<DT><A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><B>CFSA2</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>CFSA (Compact Finite State Automaton) binary format implementation, version 2:
+
+ <A HREF="./morfologik/fsa/CFSA2.html#BIT_TARGET_NEXT"><CODE>CFSA2.BIT_TARGET_NEXT</CODE></A> applicable on all arcs, not necessarily the last one.<DT><A HREF="./morfologik/fsa/CFSA2.html#CFSA2(java.io.InputStream)"><B>CFSA2(InputStream)</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>Reads an automaton from a byte stream.
+<DT><A HREF="./morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa"><B>CFSA2Serializer</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>Serializes in-memory <A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> graphs to <A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><CODE>CFSA2</CODE></A>.<DT><A HREF="./morfologik/fsa/CFSA2Serializer.html#CFSA2Serializer()"><B>CFSA2Serializer()</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/tools/FSABuildTool.html#checkSingleByte(java.lang.String)"><B>checkSingleByte(String)</B></A> -
+Static method in class morfologik.tools.<A HREF="./morfologik/tools/FSABuildTool.html" title="class in morfologik.tools">FSABuildTool</A>
+<DD>Check if the argument is a single byte after conversion using platform-default
+ encoding.
<DT><A HREF="./morfologik/stemming/WordData.html#clone()"><B>clone()</B></A> -
Method in class morfologik.stemming.<A HREF="./morfologik/stemming/WordData.html" title="class in morfologik.stemming">WordData</A>
-<DD>Declare a covariant of <CODE>Object.clone()</CODE> that returns a deep copy
- of this object.
+<DD>Declare a covariant of <CODE>Object.clone()</CODE> that returns a deep copy of
+ this object.
<DT><A HREF="./morfologik/util/FileUtils.html#close(java.io.Closeable...)"><B>close(Closeable...)</B></A> -
Static method in class morfologik.util.<A HREF="./morfologik/util/FileUtils.html" title="class in morfologik.util">FileUtils</A>
<DD>Force any non-null closeables.
-<DT><A HREF="./morfologik/util/Arrays.html#copyOf(byte[], int)"><B>copyOf(byte[], int)</B></A> -
-Static method in class morfologik.util.<A HREF="./morfologik/util/Arrays.html" title="class in morfologik.util">Arrays</A>
-<DD>&nbsp;
-<DT><A HREF="./morfologik/util/Arrays.html#copyOf(int[], int)"><B>copyOf(int[], int)</B></A> -
-Static method in class morfologik.util.<A HREF="./morfologik/util/Arrays.html" title="class in morfologik.util">Arrays</A>
-<DD>&nbsp;
-<DT><A HREF="./morfologik/util/Arrays.html#copyOf(T[], int)"><B>copyOf(T[], int)</B></A> -
-Static method in class morfologik.util.<A HREF="./morfologik/util/Arrays.html" title="class in morfologik.util">Arrays</A>
-<DD>&nbsp;
-<DT><A HREF="./morfologik/util/Arrays.html#copyOf(U[], int, java.lang.Class)"><B>copyOf(U[], int, Class&lt;? extends T[]&gt;)</B></A> -
-Static method in class morfologik.util.<A HREF="./morfologik/util/Arrays.html" title="class in morfologik.util">Arrays</A>
+<DT><A HREF="./morfologik/tools/MorphEncoder.html#commonPrefix(byte[], byte[])"><B>commonPrefix(byte[], byte[])</B></A> -
+Static method in class morfologik.tools.<A HREF="./morfologik/tools/MorphEncoder.html" title="class in morfologik.tools">MorphEncoder</A>
<DD>&nbsp;
-</DL>
+<DT><A HREF="./morfologik/fsa/FSABuilder.html#compare(byte[], int, int, byte[], int, int)"><B>compare(byte[], int, int, byte[], int, int)</B></A> -
+Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa">FSABuilder</A>
+<DD>Lexicographic order of input sequences.
+<DT><A HREF="./morfologik/fsa/FSABuilder.html#complete()"><B>complete()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa">FSABuilder</A>
+<DD>Complete the automaton.
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa"><B>ConstantArcSizeFSA</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>An FSA with constant-size arc representation produced directly
+ by <A HREF="./morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa"><CODE>FSABuilder</CODE></A>.</DL>
<HR>
<A NAME="_D_"><!-- --></A><H2>
<B>D</B></H2>
@@ -143,6 +254,12 @@ Static method in class morfologik.util.<A HREF="./morfologik/util/Arrays.html" t
Static method in class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryLookup.html" title="class in morfologik.stemming">DictionaryLookup</A>
<DD>Decode the base form of an inflected word and save its decoded form into
a byte buffer.
+<DT><A HREF="./morfologik/fsa/FSA5.html#DEFAULT_ANNOTATION"><B>DEFAULT_ANNOTATION</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Default annotation byte.
+<DT><A HREF="./morfologik/fsa/FSA5.html#DEFAULT_FILLER"><B>DEFAULT_FILLER</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Default filler byte.
<DT><A HREF="./morfologik/stemming/Dictionary.html#defaultDictionaries"><B>defaultDictionaries</B></A> -
Static variable in class morfologik.stemming.<A HREF="./morfologik/stemming/Dictionary.html" title="class in morfologik.stemming">Dictionary</A>
<DD>Default loaded dictionaries.
@@ -162,21 +279,23 @@ Constructor for class morfologik.stemming.<A HREF="./morfologik/stemming/Diction
<DT><A HREF="./morfologik/stemming/DictionaryMetadata.html" title="class in morfologik.stemming"><B>DictionaryMetadata</B></A> - Class in <A HREF="./morfologik/stemming/package-summary.html">morfologik.stemming</A><DD>Description of attributes, their types and default values.<DT><A HREF="./morfologik/stemming/DictionaryMetadata.html#DictionaryMetadata(char, java.lang.String, boolean, boolean, java.util.Map)"><B>DictionaryMetadata(char, String, boolean, boolean, Map&lt;String, String&gt;)</B></A> -
Constructor for class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryMetadata.html" title="class in morfologik.stemming">DictionaryMetadata</A>
<DD>Creates an immutable instance of <A HREF="./morfologik/stemming/DictionaryMetadata.html" title="class in morfologik.stemming"><CODE>DictionaryMetadata</CODE></A>.
-<DT><A HREF="./morfologik/tools/DumpTool.html" title="class in morfologik.tools"><B>DumpTool</B></A> - Class in <A HREF="./morfologik/tools/package-summary.html">morfologik.tools</A><DD>This utility will dump the information and contents of a given <A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A>
- dictionary.<DT><A HREF="./morfologik/tools/DumpTool.html#DumpTool()"><B>DumpTool()</B></A> -
-Constructor for class morfologik.tools.<A HREF="./morfologik/tools/DumpTool.html" title="class in morfologik.tools">DumpTool</A>
-<DD>&nbsp;
+<DT><A HREF="./morfologik/tools/FSABuildTool.html#dumpLine(byte[], int)"><B>dumpLine(byte[], int)</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/FSABuildTool.html" title="class in morfologik.tools">FSABuildTool</A>
+<DD>Dump input line, byte-by-byte.
</DL>
<HR>
<A NAME="_E_"><!-- --></A><H2>
<B>E</B></H2>
<DL>
-<DT><A HREF="./morfologik/util/PerformanceTimer.html#elemsPerSecond(int)"><B>elemsPerSecond(int)</B></A> -
-Method in class morfologik.util.<A HREF="./morfologik/util/PerformanceTimer.html" title="class in morfologik.util">PerformanceTimer</A>
-<DD>&nbsp;
<DT><A HREF="./morfologik/stemming/DictionaryMetadata.html#encoding"><B>encoding</B></A> -
Variable in class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryMetadata.html" title="class in morfologik.stemming">DictionaryMetadata</A>
<DD>Encoding used for converting bytes to characters and vice versa.
+<DT><A HREF="./morfologik/tools/IMessageLogger.html#endPart()"><B>endPart()</B></A> -
+Method in interface morfologik.tools.<A HREF="./morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/tools/WriterMessageLogger.html#endPart()"><B>endPart()</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools">WriterMessageLogger</A>
+<DD>&nbsp;
<DT><A HREF="./morfologik/util/BufferUtils.html#ensureCapacity(java.nio.ByteBuffer, int)"><B>ensureCapacity(ByteBuffer, int)</B></A> -
Static method in class morfologik.util.<A HREF="./morfologik/util/BufferUtils.html" title="class in morfologik.util">BufferUtils</A>
<DD>Ensure the byte buffer's capacity.
@@ -186,143 +305,248 @@ Static method in class morfologik.util.<A HREF="./morfologik/util/BufferUtils.ht
<DT><A HREF="./morfologik/stemming/WordData.html#equals(java.lang.Object)"><B>equals(Object)</B></A> -
Method in class morfologik.stemming.<A HREF="./morfologik/stemming/WordData.html" title="class in morfologik.stemming">WordData</A>
<DD>&nbsp;
+<DT><A HREF="./morfologik/util/Arrays.html#equals(byte[], int, byte[], int, int)"><B>equals(byte[], int, byte[], int, int)</B></A> -
+Static method in class morfologik.util.<A HREF="./morfologik/util/Arrays.html" title="class in morfologik.util">Arrays</A>
+<DD>Compare two arrays for equality.
+<DT><A HREF="./morfologik/util/Arrays.html#equals(boolean[], int, boolean[], int, int)"><B>equals(boolean[], int, boolean[], int, int)</B></A> -
+Static method in class morfologik.util.<A HREF="./morfologik/util/Arrays.html" title="class in morfologik.util">Arrays</A>
+<DD>Compare two arrays for equality.
+<DT><A HREF="./morfologik/util/Arrays.html#equals(int[], int, int[], int, int)"><B>equals(int[], int, int[], int, int)</B></A> -
+Static method in class morfologik.util.<A HREF="./morfologik/util/Arrays.html" title="class in morfologik.util">Arrays</A>
+<DD>Compare two arrays for equality.
+<DT><A HREF="./morfologik/fsa/MatchResult.html#EXACT_MATCH"><B>EXACT_MATCH</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A>
+<DD>The automaton has exactly one match for the input sequence.
</DL>
<HR>
<A NAME="_F_"><!-- --></A><H2>
<B>F</B></H2>
<DL>
-<DT><A HREF="./morfologik/util/FileUtils.html" title="class in morfologik.util"><B>FileUtils</B></A> - Class in <A HREF="./morfologik/util/package-summary.html">morfologik.util</A><DD>Utility functions.<DT><A HREF="./morfologik/fsa/FSA.html#filler"><B>filler</B></A> -
-Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>The meaning of this field is not clear (check the FSA documentation).
-<DT><A HREF="./morfologik/fsa/FSAHelpers.html#flagsToString(int)"><B>flagsToString(int)</B></A> -
-Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAHelpers.html" title="class in morfologik.fsa">FSAHelpers</A>
-<DD>Converts an integer with FSA flags to a human-readable string.
-<DT><A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa"><B>FSA</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>This class implements Finite State Automaton traversal as described in Jan
- Daciuk's <i>Incremental Construction of Finite-State Automata and
- Transducers, and Their Use in the Natural Language Processing</i> (PhD
- thesis, Technical University of Gdansk).<DT><A HREF="./morfologik/fsa/FSA.html#FSA(java.io.InputStream, java.lang.String)"><B>FSA(InputStream, String)</B></A> -
+<DT><A HREF="./morfologik/util/FileUtils.html" title="class in morfologik.util"><B>FileUtils</B></A> - Class in <A HREF="./morfologik/util/package-summary.html">morfologik.util</A><DD>Utility functions.<DT><A HREF="./morfologik/fsa/FSA5.html#filler"><B>filler</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Filler character.
+<DT><A HREF="./morfologik/fsa/FSA5Serializer.html#fillerByte"><B>fillerByte</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSAInfo.html#finalStatesCount"><B>finalStatesCount</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa">FSAInfo</A>
+<DD>Number of final states (number of input sequences stored in the automaton).
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#FLAGS_OFFSET"><B>FLAGS_OFFSET</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>Offset of the flags field inside an arc.
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#FLAGS_SIZE"><B>FLAGS_SIZE</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>Size of the flags field (constant for the builder).
+<DT><A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa"><B>FSA</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>This is a top abstract class for handling finite state automata.<DT><A HREF="./morfologik/fsa/FSA.html#FSA()"><B>FSA()</B></A> -
Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Creates a new automaton reading the FSA automaton from an input stream.
+<DD>&nbsp;
<DT><A HREF="./morfologik/stemming/Dictionary.html#fsa"><B>fsa</B></A> -
Variable in class morfologik.stemming.<A HREF="./morfologik/stemming/Dictionary.html" title="class in morfologik.stemming">Dictionary</A>
<DD><A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> automaton with the compiled dictionary data.
-<DT><A HREF="./morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa"><B>FSAFinalStatesIterator</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>An iterator that traverses all final states reachable from a given
- node and returns byte sequences corresponding to final states.<DT><A HREF="./morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa"><B>FSAFlags</B></A> - Enum in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>FSA automaton flags.<DT><A HREF="./morfologik/fsa/FSAHelpers.html" title="class in morfologik.fsa"><B>FSAHelpers</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>This class has several static utility methods for use
- with the FSA package.<DT><A HREF="./morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><B>FSAMatch</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>A matching result returned from <A HREF="./morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa"><CODE>FSATraversalHelper</CODE></A>.<DT><A HREF="./morfologik/fsa/FSAMatch.html#FSAMatch()"><B>FSAMatch()</B></A> -
-Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A>
-<DD>&nbsp;
-<DT><A HREF="./morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa"><B>FSAMatchType</B></A> - Enum in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>Type of the match returned as part of <A HREF="./morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><CODE>FSAMatch</CODE></A>.<DT><A HREF="./morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa"><B>FSATraversalHelper</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>This class implements some common matching and scanning operations on a
- generic FSA.<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa"><B>FSAVer5Impl</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>FSA (Finite State Automaton) dictionary traversal implementation for version
- 5 of the FSA automaton.<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#FSAVer5Impl(java.io.InputStream, java.lang.String)"><B>FSAVer5Impl(InputStream, String)</B></A> -
-Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
-<DD>Creates a new automaton reading it from a file in FSA format, version 5.
+<DT><A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa"><B>FSA5</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>FSA binary format implementation for version 5.<DT><A HREF="./morfologik/fsa/FSA5.html#FSA5(java.io.InputStream)"><B>FSA5(InputStream)</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Read and wrap a binary automaton in FSA version 5.
+<DT><A HREF="./morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa"><B>FSA5Serializer</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>Serializes in-memory <A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> graphs to a binary format compatible with
+ Jan Daciuk's <code>fsa</code>'s package <code>FSA5</code> format.<DT><A HREF="./morfologik/fsa/FSA5Serializer.html#FSA5Serializer()"><B>FSA5Serializer()</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa"><B>FSABuilder</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>Fast, memory-conservative finite state automaton builder, returning a
+ byte-serialized <A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa"><CODE>ConstantArcSizeFSA</CODE></A> (a tradeoff between construction
+ speed and memory consumption).<DT><A HREF="./morfologik/fsa/FSABuilder.html#FSABuilder()"><B>FSABuilder()</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa">FSABuilder</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSABuilder.html#FSABuilder(int)"><B>FSABuilder(int)</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa">FSABuilder</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa"><B>FSABuilder.InfoEntry</B></A> - Enum in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>Debug and information constants.<DT><A HREF="./morfologik/tools/FSABuildTool.html" title="class in morfologik.tools"><B>FSABuildTool</B></A> - Class in <A HREF="./morfologik/tools/package-summary.html">morfologik.tools</A><DD>Convert from plain text input to a serialized FSA in any of the
+ available <A HREF="./morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools"><CODE>FSABuildTool.Format</CODE></A>s.<DT><A HREF="./morfologik/tools/FSABuildTool.html#FSABuildTool()"><B>FSABuildTool()</B></A> -
+Constructor for class morfologik.tools.<A HREF="./morfologik/tools/FSABuildTool.html" title="class in morfologik.tools">FSABuildTool</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools"><B>FSABuildTool.Format</B></A> - Enum in <A HREF="./morfologik/tools/package-summary.html">morfologik.tools</A><DD>The serialization format to use for the binary output.<DT><A HREF="./morfologik/tools/FSADumpTool.html" title="class in morfologik.tools"><B>FSADumpTool</B></A> - Class in <A HREF="./morfologik/tools/package-summary.html">morfologik.tools</A><DD>This utility will dump the information and contents of a given <A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A>
+ dictionary.<DT><A HREF="./morfologik/tools/FSADumpTool.html#FSADumpTool()"><B>FSADumpTool()</B></A> -
+Constructor for class morfologik.tools.<A HREF="./morfologik/tools/FSADumpTool.html" title="class in morfologik.tools">FSADumpTool</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa"><B>FSAFinalStatesIterator</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>An iterator that traverses the right language of a given node (all sequences
+ reachable from a given node).<DT><A HREF="./morfologik/fsa/FSAFinalStatesIterator.html#FSAFinalStatesIterator(morfologik.fsa.FSA, int)"><B>FSAFinalStatesIterator(FSA, int)</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa">FSAFinalStatesIterator</A>
+<DD>Create an instance of the iterator for a given node.
+<DT><A HREF="./morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa"><B>FSAFlags</B></A> - Enum in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>FSA automaton flags.<DT><A HREF="./morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa"><B>FSAInfo</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>Compute additional information about an FSA: number of arcs, nodes, etc.<DT><A HREF="./morfologik/fsa/FSAInfo.html#FSAInfo(morfologik.fsa.FSA)"><B>FSAInfo(FSA)</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa">FSAInfo</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSAInfo.html#FSAInfo(int, int, int, int)"><B>FSAInfo(int, int, int, int)</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa">FSAInfo</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa"><B>FSASerializer</B></A> - Interface in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>All FSA serializers to binary formats will implement this interface.<DT><A HREF="./morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa"><B>FSATraversal</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>This class implements some common matching and scanning operations on a
+ generic FSA.<DT><A HREF="./morfologik/fsa/FSATraversal.html#FSATraversal(morfologik.fsa.FSA)"><B>FSATraversal(FSA)</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa">FSATraversal</A>
+<DD>Traversals of the given FSA.
+<DT><A HREF="./morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa"><B>FSAUtils</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>Other FSA-related utilities not directly associated with the class hierarchy.<DT><A HREF="./morfologik/fsa/FSAUtils.html#FSAUtils()"><B>FSAUtils()</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa">FSAUtils</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa"><B>FSAUtils.IntIntHolder</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>&nbsp;<DT><A HREF="./morfologik/fsa/FSAUtils.IntIntHolder.html#FSAUtils.IntIntHolder(int, int)"><B>FSAUtils.IntIntHolder(int, int)</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa">FSAUtils.IntIntHolder</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSAUtils.IntIntHolder.html#FSAUtils.IntIntHolder()"><B>FSAUtils.IntIntHolder()</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa">FSAUtils.IntIntHolder</A>
+<DD>&nbsp;
</DL>
<HR>
<A NAME="_G_"><!-- --></A><H2>
<B>G</B></H2>
<DL>
-<DT><A HREF="./morfologik/fsa/FSATraversalHelper.html#getAllSubsequences(int)"><B>getAllSubsequences(int)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa">FSATraversalHelper</A>
-<DD>Returns an <CODE>Iterator</CODE> of all subsequences available from the given
- node to all reachable final states.
-<DT><A HREF="./morfologik/fsa/FSA.html#getAnnotationSeparator()"><B>getAnnotationSeparator()</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Return the annotation separator character, converted to a character
- according to the encoding scheme passed in in the constructor of this
- class.
+<DT><A HREF="./morfologik/fsa/CFSA.html#getArc(int, byte)"><B>getArc(int, byte)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>
+<DT><A HREF="./morfologik/fsa/CFSA2.html#getArc(int, byte)"><B>getArc(int, byte)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#getArc(int, byte)"><B>getArc(int, byte)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>&nbsp;
<DT><A HREF="./morfologik/fsa/FSA.html#getArc(int, byte)"><B>getArc(int, byte)</B></A> -
Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Returns the identifier of an arc leaving <code>node</code> and labeled
- with <code>label</code>.
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#getArc(int, byte)"><B>getArc(int, byte)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
<DD>&nbsp;
-<DT><A HREF="./morfologik/fsa/FSA.html#getArcLabel(int)"><B>getArcLabel(int)</B></A> -
+<DT><A HREF="./morfologik/fsa/FSA5.html#getArc(int, byte)"><B>getArc(int, byte)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>
+<DT><A HREF="./morfologik/fsa/FSA.html#getArcCount(int)"><B>getArcCount(int)</B></A> -
Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
+<DD>Calculates the number of arcs of a given node.
+<DT><A HREF="./morfologik/fsa/CFSA.html#getArcLabel(int)"><B>getArcLabel(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Return the label associated with a given <code>arc</code>.
+<DT><A HREF="./morfologik/fsa/CFSA2.html#getArcLabel(int)"><B>getArcLabel(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
<DD>Return the label associated with a given <code>arc</code>.
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#getArcLabel(int)"><B>getArcLabel(int)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#getArcLabel(int)"><B>getArcLabel(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSA.html#getArcLabel(int)"><B>getArcLabel(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
+<DD>Return the label associated with a given <code>arc</code>.
+<DT><A HREF="./morfologik/fsa/FSA5.html#getArcLabel(int)"><B>getArcLabel(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Return the label associated with a given <code>arc</code>.
<DT><A HREF="./morfologik/stemming/DictionaryLookup.html#getDictionary()"><B>getDictionary()</B></A> -
Method in class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryLookup.html" title="class in morfologik.stemming">DictionaryLookup</A>
<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/CFSA.html#getEndNode(int)"><B>getEndNode(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Return the end node pointed to by a given <code>arc</code>.
+<DT><A HREF="./morfologik/fsa/CFSA2.html#getEndNode(int)"><B>getEndNode(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>Return the end node pointed to by a given <code>arc</code>.
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#getEndNode(int)"><B>getEndNode(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>&nbsp;
<DT><A HREF="./morfologik/fsa/FSA.html#getEndNode(int)"><B>getEndNode(int)</B></A> -
Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
<DD>Return the end node pointed to by a given <code>arc</code>.
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#getEndNode(int)"><B>getEndNode(int)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
-<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSA5.html#getEndNode(int)"><B>getEndNode(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Return the end node pointed to by a given <code>arc</code>.
<DT><A HREF="./morfologik/stemming/Dictionary.html#getExpectedFeaturesName(java.lang.String)"><B>getExpectedFeaturesName(String)</B></A> -
Static method in class morfologik.stemming.<A HREF="./morfologik/stemming/Dictionary.html" title="class in morfologik.stemming">Dictionary</A>
<DD>Returns the expected name of the metadata file, based on the name of the
FSA dictionary file.
-<DT><A HREF="./morfologik/fsa/FSA.html#getFillerCharacter()"><B>getFillerCharacter()</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Return the filler character, converted to a character according to the
- encoding scheme passed in in the constructor of this class.
-<DT><A HREF="./morfologik/fsa/FSATraversalHelper.html#getFinalStatesIterator()"><B>getFinalStatesIterator()</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa">FSATraversalHelper</A>
-<DD>Returns a new iterator for walking along the final states of this FSA.
+<DT><A HREF="./morfologik/fsa/CFSA.html#getFirstArc(int)"><B>getFirstArc(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>
+<DT><A HREF="./morfologik/fsa/CFSA2.html#getFirstArc(int)"><B>getFirstArc(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#getFirstArc(int)"><B>getFirstArc(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>&nbsp;
<DT><A HREF="./morfologik/fsa/FSA.html#getFirstArc(int)"><B>getFirstArc(int)</B></A> -
Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Returns the identifier of the first arc leaving <code>node</code> or 0 if
- the node has no outgoing arcs.
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#getFirstArc(int)"><B>getFirstArc(int)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSA5.html#getFirstArc(int)"><B>getFirstArc(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>
+<DT><A HREF="./morfologik/fsa/CFSA.html#getFlags()"><B>getFlags()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Returns a set of flags for this FSA instance.
+<DT><A HREF="./morfologik/fsa/CFSA2.html#getFlags()"><B>getFlags()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>Returns a set of flags for this FSA instance.
+<DT><A HREF="./morfologik/fsa/CFSA2Serializer.html#getFlags()"><B>getFlags()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A>
+<DD>Return supported flags.
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#getFlags()"><B>getFlags()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
<DD>&nbsp;
<DT><A HREF="./morfologik/fsa/FSA.html#getFlags()"><B>getFlags()</B></A> -
Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
<DD>Returns a set of flags for this FSA instance.
-<DT><A HREF="./morfologik/fsa/FSAHelpers.html#getFlags(int)"><B>getFlags(int)</B></A> -
-Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAHelpers.html" title="class in morfologik.fsa">FSAHelpers</A>
-<DD>Returns flags as an integer for a given version number.
+<DT><A HREF="./morfologik/fsa/FSA5.html#getFlags()"><B>getFlags()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Returns a set of flags for this FSA instance.
+<DT><A HREF="./morfologik/fsa/FSA5Serializer.html#getFlags()"><B>getFlags()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A>
+<DD>Return supported flags.
+<DT><A HREF="./morfologik/fsa/FSASerializer.html#getFlags()"><B>getFlags()</B></A> -
+Method in interface morfologik.fsa.<A HREF="./morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A>
+<DD>Returns the set of flags supported by the serializer (and the output automaton).
<DT><A HREF="./morfologik/stemming/Dictionary.html#getForLanguage(java.lang.String)"><B>getForLanguage(String)</B></A> -
Static method in class morfologik.stemming.<A HREF="./morfologik/stemming/Dictionary.html" title="class in morfologik.stemming">Dictionary</A>
<DD>Return a built-in dictionary for a given ISO language code.
-<DT><A HREF="./morfologik/fsa/FSA.html#getInstance(java.io.File, java.lang.String)"><B>getInstance(File, String)</B></A> -
-Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>This static method will attempt to instantiate an appropriate
- implementation of the FSA for the version found in file given in the
- input argument.
-<DT><A HREF="./morfologik/fsa/FSA.html#getInstance(java.io.InputStream, java.lang.String)"><B>getInstance(InputStream, String)</B></A> -
-Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>This static method will attempt to instantiate an appropriate
- implementation of the FSA for the version found in file given in the
- input argument.
-<DT><A HREF="./morfologik/fsa/FSAMatch.html#getMatchType()"><B>getMatchType()</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A>
-<DD>Return match type.
-<DT><A HREF="./morfologik/fsa/FSAMatch.html#getMismatchIndex()"><B>getMismatchIndex()</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A>
-<DD>Return the index at which a mismatch occurred.
-<DT><A HREF="./morfologik/fsa/FSAMatch.html#getMismatchNode()"><B>getMismatchNode()</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A>
-<DD>Return the node at which mismatch occurred.
-<DT><A HREF="./morfologik/fsa/FSA.html#getNextArc(int, int)"><B>getNextArc(int, int)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Returns the identifier of the next arc after <code>arc</code> and leaving
- <code>node</code>.
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#getNextArc(int, int)"><B>getNextArc(int, int)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
+<DT><A HREF="./morfologik/fsa/FSABuilder.html#getInfo()"><B>getInfo()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa">FSABuilder</A>
+<DD>Return various statistics concerning the FSA and its compilation.
+<DT><A HREF="./morfologik/fsa/CFSA.html#getNextArc(int)"><B>getNextArc(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>
+<DT><A HREF="./morfologik/fsa/CFSA2.html#getNextArc(int)"><B>getNextArc(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#getNextArc(int)"><B>getNextArc(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
<DD>&nbsp;
-<DT><A HREF="./morfologik/fsa/FSA.html#getNumberOfArcs()"><B>getNumberOfArcs()</B></A> -
+<DT><A HREF="./morfologik/fsa/FSA.html#getNextArc(int)"><B>getNextArc(int)</B></A> -
Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Returns the number of arcs in this automaton.
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#getNumberOfArcs()"><B>getNumberOfArcs()</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
-<DD>Returns the number of arcs in this automaton.
-<DT><A HREF="./morfologik/fsa/FSA.html#getNumberOfNodes()"><B>getNumberOfNodes()</B></A> -
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSA5.html#getNextArc(int)"><B>getNextArc(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>
+<DT><A HREF="./morfologik/fsa/CFSA.html#getRightLanguageCount(int)"><B>getRightLanguageCount(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>
+<DT><A HREF="./morfologik/fsa/CFSA2.html#getRightLanguageCount(int)"><B>getRightLanguageCount(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>
+<DT><A HREF="./morfologik/fsa/FSA.html#getRightLanguageCount(int)"><B>getRightLanguageCount(int)</B></A> -
Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Returns the number of nodes in this automaton.
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#getNumberOfNodes()"><B>getNumberOfNodes()</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
-<DD>Returns the number of nodes in this automaton.
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSA5.html#getRightLanguageCount(int)"><B>getRightLanguageCount(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Returns the number encoded at the given node.
+<DT><A HREF="./morfologik/fsa/CFSA.html#getRootNode()"><B>getRootNode()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Returns the start node of this automaton.
+<DT><A HREF="./morfologik/fsa/CFSA2.html#getRootNode()"><B>getRootNode()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#getRootNode()"><B>getRootNode()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>&nbsp;
<DT><A HREF="./morfologik/fsa/FSA.html#getRootNode()"><B>getRootNode()</B></A> -
Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Returns the identifier of the root node of this automaton.
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#getRootNode()"><B>getRootNode()</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSA5.html#getRootNode()"><B>getRootNode()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
<DD>Returns the start node of this automaton.
+<DT><A HREF="./morfologik/fsa/FSA.html#getSequences(int)"><B>getSequences(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
+<DD>Returns an iterator over all binary sequences starting at the given FSA
+ state (node) and ending in final nodes.
+<DT><A HREF="./morfologik/fsa/FSA.html#getSequences()"><B>getSequences()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
+<DD>An alias of calling <A HREF="./morfologik/fsa/FSA.html#iterator()"><CODE>FSA.iterator()</CODE></A> directly (<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> is also
+ <CODE>Iterable</CODE>).
+<DT><A HREF="./morfologik/tools/FSABuildTool.Format.html#getSerializer()"><B>getSerializer()</B></A> -
+Method in enum morfologik.tools.<A HREF="./morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A>
+<DD>&nbsp;
<DT><A HREF="./morfologik/stemming/WordData.html#getStem()"><B>getStem()</B></A> -
Method in class morfologik.stemming.<A HREF="./morfologik/stemming/WordData.html" title="class in morfologik.stemming">WordData</A>
<DD>&nbsp;
@@ -336,16 +560,6 @@ Method in class morfologik.stemming.<A HREF="./morfologik/stemming/WordData.html
<DT><A HREF="./morfologik/stemming/WordData.html#getTagBytes(java.nio.ByteBuffer)"><B>getTagBytes(ByteBuffer)</B></A> -
Method in class morfologik.stemming.<A HREF="./morfologik/stemming/WordData.html" title="class in morfologik.stemming">WordData</A>
<DD>Copy the tag's binary data (no charset decoding) to a custom byte buffer.
-<DT><A HREF="./morfologik/fsa/FSA.html#getTraversalHelper()"><B>getTraversalHelper()</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Returns an object which can be used to walk the edges of this finite
- state automaton and match arbitrary sequences against its states.
-<DT><A HREF="./morfologik/fsa/FSA.html#getVersion()"><B>getVersion()</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Returns the version number of the binary representation of this FSA.
-<DT><A HREF="./morfologik/fsa/FSAHelpers.html#getVersion(int)"><B>getVersion(int)</B></A> -
-Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAHelpers.html" title="class in morfologik.fsa">FSAHelpers</A>
-<DD>Returns a version number for a set of flags.
<DT><A HREF="./morfologik/stemming/WordData.html#getWord()"><B>getWord()</B></A> -
Method in class morfologik.stemming.<A HREF="./morfologik/stemming/WordData.html" title="class in morfologik.stemming">WordData</A>
<DD>&nbsp;
@@ -353,15 +567,18 @@ Method in class morfologik.stemming.<A HREF="./morfologik/stemming/WordData.html
Method in class morfologik.stemming.<A HREF="./morfologik/stemming/WordData.html" title="class in morfologik.stemming">WordData</A>
<DD>Copy the inflected word's binary data (no charset decoding) to a custom
byte buffer.
-<DT><A HREF="./morfologik/tools/DumpTool.html#go(org.apache.commons.cli.CommandLine)"><B>go(CommandLine)</B></A> -
-Method in class morfologik.tools.<A HREF="./morfologik/tools/DumpTool.html" title="class in morfologik.tools">DumpTool</A>
+<DT><A HREF="./morfologik/tools/FSABuildTool.html#go(org.apache.commons.cli.CommandLine)"><B>go(CommandLine)</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/FSABuildTool.html" title="class in morfologik.tools">FSABuildTool</A>
<DD>Command line entry point after parsing arguments.
-<DT><A HREF="./morfologik/fsa/FSA.html#gotoLength"><B>gotoLength</B></A> -
-Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Size of transition's destination node "address".
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#gotoOffset"><B>gotoOffset</B></A> -
-Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
-<DD>An offset in the arc structure, where the address field begins.
+<DT><A HREF="./morfologik/tools/FSADumpTool.html#go(org.apache.commons.cli.CommandLine)"><B>go(CommandLine)</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/FSADumpTool.html" title="class in morfologik.tools">FSADumpTool</A>
+<DD>Command line entry point after parsing arguments.
+<DT><A HREF="./morfologik/fsa/CFSA.html#gtl"><B>gtl</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Number of bytes each address takes in full, expanded form (goto length).
+<DT><A HREF="./morfologik/fsa/FSA5.html#gtl"><B>gtl</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Number of bytes each address takes in full, expanded form (goto length).
</DL>
<HR>
<A NAME="_H_"><!-- --></A><H2>
@@ -381,53 +598,165 @@ Method in class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryIte
<A NAME="_I_"><!-- --></A><H2>
<B>I</B></H2>
<DL>
+<DT><A HREF="./morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools"><B>IMessageLogger</B></A> - Interface in <A HREF="./morfologik/tools/package-summary.html">morfologik.tools</A><DD>&nbsp;<DT><A HREF="./morfologik/fsa/MatchResult.html#index"><B>index</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A>
+<DD>Input sequence's index, interpretation depends on <A HREF="./morfologik/fsa/MatchResult.html#kind"><CODE>MatchResult.kind</CODE></A>.
+<DT><A HREF="./morfologik/tools/MorphEncoder.html#infixEncode(byte[], byte[], byte[])"><B>infixEncode(byte[], byte[], byte[])</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/MorphEncoder.html" title="class in morfologik.tools">MorphEncoder</A>
+<DD>This method converts wordform, wordLemma and the tag to the form:
+
+ inflected_form + MLKending + tags
+
+
+ where '+' is a separator, M is the position of characters to be deleted
+ towards the beginning of the inflected form ("A" means from the
+ beginning, "B" from the second character, "C" - from the third one, and
+ so on), L is the number of characters to be deleted from the position
+ specified by M ("A" means none, "B" means one, "C" - 2, etc.), K is a
+ character that specifies how many characters should be deleted from the
+ end of the inflected form to produce the lexeme by concatenating the
+ stripped string with the ending ("A" means none, "B' - 1, "C" - 2, and so
+ on).
+<DT><A HREF="./morfologik/tools/MorphEncoder.html#infixEncodeUTF8(java.lang.String, java.lang.String, java.lang.String)"><B>infixEncodeUTF8(String, String, String)</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/MorphEncoder.html" title="class in morfologik.tools">MorphEncoder</A>
+<DD>A UTF-8 variant of <A HREF="./morfologik/tools/MorphEncoder.html#infixEncode(byte[], byte[], byte[])"><CODE>MorphEncoder.infixEncode(byte[], byte[], byte[])</CODE></A>.
<DT><A HREF="./morfologik/tools/InflectionFramesTool.html#inflectionFrames()"><B>inflectionFrames()</B></A> -
Method in class morfologik.tools.<A HREF="./morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools">InflectionFramesTool</A>
<DD>&nbsp;
<DT><A HREF="./morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools"><B>InflectionFramesTool</B></A> - Class in <A HREF="./morfologik/tools/package-summary.html">morfologik.tools</A><DD>Calculate inflection frames from the Polish dictionary.<DT><A HREF="./morfologik/tools/InflectionFramesTool.html#InflectionFramesTool()"><B>InflectionFramesTool()</B></A> -
Constructor for class morfologik.tools.<A HREF="./morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools">InflectionFramesTool</A>
<DD>&nbsp;
-<DT><A HREF="./morfologik/tools/DumpTool.html#initializeOptions(org.apache.commons.cli.Options)"><B>initializeOptions(Options)</B></A> -
-Method in class morfologik.tools.<A HREF="./morfologik/tools/DumpTool.html" title="class in morfologik.tools">DumpTool</A>
+<DT><A HREF="./morfologik/tools/FSABuildTool.html#initializeOptions(org.apache.commons.cli.Options)"><B>initializeOptions(Options)</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/FSABuildTool.html" title="class in morfologik.tools">FSABuildTool</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/tools/FSADumpTool.html#initializeOptions(org.apache.commons.cli.Options)"><B>initializeOptions(Options)</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/FSADumpTool.html" title="class in morfologik.tools">FSADumpTool</A>
<DD>Command line options for the tool.
+<DT><A HREF="./morfologik/fsa/CFSA.html#isArcFinal(int)"><B>isArcFinal(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Returns <code>true</code> if the destination node at the end of this
+ <code>arc</code> corresponds to an input sequence created when building
+ this automaton.
+<DT><A HREF="./morfologik/fsa/CFSA2.html#isArcFinal(int)"><B>isArcFinal(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>Returns <code>true</code> if the destination node at the end of this
+ <code>arc</code> corresponds to an input sequence created when building
+ this automaton.
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#isArcFinal(int)"><B>isArcFinal(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>&nbsp;
<DT><A HREF="./morfologik/fsa/FSA.html#isArcFinal(int)"><B>isArcFinal(int)</B></A> -
Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
<DD>Returns <code>true</code> if the destination node at the end of this
<code>arc</code> corresponds to an input sequence created when building
this automaton.
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#isArcFinal(int)"><B>isArcFinal(int)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
+<DT><A HREF="./morfologik/fsa/FSA5.html#isArcFinal(int)"><B>isArcFinal(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Returns <code>true</code> if the destination node at the end of this
+ <code>arc</code> corresponds to an input sequence created when building
+ this automaton.
+<DT><A HREF="./morfologik/fsa/CFSA.html#isArcLast(int)"><B>isArcLast(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Returns <code>true</code> if this arc has <code>NEXT</code> bit set.
+<DT><A HREF="./morfologik/fsa/CFSA2.html#isArcLast(int)"><B>isArcLast(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>Returns <code>true</code> if this arc has <code>NEXT</code> bit set.
+<DT><A HREF="./morfologik/fsa/FSA5.html#isArcLast(int)"><B>isArcLast(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Returns <code>true</code> if this arc has <code>LAST</code> bit set.
+<DT><A HREF="./morfologik/fsa/CFSA.html#isArcTerminal(int)"><B>isArcTerminal(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Returns <code>true</code> if this <code>arc</code> does not have a
+ terminating node (@link <A HREF="./morfologik/fsa/FSA.html#getEndNode(int)"><CODE>FSA.getEndNode(int)</CODE></A> will throw an
+ exception).
+<DT><A HREF="./morfologik/fsa/CFSA2.html#isArcTerminal(int)"><B>isArcTerminal(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>Returns <code>true</code> if this <code>arc</code> does not have a
+ terminating node (@link <A HREF="./morfologik/fsa/FSA.html#getEndNode(int)"><CODE>FSA.getEndNode(int)</CODE></A> will throw an
+ exception).
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#isArcTerminal(int)"><B>isArcTerminal(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
<DD>&nbsp;
<DT><A HREF="./morfologik/fsa/FSA.html#isArcTerminal(int)"><B>isArcTerminal(int)</B></A> -
Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
<DD>Returns <code>true</code> if this <code>arc</code> does not have a
- terminating node.
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#isArcTerminal(int)"><B>isArcTerminal(int)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
+ terminating node (@link <A HREF="./morfologik/fsa/FSA.html#getEndNode(int)"><CODE>FSA.getEndNode(int)</CODE></A> will throw an
+ exception).
+<DT><A HREF="./morfologik/fsa/FSA5.html#isArcTerminal(int)"><B>isArcTerminal(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Returns <code>true</code> if this <code>arc</code> does not have a
+ terminating node (@link <A HREF="./morfologik/fsa/FSA.html#getEndNode(int)"><CODE>FSA.getEndNode(int)</CODE></A> will throw an
+ exception).
+<DT><A HREF="./morfologik/fsa/CFSA.html#isLabelCompressed(int)"><B>isLabelCompressed(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Returns <code>true</code> if the label is compressed inside flags byte.
+<DT><A HREF="./morfologik/fsa/CFSA.html#isNextSet(int)"><B>isNextSet(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/CFSA2.html#isNextSet(int)"><B>isNextSet(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSA5.html#isNextSet(int)"><B>isNextSet(int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
<DD>&nbsp;
<DT><A HREF="./morfologik/fsa/FSAFlags.html#isSet(int, morfologik.fsa.FSAFlags)"><B>isSet(int, FSAFlags)</B></A> -
Static method in enum morfologik.fsa.<A HREF="./morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>
-<DD>Returns <code>true</code> if the corresponding flag is set in the
- bit set.
+<DD>Returns <code>true</code> if the corresponding flag is set in the bit set.
<DT><A HREF="./morfologik/stemming/IStemmer.html" title="interface in morfologik.stemming"><B>IStemmer</B></A> - Interface in <A HREF="./morfologik/stemming/package-summary.html">morfologik.stemming</A><DD>A generic &quot;stemmer&quot; interface in Morfologik.<DT><A HREF="./morfologik/fsa/FSA.html#iterator()"><B>iterator()</B></A> -
Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
<DD>Returns an iterator over all binary sequences starting from the initial
- FSA state and ending in final nodes.
+ FSA state (node) and ending in final nodes.
<DT><A HREF="./morfologik/stemming/DictionaryLookup.html#iterator()"><B>iterator()</B></A> -
Method in class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryLookup.html" title="class in morfologik.stemming">DictionaryLookup</A>
-<DD>Return an iterator over all <A HREF="./morfologik/stemming/WordData.html" title="class in morfologik.stemming"><CODE>WordData</CODE></A> entries available in
- the embedded <A HREF="./morfologik/stemming/Dictionary.html" title="class in morfologik.stemming"><CODE>Dictionary</CODE></A>.
+<DD>Return an iterator over all <A HREF="./morfologik/stemming/WordData.html" title="class in morfologik.stemming"><CODE>WordData</CODE></A> entries available in the
+ embedded <A HREF="./morfologik/stemming/Dictionary.html" title="class in morfologik.stemming"><CODE>Dictionary</CODE></A>.
<DT><A HREF="./morfologik/stemming/PolishStemmer.html#iterator()"><B>iterator()</B></A> -
Method in class morfologik.stemming.<A HREF="./morfologik/stemming/PolishStemmer.html" title="class in morfologik.stemming">PolishStemmer</A>
<DD>Iterates over all dictionary forms stored in this stemmer.
</DL>
<HR>
+<A NAME="_K_"><!-- --></A><H2>
+<B>K</B></H2>
+<DL>
+<DT><A HREF="./morfologik/fsa/MatchResult.html#kind"><B>kind</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A>
+<DD>One of the match kind constants defined in this class.
+</DL>
+<HR>
<A NAME="_L_"><!-- --></A><H2>
<B>L</B></H2>
<DL>
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#LABEL_OFFSET"><B>LABEL_OFFSET</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>Offset of the label field inside an arc.
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#LABEL_SIZE"><B>LABEL_SIZE</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>Size of the label field (constant for the builder).
+<DT><A HREF="./morfologik/fsa/CFSA.html#labelMapping"><B>labelMapping</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Label mapping for arcs of type (1) (see class documentation).
+<DT><A HREF="./morfologik/fsa/CFSA2.html#labelMapping"><B>labelMapping</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>Label mapping for M-indexed labels.
<DT><A HREF="./morfologik/tools/Launcher.html" title="class in morfologik.tools"><B>Launcher</B></A> - Class in <A HREF="./morfologik/tools/package-summary.html">morfologik.tools</A><DD>A launcher for other command-line tools.<DT><A HREF="./morfologik/tools/Launcher.html#Launcher()"><B>Launcher()</B></A> -
Constructor for class morfologik.tools.<A HREF="./morfologik/tools/Launcher.html" title="class in morfologik.tools">Launcher</A>
<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSABuilder.html#LEXICAL_ORDERING"><B>LEXICAL_ORDERING</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa">FSABuilder</A>
+<DD>Comparator comparing full byte arrays consistently with
+ <A HREF="./morfologik/fsa/FSABuilder.html#compare(byte[], int, int, byte[], int, int)"><CODE>FSABuilder.compare(byte[], int, int, byte[], int, int)</CODE></A>.
+<DT><A HREF="./morfologik/tools/IMessageLogger.html#log(java.lang.String)"><B>log(String)</B></A> -
+Method in interface morfologik.tools.<A HREF="./morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A>
+<DD>Log progress to the console.
+<DT><A HREF="./morfologik/tools/IMessageLogger.html#log(java.lang.String, java.lang.Object)"><B>log(String, Object)</B></A> -
+Method in interface morfologik.tools.<A HREF="./morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A>
+<DD>Log a two-part message.
+<DT><A HREF="./morfologik/tools/WriterMessageLogger.html#log(java.lang.String)"><B>log(String)</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools">WriterMessageLogger</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/tools/WriterMessageLogger.html#log(java.lang.String, java.lang.Object)"><B>log(String, Object)</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools">WriterMessageLogger</A>
+<DD>&nbsp;
<DT><A HREF="./morfologik/stemming/DictionaryLookup.html#lookup(java.lang.CharSequence)"><B>lookup(CharSequence)</B></A> -
Method in class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryLookup.html" title="class in morfologik.stemming">DictionaryLookup</A>
<DD>Searches the automaton for a symbol sequence equal to <code>word</code>,
@@ -443,8 +772,11 @@ Method in class morfologik.stemming.<A HREF="./morfologik/stemming/PolishStemmer
<A NAME="_M_"><!-- --></A><H2>
<B>M</B></H2>
<DL>
-<DT><A HREF="./morfologik/tools/DumpTool.html#main(java.lang.String[])"><B>main(String[])</B></A> -
-Static method in class morfologik.tools.<A HREF="./morfologik/tools/DumpTool.html" title="class in morfologik.tools">DumpTool</A>
+<DT><A HREF="./morfologik/tools/FSABuildTool.html#main(java.lang.String[])"><B>main(String[])</B></A> -
+Static method in class morfologik.tools.<A HREF="./morfologik/tools/FSABuildTool.html" title="class in morfologik.tools">FSABuildTool</A>
+<DD>Command line entry point.
+<DT><A HREF="./morfologik/tools/FSADumpTool.html#main(java.lang.String[])"><B>main(String[])</B></A> -
+Static method in class morfologik.tools.<A HREF="./morfologik/tools/FSADumpTool.html" title="class in morfologik.tools">FSADumpTool</A>
<DD>Command line entry point.
<DT><A HREF="./morfologik/tools/InflectionFramesTool.html#main(java.lang.String[])"><B>main(String[])</B></A> -
Static method in class morfologik.tools.<A HREF="./morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools">InflectionFramesTool</A>
@@ -452,20 +784,23 @@ Static method in class morfologik.tools.<A HREF="./morfologik/tools/InflectionFr
<DT><A HREF="./morfologik/tools/Launcher.html#main(java.lang.String[])"><B>main(String[])</B></A> -
Static method in class morfologik.tools.<A HREF="./morfologik/tools/Launcher.html" title="class in morfologik.tools">Launcher</A>
<DD>Command line entry point.
-<DT><A HREF="./morfologik/fsa/FSATraversalHelper.html#matchSequence(morfologik.fsa.FSAMatch, byte[], int, int, int)"><B>matchSequence(FSAMatch, byte[], int, int, int)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa">FSATraversalHelper</A>
-<DD>Same as <A HREF="./morfologik/fsa/FSATraversalHelper.html#matchSequence(byte[], int, int, int)"><CODE>FSATraversalHelper.matchSequence(byte[], int, int, int)</CODE></A>, but allows passing
- a reusable <A HREF="./morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><CODE>FSAMatch</CODE></A> object so that no intermediate garbage is
+<DT><A HREF="./morfologik/fsa/FSATraversal.html#match(morfologik.fsa.MatchResult, byte[], int, int, int)"><B>match(MatchResult, byte[], int, int, int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa">FSATraversal</A>
+<DD>Same as <A HREF="./morfologik/fsa/FSATraversal.html#match(byte[], int, int, int)"><CODE>FSATraversal.match(byte[], int, int, int)</CODE></A>, but allows passing
+ a reusable <A HREF="./morfologik/fsa/MatchResult.html" title="class in morfologik.fsa"><CODE>MatchResult</CODE></A> object so that no intermediate garbage is
produced.
-<DT><A HREF="./morfologik/fsa/FSATraversalHelper.html#matchSequence(byte[], int, int, int)"><B>matchSequence(byte[], int, int, int)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa">FSATraversalHelper</A>
+<DT><A HREF="./morfologik/fsa/FSATraversal.html#match(byte[], int, int, int)"><B>match(byte[], int, int, int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa">FSATraversal</A>
<DD>Finds a matching path in the dictionary for a given sequence of labels
from <code>sequence</code> and starting at node <code>node</code>.
-<DT><A HREF="./morfologik/fsa/FSATraversalHelper.html#matchSequence(byte[], int)"><B>matchSequence(byte[], int)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa">FSATraversalHelper</A>
+<DT><A HREF="./morfologik/fsa/FSATraversal.html#match(byte[], int)"><B>match(byte[], int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa">FSATraversal</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSATraversal.html#match(byte[])"><B>match(byte[])</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa">FSATraversal</A>
<DD>&nbsp;
-<DT><A HREF="./morfologik/fsa/FSATraversalHelper.html#matchSequence(byte[])"><B>matchSequence(byte[])</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa">FSATraversalHelper</A>
+<DT><A HREF="./morfologik/fsa/MatchResult.html" title="class in morfologik.fsa"><B>MatchResult</B></A> - Class in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>A matching result returned from <A HREF="./morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa"><CODE>FSATraversal</CODE></A>.<DT><A HREF="./morfologik/fsa/MatchResult.html#MatchResult()"><B>MatchResult()</B></A> -
+Constructor for class morfologik.fsa.<A HREF="./morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A>
<DD>&nbsp;
<DT><A HREF="./morfologik/stemming/Dictionary.html#metadata"><B>metadata</B></A> -
Variable in class morfologik.stemming.<A HREF="./morfologik/stemming/Dictionary.html" title="class in morfologik.stemming">Dictionary</A>
@@ -476,7 +811,13 @@ Variable in class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryM
<DT><A HREF="./morfologik/stemming/Dictionary.html#METADATA_FILE_EXTENSION"><B>METADATA_FILE_EXTENSION</B></A> -
Static variable in class morfologik.stemming.<A HREF="./morfologik/stemming/Dictionary.html" title="class in morfologik.stemming">Dictionary</A>
<DD>Expected metadata file extension.
-<DT><A HREF="./morfologik/fsa/package-summary.html"><B>morfologik.fsa</B></A> - package morfologik.fsa<DD>&nbsp;<DT><A HREF="./morfologik/stemming/package-summary.html"><B>morfologik.stemming</B></A> - package morfologik.stemming<DD>&nbsp;<DT><A HREF="./morfologik/tools/package-summary.html"><B>morfologik.tools</B></A> - package morfologik.tools<DD>&nbsp;<DT><A HREF="./morfologik/util/package-summary.html"><B>morfologik.util</B></A> - package morfologik.util<DD>&nbsp;</DL>
+<DT><A HREF="./morfologik/fsa/package-summary.html"><B>morfologik.fsa</B></A> - package morfologik.fsa<DD>&nbsp;<DT><A HREF="./morfologik/stemming/package-summary.html"><B>morfologik.stemming</B></A> - package morfologik.stemming<DD>&nbsp;<DT><A HREF="./morfologik/tools/package-summary.html"><B>morfologik.tools</B></A> - package morfologik.tools<DD>&nbsp;<DT><A HREF="./morfologik/util/package-summary.html"><B>morfologik.util</B></A> - package morfologik.util<DD>&nbsp;<DT><A HREF="./morfologik/tools/MorphEncoder.html" title="class in morfologik.tools"><B>MorphEncoder</B></A> - Class in <A HREF="./morfologik/tools/package-summary.html">morfologik.tools</A><DD>A class that converts tabular data to fsa morphological format.<DT><A HREF="./morfologik/tools/MorphEncoder.html#MorphEncoder()"><B>MorphEncoder()</B></A> -
+Constructor for class morfologik.tools.<A HREF="./morfologik/tools/MorphEncoder.html" title="class in morfologik.tools">MorphEncoder</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/tools/MorphEncoder.html#MorphEncoder(byte)"><B>MorphEncoder(byte)</B></A> -
+Constructor for class morfologik.tools.<A HREF="./morfologik/tools/MorphEncoder.html" title="class in morfologik.tools">MorphEncoder</A>
+<DD>&nbsp;
+</DL>
<HR>
<A NAME="_N_"><!-- --></A><H2>
<B>N</B></H2>
@@ -487,6 +828,23 @@ Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAFinalStatesIterator.
<DT><A HREF="./morfologik/stemming/DictionaryIterator.html#next()"><B>next()</B></A> -
Method in class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryIterator.html" title="class in morfologik.stemming">DictionaryIterator</A>
<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/MatchResult.html#NO_MATCH"><B>NO_MATCH</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A>
+<DD>The automaton has no match for the input sequence.
+<DT><A HREF="./morfologik/fsa/MatchResult.html#node"><B>node</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A>
+<DD>Automaton node, interpretation depends on the <A HREF="./morfologik/fsa/MatchResult.html#kind"><CODE>MatchResult.kind</CODE></A>.
+<DT><A HREF="./morfologik/fsa/FSAInfo.html#nodeCount"><B>nodeCount</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa">FSAInfo</A>
+<DD>Number of nodes in the automaton.
+<DT><A HREF="./morfologik/fsa/CFSA.html#nodeDataLength"><B>nodeDataLength</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>The length of the node header structure (if the automaton was compiled with
+ <code>NUMBERS</code> option).
+<DT><A HREF="./morfologik/fsa/FSA5.html#nodeDataLength"><B>nodeDataLength</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>The length of the node header structure (if the automaton was compiled with
+ <code>NUMBERS</code> option).
</DL>
<HR>
<A NAME="_O_"><!-- --></A><H2>
@@ -500,18 +858,56 @@ Static method in class morfologik.util.<A HREF="./morfologik/util/ResourceUtils.
<A NAME="_P_"><!-- --></A><H2>
<B>P</B></H2>
<DL>
-<DT><A HREF="./morfologik/util/PerformanceTimer.html" title="class in morfologik.util"><B>PerformanceTimer</B></A> - Class in <A HREF="./morfologik/util/package-summary.html">morfologik.util</A><DD>Simple, simple performance checking.<DT><A HREF="./morfologik/util/PerformanceTimer.html#PerformanceTimer()"><B>PerformanceTimer()</B></A> -
-Constructor for class morfologik.util.<A HREF="./morfologik/util/PerformanceTimer.html" title="class in morfologik.util">PerformanceTimer</A>
+<DT><A HREF="./morfologik/fsa/FSATraversal.html#perfectHash(byte[], int, int, int)"><B>perfectHash(byte[], int, int, int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa">FSATraversal</A>
+<DD>Calculate perfect hash for a given input sequence of bytes.
+<DT><A HREF="./morfologik/fsa/FSATraversal.html#perfectHash(byte[])"><B>perfectHash(byte[])</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa">FSATraversal</A>
<DD>&nbsp;
<DT><A HREF="./morfologik/stemming/PolishStemmer.html" title="class in morfologik.stemming"><B>PolishStemmer</B></A> - Class in <A HREF="./morfologik/stemming/package-summary.html">morfologik.stemming</A><DD>A dictionary-based stemmer for the Polish language.<DT><A HREF="./morfologik/stemming/PolishStemmer.html#PolishStemmer()"><B>PolishStemmer()</B></A> -
Constructor for class morfologik.stemming.<A HREF="./morfologik/stemming/PolishStemmer.html" title="class in morfologik.stemming">PolishStemmer</A>
<DD>This constructor is initialized with a built-in dictionary or fails with
a runtime exception if the dictionary is not available.
+<DT><A HREF="./morfologik/tools/MorphEncoder.html#prefixEncode(byte[], byte[], byte[])"><B>prefixEncode(byte[], byte[], byte[])</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/MorphEncoder.html" title="class in morfologik.tools">MorphEncoder</A>
+<DD>This method converts wordform, wordLemma and the tag to the form:
+
+
+
+ inflected_form + LKending + tags
+
+
+ where '+' is a separator, L is the number of characters to be deleted
+ from the beginning of the word ("A" means none, "B" means one, "C" - 2,
+ etc.), K is a character that specifies how many characters should be
+ deleted from the end of the inflected form to produce the lexeme by
+ concatenating the stripped string with the ending ("A" means none,
+ "B' - 1, "C" - 2, and so on).
+<DT><A HREF="./morfologik/tools/MorphEncoder.html#prefixEncodeUTF8(java.lang.String, java.lang.String, java.lang.String)"><B>prefixEncodeUTF8(String, String, String)</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/MorphEncoder.html" title="class in morfologik.tools">MorphEncoder</A>
+<DD>A UTF-8 variant of <A HREF="./morfologik/tools/MorphEncoder.html#prefixEncode(byte[], byte[], byte[])"><CODE>MorphEncoder.prefixEncode(byte[], byte[], byte[])</CODE></A> This
+ method converts wordform, wordLemma and the tag to the form:
+
+ inflected_form + LKending + tags
+
+
+ where '+' is a separator, L is the number of characters to be deleted
+ from the beginning of the word ("A" means none, "B" means one, "C" - 2,
+ etc.), K is a character that specifies how many characters should be
+ deleted from the end of the inflected form to produce the lexeme by
+ concatenating the stripped string with the ending ("A" means none,
+ "B' - 1, "C" - 2, and so on).
+<DT><A HREF="./morfologik/tools/FSABuildTool.html#printUsage()"><B>printUsage()</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/FSABuildTool.html" title="class in morfologik.tools">FSABuildTool</A>
+<DD>&nbsp;
</DL>
<HR>
<A NAME="_R_"><!-- --></A><H2>
<B>R</B></H2>
<DL>
+<DT><A HREF="./morfologik/fsa/FSA.html#read(java.io.InputStream)"><B>read(InputStream)</B></A> -
+Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
+<DD>A factory for reading automata in any of the supported versions.
<DT><A HREF="./morfologik/stemming/Dictionary.html#read(java.io.File)"><B>read(File)</B></A> -
Static method in class morfologik.stemming.<A HREF="./morfologik/stemming/Dictionary.html" title="class in morfologik.stemming">Dictionary</A>
<DD>Attempts to load a dictionary using the path to the FSA file and the
@@ -525,15 +921,25 @@ Static method in class morfologik.stemming.<A HREF="./morfologik/stemming/Dictio
Static method in class morfologik.stemming.<A HREF="./morfologik/stemming/Dictionary.html" title="class in morfologik.stemming">Dictionary</A>
<DD>Attempts to load a dictionary from opened streams of FSA dictionary data
and associated metadata.
-<DT><A HREF="./morfologik/fsa/FSA.html#readFully(java.io.InputStream)"><B>readFully(InputStream)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Reads all bytes from an input stream.
-<DT><A HREF="./morfologik/fsa/FSA.html#readHeader(java.io.DataInput, long)"><B>readHeader(DataInput, long)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Reads a FSA header from a stream.
-<DT><A HREF="./morfologik/fsa/FSAVer5Impl.html#readHeader(java.io.DataInput, long)"><B>readHeader(DataInput, long)</B></A> -
-Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A>
-<DD>Reads a FSA header from a stream.
+<DT><A HREF="./morfologik/util/FileUtils.html#readByte(java.io.InputStream)"><B>readByte(InputStream)</B></A> -
+Static method in class morfologik.util.<A HREF="./morfologik/util/FileUtils.html" title="class in morfologik.util">FileUtils</A>
+<DD>Read exactly one byte from the input stream.
+<DT><A HREF="./morfologik/util/FileUtils.html#readFully(java.io.InputStream)"><B>readFully(InputStream)</B></A> -
+Static method in class morfologik.util.<A HREF="./morfologik/util/FileUtils.html" title="class in morfologik.util">FileUtils</A>
+<DD>Reads all bytes from an input stream (until EOF).
+<DT><A HREF="./morfologik/util/FileUtils.html#readFully(java.io.InputStream, byte[])"><B>readFully(InputStream, byte[])</B></A> -
+Static method in class morfologik.util.<A HREF="./morfologik/util/FileUtils.html" title="class in morfologik.util">FileUtils</A>
+<DD>Read enough bytes to fill <code>array</code> If there are not enough
+ bytes, throw an exception.
+<DT><A HREF="./morfologik/util/FileUtils.html#readInt(java.io.InputStream)"><B>readInt(InputStream)</B></A> -
+Static method in class morfologik.util.<A HREF="./morfologik/util/FileUtils.html" title="class in morfologik.util">FileUtils</A>
+<DD>Read exactly 4 bytes from the input stream.
+<DT><A HREF="./morfologik/util/FileUtils.html#readShort(java.io.InputStream)"><B>readShort(InputStream)</B></A> -
+Static method in class morfologik.util.<A HREF="./morfologik/util/FileUtils.html" title="class in morfologik.util">FileUtils</A>
+<DD>Read exactly 2 bytes from the input stream.
+<DT><A HREF="./morfologik/util/Arrays.html#referenceEquals(java.lang.Object[], int, java.lang.Object[], int, int)"><B>referenceEquals(Object[], int, Object[], int, int)</B></A> -
+Static method in class morfologik.util.<A HREF="./morfologik/util/Arrays.html" title="class in morfologik.util">Arrays</A>
+<DD>Compare two lists of objects for reference-equality.
<DT><A HREF="./morfologik/fsa/FSAFinalStatesIterator.html#remove()"><B>remove()</B></A> -
Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa">FSAFinalStatesIterator</A>
<DD>Not implemented in this iterator.
@@ -543,10 +949,12 @@ Method in class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryIte
<DT><A HREF="./morfologik/util/ResourceUtils.html" title="class in morfologik.util"><B>ResourceUtils</B></A> - Class in <A HREF="./morfologik/util/package-summary.html">morfologik.util</A><DD>Resource management utilities.<DT><A HREF="./morfologik/fsa/FSAFinalStatesIterator.html#restartFrom(int)"><B>restartFrom(int)</B></A> -
Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa">FSAFinalStatesIterator</A>
<DD>Restart walking from <code>node</code>.
-<DT><A HREF="./morfologik/util/PerformanceTimer.html#run(java.util.concurrent.Callable, int, int)"><B>run(Callable&lt;Void&gt;, int, int)</B></A> -
-Static method in class morfologik.util.<A HREF="./morfologik/util/PerformanceTimer.html" title="class in morfologik.util">PerformanceTimer</A>
-<DD>Run the task with a given number of warm-up rounds and the given number
- of cycles.
+<DT><A HREF="./morfologik/fsa/FSAUtils.html#rightLanguage(morfologik.fsa.FSA, int)"><B>rightLanguage(FSA, int)</B></A> -
+Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa">FSAUtils</A>
+<DD>All byte sequences generated as the right language of <code>state</code>.
+<DT><A HREF="./morfologik/fsa/FSAUtils.html#rightLanguageForAllStates(morfologik.fsa.FSA)"><B>rightLanguageForAllStates(FSA)</B></A> -
+Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa">FSAUtils</A>
+<DD>Calculate the size of right language for each state in an FSA.
</DL>
<HR>
<A NAME="_S_"><!-- --></A><H2>
@@ -555,14 +963,81 @@ Static method in class morfologik.util.<A HREF="./morfologik/util/PerformanceTim
<DT><A HREF="./morfologik/stemming/DictionaryMetadata.html#separator"><B>separator</B></A> -
Variable in class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryMetadata.html" title="class in morfologik.stemming">DictionaryMetadata</A>
<DD>A separator character between fields (stem, lemma, form).
-</DL>
+<DT><A HREF="./morfologik/fsa/MatchResult.html#SEQUENCE_IS_A_PREFIX"><B>SEQUENCE_IS_A_PREFIX</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A>
+<DD>The sequence is a prefix of at least one sequence in the automaton.
+<DT><A HREF="./morfologik/fsa/CFSA2Serializer.html#serialize(morfologik.fsa.FSA, T)"><B>serialize(FSA, T)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A>
+<DD>Serializes any <A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> to <A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><CODE>CFSA2</CODE></A> stream.
+<DT><A HREF="./morfologik/fsa/FSA5Serializer.html#serialize(morfologik.fsa.FSA, T)"><B>serialize(FSA, T)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A>
+<DD>Serialize root state <code>s</code> to an output stream in
+ <code>FSA5</code> format.
+<DT><A HREF="./morfologik/fsa/FSASerializer.html#serialize(morfologik.fsa.FSA, T)"><B>serialize(FSA, T)</B></A> -
+Method in interface morfologik.fsa.<A HREF="./morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A>
+<DD>Serialize a finite state automaton to an output stream.
+<DT><A HREF="./morfologik/fsa/FSAInfo.html#size"><B>size</B></A> -
+Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa">FSAInfo</A>
+<DD>Arcs size (in serialized form).
+<DT><A HREF="./morfologik/tools/MorphEncoder.html#standardEncode(byte[], byte[], byte[])"><B>standardEncode(byte[], byte[], byte[])</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/MorphEncoder.html" title="class in morfologik.tools">MorphEncoder</A>
+<DD>This method converts the wordForm, wordLemma and tag to the form:
+
+
+ wordForm + Kending + tags
+
+
+ where '+' is a separator, K is a character that specifies how many
+ characters should be deleted from the end of the inflected form to
+ produce the lexeme by concatenating the stripped string with the ending.
+<DT><A HREF="./morfologik/tools/MorphEncoder.html#standardEncodeUTF8(java.lang.String, java.lang.String, java.lang.String)"><B>standardEncodeUTF8(String, String, String)</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/MorphEncoder.html" title="class in morfologik.tools">MorphEncoder</A>
+<DD>A UTF-8 variant of <A HREF="./morfologik/tools/MorphEncoder.html#standardEncode(byte[], byte[], byte[])"><CODE>MorphEncoder.standardEncode(byte[], byte[], byte[])</CODE></A> This
+ method converts the wordForm, wordLemma and tag to the form:
+
+
+ wordForm + Kending + tags
+
+
+ where '+' is a separator, K is a character that specifies how many
+ characters should be deleted from the end of the inflected form to
+ produce the lexeme by concatenating the stripped string with the ending.
+<DT><A HREF="./morfologik/tools/IMessageLogger.html#startPart(java.lang.String)"><B>startPart(String)</B></A> -
+Method in interface morfologik.tools.<A HREF="./morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A>
+<DD>Log message header and save current time.
+<DT><A HREF="./morfologik/tools/WriterMessageLogger.html#startPart(java.lang.String)"><B>startPart(String)</B></A> -
+Method in class morfologik.tools.<A HREF="./morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools">WriterMessageLogger</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa"><B>StateVisitor</B></A> - Interface in <A HREF="./morfologik/fsa/package-summary.html">morfologik.fsa</A><DD>State visitor.</DL>
<HR>
<A NAME="_T_"><!-- --></A><H2>
<B>T</B></H2>
<DL>
-<DT><A HREF="./morfologik/util/PerformanceTimer.html#toString()"><B>toString()</B></A> -
-Method in class morfologik.util.<A HREF="./morfologik/util/PerformanceTimer.html" title="class in morfologik.util">PerformanceTimer</A>
+<DT><A HREF="./morfologik/fsa/ConstantArcSizeFSA.html#TARGET_ADDRESS_SIZE"><B>TARGET_ADDRESS_SIZE</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>
+<DD>Size of the target address field (constant for the builder).
+<DT><A HREF="./morfologik/fsa/FSAUtils.html#toDot(morfologik.fsa.FSA, int)"><B>toDot(FSA, int)</B></A> -
+Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa">FSAUtils</A>
+<DD>Returns the right-language reachable from a given FSA node, formatted
+ as an input for the graphviz package (expressed in the <code>dot</code>
+ language).
+<DT><A HREF="./morfologik/fsa/FSAUtils.html#toDot(java.io.Writer, morfologik.fsa.FSA, int)"><B>toDot(Writer, FSA, int)</B></A> -
+Static method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa">FSAUtils</A>
+<DD>Saves the right-language reachable from a given FSA node, formatted
+ as an input for the graphviz package (expressed in the <code>dot</code>
+ language), to the given writer.
+<DT><A HREF="./morfologik/fsa/FSABuilder.InfoEntry.html#toString()"><B>toString()</B></A> -
+Method in enum morfologik.fsa.<A HREF="./morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSAInfo.html#toString()"><B>toString()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa">FSAInfo</A>
<DD>&nbsp;
+<DT><A HREF="./morfologik/util/Arrays.html#toString(byte[], int, int)"><B>toString(byte[], int, int)</B></A> -
+Static method in class morfologik.util.<A HREF="./morfologik/util/Arrays.html" title="class in morfologik.util">Arrays</A>
+<DD>Convert an array of strings to bytes.
+<DT><A HREF="./morfologik/util/BufferUtils.html#toString(java.nio.ByteBuffer)"><B>toString(ByteBuffer)</B></A> -
+Static method in class morfologik.util.<A HREF="./morfologik/util/BufferUtils.html" title="class in morfologik.util">BufferUtils</A>
+<DD>Convert a byte buffer to a string in platform default encoding.
</DL>
<HR>
<A NAME="_U_"><!-- --></A><H2>
@@ -579,34 +1054,107 @@ Variable in class morfologik.stemming.<A HREF="./morfologik/stemming/DictionaryM
<A NAME="_V_"><!-- --></A><H2>
<B>V</B></H2>
<DL>
+<DT><A HREF="./morfologik/fsa/FSABuilder.InfoEntry.html#valueOf(java.lang.String)"><B>valueOf(String)</B></A> -
+Static method in enum morfologik.fsa.<A HREF="./morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A>
+<DD>Returns the enum constant of this type with the specified name.
<DT><A HREF="./morfologik/fsa/FSAFlags.html#valueOf(java.lang.String)"><B>valueOf(String)</B></A> -
Static method in enum morfologik.fsa.<A HREF="./morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>
<DD>Returns the enum constant of this type with the specified name.
-<DT><A HREF="./morfologik/fsa/FSAMatchType.html#valueOf(java.lang.String)"><B>valueOf(String)</B></A> -
-Static method in enum morfologik.fsa.<A HREF="./morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A>
+<DT><A HREF="./morfologik/tools/FSABuildTool.Format.html#valueOf(java.lang.String)"><B>valueOf(String)</B></A> -
+Static method in enum morfologik.tools.<A HREF="./morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A>
<DD>Returns the enum constant of this type with the specified name.
+<DT><A HREF="./morfologik/fsa/FSABuilder.InfoEntry.html#values()"><B>values()</B></A> -
+Static method in enum morfologik.fsa.<A HREF="./morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A>
+<DD>Returns an array containing the constants of this enum type, in
+the order they are declared.
<DT><A HREF="./morfologik/fsa/FSAFlags.html#values()"><B>values()</B></A> -
Static method in enum morfologik.fsa.<A HREF="./morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>
<DD>Returns an array containing the constants of this enum type, in
the order they are declared.
-<DT><A HREF="./morfologik/fsa/FSAMatchType.html#values()"><B>values()</B></A> -
-Static method in enum morfologik.fsa.<A HREF="./morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A>
+<DT><A HREF="./morfologik/tools/FSABuildTool.Format.html#values()"><B>values()</B></A> -
+Static method in enum morfologik.tools.<A HREF="./morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A>
<DD>Returns an array containing the constants of this enum type, in
the order they are declared.
-<DT><A HREF="./morfologik/fsa/FSA.html#version"><B>version</B></A> -
-Variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Dictionary version (derived from the combination of flags).
-<DT><A HREF="./morfologik/fsa/FSA.html#VERSION_5"><B>VERSION_5</B></A> -
-Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
-<DD>Version number for version 5 of the automaton.
+<DT><A HREF="./morfologik/fsa/CFSA.html#VERSION"><B>VERSION</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>
+<DD>Automaton header version value.
+<DT><A HREF="./morfologik/fsa/CFSA2.html#VERSION"><B>VERSION</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>
+<DD>Automaton header version value.
+<DT><A HREF="./morfologik/fsa/FSA5.html#VERSION"><B>VERSION</B></A> -
+Static variable in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A>
+<DD>Automaton version as in the file header.
+<DT><A HREF="./morfologik/fsa/FSA.html#visitAllStates(T)"><B>visitAllStates(T)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
+<DD>Visit all states.
+<DT><A HREF="./morfologik/fsa/FSA.html#visitInPostOrder(T)"><B>visitInPostOrder(T)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
+<DD>Same as <A HREF="./morfologik/fsa/FSA.html#visitInPostOrder(T, int)"><CODE>FSA.visitInPostOrder(StateVisitor, int)</CODE></A>,
+ starting from root automaton node.
+<DT><A HREF="./morfologik/fsa/FSA.html#visitInPostOrder(T, int)"><B>visitInPostOrder(T, int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
+<DD>Visits all states reachable from <code>node</code> in postorder.
+<DT><A HREF="./morfologik/fsa/FSA.html#visitInPreOrder(T)"><B>visitInPreOrder(T)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
+<DD>Same as <A HREF="./morfologik/fsa/FSA.html#visitInPreOrder(T, int)"><CODE>FSA.visitInPreOrder(StateVisitor, int)</CODE></A>, starting from root automaton node.
+<DT><A HREF="./morfologik/fsa/FSA.html#visitInPreOrder(T, int)"><B>visitInPreOrder(T, int)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>
+<DD>Visits all states in preorder.
</DL>
<HR>
<A NAME="_W_"><!-- --></A><H2>
<B>W</B></H2>
<DL>
-<DT><A HREF="./morfologik/stemming/WordData.html" title="class in morfologik.stemming"><B>WordData</B></A> - Class in <A HREF="./morfologik/stemming/package-summary.html">morfologik.stemming</A><DD>Stem and tag data associated with a given word.</DL>
+<DT><A HREF="./morfologik/fsa/CFSA2Serializer.html#withAnnotationSeparator(byte)"><B>withAnnotationSeparator(byte)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSA5Serializer.html#withAnnotationSeparator(byte)"><B>withAnnotationSeparator(byte)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A>
+<DD>Supports built-in annotation separator.
+<DT><A HREF="./morfologik/fsa/FSASerializer.html#withAnnotationSeparator(byte)"><B>withAnnotationSeparator(byte)</B></A> -
+Method in interface morfologik.fsa.<A HREF="./morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A>
+<DD>Supports built-in annotation separator.
+<DT><A HREF="./morfologik/fsa/CFSA2Serializer.html#withFiller(byte)"><B>withFiller(byte)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSA5Serializer.html#withFiller(byte)"><B>withFiller(byte)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A>
+<DD>Supports built-in filler separator.
+<DT><A HREF="./morfologik/fsa/FSASerializer.html#withFiller(byte)"><B>withFiller(byte)</B></A> -
+Method in interface morfologik.fsa.<A HREF="./morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A>
+<DD>Supports built-in filler separator.
+<DT><A HREF="./morfologik/fsa/CFSA2Serializer.html#withLogger(morfologik.tools.IMessageLogger)"><B>withLogger(IMessageLogger)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/fsa/FSA5Serializer.html#withLogger(morfologik.tools.IMessageLogger)"><B>withLogger(IMessageLogger)</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A>
+<DD>Log extra messages during construction.
+<DT><A HREF="./morfologik/fsa/FSASerializer.html#withLogger(morfologik.tools.IMessageLogger)"><B>withLogger(IMessageLogger)</B></A> -
+Method in interface morfologik.fsa.<A HREF="./morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A>
+<DD>Log extra messages during construction.
+<DT><A HREF="./morfologik/fsa/CFSA2Serializer.html#withNumbers()"><B>withNumbers()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A>
+<DD>Serialize the automaton with the number of right-language sequences in
+ each node.
+<DT><A HREF="./morfologik/fsa/FSA5Serializer.html#withNumbers()"><B>withNumbers()</B></A> -
+Method in class morfologik.fsa.<A HREF="./morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A>
+<DD>Serialize the automaton with the number of right-language sequences in
+ each node.
+<DT><A HREF="./morfologik/fsa/FSASerializer.html#withNumbers()"><B>withNumbers()</B></A> -
+Method in interface morfologik.fsa.<A HREF="./morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A>
+<DD>Supports built-in right language count on nodes, speeding up perfect hash counts.
+<DT><A HREF="./morfologik/stemming/WordData.html" title="class in morfologik.stemming"><B>WordData</B></A> - Class in <A HREF="./morfologik/stemming/package-summary.html">morfologik.stemming</A><DD>Stem and tag data associated with a given word.<DT><A HREF="./morfologik/util/FileUtils.html#writeInt(java.io.OutputStream, int)"><B>writeInt(OutputStream, int)</B></A> -
+Static method in class morfologik.util.<A HREF="./morfologik/util/FileUtils.html" title="class in morfologik.util">FileUtils</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools"><B>WriterMessageLogger</B></A> - Class in <A HREF="./morfologik/tools/package-summary.html">morfologik.tools</A><DD>A logger dumping info to <code>System.err</code>.<DT><A HREF="./morfologik/tools/WriterMessageLogger.html#WriterMessageLogger(java.io.PrintWriter)"><B>WriterMessageLogger(PrintWriter)</B></A> -
+Constructor for class morfologik.tools.<A HREF="./morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools">WriterMessageLogger</A>
+<DD>&nbsp;
+<DT><A HREF="./morfologik/util/FileUtils.html#writeShort(java.io.OutputStream, short)"><B>writeShort(OutputStream, short)</B></A> -
+Static method in class morfologik.util.<A HREF="./morfologik/util/FileUtils.html" title="class in morfologik.util">FileUtils</A>
+<DD>&nbsp;
+</DL>
<HR>
-<A HREF="#_A_">A</A> <A HREF="#_B_">B</A> <A HREF="#_C_">C</A> <A HREF="#_D_">D</A> <A HREF="#_E_">E</A> <A HREF="#_F_">F</A> <A HREF="#_G_">G</A> <A HREF="#_H_">H</A> <A HREF="#_I_">I</A> <A HREF="#_L_">L</A> <A HREF="#_M_">M</A> <A HREF="#_N_">N</A> <A HREF="#_O_">O</A> <A HREF="#_P_">P</A> <A HREF="#_R_">R</A> <A HREF="#_S_">S</A> <A HREF="#_T_">T</A> <A HREF="#_U_">U</A> <A HREF="#_V_">V</A> <A HREF="#_W_">W</A>
+<A HREF="#_A_">A</A> <A HREF="#_B_">B</A> <A HREF="#_C_">C</A> <A HREF="#_D_">D</A> <A HREF="#_E_">E</A> <A HREF="#_F_">F</A> <A HREF="#_G_">G</A> <A HREF="#_H_">H</A> <A HREF="#_I_">I</A> <A HREF="#_K_">K</A> <A HREF="#_L_">L</A> <A HREF="#_M_">M</A> <A HREF="#_N_">N</A> <A HREF="#_O_">O</A> <A HREF="#_P_">P</A> <A HREF="#_R_">R</A> <A HREF="#_S_">S</A> <A HREF="#_T_">T</A> <A HREF="#_U_">U</A> <A HREF="#_V_">V</A> <A HREF="#_W_">W</A>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<A NAME="navbar_bottom"><!-- --></A>
diff --git a/doc/api/index.html b/doc/api/index.html
index 4fa9af1..866e191 100644
--- a/doc/api/index.html
+++ b/doc/api/index.html
@@ -2,7 +2,7 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc on Mon Sep 21 12:09:37 CEST 2009-->
+<!-- Generated by javadoc on Wed Jan 26 18:49:38 CET 2011-->
<TITLE>
Generated Documentation (Untitled)
</TITLE>
diff --git a/doc/api/morfologik/fsa/CFSA.html b/doc/api/morfologik/fsa/CFSA.html
new file mode 100644
index 0000000..1b0b2ff
--- /dev/null
+++ b/doc/api/morfologik/fsa/CFSA.html
@@ -0,0 +1,871 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
+<TITLE>
+CFSA
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="CFSA";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/CFSA.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="CFSA.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.fsa</FONT>
+<BR>
+Class CFSA</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">morfologik.fsa.FSA</A>
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.CFSA</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.lang.Iterable&lt;java.nio.ByteBuffer&gt;</DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public final class <B>CFSA</B><DT>extends <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></DL>
+</PRE>
+
+<P>
+CFSA (Compact Finite State Automaton) binary format implementation. This is a
+ slightly reorganized version of <A HREF="../../morfologik/fsa/FSA5.html" title="class in morfologik.fsa"><CODE>FSA5</CODE></A> offering smaller automata size
+ at some (minor) performance penalty.
+
+ <p><b>Note:</b> Serialize to <A HREF="../../morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><CODE>CFSA2</CODE></A> for new code.</p>
+
+ <p>The encoding of automaton body is as follows.</p>
+
+ <pre>
+ ---- FSA header (standard)
+ Byte Description
+ +-+-+-+-+-+-+-+-+\
+ 0 | | | | | | | | | +------ '\'
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 1 | | | | | | | | | +------ 'f'
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 2 | | | | | | | | | +------ 's'
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 3 | | | | | | | | | +------ 'a'
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 4 | | | | | | | | | +------ version (fixed 0xc5)
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 5 | | | | | | | | | +------ filler character
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 6 | | | | | | | | | +------ annot character
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 7 |C|C|C|C|G|G|G|G| +------ C - node data size (ctl), G - address size (gotoLength)
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 8-32 | | | | | | | | | +------ labels mapped for type (1) of arc encoding.
+ : : : : : : : : : |
+ +-+-+-+-+-+-+-+-+/
+
+ ---- Start of a node; only if automaton was compiled with NUMBERS option.
+
+ Byte
+ +-+-+-+-+-+-+-+-+\
+ 0 | | | | | | | | | \ LSB
+ +-+-+-+-+-+-+-+-+ +
+ 1 | | | | | | | | | | number of strings recognized
+ +-+-+-+-+-+-+-+-+ +----- by the automaton starting
+ : : : : : : : : : | from this node.
+ +-+-+-+-+-+-+-+-+ +
+ ctl-1 | | | | | | | | | / MSB
+ +-+-+-+-+-+-+-+-+/
+
+ ---- A vector of node's arcs. Conditional format, depending on flags.
+
+ 1) NEXT bit set, mapped arc label.
+
+ +--------------- arc's label mapped in M bits if M's field value > 0
+ | +------------- node pointed to is next
+ | | +----------- the last arc of the node
+ _______| | | +--------- the arc is final
+ / | | | |
+ +-+-+-+-+-+-+-+-+\
+ 0 |M|M|M|M|M|1|L|F| +------ flags + (M) index of the mapped label.
+ +-+-+-+-+-+-+-+-+/
+
+ 2) NEXT bit set, label separate.
+
+ +--------------- arc's label stored separately (M's field is zero).
+ | +------------- node pointed to is next
+ | | +----------- the last arc of the node
+ | | | +--------- the arc is final
+ | | | |
+ +-+-+-+-+-+-+-+-+\
+ 0 |0|0|0|0|0|1|L|F| +------ flags
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 1 | | | | | | | | | +------ label
+ +-+-+-+-+-+-+-+-+/
+
+ 3) NEXT bit not set. Full arc.
+
+ +------------- node pointed to is next
+ | +----------- the last arc of the node
+ | | +--------- the arc is final
+ | | |
+ +-+-+-+-+-+-+-+-+\
+ 0 |A|A|A|A|A|0|L|F| +------ flags + (A) address field, lower bits
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 1 | | | | | | | | | +------ label
+ +-+-+-+-+-+-+-+-+/
+ : : : : : : : : :
+ +-+-+-+-+-+-+-+-+\
+ gtl-1 |A|A|A|A|A|A|A|A| +------ address, continuation (MSB)
+ +-+-+-+-+-+-+-+-+/
+ </pre>
+<P>
+
+<P>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#arcs">arcs</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An array of bytes with the internal representation of the automaton.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#BIT_FINAL_ARC">BIT_FINAL_ARC</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bitmask indicating that an arc corresponds to the last character of a
+ sequence available when building the automaton.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#BIT_LAST_ARC">BIT_LAST_ARC</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bitmask indicating that an arc is the last one of the node's list and the
+ following one belongs to another node.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#BIT_TARGET_NEXT">BIT_TARGET_NEXT</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bitmask indicating that the target node of this arc follows it in the
+ compressed automaton structure (no goto field).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#gtl">gtl</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Number of bytes each address takes in full, expanded form (goto length).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#labelMapping">labelMapping</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Label mapping for arcs of type (1) (see class documentation).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#nodeDataLength">nodeDataLength</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The length of the node header structure (if the automaton was compiled with
+ <code>NUMBERS</code> option).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#VERSION">VERSION</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Automaton header version value.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#CFSA(java.io.InputStream)">CFSA</A></B>(java.io.InputStream&nbsp;fsaStream)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a new automaton, reading it from a file in FSA format, version 5.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#getArc(int, byte)">getArc</A></B>(int&nbsp;node,
+ byte&nbsp;label)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#getArcLabel(int)">getArcLabel</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the label associated with a given <code>arc</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#getEndNode(int)">getEndNode</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the end node pointed to by a given <code>arc</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#getFirstArc(int)">getFirstArc</A></B>(int&nbsp;node)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#getFlags()">getFlags</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a set of flags for this FSA instance.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#getNextArc(int)">getNextArc</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#getRightLanguageCount(int)">getRightLanguageCount</A></B>(int&nbsp;node)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#getRootNode()">getRootNode</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the start node of this automaton.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#isArcFinal(int)">isArcFinal</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if the destination node at the end of this
+ <code>arc</code> corresponds to an input sequence created when building
+ this automaton.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#isArcLast(int)">isArcLast</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if this arc has <code>NEXT</code> bit set.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#isArcTerminal(int)">isArcTerminal</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if this <code>arc</code> does not have a
+ terminating node (@link <A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)"><CODE>FSA.getEndNode(int)</CODE></A> will throw an
+ exception).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#isLabelCompressed(int)">isLabelCompressed</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if the label is compressed inside flags byte.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA.html#isNextSet(int)">isNextSet</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_morfologik.fsa.FSA"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class morfologik.fsa.<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../morfologik/fsa/FSA.html#getArcCount(int)">getArcCount</A>, <A HREF="../../morfologik/fsa/FSA.html#getSequences()">getSequences</A>, <A HREF="../../morfologik/fsa/FSA.html#getSequences(int)">getSequences</A>, <A HREF="../../morfologik/fsa/FSA.html#iterator()">iterator</A>, <A HREF="../../morfologik/fsa/FSA.html#read(java.io.InputStream)">read</A>, <A HREF="../../morfologik/fsa/FSA.html#visitAllStates(T)">visitAllStates</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPostOrder(T)">visitInPostOrder</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPostOrder(T, int)">visitInPostOrder</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPreOrder(T)">visitInPreOrder</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPreOrder(T, int)">visitInPreOrder</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="VERSION"><!-- --></A><H3>
+VERSION</H3>
+<PRE>
+public static final byte <B>VERSION</B></PRE>
+<DL>
+<DD>Automaton header version value.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.CFSA.VERSION">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="BIT_FINAL_ARC"><!-- --></A><H3>
+BIT_FINAL_ARC</H3>
+<PRE>
+public static final int <B>BIT_FINAL_ARC</B></PRE>
+<DL>
+<DD>Bitmask indicating that an arc corresponds to the last character of a
+ sequence available when building the automaton.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.CFSA.BIT_FINAL_ARC">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="BIT_LAST_ARC"><!-- --></A><H3>
+BIT_LAST_ARC</H3>
+<PRE>
+public static final int <B>BIT_LAST_ARC</B></PRE>
+<DL>
+<DD>Bitmask indicating that an arc is the last one of the node's list and the
+ following one belongs to another node.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.CFSA.BIT_LAST_ARC">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="BIT_TARGET_NEXT"><!-- --></A><H3>
+BIT_TARGET_NEXT</H3>
+<PRE>
+public static final int <B>BIT_TARGET_NEXT</B></PRE>
+<DL>
+<DD>Bitmask indicating that the target node of this arc follows it in the
+ compressed automaton structure (no goto field).
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.CFSA.BIT_TARGET_NEXT">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="arcs"><!-- --></A><H3>
+arcs</H3>
+<PRE>
+public byte[] <B>arcs</B></PRE>
+<DL>
+<DD>An array of bytes with the internal representation of the automaton.
+ Please see the documentation of this class for more information on how
+ this structure is organized.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="nodeDataLength"><!-- --></A><H3>
+nodeDataLength</H3>
+<PRE>
+public final int <B>nodeDataLength</B></PRE>
+<DL>
+<DD>The length of the node header structure (if the automaton was compiled with
+ <code>NUMBERS</code> option). Otherwise zero.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="gtl"><!-- --></A><H3>
+gtl</H3>
+<PRE>
+public final int <B>gtl</B></PRE>
+<DL>
+<DD>Number of bytes each address takes in full, expanded form (goto length).
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="labelMapping"><!-- --></A><H3>
+labelMapping</H3>
+<PRE>
+public final byte[] <B>labelMapping</B></PRE>
+<DL>
+<DD>Label mapping for arcs of type (1) (see class documentation). The array
+ is indexed by mapped label's value and contains the original label.
+<P>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="CFSA(java.io.InputStream)"><!-- --></A><H3>
+CFSA</H3>
+<PRE>
+public <B>CFSA</B>(java.io.InputStream&nbsp;fsaStream)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Creates a new automaton, reading it from a file in FSA format, version 5.
+<P>
+<DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getRootNode()"><!-- --></A><H3>
+getRootNode</H3>
+<PRE>
+public int <B>getRootNode</B>()</PRE>
+<DL>
+<DD>Returns the start node of this automaton. May return <code>0</code> if
+ the start node is also an end node.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getRootNode()">getRootNode</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the root node of this automaton.
+ Returns 0 if the start node is also the end node (the automaton
+ is empty).</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFirstArc(int)"><!-- --></A><H3>
+getFirstArc</H3>
+<PRE>
+public final int <B>getFirstArc</B>(int&nbsp;node)</PRE>
+<DL>
+<DD>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getFirstArc(int)">getFirstArc</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the first arc leaving <code>node</code>
+ or 0 if the node has no outgoing arcs.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNextArc(int)"><!-- --></A><H3>
+getNextArc</H3>
+<PRE>
+public final int <B>getNextArc</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getNextArc(int)">getNextArc</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the next arc after <code>arc</code> and
+ leaving <code>node</code>. Zero is returned if no more arcs are
+ available for the node.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArc(int, byte)"><!-- --></A><H3>
+getArc</H3>
+<PRE>
+public int <B>getArc</B>(int&nbsp;node,
+ byte&nbsp;label)</PRE>
+<DL>
+<DD>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getArc(int, byte)">getArc</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of an arc leaving <code>node</code> and
+ labeled with <code>label</code>. An identifier equal to 0 means
+ the node has no outgoing arc labeled <code>label</code>.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getEndNode(int)"><!-- --></A><H3>
+getEndNode</H3>
+<PRE>
+public int <B>getEndNode</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>Return the end node pointed to by a given <code>arc</code>. Terminal arcs
+ (those that point to a terminal state) have no end node representation
+ and throw a runtime exception.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)">getEndNode</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArcLabel(int)"><!-- --></A><H3>
+getArcLabel</H3>
+<PRE>
+public byte <B>getArcLabel</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>Return the label associated with a given <code>arc</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getArcLabel(int)">getArcLabel</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRightLanguageCount(int)"><!-- --></A><H3>
+getRightLanguageCount</H3>
+<PRE>
+public int <B>getRightLanguageCount</B>(int&nbsp;node)</PRE>
+<DL>
+<DD>
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getRightLanguageCount(int)">getRightLanguageCount</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the number of sequences reachable from the given state if
+ the automaton was compiled with <A HREF="../../morfologik/fsa/FSAFlags.html#NUMBERS"><CODE>FSAFlags.NUMBERS</CODE></A>. The size of
+ the right language of the state, in other words.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isArcFinal(int)"><!-- --></A><H3>
+isArcFinal</H3>
+<PRE>
+public boolean <B>isArcFinal</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>Returns <code>true</code> if the destination node at the end of this
+ <code>arc</code> corresponds to an input sequence created when building
+ this automaton.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#isArcFinal(int)">isArcFinal</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isArcTerminal(int)"><!-- --></A><H3>
+isArcTerminal</H3>
+<PRE>
+public boolean <B>isArcTerminal</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>Returns <code>true</code> if this <code>arc</code> does not have a
+ terminating node (@link <A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)"><CODE>FSA.getEndNode(int)</CODE></A> will throw an
+ exception). Implies <A HREF="../../morfologik/fsa/FSA.html#isArcFinal(int)"><CODE>FSA.isArcFinal(int)</CODE></A>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#isArcTerminal(int)">isArcTerminal</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isArcLast(int)"><!-- --></A><H3>
+isArcLast</H3>
+<PRE>
+public boolean <B>isArcLast</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>Returns <code>true</code> if this arc has <code>NEXT</code> bit set.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/CFSA.html#BIT_LAST_ARC"><CODE>BIT_LAST_ARC</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isNextSet(int)"><!-- --></A><H3>
+isNextSet</H3>
+<PRE>
+public boolean <B>isNextSet</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/CFSA.html#BIT_TARGET_NEXT"><CODE>BIT_TARGET_NEXT</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isLabelCompressed(int)"><!-- --></A><H3>
+isLabelCompressed</H3>
+<PRE>
+public boolean <B>isLabelCompressed</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>Returns <code>true</code> if the label is compressed inside flags byte.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFlags()"><!-- --></A><H3>
+getFlags</H3>
+<PRE>
+public java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt; <B>getFlags</B>()</PRE>
+<DL>
+<DD>Returns a set of flags for this FSA instance.
+
+ <p>For this automaton version, an additional <A HREF="../../morfologik/fsa/FSAFlags.html#NUMBERS"><CODE>FSAFlags.NUMBERS</CODE></A> flag
+ may be set to indicate the automaton contains extra fields for each node.</p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getFlags()">getFlags</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/CFSA.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="CFSA.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/fsa/FSAVer5Impl.html b/doc/api/morfologik/fsa/CFSA2.html
index 8c3265e..78c00ef 100644
--- a/doc/api/morfologik/fsa/FSAVer5Impl.html
+++ b/doc/api/morfologik/fsa/CFSA2.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
<TITLE>
-FSAVer5Impl
+CFSA2
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -15,7 +15,7 @@ FSAVer5Impl
function windowTitle()
{
if (location.href.indexOf('is-external=true') == -1) {
- parent.document.title="FSAVer5Impl";
+ parent.document.title="CFSA2";
}
}
</SCRIPT>
@@ -54,11 +54,11 @@ function windowTitle()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;NEXT CLASS</FONT></TD>
+&nbsp;<A HREF="../../morfologik/fsa/CFSA.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/fsa/FSAVer5Impl.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="FSAVer5Impl.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+ <A HREF="../../index.html?morfologik/fsa/CFSA2.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="CFSA2.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
@@ -89,60 +89,95 @@ DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor
<FONT SIZE="-1">
morfologik.fsa</FONT>
<BR>
-Class FSAVer5Impl</H2>
+Class CFSA2</H2>
<PRE>
java.lang.Object
<IMG SRC="../../resources/inherit.gif" ALT="extended by "><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">morfologik.fsa.FSA</A>
- <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.FSAVer5Impl</B>
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.CFSA2</B>
</PRE>
<DL>
<DT><B>All Implemented Interfaces:</B> <DD>java.lang.Iterable&lt;java.nio.ByteBuffer&gt;</DD>
</DL>
<HR>
<DL>
-<DT><PRE>public final class <B>FSAVer5Impl</B><DT>extends <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></DL>
+<DT><PRE>public final class <B>CFSA2</B><DT>extends <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></DL>
</PRE>
<P>
-FSA (Finite State Automaton) dictionary traversal implementation for version
- 5 of the FSA automaton.
+CFSA (Compact Finite State Automaton) binary format implementation, version 2:
+ <ul>
+ <li><A HREF="../../morfologik/fsa/CFSA2.html#BIT_TARGET_NEXT"><CODE>BIT_TARGET_NEXT</CODE></A> applicable on all arcs, not necessarily the last one.</li>
+ <li>v-coded goto field</li>
+ <li>v-coded perfect hashing numbers, if any</li>
+ <li>31 most frequent labels integrated with flags byte</li>
+ </ul>
- <p>
- Version 5 indicates the dictionary was built with these flags:
- <A HREF="../../morfologik/fsa/FSAFlags.html#FLEXIBLE"><CODE>FSAFlags.FLEXIBLE</CODE></A>, <A HREF="../../morfologik/fsa/FSAFlags.html#STOPBIT"><CODE>FSAFlags.STOPBIT</CODE></A> and
- <A HREF="../../morfologik/fsa/FSAFlags.html#NEXTBIT"><CODE>FSAFlags.NEXTBIT</CODE></A>. The internal representation of the FSA must
- therefore follow this description (please note this format describes only a
- single transition (arc), not the entire dictionary file).
+ <p>The encoding of automaton body is as follows.</p>
<pre>
- Byte
+ ---- CFSA header
+ Byte Description
+ +-+-+-+-+-+-+-+-+\
+ 0 | | | | | | | | | +------ '\'
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 1 | | | | | | | | | +------ 'f'
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 2 | | | | | | | | | +------ 's'
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 3 | | | | | | | | | +------ 'a'
+ +-+-+-+-+-+-+-+-+/
+-+-+-+-+-+-+-+-+\
- 0 | | | | | | | | | +------ label
+ 4 | | | | | | | | | +------ version (fixed 0xc6)
+-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 5 | | | | | | | | | +----\
+ +-+-+-+-+-+-+-+-+/ \ flags [MSB first]
+ +-+-+-+-+-+-+-+-+\ /
+ 6 | | | | | | | | | +----/
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 7 | | | | | | | | | +------ label lookup table size
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 8-32 | | | | | | | | | +------ label value lookup table
+ : : : : : : : : : |
+ +-+-+-+-+-+-+-+-+/
+
+ ---- Start of a node; only if automaton was compiled with NUMBERS option.
+
+ Byte
+ +-+-+-+-+-+-+-+-+\
+ 0 | | | | | | | | | \
+ +-+-+-+-+-+-+-+-+ +
+ 1 | | | | | | | | | | number of strings recognized
+ +-+-+-+-+-+-+-+-+ +----- by the automaton starting
+ : : : : : : : : : | from this node. v-coding
+ +-+-+-+-+-+-+-+-+ +
+ | | | | | | | | | /
+ +-+-+-+-+-+-+-+-+/
+
+ ---- A vector of this node's arcs. An arc's layout depends on the combination of flags.
- +------------- node pointed to is next
- | +----------- the last arc of the node
- | | +--------- the arc is final
- | | |
- +-----------+
- | | | | |
- ___+___ | | | |
- / \ | | | |
- MSB LSB |
- 7 6 5 4 3 2 1 0 |
- +-+-+-+-+-+-+-+-+ |
- 1 | | | | | | | | | \ \
- +-+-+-+-+-+-+-+-+ \ \ LSB
- +-+-+-+-+-+-+-+-+ +
- 2 | | | | | | | | | |
- +-+-+-+-+-+-+-+-+ |
- 3 | | | | | | | | | +----- target node address (in bytes)
- +-+-+-+-+-+-+-+-+ | (not present except for the byte
- : : : : : : : : : | with flags if the node pointed to
- +-+-+-+-+-+-+-+-+ + is next)
- gtl | | | | | | | | | / MSB
- +-+-+-+-+-+-+-+-+ /
- gtl+1 (gtl = gotoLength)
+ 1) NEXT bit set, mapped arc label.
+
+ +----------------------- node pointed to is next
+ | +--------------------- the last arc of the node
+ | | +------------------- this arc leads to a final state (acceptor)
+ | | | _______+--------- arc's label; indexed if M > 0, otherwise explicit label follows
+ | | | / | | | |
+ +-+-+-+-+-+-+-+-+\
+ 0 |N|L|F|M|M|M|M|M| +------ flags + (M) index of the mapped label.
+ +-+-+-+-+-+-+-+-+/
+ +-+-+-+-+-+-+-+-+\
+ 1 | | | | | | | | | +------ optional label if M == 0
+ +-+-+-+-+-+-+-+-+/
+ : : : : : : : : :
+ +-+-+-+-+-+-+-+-+\
+ |A|A|A|A|A|A|A|A| +------ v-coded goto address
+ +-+-+-+-+-+-+-+-+/
</pre>
<P>
@@ -160,36 +195,53 @@ FSA (Finite State Automaton) dictionary traversal implementation for version
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>protected &nbsp;byte[]</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#arcs">arcs</A></B></CODE>
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#arcs">arcs</A></B></CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An array of bytes with the internal representation of the automaton.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>protected &nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#arcSize">arcSize</A></B></CODE>
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#BIT_FINAL_ARC">BIT_FINAL_ARC</A></B></CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Size of a single arc (in bytes).</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The arc corresponds to the last character of a sequence
+ available when building the automaton (acceptor transition).</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>protected static&nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#gotoOffset">gotoOffset</A></B></CODE>
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#BIT_LAST_ARC">BIT_LAST_ARC</A></B></CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An offset in the arc structure, where the address field begins.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The arc is the last one from the current node's arcs list.</TD>
</TR>
-</TABLE>
-&nbsp;<A NAME="fields_inherited_from_class_morfologik.fsa.FSA"><!-- --></A>
-<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
-<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
-<TH ALIGN="left"><B>Fields inherited from class morfologik.fsa.<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></B></TH>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#BIT_TARGET_NEXT">BIT_TARGET_NEXT</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The target node of this arc follows the last arc of the current state
+ (no goto field).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#labelMapping">labelMapping</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Label mapping for M-indexed labels.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><A HREF="../../morfologik/fsa/FSA.html#filler">filler</A>, <A HREF="../../morfologik/fsa/FSA.html#gotoLength">gotoLength</A>, <A HREF="../../morfologik/fsa/FSA.html#version">version</A>, <A HREF="../../morfologik/fsa/FSA.html#VERSION_5">VERSION_5</A></CODE></TD>
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#VERSION">VERSION</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Automaton header version value.</TD>
</TR>
</TABLE>
&nbsp;
@@ -202,11 +254,10 @@ FSA (Finite State Automaton) dictionary traversal implementation for version
<B>Constructor Summary</B></FONT></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#FSAVer5Impl(java.io.InputStream, java.lang.String)">FSAVer5Impl</A></B>(java.io.InputStream&nbsp;fsaStream,
- java.lang.String&nbsp;dictionaryEncoding)</CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#CFSA2(java.io.InputStream)">CFSA2</A></B>(java.io.InputStream&nbsp;in)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a new automaton reading it from a file in FSA format, version 5.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reads an automaton from a byte stream.</TD>
</TR>
</TABLE>
&nbsp;
@@ -221,17 +272,16 @@ FSA (Finite State Automaton) dictionary traversal implementation for version
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>&nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#getArc(int, byte)">getArc</A></B>(int&nbsp;node,
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#getArc(int, byte)">getArc</A></B>(int&nbsp;node,
byte&nbsp;label)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the identifier of an arc leaving <code>node</code> and labeled
- with <code>label</code>.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>&nbsp;byte</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#getArcLabel(int)">getArcLabel</A></B>(int&nbsp;arc)</CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#getArcLabel(int)">getArcLabel</A></B>(int&nbsp;arc)</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the label associated with a given <code>arc</code>.</TD>
@@ -239,7 +289,7 @@ FSA (Finite State Automaton) dictionary traversal implementation for version
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>&nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#getEndNode(int)">getEndNode</A></B>(int&nbsp;arc)</CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#getEndNode(int)">getEndNode</A></B>(int&nbsp;arc)</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the end node pointed to by a given <code>arc</code>.</TD>
@@ -247,50 +297,47 @@ FSA (Finite State Automaton) dictionary traversal implementation for version
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>&nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#getFirstArc(int)">getFirstArc</A></B>(int&nbsp;node)</CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#getFirstArc(int)">getFirstArc</A></B>(int&nbsp;node)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the identifier of the first arc leaving <code>node</code> or 0 if
- the node has no outgoing arcs.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#getNextArc(int, int)">getNextArc</A></B>(int&nbsp;node,
- int&nbsp;arc)</CODE>
+<CODE>&nbsp;java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#getFlags()">getFlags</A></B>()</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the identifier of the next arc after <code>arc</code> and leaving
- <code>node</code>.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a set of flags for this FSA instance.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>&nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#getNumberOfArcs()">getNumberOfArcs</A></B>()</CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#getNextArc(int)">getNextArc</A></B>(int&nbsp;arc)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the number of arcs in this automaton.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>&nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#getNumberOfNodes()">getNumberOfNodes</A></B>()</CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#getRightLanguageCount(int)">getRightLanguageCount</A></B>(int&nbsp;node)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the number of nodes in this automaton.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>&nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#getRootNode()">getRootNode</A></B>()</CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#getRootNode()">getRootNode</A></B>()</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the start node of this automaton.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>&nbsp;boolean</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#isArcFinal(int)">isArcFinal</A></B>(int&nbsp;arc)</CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#isArcFinal(int)">isArcFinal</A></B>(int&nbsp;arc)</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if the destination node at the end of this
@@ -300,20 +347,28 @@ FSA (Finite State Automaton) dictionary traversal implementation for version
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>&nbsp;boolean</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#isArcTerminal(int)">isArcTerminal</A></B>(int&nbsp;arc)</CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#isArcLast(int)">isArcLast</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if this arc has <code>NEXT</code> bit set.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#isArcTerminal(int)">isArcTerminal</A></B>(int&nbsp;arc)</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if this <code>arc</code> does not have a
- terminating node.</TD>
+ terminating node (@link <A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)"><CODE>FSA.getEndNode(int)</CODE></A> will throw an
+ exception).</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>protected &nbsp;void</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html#readHeader(java.io.DataInput, long)">readHeader</A></B>(java.io.DataInput&nbsp;in,
- long&nbsp;fileSize)</CODE>
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2.html#isNextSet(int)">isNextSet</A></B>(int&nbsp;arc)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reads a FSA header from a stream.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
</TABLE>
&nbsp;<A NAME="methods_inherited_from_class_morfologik.fsa.FSA"><!-- --></A>
@@ -322,7 +377,7 @@ FSA (Finite State Automaton) dictionary traversal implementation for version
<TH ALIGN="left"><B>Methods inherited from class morfologik.fsa.<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></B></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><A HREF="../../morfologik/fsa/FSA.html#getAnnotationSeparator()">getAnnotationSeparator</A>, <A HREF="../../morfologik/fsa/FSA.html#getFillerCharacter()">getFillerCharacter</A>, <A HREF="../../morfologik/fsa/FSA.html#getFlags()">getFlags</A>, <A HREF="../../morfologik/fsa/FSA.html#getInstance(java.io.File, java.lang.String)">getInstance</A>, <A HREF="../../morfologik/fsa/FSA.html#getInstance(java.io.InputStream, java.lang.String)">getInstance</A>, <A HREF="../../morfologik/fsa/FSA.html#getTraversalHelper()">getTraversalHelper</A>, <A HREF="../../morfologik/fsa/FSA.html#getVersion()">getVersion</A>, <A HREF="../../morfologik/fsa/FSA.html#iterator()">iterator</A>, <A HREF="../../morfologik/fsa/FSA.html#readFully(java.io.InputStream)">readFully</A></CODE></TD>
+<TD><CODE><A HREF="../../morfologik/fsa/FSA.html#getArcCount(int)">getArcCount</A>, <A HREF="../../morfologik/fsa/FSA.html#getSequences()">getSequences</A>, <A HREF="../../morfologik/fsa/FSA.html#getSequences(int)">getSequences</A>, <A HREF="../../morfologik/fsa/FSA.html#iterator()">iterator</A>, <A HREF="../../morfologik/fsa/FSA.html#read(java.io.InputStream)">read</A>, <A HREF="../../morfologik/fsa/FSA.html#visitAllStates(T)">visitAllStates</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPostOrder(T)">visitInPostOrder</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPostOrder(T, int)">visitInPostOrder</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPreOrder(T)">visitInPreOrder</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPreOrder(T, int)">visitInPreOrder</A></CODE></TD>
</TR>
</TABLE>
&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
@@ -347,35 +402,60 @@ FSA (Finite State Automaton) dictionary traversal implementation for version
</TR>
</TABLE>
-<A NAME="arcSize"><!-- --></A><H3>
-arcSize</H3>
+<A NAME="VERSION"><!-- --></A><H3>
+VERSION</H3>
+<PRE>
+public static final byte <B>VERSION</B></PRE>
+<DL>
+<DD>Automaton header version value.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.CFSA2.VERSION">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="BIT_TARGET_NEXT"><!-- --></A><H3>
+BIT_TARGET_NEXT</H3>
<PRE>
-protected int <B>arcSize</B></PRE>
+public static final int <B>BIT_TARGET_NEXT</B></PRE>
<DL>
-<DD>Size of a single arc (in bytes).
+<DD>The target node of this arc follows the last arc of the current state
+ (no goto field).
<P>
<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.CFSA2.BIT_TARGET_NEXT">Constant Field Values</A></DL>
</DL>
+<HR>
+
+<A NAME="BIT_LAST_ARC"><!-- --></A><H3>
+BIT_LAST_ARC</H3>
+<PRE>
+public static final int <B>BIT_LAST_ARC</B></PRE>
+<DL>
+<DD>The arc is the last one from the current node's arcs list.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.CFSA2.BIT_LAST_ARC">Constant Field Values</A></DL>
</DL>
<HR>
-<A NAME="gotoOffset"><!-- --></A><H3>
-gotoOffset</H3>
+<A NAME="BIT_FINAL_ARC"><!-- --></A><H3>
+BIT_FINAL_ARC</H3>
<PRE>
-protected static final int <B>gotoOffset</B></PRE>
+public static final int <B>BIT_FINAL_ARC</B></PRE>
<DL>
-<DD>An offset in the arc structure, where the address field begins. For this
- version of the automaton, this is a constant value.
+<DD>The arc corresponds to the last character of a sequence
+ available when building the automaton (acceptor transition).
<P>
<DL>
-<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.FSAVer5Impl.gotoOffset">Constant Field Values</A></DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.CFSA2.BIT_FINAL_ARC">Constant Field Values</A></DL>
</DL>
<HR>
<A NAME="arcs"><!-- --></A><H3>
arcs</H3>
<PRE>
-protected byte[] <B>arcs</B></PRE>
+public byte[] <B>arcs</B></PRE>
<DL>
<DD>An array of bytes with the internal representation of the automaton.
Please see the documentation of this class for more information on how
@@ -384,6 +464,18 @@ protected byte[] <B>arcs</B></PRE>
<DL>
</DL>
</DL>
+<HR>
+
+<A NAME="labelMapping"><!-- --></A><H3>
+labelMapping</H3>
+<PRE>
+public final byte[] <B>labelMapping</B></PRE>
+<DL>
+<DD>Label mapping for M-indexed labels.
+<P>
+<DL>
+</DL>
+</DL>
<!-- ========= CONSTRUCTOR DETAIL ======== -->
@@ -395,14 +487,13 @@ protected byte[] <B>arcs</B></PRE>
</TR>
</TABLE>
-<A NAME="FSAVer5Impl(java.io.InputStream, java.lang.String)"><!-- --></A><H3>
-FSAVer5Impl</H3>
+<A NAME="CFSA2(java.io.InputStream)"><!-- --></A><H3>
+CFSA2</H3>
<PRE>
-public <B>FSAVer5Impl</B>(java.io.InputStream&nbsp;fsaStream,
- java.lang.String&nbsp;dictionaryEncoding)
- throws java.io.IOException</PRE>
+public <B>CFSA2</B>(java.io.InputStream&nbsp;in)
+ throws java.io.IOException</PRE>
<DL>
-<DD>Creates a new automaton reading it from a file in FSA format, version 5.
+<DD>Reads an automaton from a byte stream.
<P>
<DL>
@@ -420,74 +511,21 @@ public <B>FSAVer5Impl</B>(java.io.InputStream&nbsp;fsaStream,
</TR>
</TABLE>
-<A NAME="getNumberOfArcs()"><!-- --></A><H3>
-getNumberOfArcs</H3>
-<PRE>
-public int <B>getNumberOfArcs</B>()</PRE>
-<DL>
-<DD>Returns the number of arcs in this automaton. This method performs a full
- scan of all arcs in this automaton.
-<P>
-<DD><DL>
-<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getNumberOfArcs()">getNumberOfArcs</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
-</DD>
-<DD><DL>
-</DL>
-</DD>
-</DL>
-<HR>
-
-<A NAME="getNumberOfNodes()"><!-- --></A><H3>
-getNumberOfNodes</H3>
-<PRE>
-public int <B>getNumberOfNodes</B>()</PRE>
-<DL>
-<DD>Returns the number of nodes in this automaton. This method performs a
- full scan of all arcs in this automaton.
-<P>
-<DD><DL>
-<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getNumberOfNodes()">getNumberOfNodes</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
-</DD>
-<DD><DL>
-</DL>
-</DD>
-</DL>
-<HR>
-
<A NAME="getRootNode()"><!-- --></A><H3>
getRootNode</H3>
<PRE>
public int <B>getRootNode</B>()</PRE>
<DL>
-<DD>Returns the start node of this automaton. May return <code>0</code> if
- the start node is also an end node.
+<DD>
<P>
<DD><DL>
<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getRootNode()">getRootNode</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
</DD>
<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA.html#getTraversalHelper()"><CODE>FSA.getTraversalHelper()</CODE></A></DL>
-</DD>
-</DL>
-<HR>
-
-<A NAME="readHeader(java.io.DataInput, long)"><!-- --></A><H3>
-readHeader</H3>
-<PRE>
-protected void <B>readHeader</B>(java.io.DataInput&nbsp;in,
- long&nbsp;fileSize)
- throws java.io.IOException</PRE>
-<DL>
-<DD>Reads a FSA header from a stream.
-<P>
-<DD><DL>
-<DT><B>Overrides:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#readHeader(java.io.DataInput, long)">readHeader</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
-</DD>
-<DD><DL>
-<DT><B>Throws:</B>
-<DD><CODE>java.io.IOException</CODE> - If the stream is not a dictionary, or if the version is not
- supported.</DL>
+<DT><B>Returns:</B><DD>Returns the identifier of the root node of this automaton.
+ Returns 0 if the start node is also the end node (the automaton
+ is empty).</DL>
</DD>
</DL>
<HR>
@@ -497,35 +535,34 @@ getFirstArc</H3>
<PRE>
public final int <B>getFirstArc</B>(int&nbsp;node)</PRE>
<DL>
-<DD><B>Description copied from class: <CODE><A HREF="../../morfologik/fsa/FSA.html#getFirstArc(int)">FSA</A></CODE></B></DD>
-<DD>Returns the identifier of the first arc leaving <code>node</code> or 0 if
- the node has no outgoing arcs.
+<DD>
<P>
<DD><DL>
<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getFirstArc(int)">getFirstArc</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
</DD>
<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA.html#getTraversalHelper()"><CODE>FSA.getTraversalHelper()</CODE></A></DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the first arc leaving <code>node</code>
+ or 0 if the node has no outgoing arcs.</DL>
</DD>
</DL>
<HR>
-<A NAME="getNextArc(int, int)"><!-- --></A><H3>
+<A NAME="getNextArc(int)"><!-- --></A><H3>
getNextArc</H3>
<PRE>
-public final int <B>getNextArc</B>(int&nbsp;node,
- int&nbsp;arc)</PRE>
+public final int <B>getNextArc</B>(int&nbsp;arc)</PRE>
<DL>
-<DD><B>Description copied from class: <CODE><A HREF="../../morfologik/fsa/FSA.html#getNextArc(int, int)">FSA</A></CODE></B></DD>
-<DD>Returns the identifier of the next arc after <code>arc</code> and leaving
- <code>node</code>. Zero is returned if no more arcs are available for the
- node.
+<DD>
<P>
<DD><DL>
-<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getNextArc(int, int)">getNextArc</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getNextArc(int)">getNextArc</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
</DD>
<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA.html#getTraversalHelper()"><CODE>FSA.getTraversalHelper()</CODE></A></DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the next arc after <code>arc</code> and
+ leaving <code>node</code>. Zero is returned if no more arcs are
+ available for the node.</DL>
</DD>
</DL>
<HR>
@@ -536,16 +573,16 @@ getArc</H3>
public int <B>getArc</B>(int&nbsp;node,
byte&nbsp;label)</PRE>
<DL>
-<DD><B>Description copied from class: <CODE><A HREF="../../morfologik/fsa/FSA.html#getArc(int, byte)">FSA</A></CODE></B></DD>
-<DD>Returns the identifier of an arc leaving <code>node</code> and labeled
- with <code>label</code>. An identifier equal to 0 means the node has no
- outgoing arc labeled <code>label</code>.
+<DD>
<P>
<DD><DL>
<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getArc(int, byte)">getArc</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
</DD>
<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA.html#getTraversalHelper()"><CODE>FSA.getTraversalHelper()</CODE></A></DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of an arc leaving <code>node</code> and
+ labeled with <code>label</code>. An identifier equal to 0 means
+ the node has no outgoing arc labeled <code>label</code>.</DL>
</DD>
</DL>
<HR>
@@ -555,7 +592,6 @@ getEndNode</H3>
<PRE>
public int <B>getEndNode</B>(int&nbsp;arc)</PRE>
<DL>
-<DD><B>Description copied from class: <CODE><A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)">FSA</A></CODE></B></DD>
<DD>Return the end node pointed to by a given <code>arc</code>. Terminal arcs
(those that point to a terminal state) have no end node representation
and throw a runtime exception.
@@ -564,7 +600,7 @@ public int <B>getEndNode</B>(int&nbsp;arc)</PRE>
<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)">getEndNode</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
</DD>
<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA.html#getTraversalHelper()"><CODE>FSA.getTraversalHelper()</CODE></A></DL>
+</DL>
</DD>
</DL>
<HR>
@@ -574,7 +610,6 @@ getArcLabel</H3>
<PRE>
public byte <B>getArcLabel</B>(int&nbsp;arc)</PRE>
<DL>
-<DD><B>Description copied from class: <CODE><A HREF="../../morfologik/fsa/FSA.html#getArcLabel(int)">FSA</A></CODE></B></DD>
<DD>Return the label associated with a given <code>arc</code>.
<P>
<DD><DL>
@@ -586,12 +621,30 @@ public byte <B>getArcLabel</B>(int&nbsp;arc)</PRE>
</DL>
<HR>
+<A NAME="getRightLanguageCount(int)"><!-- --></A><H3>
+getRightLanguageCount</H3>
+<PRE>
+public int <B>getRightLanguageCount</B>(int&nbsp;node)</PRE>
+<DL>
+<DD>
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getRightLanguageCount(int)">getRightLanguageCount</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the number of sequences reachable from the given state if
+ the automaton was compiled with <A HREF="../../morfologik/fsa/FSAFlags.html#NUMBERS"><CODE>FSAFlags.NUMBERS</CODE></A>. The size of
+ the right language of the state, in other words.</DL>
+</DD>
+</DL>
+<HR>
+
<A NAME="isArcFinal(int)"><!-- --></A><H3>
isArcFinal</H3>
<PRE>
public boolean <B>isArcFinal</B>(int&nbsp;arc)</PRE>
<DL>
-<DD><B>Description copied from class: <CODE><A HREF="../../morfologik/fsa/FSA.html#isArcFinal(int)">FSA</A></CODE></B></DD>
<DD>Returns <code>true</code> if the destination node at the end of this
<code>arc</code> corresponds to an input sequence created when building
this automaton.
@@ -610,9 +663,9 @@ isArcTerminal</H3>
<PRE>
public boolean <B>isArcTerminal</B>(int&nbsp;arc)</PRE>
<DL>
-<DD><B>Description copied from class: <CODE><A HREF="../../morfologik/fsa/FSA.html#isArcTerminal(int)">FSA</A></CODE></B></DD>
<DD>Returns <code>true</code> if this <code>arc</code> does not have a
- terminating node.
+ terminating node (@link <A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)"><CODE>FSA.getEndNode(int)</CODE></A> will throw an
+ exception). Implies <A HREF="../../morfologik/fsa/FSA.html#isArcFinal(int)"><CODE>FSA.isArcFinal(int)</CODE></A>.
<P>
<DD><DL>
<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#isArcTerminal(int)">isArcTerminal</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
@@ -621,6 +674,46 @@ public boolean <B>isArcTerminal</B>(int&nbsp;arc)</PRE>
</DL>
</DD>
</DL>
+<HR>
+
+<A NAME="isArcLast(int)"><!-- --></A><H3>
+isArcLast</H3>
+<PRE>
+public boolean <B>isArcLast</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>Returns <code>true</code> if this arc has <code>NEXT</code> bit set.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/CFSA2.html#BIT_LAST_ARC"><CODE>BIT_LAST_ARC</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isNextSet(int)"><!-- --></A><H3>
+isNextSet</H3>
+<PRE>
+public boolean <B>isNextSet</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/CFSA2.html#BIT_TARGET_NEXT"><CODE>BIT_TARGET_NEXT</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFlags()"><!-- --></A><H3>
+getFlags</H3>
+<PRE>
+public java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt; <B>getFlags</B>()</PRE>
+<DL>
+<DD>Returns a set of flags for this FSA instance.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getFlags()">getFlags</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
<!-- ========= END OF CLASS DATA ========= -->
<HR>
@@ -651,11 +744,11 @@ public boolean <B>isArcTerminal</B>(int&nbsp;arc)</PRE>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;NEXT CLASS</FONT></TD>
+&nbsp;<A HREF="../../morfologik/fsa/CFSA.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/fsa/FSAVer5Impl.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="FSAVer5Impl.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+ <A HREF="../../index.html?morfologik/fsa/CFSA2.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="CFSA2.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
diff --git a/doc/api/morfologik/fsa/CFSA2Serializer.html b/doc/api/morfologik/fsa/CFSA2Serializer.html
new file mode 100644
index 0000000..159fe3e
--- /dev/null
+++ b/doc/api/morfologik/fsa/CFSA2Serializer.html
@@ -0,0 +1,414 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
+<TITLE>
+CFSA2Serializer
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="CFSA2Serializer";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/CFSA2Serializer.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="CFSA2Serializer.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.fsa</FONT>
+<BR>
+Class CFSA2Serializer</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.CFSA2Serializer</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public final class <B>CFSA2Serializer</B><DT>extends java.lang.Object<DT>implements <A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></DL>
+</PRE>
+
+<P>
+Serializes in-memory <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> graphs to <A HREF="../../morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><CODE>CFSA2</CODE></A>.
+
+ <p>
+ It is possible to serialize the automaton with numbers required for perfect
+ hashing. See <A HREF="../../morfologik/fsa/CFSA2Serializer.html#withNumbers()"><CODE>withNumbers()</CODE></A> method.
+ </p>
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><CODE>CFSA2</CODE></A>,
+<A HREF="../../morfologik/fsa/FSA.html#read(java.io.InputStream)"><CODE>FSA.read(java.io.InputStream)</CODE></A></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2Serializer.html#CFSA2Serializer()">CFSA2Serializer</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2Serializer.html#getFlags()">getFlags</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return supported flags.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T extends java.io.OutputStream&gt;
+<BR>
+T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2Serializer.html#serialize(morfologik.fsa.FSA, T)">serialize</A></B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ T&nbsp;os)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serializes any <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> to <A HREF="../../morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><CODE>CFSA2</CODE></A> stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2Serializer.html#withAnnotationSeparator(byte)">withAnnotationSeparator</A></B>(byte&nbsp;annotationSeparator)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Supports built-in annotation separator.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2Serializer.html#withFiller(byte)">withFiller</A></B>(byte&nbsp;filler)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Supports built-in filler separator.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2Serializer.html#withLogger(morfologik.tools.IMessageLogger)">withLogger</A></B>(<A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A>&nbsp;logger)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log extra messages during construction.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/CFSA2Serializer.html#withNumbers()">withNumbers</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serialize the automaton with the number of right-language sequences in
+ each node.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="CFSA2Serializer()"><!-- --></A><H3>
+CFSA2Serializer</H3>
+<PRE>
+public <B>CFSA2Serializer</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="withNumbers()"><!-- --></A><H3>
+withNumbers</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A> <B>withNumbers</B>()</PRE>
+<DL>
+<DD>Serialize the automaton with the number of right-language sequences in
+ each node. This is required to implement perfect hashing. The numbering
+ also preserves the order of input sequences.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSASerializer.html#withNumbers()">withNumbers</A></CODE> in interface <CODE><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the same object for easier call chaining.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="serialize(morfologik.fsa.FSA,java.io.OutputStream)"><!-- --></A><A NAME="serialize(morfologik.fsa.FSA, T)"><!-- --></A><H3>
+serialize</H3>
+<PRE>
+public &lt;T extends java.io.OutputStream&gt; T <B>serialize</B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ T&nbsp;os)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Serializes any <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> to <A HREF="../../morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><CODE>CFSA2</CODE></A> stream.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSASerializer.html#serialize(morfologik.fsa.FSA, T)">serialize</A></CODE> in interface <CODE><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns <code>os</code> for chaining.
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE><DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/CFSA2Serializer.html#withNumbers"><CODE>withNumbers</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFlags()"><!-- --></A><H3>
+getFlags</H3>
+<PRE>
+public java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt; <B>getFlags</B>()</PRE>
+<DL>
+<DD>Return supported flags.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSASerializer.html#getFlags()">getFlags</A></CODE> in interface <CODE><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="withFiller(byte)"><!-- --></A><H3>
+withFiller</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A> <B>withFiller</B>(byte&nbsp;filler)</PRE>
+<DL>
+<DD><B>Description copied from interface: <CODE><A HREF="../../morfologik/fsa/FSASerializer.html#withFiller(byte)">FSASerializer</A></CODE></B></DD>
+<DD>Supports built-in filler separator. Only if <A HREF="../../morfologik/fsa/FSASerializer.html#getFlags()"><CODE>FSASerializer.getFlags()</CODE></A> returns
+ <A HREF="../../morfologik/fsa/FSAFlags.html#SEPARATORS"><CODE>FSAFlags.SEPARATORS</CODE></A>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSASerializer.html#withFiller(byte)">withFiller</A></CODE> in interface <CODE><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="withAnnotationSeparator(byte)"><!-- --></A><H3>
+withAnnotationSeparator</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A> <B>withAnnotationSeparator</B>(byte&nbsp;annotationSeparator)</PRE>
+<DL>
+<DD><B>Description copied from interface: <CODE><A HREF="../../morfologik/fsa/FSASerializer.html#withAnnotationSeparator(byte)">FSASerializer</A></CODE></B></DD>
+<DD>Supports built-in annotation separator. Only if <A HREF="../../morfologik/fsa/FSASerializer.html#getFlags()"><CODE>FSASerializer.getFlags()</CODE></A> returns
+ <A HREF="../../morfologik/fsa/FSAFlags.html#SEPARATORS"><CODE>FSAFlags.SEPARATORS</CODE></A>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSASerializer.html#withAnnotationSeparator(byte)">withAnnotationSeparator</A></CODE> in interface <CODE><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="withLogger(morfologik.tools.IMessageLogger)"><!-- --></A><H3>
+withLogger</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A> <B>withLogger</B>(<A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A>&nbsp;logger)</PRE>
+<DL>
+<DD><B>Description copied from interface: <CODE><A HREF="../../morfologik/fsa/FSASerializer.html#withLogger(morfologik.tools.IMessageLogger)">FSASerializer</A></CODE></B></DD>
+<DD>Log extra messages during construction.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSASerializer.html#withLogger(morfologik.tools.IMessageLogger)">withLogger</A></CODE> in interface <CODE><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/CFSA2Serializer.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="CFSA2Serializer.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/fsa/ConstantArcSizeFSA.html b/doc/api/morfologik/fsa/ConstantArcSizeFSA.html
new file mode 100644
index 0000000..e73b13a
--- /dev/null
+++ b/doc/api/morfologik/fsa/ConstantArcSizeFSA.html
@@ -0,0 +1,654 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
+<TITLE>
+ConstantArcSizeFSA
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="ConstantArcSizeFSA";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/ConstantArcSizeFSA.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ConstantArcSizeFSA.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.fsa</FONT>
+<BR>
+Class ConstantArcSizeFSA</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">morfologik.fsa.FSA</A>
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.ConstantArcSizeFSA</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.lang.Iterable&lt;java.nio.ByteBuffer&gt;</DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public final class <B>ConstantArcSizeFSA</B><DT>extends <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></DL>
+</PRE>
+
+<P>
+An FSA with constant-size arc representation produced directly
+ by <A HREF="../../morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa"><CODE>FSABuilder</CODE></A>.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa"><CODE>FSABuilder</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#ADDRESS_OFFSET">ADDRESS_OFFSET</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Offset of the address field inside an arc.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#ARC_SIZE">ARC_SIZE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Size of a single arc structure.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#BIT_ARC_FINAL">BIT_ARC_FINAL</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An arc flag indicating the target node of an arc corresponds to a final
+ state.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#BIT_ARC_LAST">BIT_ARC_LAST</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An arc flag indicating the arc is last within its state.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#FLAGS_OFFSET">FLAGS_OFFSET</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Offset of the flags field inside an arc.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#FLAGS_SIZE">FLAGS_SIZE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Size of the flags field (constant for the builder).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#LABEL_OFFSET">LABEL_OFFSET</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Offset of the label field inside an arc.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#LABEL_SIZE">LABEL_SIZE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Size of the label field (constant for the builder).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#TARGET_ADDRESS_SIZE">TARGET_ADDRESS_SIZE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Size of the target address field (constant for the builder).</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#getArc(int, byte)">getArc</A></B>(int&nbsp;node,
+ byte&nbsp;label)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#getArcLabel(int)">getArcLabel</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the label associated with a given <code>arc</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#getEndNode(int)">getEndNode</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the end node pointed to by a given <code>arc</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#getFirstArc(int)">getFirstArc</A></B>(int&nbsp;node)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#getFlags()">getFlags</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a set of flags for this FSA instance.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#getNextArc(int)">getNextArc</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#getRootNode()">getRootNode</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#isArcFinal(int)">isArcFinal</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if the destination node at the end of this
+ <code>arc</code> corresponds to an input sequence created when building
+ this automaton.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html#isArcTerminal(int)">isArcTerminal</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if this <code>arc</code> does not have a
+ terminating node (@link <A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)"><CODE>FSA.getEndNode(int)</CODE></A> will throw an
+ exception).</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_morfologik.fsa.FSA"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class morfologik.fsa.<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../morfologik/fsa/FSA.html#getArcCount(int)">getArcCount</A>, <A HREF="../../morfologik/fsa/FSA.html#getRightLanguageCount(int)">getRightLanguageCount</A>, <A HREF="../../morfologik/fsa/FSA.html#getSequences()">getSequences</A>, <A HREF="../../morfologik/fsa/FSA.html#getSequences(int)">getSequences</A>, <A HREF="../../morfologik/fsa/FSA.html#iterator()">iterator</A>, <A HREF="../../morfologik/fsa/FSA.html#read(java.io.InputStream)">read</A>, <A HREF="../../morfologik/fsa/FSA.html#visitAllStates(T)">visitAllStates</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPostOrder(T)">visitInPostOrder</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPostOrder(T, int)">visitInPostOrder</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPreOrder(T)">visitInPreOrder</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPreOrder(T, int)">visitInPreOrder</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="TARGET_ADDRESS_SIZE"><!-- --></A><H3>
+TARGET_ADDRESS_SIZE</H3>
+<PRE>
+public static final int <B>TARGET_ADDRESS_SIZE</B></PRE>
+<DL>
+<DD>Size of the target address field (constant for the builder).
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.ConstantArcSizeFSA.TARGET_ADDRESS_SIZE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FLAGS_SIZE"><!-- --></A><H3>
+FLAGS_SIZE</H3>
+<PRE>
+public static final int <B>FLAGS_SIZE</B></PRE>
+<DL>
+<DD>Size of the flags field (constant for the builder).
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.ConstantArcSizeFSA.FLAGS_SIZE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="LABEL_SIZE"><!-- --></A><H3>
+LABEL_SIZE</H3>
+<PRE>
+public static final int <B>LABEL_SIZE</B></PRE>
+<DL>
+<DD>Size of the label field (constant for the builder).
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.ConstantArcSizeFSA.LABEL_SIZE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="ARC_SIZE"><!-- --></A><H3>
+ARC_SIZE</H3>
+<PRE>
+public static final int <B>ARC_SIZE</B></PRE>
+<DL>
+<DD>Size of a single arc structure.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.ConstantArcSizeFSA.ARC_SIZE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FLAGS_OFFSET"><!-- --></A><H3>
+FLAGS_OFFSET</H3>
+<PRE>
+public static final int <B>FLAGS_OFFSET</B></PRE>
+<DL>
+<DD>Offset of the flags field inside an arc.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.ConstantArcSizeFSA.FLAGS_OFFSET">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="LABEL_OFFSET"><!-- --></A><H3>
+LABEL_OFFSET</H3>
+<PRE>
+public static final int <B>LABEL_OFFSET</B></PRE>
+<DL>
+<DD>Offset of the label field inside an arc.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.ConstantArcSizeFSA.LABEL_OFFSET">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="ADDRESS_OFFSET"><!-- --></A><H3>
+ADDRESS_OFFSET</H3>
+<PRE>
+public static final int <B>ADDRESS_OFFSET</B></PRE>
+<DL>
+<DD>Offset of the address field inside an arc.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.ConstantArcSizeFSA.ADDRESS_OFFSET">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="BIT_ARC_FINAL"><!-- --></A><H3>
+BIT_ARC_FINAL</H3>
+<PRE>
+public static final int <B>BIT_ARC_FINAL</B></PRE>
+<DL>
+<DD>An arc flag indicating the target node of an arc corresponds to a final
+ state.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.ConstantArcSizeFSA.BIT_ARC_FINAL">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="BIT_ARC_LAST"><!-- --></A><H3>
+BIT_ARC_LAST</H3>
+<PRE>
+public static final int <B>BIT_ARC_LAST</B></PRE>
+<DL>
+<DD>An arc flag indicating the arc is last within its state.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.ConstantArcSizeFSA.BIT_ARC_LAST">Constant Field Values</A></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getRootNode()"><!-- --></A><H3>
+getRootNode</H3>
+<PRE>
+public int <B>getRootNode</B>()</PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getRootNode()">getRootNode</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the root node of this automaton.
+ Returns 0 if the start node is also the end node (the automaton
+ is empty).</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFirstArc(int)"><!-- --></A><H3>
+getFirstArc</H3>
+<PRE>
+public int <B>getFirstArc</B>(int&nbsp;node)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getFirstArc(int)">getFirstArc</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the first arc leaving <code>node</code>
+ or 0 if the node has no outgoing arcs.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArc(int, byte)"><!-- --></A><H3>
+getArc</H3>
+<PRE>
+public int <B>getArc</B>(int&nbsp;node,
+ byte&nbsp;label)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getArc(int, byte)">getArc</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of an arc leaving <code>node</code> and
+ labeled with <code>label</code>. An identifier equal to 0 means
+ the node has no outgoing arc labeled <code>label</code>.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNextArc(int)"><!-- --></A><H3>
+getNextArc</H3>
+<PRE>
+public int <B>getNextArc</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getNextArc(int)">getNextArc</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the next arc after <code>arc</code> and
+ leaving <code>node</code>. Zero is returned if no more arcs are
+ available for the node.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArcLabel(int)"><!-- --></A><H3>
+getArcLabel</H3>
+<PRE>
+public byte <B>getArcLabel</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD><B>Description copied from class: <CODE><A HREF="../../morfologik/fsa/FSA.html#getArcLabel(int)">FSA</A></CODE></B></DD>
+<DD>Return the label associated with a given <code>arc</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getArcLabel(int)">getArcLabel</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isArcFinal(int)"><!-- --></A><H3>
+isArcFinal</H3>
+<PRE>
+public boolean <B>isArcFinal</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD><B>Description copied from class: <CODE><A HREF="../../morfologik/fsa/FSA.html#isArcFinal(int)">FSA</A></CODE></B></DD>
+<DD>Returns <code>true</code> if the destination node at the end of this
+ <code>arc</code> corresponds to an input sequence created when building
+ this automaton.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#isArcFinal(int)">isArcFinal</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isArcTerminal(int)"><!-- --></A><H3>
+isArcTerminal</H3>
+<PRE>
+public boolean <B>isArcTerminal</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD><B>Description copied from class: <CODE><A HREF="../../morfologik/fsa/FSA.html#isArcTerminal(int)">FSA</A></CODE></B></DD>
+<DD>Returns <code>true</code> if this <code>arc</code> does not have a
+ terminating node (@link <A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)"><CODE>FSA.getEndNode(int)</CODE></A> will throw an
+ exception). Implies <A HREF="../../morfologik/fsa/FSA.html#isArcFinal(int)"><CODE>FSA.isArcFinal(int)</CODE></A>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#isArcTerminal(int)">isArcTerminal</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getEndNode(int)"><!-- --></A><H3>
+getEndNode</H3>
+<PRE>
+public int <B>getEndNode</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD><B>Description copied from class: <CODE><A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)">FSA</A></CODE></B></DD>
+<DD>Return the end node pointed to by a given <code>arc</code>. Terminal arcs
+ (those that point to a terminal state) have no end node representation
+ and throw a runtime exception.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)">getEndNode</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFlags()"><!-- --></A><H3>
+getFlags</H3>
+<PRE>
+public java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt; <B>getFlags</B>()</PRE>
+<DL>
+<DD><B>Description copied from class: <CODE><A HREF="../../morfologik/fsa/FSA.html#getFlags()">FSA</A></CODE></B></DD>
+<DD>Returns a set of flags for this FSA instance.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getFlags()">getFlags</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/ConstantArcSizeFSA.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ConstantArcSizeFSA.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/fsa/FSA.html b/doc/api/morfologik/fsa/FSA.html
index cdaccea..b75dd1a 100644
--- a/doc/api/morfologik/fsa/FSA.html
+++ b/doc/api/morfologik/fsa/FSA.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:35 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
<TITLE>
FSA
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -54,8 +54,8 @@ function windowTitle()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;PREV CLASS&nbsp;
-&nbsp;<A HREF="../../morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSA5.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/fsa/FSA.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="FSA.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
@@ -75,9 +75,9 @@ function windowTitle()
</TR>
<TR>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
- SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
-DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_top"></A>
@@ -98,7 +98,7 @@ java.lang.Object
<DT><B>All Implemented Interfaces:</B> <DD>java.lang.Iterable&lt;java.nio.ByteBuffer&gt;</DD>
</DL>
<DL>
-<DT><B>Direct Known Subclasses:</B> <DD><A HREF="../../morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A></DD>
+<DT><B>Direct Known Subclasses:</B> <DD><A HREF="../../morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A>, <A HREF="../../morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A>, <A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A>, <A HREF="../../morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A></DD>
</DL>
<HR>
<DL>
@@ -106,62 +106,24 @@ java.lang.Object
</PRE>
<P>
-This class implements Finite State Automaton traversal as described in Jan
- Daciuk's <i>Incremental Construction of Finite-State Automata and
- Transducers, and Their Use in the Natural Language Processing</i> (PhD
- thesis, Technical University of Gdansk).
+This is a top abstract class for handling finite state automata. These
+ automata are arc-based, a design described in Jan Daciuk's <i>Incremental
+ Construction of Finite-State Automata and Transducers, and Their Use in the
+ Natural Language Processing</i> (PhD thesis, Technical University of Gdansk).
<p>
- This is an abstract base class for all forms of binary storage present in Jan
- Daciuk's FSA package.
+ Concrete subclasses (implementations) provide varying tradeoffs and features:
+ traversal speed vs. memory size, for example.
+ </p>
<P>
<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa"><CODE>FSABuilder</CODE></A></DL>
<HR>
<P>
-<!-- =========== FIELD SUMMARY =========== -->
-
-<A NAME="field_summary"><!-- --></A>
-<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
-<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
-<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
-<B>Field Summary</B></FONT></TH>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>protected &nbsp;byte</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#filler">filler</A></B></CODE>
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The meaning of this field is not clear (check the FSA documentation).</TD>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>protected &nbsp;byte</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#gotoLength">gotoLength</A></B></CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Size of transition's destination node "address".</TD>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>protected &nbsp;byte</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#version">version</A></B></CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dictionary version (derived from the combination of flags).</TD>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>static&nbsp;byte</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#VERSION_5">VERSION_5</A></B></CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Version number for version 5 of the automaton.</TD>
-</TR>
-</TABLE>
-&nbsp;
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
<A NAME="constructor_summary"><!-- --></A>
@@ -171,13 +133,10 @@ This class implements Finite State Automaton traversal as described in Jan
<B>Constructor Summary</B></FONT></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>protected </CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#FSA(java.io.InputStream, java.lang.String)">FSA</A></B>(java.io.InputStream&nbsp;fsaStream,
- java.lang.String&nbsp;dictionaryEncoding)</CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#FSA()">FSA</A></B>()</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a new automaton reading the FSA automaton from an input stream.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
</TABLE>
&nbsp;
@@ -191,23 +150,20 @@ This class implements Finite State Automaton traversal as described in Jan
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;char</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getAnnotationSeparator()">getAnnotationSeparator</A></B>()</CODE>
+<CODE>abstract &nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getArc(int, byte)">getArc</A></B>(int&nbsp;node,
+ byte&nbsp;label)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the annotation separator character, converted to a character
- according to the encoding scheme passed in in the constructor of this
- class.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>abstract &nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getArc(int, byte)">getArc</A></B>(int&nbsp;node,
- byte&nbsp;label)</CODE>
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getArcCount(int)">getArcCount</A></B>(int&nbsp;node)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the identifier of an arc leaving <code>node</code> and labeled
- with <code>label</code>.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Calculates the number of arcs of a given node.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
@@ -227,25 +183,15 @@ This class implements Finite State Automaton traversal as described in Jan
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;char</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getFillerCharacter()">getFillerCharacter</A></B>()</CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the filler character, converted to a character according to the
- encoding scheme passed in in the constructor of this class.</TD>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>abstract &nbsp;int</CODE></FONT></TD>
<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getFirstArc(int)">getFirstArc</A></B>(int&nbsp;node)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the identifier of the first arc leaving <code>node</code> or 0 if
- the node has no outgoing arcs.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;int</CODE></FONT></TD>
+<CODE>abstract &nbsp;java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt;</CODE></FONT></TD>
<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getFlags()">getFlags</A></B>()</CODE>
<BR>
@@ -253,121 +199,179 @@ This class implements Finite State Automaton traversal as described in Jan
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>static&nbsp;<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getInstance(java.io.File, java.lang.String)">getInstance</A></B>(java.io.File&nbsp;fsaFile,
- java.lang.String&nbsp;dictionaryEncoding)</CODE>
+<CODE>abstract &nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getNextArc(int)">getNextArc</A></B>(int&nbsp;arc)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This static method will attempt to instantiate an appropriate
- implementation of the FSA for the version found in file given in the
- input argument.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>static&nbsp;<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getInstance(java.io.InputStream, java.lang.String)">getInstance</A></B>(java.io.InputStream&nbsp;fsaStream,
- java.lang.String&nbsp;dictionaryEncoding)</CODE>
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getRightLanguageCount(int)">getRightLanguageCount</A></B>(int&nbsp;node)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This static method will attempt to instantiate an appropriate
- implementation of the FSA for the version found in file given in the
- input argument.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>abstract &nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getNextArc(int, int)">getNextArc</A></B>(int&nbsp;node,
- int&nbsp;arc)</CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getRootNode()">getRootNode</A></B>()</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the identifier of the next arc after <code>arc</code> and leaving
- <code>node</code>.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>abstract &nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getNumberOfArcs()">getNumberOfArcs</A></B>()</CODE>
+<CODE>&nbsp;java.lang.Iterable&lt;java.nio.ByteBuffer&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getSequences()">getSequences</A></B>()</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the number of arcs in this automaton.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An alias of calling <A HREF="../../morfologik/fsa/FSA.html#iterator()"><CODE>iterator()</CODE></A> directly (<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> is also
+ <CODE>Iterable</CODE>).</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>abstract &nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getNumberOfNodes()">getNumberOfNodes</A></B>()</CODE>
+<CODE>&nbsp;java.lang.Iterable&lt;java.nio.ByteBuffer&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getSequences(int)">getSequences</A></B>(int&nbsp;node)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the number of nodes in this automaton.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an iterator over all binary sequences starting at the given FSA
+ state (node) and ending in final nodes.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>abstract &nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getRootNode()">getRootNode</A></B>()</CODE>
+<CODE>abstract &nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#isArcFinal(int)">isArcFinal</A></B>(int&nbsp;arc)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the identifier of the root node of this automaton.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if the destination node at the end of this
+ <code>arc</code> corresponds to an input sequence created when building
+ this automaton.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa">FSATraversalHelper</A></CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getTraversalHelper()">getTraversalHelper</A></B>()</CODE>
+<CODE>abstract &nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#isArcTerminal(int)">isArcTerminal</A></B>(int&nbsp;arc)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an object which can be used to walk the edges of this finite
- state automaton and match arbitrary sequences against its states.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if this <code>arc</code> does not have a
+ terminating node (@link <A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)"><CODE>getEndNode(int)</CODE></A> will throw an
+ exception).</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#getVersion()">getVersion</A></B>()</CODE>
+<CODE>&nbsp;java.util.Iterator&lt;java.nio.ByteBuffer&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#iterator()">iterator</A></B>()</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the version number of the binary representation of this FSA.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an iterator over all binary sequences starting from the initial
+ FSA state (node) and ending in final nodes.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>abstract &nbsp;boolean</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#isArcFinal(int)">isArcFinal</A></B>(int&nbsp;arc)</CODE>
+<CODE>static
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T extends <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&gt;
+<BR>
+T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#read(java.io.InputStream)">read</A></B>(java.io.InputStream&nbsp;in)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if the destination node at the end of this
- <code>arc</code> corresponds to an input sequence created when building
- this automaton.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A factory for reading automata in any of the supported versions.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>abstract &nbsp;boolean</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#isArcTerminal(int)">isArcTerminal</A></B>(int&nbsp;arc)</CODE>
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T extends <A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa">StateVisitor</A>&gt;
+<BR>
+T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#visitAllStates(T)">visitAllStates</A></B>(T&nbsp;v)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if this <code>arc</code> does not have a
- terminating node.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Visit all states.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;java.util.Iterator&lt;java.nio.ByteBuffer&gt;</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#iterator()">iterator</A></B>()</CODE>
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T extends <A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa">StateVisitor</A>&gt;
+<BR>
+T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#visitInPostOrder(T)">visitInPostOrder</A></B>(T&nbsp;v)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an iterator over all binary sequences starting from the initial
- FSA state and ending in final nodes.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Same as <A HREF="../../morfologik/fsa/FSA.html#visitInPostOrder(T, int)"><CODE>visitInPostOrder(StateVisitor, int)</CODE></A>,
+ starting from root automaton node.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>protected &nbsp;byte[]</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#readFully(java.io.InputStream)">readFully</A></B>(java.io.InputStream&nbsp;stream)</CODE>
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T extends <A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa">StateVisitor</A>&gt;
+<BR>
+T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#visitInPostOrder(T, int)">visitInPostOrder</A></B>(T&nbsp;v,
+ int&nbsp;node)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reads all bytes from an input stream.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Visits all states reachable from <code>node</code> in postorder.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>protected &nbsp;void</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#readHeader(java.io.DataInput, long)">readHeader</A></B>(java.io.DataInput&nbsp;in,
- long&nbsp;fileSize)</CODE>
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T extends <A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa">StateVisitor</A>&gt;
+<BR>
+T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#visitInPreOrder(T)">visitInPreOrder</A></B>(T&nbsp;v)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Same as <A HREF="../../morfologik/fsa/FSA.html#visitInPreOrder(T, int)"><CODE>visitInPreOrder(StateVisitor, int)</CODE></A>, starting from root automaton node.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T extends <A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa">StateVisitor</A>&gt;
+<BR>
+T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA.html#visitInPreOrder(T, int)">visitInPreOrder</A></B>(T&nbsp;v,
+ int&nbsp;node)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reads a FSA header from a stream.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Visits all states in preorder.</TD>
</TR>
</TABLE>
&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
@@ -382,65 +386,6 @@ This class implements Finite State Automaton traversal as described in Jan
&nbsp;
<P>
-<!-- ============ FIELD DETAIL =========== -->
-
-<A NAME="field_detail"><!-- --></A>
-<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
-<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
-<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
-<B>Field Detail</B></FONT></TH>
-</TR>
-</TABLE>
-
-<A NAME="VERSION_5"><!-- --></A><H3>
-VERSION_5</H3>
-<PRE>
-public static final byte <B>VERSION_5</B></PRE>
-<DL>
-<DD>Version number for version 5 of the automaton.
-<P>
-<DL>
-<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.FSA.VERSION_5">Constant Field Values</A></DL>
-</DL>
-<HR>
-
-<A NAME="version"><!-- --></A><H3>
-version</H3>
-<PRE>
-protected byte <B>version</B></PRE>
-<DL>
-<DD>Dictionary version (derived from the combination of flags).
-<P>
-<DL>
-</DL>
-</DL>
-<HR>
-
-<A NAME="filler"><!-- --></A><H3>
-filler</H3>
-<PRE>
-protected byte <B>filler</B></PRE>
-<DL>
-<DD>The meaning of this field is not clear (check the FSA documentation).
-<P>
-<DL>
-</DL>
-</DL>
-<HR>
-
-<A NAME="gotoLength"><!-- --></A><H3>
-gotoLength</H3>
-<PRE>
-protected byte <B>gotoLength</B></PRE>
-<DL>
-<DD>Size of transition's destination node "address". This field may also have
- different interpretation, or may not be used at all. It depends on the
- combination of flags used for building FSA.
-<P>
-<DL>
-</DL>
-</DL>
-
<!-- ========= CONSTRUCTOR DETAIL ======== -->
<A NAME="constructor_detail"><!-- --></A>
@@ -451,20 +396,11 @@ protected byte <B>gotoLength</B></PRE>
</TR>
</TABLE>
-<A NAME="FSA(java.io.InputStream, java.lang.String)"><!-- --></A><H3>
+<A NAME="FSA()"><!-- --></A><H3>
FSA</H3>
<PRE>
-protected <B>FSA</B>(java.io.InputStream&nbsp;fsaStream,
- java.lang.String&nbsp;dictionaryEncoding)
- throws java.io.IOException</PRE>
-<DL>
-<DD>Creates a new automaton reading the FSA automaton from an input stream.
-<P>
+public <B>FSA</B>()</PRE>
<DL>
-<DT><B>Parameters:</B><DD><CODE>fsaStream</CODE> - An input stream with FSA automaton.
-<DT><B>Throws:</B>
-<DD><CODE>java.io.IOException</CODE> - if the dictionary file cannot be read, or version of the file
- is not supported.</DL>
</DL>
<!-- ============ METHOD DETAIL ========== -->
@@ -477,89 +413,80 @@ protected <B>FSA</B>(java.io.InputStream&nbsp;fsaStream,
</TR>
</TABLE>
-<A NAME="getVersion()"><!-- --></A><H3>
-getVersion</H3>
+<A NAME="getRootNode()"><!-- --></A><H3>
+getRootNode</H3>
<PRE>
-public final int <B>getVersion</B>()</PRE>
+public abstract int <B>getRootNode</B>()</PRE>
<DL>
-<DD>Returns the version number of the binary representation of this FSA.
-
- <p>
- The version number is a derivation of combination of flags and is exactly
- the same as in Jan Daciuk's FSA package.
-<P>
<DD><DL>
</DL>
</DD>
<DD><DL>
-</DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the root node of this automaton.
+ Returns 0 if the start node is also the end node (the automaton
+ is empty).</DL>
</DD>
</DL>
<HR>
-<A NAME="getFlags()"><!-- --></A><H3>
-getFlags</H3>
+<A NAME="getFirstArc(int)"><!-- --></A><H3>
+getFirstArc</H3>
<PRE>
-public final int <B>getFlags</B>()</PRE>
+public abstract int <B>getFirstArc</B>(int&nbsp;node)</PRE>
<DL>
-<DD>Returns a set of flags for this FSA instance. Each flag is represented by
- a unique bit in the integer returned. Therefore to check whether the
- dictionary has been built using <A HREF="../../morfologik/fsa/FSAFlags.html#FLEXIBLE"><CODE>FSAFlags.FLEXIBLE</CODE></A> flag, one must
- perform a bitwise AND:
- <code>boolean isFlexible = ((dict.getFlags() &amp; FSA.FSA_FLEXIBLE ) != 0)</code>
-<P>
<DD><DL>
</DL>
</DD>
<DD><DL>
-</DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the first arc leaving <code>node</code>
+ or 0 if the node has no outgoing arcs.</DL>
</DD>
</DL>
<HR>
-<A NAME="getAnnotationSeparator()"><!-- --></A><H3>
-getAnnotationSeparator</H3>
+<A NAME="getNextArc(int)"><!-- --></A><H3>
+getNextArc</H3>
<PRE>
-public final char <B>getAnnotationSeparator</B>()</PRE>
+public abstract int <B>getNextArc</B>(int&nbsp;arc)</PRE>
<DL>
-<DD>Return the annotation separator character, converted to a character
- according to the encoding scheme passed in in the constructor of this
- class.
-<P>
<DD><DL>
</DL>
</DD>
<DD><DL>
-</DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the next arc after <code>arc</code> and
+ leaving <code>node</code>. Zero is returned if no more arcs are
+ available for the node.</DL>
</DD>
</DL>
<HR>
-<A NAME="getFillerCharacter()"><!-- --></A><H3>
-getFillerCharacter</H3>
+<A NAME="getArc(int, byte)"><!-- --></A><H3>
+getArc</H3>
<PRE>
-public final char <B>getFillerCharacter</B>()</PRE>
+public abstract int <B>getArc</B>(int&nbsp;node,
+ byte&nbsp;label)</PRE>
<DL>
-<DD>Return the filler character, converted to a character according to the
- encoding scheme passed in in the constructor of this class.
-<P>
<DD><DL>
</DL>
</DD>
<DD><DL>
-</DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of an arc leaving <code>node</code> and
+ labeled with <code>label</code>. An identifier equal to 0 means
+ the node has no outgoing arc labeled <code>label</code>.</DL>
</DD>
</DL>
<HR>
-<A NAME="getNumberOfArcs()"><!-- --></A><H3>
-getNumberOfArcs</H3>
+<A NAME="getArcLabel(int)"><!-- --></A><H3>
+getArcLabel</H3>
<PRE>
-public abstract int <B>getNumberOfArcs</B>()</PRE>
+public abstract byte <B>getArcLabel</B>(int&nbsp;arc)</PRE>
<DL>
-<DD>Returns the number of arcs in this automaton. <b>Depending on the
- representation of the automaton, this method may take a long time to
- finish.</b>
+<DD>Return the label associated with a given <code>arc</code>.
<P>
<DD><DL>
</DL>
@@ -570,14 +497,14 @@ public abstract int <B>getNumberOfArcs</B>()</PRE>
</DL>
<HR>
-<A NAME="getNumberOfNodes()"><!-- --></A><H3>
-getNumberOfNodes</H3>
+<A NAME="isArcFinal(int)"><!-- --></A><H3>
+isArcFinal</H3>
<PRE>
-public abstract int <B>getNumberOfNodes</B>()</PRE>
+public abstract boolean <B>isArcFinal</B>(int&nbsp;arc)</PRE>
<DL>
-<DD>Returns the number of nodes in this automaton. <b>Depending on the
- representation of the automaton, this method may take a long time to
- finish.</b>
+<DD>Returns <code>true</code> if the destination node at the end of this
+ <code>arc</code> corresponds to an input sequence created when building
+ this automaton.
<P>
<DD><DL>
</DL>
@@ -588,13 +515,14 @@ public abstract int <B>getNumberOfNodes</B>()</PRE>
</DL>
<HR>
-<A NAME="getTraversalHelper()"><!-- --></A><H3>
-getTraversalHelper</H3>
+<A NAME="isArcTerminal(int)"><!-- --></A><H3>
+isArcTerminal</H3>
<PRE>
-public <A HREF="../../morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa">FSATraversalHelper</A> <B>getTraversalHelper</B>()</PRE>
+public abstract boolean <B>isArcTerminal</B>(int&nbsp;arc)</PRE>
<DL>
-<DD>Returns an object which can be used to walk the edges of this finite
- state automaton and match arbitrary sequences against its states.
+<DD>Returns <code>true</code> if this <code>arc</code> does not have a
+ terminating node (@link <A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)"><CODE>getEndNode(int)</CODE></A> will throw an
+ exception). Implies <A HREF="../../morfologik/fsa/FSA.html#isArcFinal(int)"><CODE>isArcFinal(int)</CODE></A>.
<P>
<DD><DL>
</DL>
@@ -605,212 +533,217 @@ public <A HREF="../../morfologik/fsa/FSATraversalHelper.html" title="class in mo
</DL>
<HR>
-<A NAME="getInstance(java.io.File, java.lang.String)"><!-- --></A><H3>
-getInstance</H3>
+<A NAME="getEndNode(int)"><!-- --></A><H3>
+getEndNode</H3>
<PRE>
-public static <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A> <B>getInstance</B>(java.io.File&nbsp;fsaFile,
- java.lang.String&nbsp;dictionaryEncoding)
- throws java.io.IOException</PRE>
+public abstract int <B>getEndNode</B>(int&nbsp;arc)</PRE>
<DL>
-<DD>This static method will attempt to instantiate an appropriate
- implementation of the FSA for the version found in file given in the
- input argument.
+<DD>Return the end node pointed to by a given <code>arc</code>. Terminal arcs
+ (those that point to a terminal state) have no end node representation
+ and throw a runtime exception.
<P>
<DD><DL>
</DL>
</DD>
<DD><DL>
-
-<DT><B>Throws:</B>
-<DD><CODE>java.io.IOException</CODE> - An exception is thrown if no corresponding FSA parser is
- found or if the input file cannot be opened.</DL>
+</DL>
</DD>
</DL>
<HR>
-<A NAME="getInstance(java.io.InputStream, java.lang.String)"><!-- --></A><H3>
-getInstance</H3>
+<A NAME="getFlags()"><!-- --></A><H3>
+getFlags</H3>
<PRE>
-public static <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A> <B>getInstance</B>(java.io.InputStream&nbsp;fsaStream,
- java.lang.String&nbsp;dictionaryEncoding)
- throws java.io.IOException</PRE>
+public abstract java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt; <B>getFlags</B>()</PRE>
<DL>
-<DD>This static method will attempt to instantiate an appropriate
- implementation of the FSA for the version found in file given in the
- input argument.
+<DD>Returns a set of flags for this FSA instance.
<P>
<DD><DL>
</DL>
</DD>
<DD><DL>
-
-<DT><B>Throws:</B>
-<DD><CODE>java.io.IOException</CODE> - An exception is thrown if no corresponding FSA parser is
- found or if the input file cannot be opened.</DL>
+</DL>
</DD>
</DL>
<HR>
-<A NAME="readHeader(java.io.DataInput, long)"><!-- --></A><H3>
-readHeader</H3>
+<A NAME="getArcCount(int)"><!-- --></A><H3>
+getArcCount</H3>
<PRE>
-protected void <B>readHeader</B>(java.io.DataInput&nbsp;in,
- long&nbsp;fileSize)
- throws java.io.IOException</PRE>
-<DL>
-<DD>Reads a FSA header from a stream.
+public int <B>getArcCount</B>(int&nbsp;node)</PRE>
+<DL>
+<DD>Calculates the number of arcs of a given node. Unless really required,
+ use the following idiom for looping through all arcs:
+ <pre>
+ for (int arc = fsa.getFirstArc(node); arc != 0; arc = fsa.getNextArc(arc)) {
+ }
+ </pre>
<P>
<DD><DL>
</DL>
</DD>
<DD><DL>
-
-<DT><B>Throws:</B>
-<DD><CODE>java.io.IOException</CODE> - If the stream is not a dictionary, or if the version is not
- supported.</DL>
+</DL>
</DD>
</DL>
<HR>
-<A NAME="readFully(java.io.InputStream)"><!-- --></A><H3>
-readFully</H3>
+<A NAME="getRightLanguageCount(int)"><!-- --></A><H3>
+getRightLanguageCount</H3>
<PRE>
-protected byte[] <B>readFully</B>(java.io.InputStream&nbsp;stream)
- throws java.io.IOException</PRE>
+public int <B>getRightLanguageCount</B>(int&nbsp;node)</PRE>
<DL>
-<DD>Reads all bytes from an input stream.
-<P>
<DD><DL>
</DL>
</DD>
<DD><DL>
-<DT><B>Parameters:</B><DD><CODE>stream</CODE> -
-<DT><B>Returns:</B><DD>Returns an array of read bytes.
+
+<DT><B>Returns:</B><DD>Returns the number of sequences reachable from the given state if
+ the automaton was compiled with <A HREF="../../morfologik/fsa/FSAFlags.html#NUMBERS"><CODE>FSAFlags.NUMBERS</CODE></A>. The size of
+ the right language of the state, in other words.
<DT><B>Throws:</B>
-<DD><CODE>java.io.IOException</CODE></DL>
+<DD><CODE>java.lang.UnsupportedOperationException</CODE> - If the automaton was not compiled with
+ <A HREF="../../morfologik/fsa/FSAFlags.html#NUMBERS"><CODE>FSAFlags.NUMBERS</CODE></A>. The value can then be computed by manual count
+ of <A HREF="../../morfologik/fsa/FSA.html#getSequences(int)"><CODE>getSequences(int)</CODE></A>.</DL>
</DD>
</DL>
<HR>
-<A NAME="iterator()"><!-- --></A><H3>
-iterator</H3>
+<A NAME="getSequences(int)"><!-- --></A><H3>
+getSequences</H3>
<PRE>
-public java.util.Iterator&lt;java.nio.ByteBuffer&gt; <B>iterator</B>()</PRE>
+public java.lang.Iterable&lt;java.nio.ByteBuffer&gt; <B>getSequences</B>(int&nbsp;node)</PRE>
<DL>
-<DD>Returns an iterator over all binary sequences starting from the initial
- FSA state and ending in final nodes. The returned iterator is a
- <CODE>ByteBuffer</CODE> that changes on each call to <CODE>Iterator.next()</CODE>,
- so if the content should be preserved, it must be copied somewhere else.
+<DD>Returns an iterator over all binary sequences starting at the given FSA
+ state (node) and ending in final nodes. This corresponds to a set of
+ suffixes of a given prefix from all sequences stored in the automaton.
<p>
- It is guaranteed that the returned byte buffer is backed by a byte array
- and that the content of the byte buffer starts at the array's index 0.
+ The returned iterator is a <CODE>ByteBuffer</CODE> whose contents changes on
+ each call to <CODE>Iterator.next()</CODE>. The keep the contents between calls
+ to <CODE>Iterator.next()</CODE>, one must copy the buffer to some other
+ location.
+ </p>
+
+ <p>
+ <b>Important.</b> It is guaranteed that the returned byte buffer is
+ backed by a byte array and that the content of the byte buffer starts at
+ the array's index 0.
+ </p>
<P>
<DD><DL>
-<DT><B>Specified by:</B><DD><CODE>iterator</CODE> in interface <CODE>java.lang.Iterable&lt;java.nio.ByteBuffer&gt;</CODE></DL>
+</DL>
</DD>
<DD><DL>
-</DL>
+<DT><B>See Also:</B><DD><CODE>Iterable</CODE></DL>
</DD>
</DL>
<HR>
-<A NAME="getRootNode()"><!-- --></A><H3>
-getRootNode</H3>
+<A NAME="getSequences()"><!-- --></A><H3>
+getSequences</H3>
<PRE>
-public abstract int <B>getRootNode</B>()</PRE>
+public final java.lang.Iterable&lt;java.nio.ByteBuffer&gt; <B>getSequences</B>()</PRE>
<DL>
-<DD>Returns the identifier of the root node of this automaton. May return 0
- if the start node is also the end node.
+<DD>An alias of calling <A HREF="../../morfologik/fsa/FSA.html#iterator()"><CODE>iterator()</CODE></A> directly (<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> is also
+ <CODE>Iterable</CODE>).
<P>
<DD><DL>
</DL>
</DD>
<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA.html#getTraversalHelper()"><CODE>getTraversalHelper()</CODE></A></DL>
+</DL>
</DD>
</DL>
<HR>
-<A NAME="getFirstArc(int)"><!-- --></A><H3>
-getFirstArc</H3>
+<A NAME="iterator()"><!-- --></A><H3>
+iterator</H3>
<PRE>
-public abstract int <B>getFirstArc</B>(int&nbsp;node)</PRE>
+public final java.util.Iterator&lt;java.nio.ByteBuffer&gt; <B>iterator</B>()</PRE>
<DL>
-<DD>Returns the identifier of the first arc leaving <code>node</code> or 0 if
- the node has no outgoing arcs.
+<DD>Returns an iterator over all binary sequences starting from the initial
+ FSA state (node) and ending in final nodes. The returned iterator is a
+ <CODE>ByteBuffer</CODE> whose contents changes on each call to
+ <CODE>Iterator.next()</CODE>. The keep the contents between calls to
+ <CODE>Iterator.next()</CODE>, one must copy the buffer to some other location.
+
+ <p>
+ <b>Important.</b> It is guaranteed that the returned byte buffer is
+ backed by a byte array and that the content of the byte buffer starts at
+ the array's index 0.
+ </p>
<P>
<DD><DL>
-</DL>
+<DT><B>Specified by:</B><DD><CODE>iterator</CODE> in interface <CODE>java.lang.Iterable&lt;java.nio.ByteBuffer&gt;</CODE></DL>
</DD>
<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA.html#getTraversalHelper()"><CODE>getTraversalHelper()</CODE></A></DL>
+<DT><B>See Also:</B><DD><CODE>Iterable</CODE></DL>
</DD>
</DL>
<HR>
-<A NAME="getArc(int, byte)"><!-- --></A><H3>
-getArc</H3>
+<A NAME="visitAllStates(morfologik.fsa.StateVisitor)"><!-- --></A><A NAME="visitAllStates(T)"><!-- --></A><H3>
+visitAllStates</H3>
<PRE>
-public abstract int <B>getArc</B>(int&nbsp;node,
- byte&nbsp;label)</PRE>
+public &lt;T extends <A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa">StateVisitor</A>&gt; T <B>visitAllStates</B>(T&nbsp;v)</PRE>
<DL>
-<DD>Returns the identifier of an arc leaving <code>node</code> and labeled
- with <code>label</code>. An identifier equal to 0 means the node has no
- outgoing arc labeled <code>label</code>.
+<DD>Visit all states. The order of visiting is undefined. This method may be faster
+ than traversing the automaton in post or preorder since it can scan states
+ linearly. Returning false from <A HREF="../../morfologik/fsa/StateVisitor.html#accept(int)"><CODE>StateVisitor.accept(int)</CODE></A>
+ immediately terminates the traversal.
<P>
<DD><DL>
</DL>
</DD>
<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA.html#getTraversalHelper()"><CODE>getTraversalHelper()</CODE></A></DL>
+</DL>
</DD>
</DL>
<HR>
-<A NAME="getNextArc(int, int)"><!-- --></A><H3>
-getNextArc</H3>
+<A NAME="visitInPostOrder(morfologik.fsa.StateVisitor)"><!-- --></A><A NAME="visitInPostOrder(T)"><!-- --></A><H3>
+visitInPostOrder</H3>
<PRE>
-public abstract int <B>getNextArc</B>(int&nbsp;node,
- int&nbsp;arc)</PRE>
+public &lt;T extends <A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa">StateVisitor</A>&gt; T <B>visitInPostOrder</B>(T&nbsp;v)</PRE>
<DL>
-<DD>Returns the identifier of the next arc after <code>arc</code> and leaving
- <code>node</code>. Zero is returned if no more arcs are available for the
- node.
+<DD>Same as <A HREF="../../morfologik/fsa/FSA.html#visitInPostOrder(T, int)"><CODE>visitInPostOrder(StateVisitor, int)</CODE></A>,
+ starting from root automaton node.
<P>
<DD><DL>
</DL>
</DD>
<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA.html#getTraversalHelper()"><CODE>getTraversalHelper()</CODE></A></DL>
+</DL>
</DD>
</DL>
<HR>
-<A NAME="getEndNode(int)"><!-- --></A><H3>
-getEndNode</H3>
+<A NAME="visitInPostOrder(morfologik.fsa.StateVisitor,int)"><!-- --></A><A NAME="visitInPostOrder(T, int)"><!-- --></A><H3>
+visitInPostOrder</H3>
<PRE>
-public abstract int <B>getEndNode</B>(int&nbsp;arc)</PRE>
+public &lt;T extends <A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa">StateVisitor</A>&gt; T <B>visitInPostOrder</B>(T&nbsp;v,
+ int&nbsp;node)</PRE>
<DL>
-<DD>Return the end node pointed to by a given <code>arc</code>. Terminal arcs
- (those that point to a terminal state) have no end node representation
- and throw a runtime exception.
+<DD>Visits all states reachable from <code>node</code> in postorder.
+ Returning false from <A HREF="../../morfologik/fsa/StateVisitor.html#accept(int)"><CODE>StateVisitor.accept(int)</CODE></A>
+ immediately terminates the traversal.
<P>
<DD><DL>
</DL>
</DD>
<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA.html#getTraversalHelper()"><CODE>getTraversalHelper()</CODE></A></DL>
+</DL>
</DD>
</DL>
<HR>
-<A NAME="getArcLabel(int)"><!-- --></A><H3>
-getArcLabel</H3>
+<A NAME="visitInPreOrder(morfologik.fsa.StateVisitor)"><!-- --></A><A NAME="visitInPreOrder(T)"><!-- --></A><H3>
+visitInPreOrder</H3>
<PRE>
-public abstract byte <B>getArcLabel</B>(int&nbsp;arc)</PRE>
+public &lt;T extends <A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa">StateVisitor</A>&gt; T <B>visitInPreOrder</B>(T&nbsp;v)</PRE>
<DL>
-<DD>Return the label associated with a given <code>arc</code>.
+<DD>Same as <A HREF="../../morfologik/fsa/FSA.html#visitInPreOrder(T, int)"><CODE>visitInPreOrder(StateVisitor, int)</CODE></A>, starting from root automaton node.
<P>
<DD><DL>
</DL>
@@ -821,14 +754,14 @@ public abstract byte <B>getArcLabel</B>(int&nbsp;arc)</PRE>
</DL>
<HR>
-<A NAME="isArcFinal(int)"><!-- --></A><H3>
-isArcFinal</H3>
+<A NAME="visitInPreOrder(morfologik.fsa.StateVisitor,int)"><!-- --></A><A NAME="visitInPreOrder(T, int)"><!-- --></A><H3>
+visitInPreOrder</H3>
<PRE>
-public abstract boolean <B>isArcFinal</B>(int&nbsp;arc)</PRE>
+public &lt;T extends <A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa">StateVisitor</A>&gt; T <B>visitInPreOrder</B>(T&nbsp;v,
+ int&nbsp;node)</PRE>
<DL>
-<DD>Returns <code>true</code> if the destination node at the end of this
- <code>arc</code> corresponds to an input sequence created when building
- this automaton.
+<DD>Visits all states in preorder. Returning false from <A HREF="../../morfologik/fsa/StateVisitor.html#accept(int)"><CODE>StateVisitor.accept(int)</CODE></A>
+ skips traversal of all sub-states of a given state.
<P>
<DD><DL>
</DL>
@@ -839,19 +772,22 @@ public abstract boolean <B>isArcFinal</B>(int&nbsp;arc)</PRE>
</DL>
<HR>
-<A NAME="isArcTerminal(int)"><!-- --></A><H3>
-isArcTerminal</H3>
+<A NAME="read(java.io.InputStream)"><!-- --></A><H3>
+read</H3>
<PRE>
-public abstract boolean <B>isArcTerminal</B>(int&nbsp;arc)</PRE>
+public static &lt;T extends <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&gt; T <B>read</B>(java.io.InputStream&nbsp;in)
+ throws java.io.IOException</PRE>
<DL>
-<DD>Returns <code>true</code> if this <code>arc</code> does not have a
- terminating node.
+<DD>A factory for reading automata in any of the supported versions. If
+ possible, explicit constructors should be used.
<P>
<DD><DL>
</DL>
</DD>
<DD><DL>
-</DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE><DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA5.html#FSA5(java.io.InputStream)"><CODE>FSA5.FSA5(InputStream)</CODE></A></DL>
</DD>
</DL>
<!-- ========= END OF CLASS DATA ========= -->
@@ -884,8 +820,8 @@ public abstract boolean <B>isArcTerminal</B>(int&nbsp;arc)</PRE>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;PREV CLASS&nbsp;
-&nbsp;<A HREF="../../morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSA5.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/fsa/FSA.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="FSA.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
@@ -905,9 +841,9 @@ public abstract boolean <B>isArcTerminal</B>(int&nbsp;arc)</PRE>
</TR>
<TR>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
- SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
-DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_bottom"></A>
diff --git a/doc/api/morfologik/fsa/FSA5.html b/doc/api/morfologik/fsa/FSA5.html
new file mode 100644
index 0000000..c6ae2cf
--- /dev/null
+++ b/doc/api/morfologik/fsa/FSA5.html
@@ -0,0 +1,887 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
+<TITLE>
+FSA5
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="FSA5";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSA5.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSA5.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.fsa</FONT>
+<BR>
+Class FSA5</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">morfologik.fsa.FSA</A>
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.FSA5</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.lang.Iterable&lt;java.nio.ByteBuffer&gt;</DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public final class <B>FSA5</B><DT>extends <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></DL>
+</PRE>
+
+<P>
+FSA binary format implementation for version 5.
+
+ <p>
+ Version 5 indicates the dictionary was built with these flags:
+ <A HREF="../../morfologik/fsa/FSAFlags.html#FLEXIBLE"><CODE>FSAFlags.FLEXIBLE</CODE></A>, <A HREF="../../morfologik/fsa/FSAFlags.html#STOPBIT"><CODE>FSAFlags.STOPBIT</CODE></A> and
+ <A HREF="../../morfologik/fsa/FSAFlags.html#NEXTBIT"><CODE>FSAFlags.NEXTBIT</CODE></A>. The internal representation of the FSA must
+ therefore follow this description (please note this format describes only a
+ single transition (arc), not the entire dictionary file).
+
+ <pre>
+ ---- this node header present only if automaton was compiled with NUMBERS option.
+ Byte
+ +-+-+-+-+-+-+-+-+\
+ 0 | | | | | | | | | \ LSB
+ +-+-+-+-+-+-+-+-+ +
+ 1 | | | | | | | | | | number of strings recognized
+ +-+-+-+-+-+-+-+-+ +----- by the automaton starting
+ : : : : : : : : : | from this node.
+ +-+-+-+-+-+-+-+-+ +
+ ctl-1 | | | | | | | | | / MSB
+ +-+-+-+-+-+-+-+-+/
+
+ ---- remaining part of the node
+
+ Byte
+ +-+-+-+-+-+-+-+-+\
+ 0 | | | | | | | | | +------ label
+ +-+-+-+-+-+-+-+-+/
+
+ +------------- node pointed to is next
+ | +----------- the last arc of the node
+ | | +--------- the arc is final
+ | | |
+ +-----------+
+ | | | | |
+ ___+___ | | | |
+ / \ | | | |
+ MSB LSB |
+ 7 6 5 4 3 2 1 0 |
+ +-+-+-+-+-+-+-+-+ |
+ 1 | | | | | | | | | \ \
+ +-+-+-+-+-+-+-+-+ \ \ LSB
+ +-+-+-+-+-+-+-+-+ +
+ 2 | | | | | | | | | |
+ +-+-+-+-+-+-+-+-+ |
+ 3 | | | | | | | | | +----- target node address (in bytes)
+ +-+-+-+-+-+-+-+-+ | (not present except for the byte
+ : : : : : : : : : | with flags if the node pointed to
+ +-+-+-+-+-+-+-+-+ + is next)
+ gtl | | | | | | | | | / MSB
+ +-+-+-+-+-+-+-+-+ /
+ gtl+1 (gtl = gotoLength)
+ </pre>
+<P>
+
+<P>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#ADDRESS_OFFSET">ADDRESS_OFFSET</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An offset in the arc structure, where the address and flags field begins.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#annotation">annotation</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Annotation character.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#arcs">arcs</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;An array of bytes with the internal representation of the automaton.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#BIT_FINAL_ARC">BIT_FINAL_ARC</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bit indicating that an arc corresponds to the last character of a
+ sequence available when building the automaton.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#BIT_LAST_ARC">BIT_LAST_ARC</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bit indicating that an arc is the last one of the node's list and the
+ following one belongs to another node.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#BIT_TARGET_NEXT">BIT_TARGET_NEXT</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bit indicating that the target node of this arc follows it in the
+ compressed automaton structure (no goto field).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#DEFAULT_ANNOTATION">DEFAULT_ANNOTATION</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Default annotation byte.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#DEFAULT_FILLER">DEFAULT_FILLER</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Default filler byte.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#filler">filler</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Filler character.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#gtl">gtl</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Number of bytes each address takes in full, expanded form (goto length).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#nodeDataLength">nodeDataLength</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The length of the node header structure (if the automaton was compiled with
+ <code>NUMBERS</code> option).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#VERSION">VERSION</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Automaton version as in the file header.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#FSA5(java.io.InputStream)">FSA5</A></B>(java.io.InputStream&nbsp;fsaStream)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Read and wrap a binary automaton in FSA version 5.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#getArc(int, byte)">getArc</A></B>(int&nbsp;node,
+ byte&nbsp;label)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#getArcLabel(int)">getArcLabel</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the label associated with a given <code>arc</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#getEndNode(int)">getEndNode</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the end node pointed to by a given <code>arc</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#getFirstArc(int)">getFirstArc</A></B>(int&nbsp;node)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#getFlags()">getFlags</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a set of flags for this FSA instance.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#getNextArc(int)">getNextArc</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#getRightLanguageCount(int)">getRightLanguageCount</A></B>(int&nbsp;node)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the number encoded at the given node.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#getRootNode()">getRootNode</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the start node of this automaton.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#isArcFinal(int)">isArcFinal</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if the destination node at the end of this
+ <code>arc</code> corresponds to an input sequence created when building
+ this automaton.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#isArcLast(int)">isArcLast</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if this arc has <code>LAST</code> bit set.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#isArcTerminal(int)">isArcTerminal</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if this <code>arc</code> does not have a
+ terminating node (@link <A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)"><CODE>FSA.getEndNode(int)</CODE></A> will throw an
+ exception).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5.html#isNextSet(int)">isNextSet</A></B>(int&nbsp;arc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_morfologik.fsa.FSA"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class morfologik.fsa.<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../morfologik/fsa/FSA.html#getArcCount(int)">getArcCount</A>, <A HREF="../../morfologik/fsa/FSA.html#getSequences()">getSequences</A>, <A HREF="../../morfologik/fsa/FSA.html#getSequences(int)">getSequences</A>, <A HREF="../../morfologik/fsa/FSA.html#iterator()">iterator</A>, <A HREF="../../morfologik/fsa/FSA.html#read(java.io.InputStream)">read</A>, <A HREF="../../morfologik/fsa/FSA.html#visitAllStates(T)">visitAllStates</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPostOrder(T)">visitInPostOrder</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPostOrder(T, int)">visitInPostOrder</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPreOrder(T)">visitInPreOrder</A>, <A HREF="../../morfologik/fsa/FSA.html#visitInPreOrder(T, int)">visitInPreOrder</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="DEFAULT_FILLER"><!-- --></A><H3>
+DEFAULT_FILLER</H3>
+<PRE>
+public static final byte <B>DEFAULT_FILLER</B></PRE>
+<DL>
+<DD>Default filler byte.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.FSA5.DEFAULT_FILLER">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="DEFAULT_ANNOTATION"><!-- --></A><H3>
+DEFAULT_ANNOTATION</H3>
+<PRE>
+public static final byte <B>DEFAULT_ANNOTATION</B></PRE>
+<DL>
+<DD>Default annotation byte.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.FSA5.DEFAULT_ANNOTATION">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="VERSION"><!-- --></A><H3>
+VERSION</H3>
+<PRE>
+public static final byte <B>VERSION</B></PRE>
+<DL>
+<DD>Automaton version as in the file header.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.FSA5.VERSION">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="BIT_FINAL_ARC"><!-- --></A><H3>
+BIT_FINAL_ARC</H3>
+<PRE>
+public static final int <B>BIT_FINAL_ARC</B></PRE>
+<DL>
+<DD>Bit indicating that an arc corresponds to the last character of a
+ sequence available when building the automaton.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.FSA5.BIT_FINAL_ARC">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="BIT_LAST_ARC"><!-- --></A><H3>
+BIT_LAST_ARC</H3>
+<PRE>
+public static final int <B>BIT_LAST_ARC</B></PRE>
+<DL>
+<DD>Bit indicating that an arc is the last one of the node's list and the
+ following one belongs to another node.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.FSA5.BIT_LAST_ARC">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="BIT_TARGET_NEXT"><!-- --></A><H3>
+BIT_TARGET_NEXT</H3>
+<PRE>
+public static final int <B>BIT_TARGET_NEXT</B></PRE>
+<DL>
+<DD>Bit indicating that the target node of this arc follows it in the
+ compressed automaton structure (no goto field).
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.FSA5.BIT_TARGET_NEXT">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="ADDRESS_OFFSET"><!-- --></A><H3>
+ADDRESS_OFFSET</H3>
+<PRE>
+public static final int <B>ADDRESS_OFFSET</B></PRE>
+<DL>
+<DD>An offset in the arc structure, where the address and flags field begins.
+ In version 5 of FSA automata, this value is constant (1, skip label).
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.FSA5.ADDRESS_OFFSET">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="arcs"><!-- --></A><H3>
+arcs</H3>
+<PRE>
+public final byte[] <B>arcs</B></PRE>
+<DL>
+<DD>An array of bytes with the internal representation of the automaton.
+ Please see the documentation of this class for more information on how
+ this structure is organized.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="nodeDataLength"><!-- --></A><H3>
+nodeDataLength</H3>
+<PRE>
+public final int <B>nodeDataLength</B></PRE>
+<DL>
+<DD>The length of the node header structure (if the automaton was compiled with
+ <code>NUMBERS</code> option). Otherwise zero.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="gtl"><!-- --></A><H3>
+gtl</H3>
+<PRE>
+public final int <B>gtl</B></PRE>
+<DL>
+<DD>Number of bytes each address takes in full, expanded form (goto length).
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="filler"><!-- --></A><H3>
+filler</H3>
+<PRE>
+public final byte <B>filler</B></PRE>
+<DL>
+<DD>Filler character.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="annotation"><!-- --></A><H3>
+annotation</H3>
+<PRE>
+public final byte <B>annotation</B></PRE>
+<DL>
+<DD>Annotation character.
+<P>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="FSA5(java.io.InputStream)"><!-- --></A><H3>
+FSA5</H3>
+<PRE>
+public <B>FSA5</B>(java.io.InputStream&nbsp;fsaStream)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Read and wrap a binary automaton in FSA version 5.
+<P>
+<DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getRootNode()"><!-- --></A><H3>
+getRootNode</H3>
+<PRE>
+public int <B>getRootNode</B>()</PRE>
+<DL>
+<DD>Returns the start node of this automaton.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getRootNode()">getRootNode</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the root node of this automaton.
+ Returns 0 if the start node is also the end node (the automaton
+ is empty).</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFirstArc(int)"><!-- --></A><H3>
+getFirstArc</H3>
+<PRE>
+public final int <B>getFirstArc</B>(int&nbsp;node)</PRE>
+<DL>
+<DD>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getFirstArc(int)">getFirstArc</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the first arc leaving <code>node</code>
+ or 0 if the node has no outgoing arcs.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNextArc(int)"><!-- --></A><H3>
+getNextArc</H3>
+<PRE>
+public final int <B>getNextArc</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getNextArc(int)">getNextArc</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of the next arc after <code>arc</code> and
+ leaving <code>node</code>. Zero is returned if no more arcs are
+ available for the node.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArc(int, byte)"><!-- --></A><H3>
+getArc</H3>
+<PRE>
+public int <B>getArc</B>(int&nbsp;node,
+ byte&nbsp;label)</PRE>
+<DL>
+<DD>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getArc(int, byte)">getArc</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the identifier of an arc leaving <code>node</code> and
+ labeled with <code>label</code>. An identifier equal to 0 means
+ the node has no outgoing arc labeled <code>label</code>.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getEndNode(int)"><!-- --></A><H3>
+getEndNode</H3>
+<PRE>
+public int <B>getEndNode</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>Return the end node pointed to by a given <code>arc</code>. Terminal arcs
+ (those that point to a terminal state) have no end node representation
+ and throw a runtime exception.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)">getEndNode</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArcLabel(int)"><!-- --></A><H3>
+getArcLabel</H3>
+<PRE>
+public byte <B>getArcLabel</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>Return the label associated with a given <code>arc</code>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getArcLabel(int)">getArcLabel</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isArcFinal(int)"><!-- --></A><H3>
+isArcFinal</H3>
+<PRE>
+public boolean <B>isArcFinal</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>Returns <code>true</code> if the destination node at the end of this
+ <code>arc</code> corresponds to an input sequence created when building
+ this automaton.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#isArcFinal(int)">isArcFinal</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isArcTerminal(int)"><!-- --></A><H3>
+isArcTerminal</H3>
+<PRE>
+public boolean <B>isArcTerminal</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>Returns <code>true</code> if this <code>arc</code> does not have a
+ terminating node (@link <A HREF="../../morfologik/fsa/FSA.html#getEndNode(int)"><CODE>FSA.getEndNode(int)</CODE></A> will throw an
+ exception). Implies <A HREF="../../morfologik/fsa/FSA.html#isArcFinal(int)"><CODE>FSA.isArcFinal(int)</CODE></A>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#isArcTerminal(int)">isArcTerminal</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRightLanguageCount(int)"><!-- --></A><H3>
+getRightLanguageCount</H3>
+<PRE>
+public int <B>getRightLanguageCount</B>(int&nbsp;node)</PRE>
+<DL>
+<DD>Returns the number encoded at the given node. The number equals the count
+ of the set of suffixes reachable from <code>node</code> (called its right
+ language).
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getRightLanguageCount(int)">getRightLanguageCount</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the number of sequences reachable from the given state if
+ the automaton was compiled with <A HREF="../../morfologik/fsa/FSAFlags.html#NUMBERS"><CODE>FSAFlags.NUMBERS</CODE></A>. The size of
+ the right language of the state, in other words.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFlags()"><!-- --></A><H3>
+getFlags</H3>
+<PRE>
+public java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt; <B>getFlags</B>()</PRE>
+<DL>
+<DD>Returns a set of flags for this FSA instance.
+
+ <p>For this automaton version, an additional <A HREF="../../morfologik/fsa/FSAFlags.html#NUMBERS"><CODE>FSAFlags.NUMBERS</CODE></A> flag
+ may be set to indicate the automaton contains extra fields for each node.</p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSA.html#getFlags()">getFlags</A></CODE> in class <CODE><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isArcLast(int)"><!-- --></A><H3>
+isArcLast</H3>
+<PRE>
+public boolean <B>isArcLast</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD>Returns <code>true</code> if this arc has <code>LAST</code> bit set.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA5.html#BIT_LAST_ARC"><CODE>BIT_LAST_ARC</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isNextSet(int)"><!-- --></A><H3>
+isNextSet</H3>
+<PRE>
+public boolean <B>isNextSet</B>(int&nbsp;arc)</PRE>
+<DL>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA5.html#BIT_TARGET_NEXT"><CODE>BIT_TARGET_NEXT</CODE></A></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSA5.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSA5.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/fsa/FSA5Serializer.html b/doc/api/morfologik/fsa/FSA5Serializer.html
new file mode 100644
index 0000000..8a7a237
--- /dev/null
+++ b/doc/api/morfologik/fsa/FSA5Serializer.html
@@ -0,0 +1,468 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
+<TITLE>
+FSA5Serializer
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="FSA5Serializer";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSA5.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSA5Serializer.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSA5Serializer.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.fsa</FONT>
+<BR>
+Class FSA5Serializer</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.FSA5Serializer</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public final class <B>FSA5Serializer</B><DT>extends java.lang.Object<DT>implements <A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></DL>
+</PRE>
+
+<P>
+Serializes in-memory <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> graphs to a binary format compatible with
+ Jan Daciuk's <code>fsa</code>'s package <code>FSA5</code> format.
+
+ <p>
+ It is possible to serialize the automaton with numbers required for perfect
+ hashing. See <A HREF="../../morfologik/fsa/FSA5Serializer.html#withNumbers()"><CODE>withNumbers()</CODE></A> method.
+ </p>
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA5.html" title="class in morfologik.fsa"><CODE>FSA5</CODE></A>,
+<A HREF="../../morfologik/fsa/FSA.html#read(java.io.InputStream)"><CODE>FSA.read(java.io.InputStream)</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5Serializer.html#annotationByte">annotationByte</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5Serializer.html#fillerByte">fillerByte</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5Serializer.html#FSA5Serializer()">FSA5Serializer</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5Serializer.html#getFlags()">getFlags</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return supported flags.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T extends java.io.OutputStream&gt;
+<BR>
+T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5Serializer.html#serialize(morfologik.fsa.FSA, T)">serialize</A></B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ T&nbsp;os)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serialize root state <code>s</code> to an output stream in
+ <code>FSA5</code> format.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5Serializer.html#withAnnotationSeparator(byte)">withAnnotationSeparator</A></B>(byte&nbsp;annotationSeparator)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Supports built-in annotation separator.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5Serializer.html#withFiller(byte)">withFiller</A></B>(byte&nbsp;filler)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Supports built-in filler separator.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5Serializer.html#withLogger(morfologik.tools.IMessageLogger)">withLogger</A></B>(<A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A>&nbsp;logger)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log extra messages during construction.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSA5Serializer.html#withNumbers()">withNumbers</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serialize the automaton with the number of right-language sequences in
+ each node.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="fillerByte"><!-- --></A><H3>
+fillerByte</H3>
+<PRE>
+public byte <B>fillerByte</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA5.html#filler"><CODE>FSA5.filler</CODE></A></DL>
+</DL>
+<HR>
+
+<A NAME="annotationByte"><!-- --></A><H3>
+annotationByte</H3>
+<PRE>
+public byte <B>annotationByte</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA5.html#annotation"><CODE>FSA5.annotation</CODE></A></DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="FSA5Serializer()"><!-- --></A><H3>
+FSA5Serializer</H3>
+<PRE>
+public <B>FSA5Serializer</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="withNumbers()"><!-- --></A><H3>
+withNumbers</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A> <B>withNumbers</B>()</PRE>
+<DL>
+<DD>Serialize the automaton with the number of right-language sequences in
+ each node. This is required to implement perfect hashing. The numbering
+ also preserves the order of input sequences.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSASerializer.html#withNumbers()">withNumbers</A></CODE> in interface <CODE><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns the same object for easier call chaining.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="withFiller(byte)"><!-- --></A><H3>
+withFiller</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A> <B>withFiller</B>(byte&nbsp;filler)</PRE>
+<DL>
+<DD>Supports built-in filler separator. Only if <A HREF="../../morfologik/fsa/FSASerializer.html#getFlags()"><CODE>FSASerializer.getFlags()</CODE></A> returns
+ <A HREF="../../morfologik/fsa/FSAFlags.html#SEPARATORS"><CODE>FSAFlags.SEPARATORS</CODE></A>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSASerializer.html#withFiller(byte)">withFiller</A></CODE> in interface <CODE><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="withAnnotationSeparator(byte)"><!-- --></A><H3>
+withAnnotationSeparator</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A> <B>withAnnotationSeparator</B>(byte&nbsp;annotationSeparator)</PRE>
+<DL>
+<DD>Supports built-in annotation separator. Only if <A HREF="../../morfologik/fsa/FSASerializer.html#getFlags()"><CODE>FSASerializer.getFlags()</CODE></A> returns
+ <A HREF="../../morfologik/fsa/FSAFlags.html#SEPARATORS"><CODE>FSAFlags.SEPARATORS</CODE></A>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSASerializer.html#withAnnotationSeparator(byte)">withAnnotationSeparator</A></CODE> in interface <CODE><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="withLogger(morfologik.tools.IMessageLogger)"><!-- --></A><H3>
+withLogger</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A> <B>withLogger</B>(<A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A>&nbsp;logger)</PRE>
+<DL>
+<DD>Log extra messages during construction.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSASerializer.html#withLogger(morfologik.tools.IMessageLogger)">withLogger</A></CODE> in interface <CODE><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="serialize(morfologik.fsa.FSA,java.io.OutputStream)"><!-- --></A><A NAME="serialize(morfologik.fsa.FSA, T)"><!-- --></A><H3>
+serialize</H3>
+<PRE>
+public &lt;T extends java.io.OutputStream&gt; T <B>serialize</B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ T&nbsp;os)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Serialize root state <code>s</code> to an output stream in
+ <code>FSA5</code> format.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSASerializer.html#serialize(morfologik.fsa.FSA, T)">serialize</A></CODE> in interface <CODE><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Returns <code>os</code> for chaining.
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE><DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA5Serializer.html#withNumbers"><CODE>withNumbers</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFlags()"><!-- --></A><H3>
+getFlags</H3>
+<PRE>
+public java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt; <B>getFlags</B>()</PRE>
+<DL>
+<DD>Return supported flags.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/fsa/FSASerializer.html#getFlags()">getFlags</A></CODE> in interface <CODE><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSA5.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSA5Serializer.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSA5Serializer.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/fsa/FSABuilder.InfoEntry.html b/doc/api/morfologik/fsa/FSABuilder.InfoEntry.html
new file mode 100644
index 0000000..67fc1e3
--- /dev/null
+++ b/doc/api/morfologik/fsa/FSABuilder.InfoEntry.html
@@ -0,0 +1,431 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
+<TITLE>
+FSABuilder.InfoEntry
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="FSABuilder.InfoEntry";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSABuilder.InfoEntry.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSABuilder.InfoEntry.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#enum_constant_summary">ENUM CONSTANTS</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#enum_constant_detail">ENUM CONSTANTS</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.fsa</FONT>
+<BR>
+Enum FSABuilder.InfoEntry</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by ">java.lang.Enum&lt;<A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A>&gt;
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.FSABuilder.InfoEntry</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable, java.lang.Comparable&lt;<A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A>&gt;</DD>
+</DL>
+<DL>
+<DT><B>Enclosing class:</B><DD><A HREF="../../morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa">FSABuilder</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public static enum <B>FSABuilder.InfoEntry</B><DT>extends java.lang.Enum&lt;<A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A>&gt;</DL>
+</PRE>
+
+<P>
+Debug and information constants.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSABuilder.html#getInfo()"><CODE>FSABuilder.getInfo()</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== ENUM CONSTANT SUMMARY =========== -->
+
+<A NAME="enum_constant_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Enum Constant Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html#CONSTANT_ARC_AUTOMATON_SIZE">CONSTANT_ARC_AUTOMATON_SIZE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html#ESTIMATED_MEMORY_CONSUMPTION_MB">ESTIMATED_MEMORY_CONSUMPTION_MB</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html#MAX_ACTIVE_PATH_LENGTH">MAX_ACTIVE_PATH_LENGTH</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html#SERIALIZATION_BUFFER_REALLOCATIONS">SERIALIZATION_BUFFER_REALLOCATIONS</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html#SERIALIZATION_BUFFER_SIZE">SERIALIZATION_BUFFER_SIZE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html#STATE_REGISTRY_SIZE">STATE_REGISTRY_SIZE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html#STATE_REGISTRY_TABLE_SLOTS">STATE_REGISTRY_TABLE_SLOTS</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html#toString()">toString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html#valueOf(java.lang.String)">valueOf</A></B>(java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the enum constant of this type with the specified name.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A>[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html#values()">values</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an array containing the constants of this enum type, in
+the order they are declared.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Enum"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Enum</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, compareTo, equals, finalize, getDeclaringClass, hashCode, name, ordinal, valueOf</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>getClass, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ ENUM CONSTANT DETAIL =========== -->
+
+<A NAME="enum_constant_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Enum Constant Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="SERIALIZATION_BUFFER_SIZE"><!-- --></A><H3>
+SERIALIZATION_BUFFER_SIZE</H3>
+<PRE>
+public static final <A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A> <B>SERIALIZATION_BUFFER_SIZE</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="SERIALIZATION_BUFFER_REALLOCATIONS"><!-- --></A><H3>
+SERIALIZATION_BUFFER_REALLOCATIONS</H3>
+<PRE>
+public static final <A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A> <B>SERIALIZATION_BUFFER_REALLOCATIONS</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="CONSTANT_ARC_AUTOMATON_SIZE"><!-- --></A><H3>
+CONSTANT_ARC_AUTOMATON_SIZE</H3>
+<PRE>
+public static final <A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A> <B>CONSTANT_ARC_AUTOMATON_SIZE</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="MAX_ACTIVE_PATH_LENGTH"><!-- --></A><H3>
+MAX_ACTIVE_PATH_LENGTH</H3>
+<PRE>
+public static final <A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A> <B>MAX_ACTIVE_PATH_LENGTH</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="STATE_REGISTRY_TABLE_SLOTS"><!-- --></A><H3>
+STATE_REGISTRY_TABLE_SLOTS</H3>
+<PRE>
+public static final <A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A> <B>STATE_REGISTRY_TABLE_SLOTS</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="STATE_REGISTRY_SIZE"><!-- --></A><H3>
+STATE_REGISTRY_SIZE</H3>
+<PRE>
+public static final <A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A> <B>STATE_REGISTRY_SIZE</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="ESTIMATED_MEMORY_CONSUMPTION_MB"><!-- --></A><H3>
+ESTIMATED_MEMORY_CONSUMPTION_MB</H3>
+<PRE>
+public static final <A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A> <B>ESTIMATED_MEMORY_CONSUMPTION_MB</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="values()"><!-- --></A><H3>
+values</H3>
+<PRE>
+public static <A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A>[] <B>values</B>()</PRE>
+<DL>
+<DD>Returns an array containing the constants of this enum type, in
+the order they are declared. This method may be used to iterate
+over the constants as follows:
+<pre>
+for (FSABuilder.InfoEntry c : FSABuilder.InfoEntry.values())
+&nbsp; System.out.println(c);
+</pre>
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an array containing the constants of this enum type, in
+the order they are declared</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="valueOf(java.lang.String)"><!-- --></A><H3>
+valueOf</H3>
+<PRE>
+public static <A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A> <B>valueOf</B>(java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Returns the enum constant of this type with the specified name.
+The string must match <I>exactly</I> an identifier used to declare an
+enum constant in this type. (Extraneous whitespace characters are
+not permitted.)
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the enum constant to be returned.
+<DT><B>Returns:</B><DD>the enum constant with the specified name
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalArgumentException</CODE> - if this enum type has no constant
+with the specified name
+<DD><CODE>java.lang.NullPointerException</CODE> - if the argument is null</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toString()"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public java.lang.String <B>toString</B>()</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>toString</CODE> in class <CODE>java.lang.Enum&lt;<A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A>&gt;</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSABuilder.InfoEntry.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSABuilder.InfoEntry.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#enum_constant_summary">ENUM CONSTANTS</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#enum_constant_detail">ENUM CONSTANTS</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/fsa/FSABuilder.html b/doc/api/morfologik/fsa/FSABuilder.html
new file mode 100644
index 0000000..b862e6c
--- /dev/null
+++ b/doc/api/morfologik/fsa/FSABuilder.html
@@ -0,0 +1,450 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
+<TITLE>
+FSABuilder
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="FSABuilder";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSABuilder.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSABuilder.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.fsa</FONT>
+<BR>
+Class FSABuilder</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.FSABuilder</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public final class <B>FSABuilder</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+Fast, memory-conservative finite state automaton builder, returning a
+ byte-serialized <A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa"><CODE>ConstantArcSizeFSA</CODE></A> (a tradeoff between construction
+ speed and memory consumption).
+<P>
+
+<P>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+<A NAME="nested_class_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Nested Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Debug and information constants.</TD>
+</TR>
+</TABLE>
+&nbsp;<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.util.Comparator&lt;byte[]&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.html#LEXICAL_ORDERING">LEXICAL_ORDERING</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Comparator comparing full byte arrays consistently with
+ <A HREF="../../morfologik/fsa/FSABuilder.html#compare(byte[], int, int, byte[], int, int)"><CODE>compare(byte[], int, int, byte[], int, int)</CODE></A>.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.html#FSABuilder()">FSABuilder</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.html#FSABuilder(int)">FSABuilder</A></B>(int&nbsp;bufferGrowthSize)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.html#add(byte[], int, int)">add</A></B>(byte[]&nbsp;sequence,
+ int&nbsp;start,
+ int&nbsp;len)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add a single sequence of bytes to the FSA.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.html#build(byte[][])">build</A></B>(byte[][]&nbsp;input)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Build a minimal, deterministic automaton from a sorted list of byte sequences.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.html#build(java.lang.Iterable)">build</A></B>(java.lang.Iterable&lt;byte[]&gt;&nbsp;input)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Build a minimal, deterministic automaton from an iterable list of byte sequences.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.html#compare(byte[], int, int, byte[], int, int)">compare</A></B>(byte[]&nbsp;s1,
+ int&nbsp;start1,
+ int&nbsp;lens1,
+ byte[]&nbsp;s2,
+ int&nbsp;start2,
+ int&nbsp;lens2)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Lexicographic order of input sequences.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.html#complete()">complete</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Complete the automaton.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Map&lt;<A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A>,java.lang.Object&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSABuilder.html#getInfo()">getInfo</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return various statistics concerning the FSA and its compilation.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="LEXICAL_ORDERING"><!-- --></A><H3>
+LEXICAL_ORDERING</H3>
+<PRE>
+public static final java.util.Comparator&lt;byte[]&gt; <B>LEXICAL_ORDERING</B></PRE>
+<DL>
+<DD>Comparator comparing full byte arrays consistently with
+ <A HREF="../../morfologik/fsa/FSABuilder.html#compare(byte[], int, int, byte[], int, int)"><CODE>compare(byte[], int, int, byte[], int, int)</CODE></A>.
+<P>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="FSABuilder()"><!-- --></A><H3>
+FSABuilder</H3>
+<PRE>
+public <B>FSABuilder</B>()</PRE>
+<DL>
+</DL>
+<HR>
+
+<A NAME="FSABuilder(int)"><!-- --></A><H3>
+FSABuilder</H3>
+<PRE>
+public <B>FSABuilder</B>(int&nbsp;bufferGrowthSize)</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="add(byte[], int, int)"><!-- --></A><H3>
+add</H3>
+<PRE>
+public void <B>add</B>(byte[]&nbsp;sequence,
+ int&nbsp;start,
+ int&nbsp;len)</PRE>
+<DL>
+<DD>Add a single sequence of bytes to the FSA. The input must be lexicographically greater
+ than any previously added sequence.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="complete()"><!-- --></A><H3>
+complete</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A> <B>complete</B>()</PRE>
+<DL>
+<DD>Complete the automaton.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="build(byte[][])"><!-- --></A><H3>
+build</H3>
+<PRE>
+public static <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A> <B>build</B>(byte[][]&nbsp;input)</PRE>
+<DL>
+<DD>Build a minimal, deterministic automaton from a sorted list of byte sequences.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="build(java.lang.Iterable)"><!-- --></A><H3>
+build</H3>
+<PRE>
+public static <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A> <B>build</B>(java.lang.Iterable&lt;byte[]&gt;&nbsp;input)</PRE>
+<DL>
+<DD>Build a minimal, deterministic automaton from an iterable list of byte sequences.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getInfo()"><!-- --></A><H3>
+getInfo</H3>
+<PRE>
+public java.util.Map&lt;<A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A>,java.lang.Object&gt; <B>getInfo</B>()</PRE>
+<DL>
+<DD>Return various statistics concerning the FSA and its compilation.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="compare(byte[], int, int, byte[], int, int)"><!-- --></A><H3>
+compare</H3>
+<PRE>
+public static int <B>compare</B>(byte[]&nbsp;s1,
+ int&nbsp;start1,
+ int&nbsp;lens1,
+ byte[]&nbsp;s2,
+ int&nbsp;start2,
+ int&nbsp;lens2)</PRE>
+<DL>
+<DD>Lexicographic order of input sequences. By default, consistent with the "C" sort
+ (absolute value of bytes, 0-255).
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSABuilder.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSABuilder.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/fsa/FSAFinalStatesIterator.html b/doc/api/morfologik/fsa/FSAFinalStatesIterator.html
index 994e490..796922a 100644
--- a/doc/api/morfologik/fsa/FSAFinalStatesIterator.html
+++ b/doc/api/morfologik/fsa/FSAFinalStatesIterator.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
<TITLE>
FSAFinalStatesIterator
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -54,7 +54,7 @@ function windowTitle()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
&nbsp;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/fsa/FSAFinalStatesIterator.html" target="_top"><B>FRAMES</B></A> &nbsp;
@@ -75,9 +75,9 @@ function windowTitle()
</TR>
<TR>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
- SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
-DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_top"></A>
@@ -103,8 +103,8 @@ java.lang.Object
</PRE>
<P>
-An iterator that traverses all final states reachable from a given
- node and returns byte sequences corresponding to final states.
+An iterator that traverses the right language of a given node (all sequences
+ reachable from a given node).
<P>
<P>
@@ -112,6 +112,23 @@ An iterator that traverses all final states reachable from a given
<P>
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFinalStatesIterator.html#FSAFinalStatesIterator(morfologik.fsa.FSA, int)">FSAFinalStatesIterator</A></B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ int&nbsp;node)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create an instance of the iterator for a given node.</TD>
+</TR>
+</TABLE>
+&nbsp;
<!-- ========== METHOD SUMMARY =========== -->
<A NAME="method_summary"><!-- --></A>
@@ -165,6 +182,26 @@ An iterator that traverses all final states reachable from a given
&nbsp;
<P>
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="FSAFinalStatesIterator(morfologik.fsa.FSA, int)"><!-- --></A><H3>
+FSAFinalStatesIterator</H3>
+<PRE>
+public <B>FSAFinalStatesIterator</B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ int&nbsp;node)</PRE>
+<DL>
+<DD>Create an instance of the iterator for a given node.
+<P>
+</DL>
+
<!-- ============ METHOD DETAIL ========== -->
<A NAME="method_detail"><!-- --></A>
@@ -180,7 +217,7 @@ restartFrom</H3>
<PRE>
public void <B>restartFrom</B>(int&nbsp;node)</PRE>
<DL>
-<DD>Restart walking from <code>node</code>.
+<DD>Restart walking from <code>node</code>. Allows iterator reuse.
<P>
<DD><DL>
</DL>
@@ -217,8 +254,8 @@ public java.nio.ByteBuffer <B>next</B>()</PRE>
</DD>
<DD><DL>
-<DT><B>Returns:</B><DD>Returns a <CODE>ByteBuffer</CODE> with the sequence corresponding
- to the next final state in the automaton.</DL>
+<DT><B>Returns:</B><DD>Returns a <CODE>ByteBuffer</CODE> with the sequence corresponding to
+ the next final state in the automaton.</DL>
</DD>
</DL>
<HR>
@@ -226,7 +263,7 @@ public java.nio.ByteBuffer <B>next</B>()</PRE>
<A NAME="remove()"><!-- --></A><H3>
remove</H3>
<PRE>
-public final void <B>remove</B>()</PRE>
+public void <B>remove</B>()</PRE>
<DL>
<DD>Not implemented in this iterator.
<P>
@@ -267,7 +304,7 @@ public final void <B>remove</B>()</PRE>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
&nbsp;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/fsa/FSAFinalStatesIterator.html" target="_top"><B>FRAMES</B></A> &nbsp;
@@ -288,9 +325,9 @@ public final void <B>remove</B>()</PRE>
</TR>
<TR>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
- SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
-DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_bottom"></A>
diff --git a/doc/api/morfologik/fsa/FSAFlags.html b/doc/api/morfologik/fsa/FSAFlags.html
index dde0bbb..4e24416 100644
--- a/doc/api/morfologik/fsa/FSAFlags.html
+++ b/doc/api/morfologik/fsa/FSAFlags.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
<TITLE>
FSAFlags
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -55,7 +55,7 @@ function windowTitle()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;<A HREF="../../morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/fsa/FSAHelpers.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/fsa/FSAFlags.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="FSAFlags.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
@@ -104,7 +104,7 @@ java.lang.Object
</PRE>
<P>
-FSA automaton flags.
+FSA automaton flags. Where applicable, flags follow Daciuk's <code>fsa</code> package.
<P>
<P>
@@ -123,37 +123,38 @@ FSA automaton flags.
<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFlags.html#FLEXIBLE">FLEXIBLE</A></B></CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Daciuk: flexible FSA encoding.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFlags.html#LARGE_DICTIONARIES">LARGE_DICTIONARIES</A></B></CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFlags.html#NEXTBIT">NEXTBIT</A></B></CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Daciuk: next bit in use.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFlags.html#NEXTBIT">NEXTBIT</A></B></CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFlags.html#NUMBERS">NUMBERS</A></B></CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The FSA contains right-language count numbers on states.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFlags.html#STOPBIT">STOPBIT</A></B></CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFlags.html#SEPARATORS">SEPARATORS</A></B></CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The FSA supports legacy built-in separator and filler characters (Daciuk's FSA package
+ compatibility).</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFlags.html#TAILS">TAILS</A></B></CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFlags.html#STOPBIT">STOPBIT</A></B></CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Daciuk: stop bit in use.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFlags.html#WEIGHTED">WEIGHTED</A></B></CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFlags.html#TAILS">TAILS</A></B></CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Daciuk: tails compression.</TD>
</TR>
</TABLE>
&nbsp;<!-- =========== FIELD SUMMARY =========== -->
@@ -184,13 +185,20 @@ FSA automaton flags.
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;short</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFlags.html#asShort(java.util.Set)">asShort</A></B>(java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt;&nbsp;flags)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the set of flags encoded in a single short.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>static&nbsp;boolean</CODE></FONT></TD>
<TD><CODE><B><A HREF="../../morfologik/fsa/FSAFlags.html#isSet(int, morfologik.fsa.FSAFlags)">isSet</A></B>(int&nbsp;flags,
<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&nbsp;flag)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if the corresponding flag is set in the
- bit set.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns <code>true</code> if the corresponding flag is set in the bit set.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
@@ -246,6 +254,8 @@ FLEXIBLE</H3>
<PRE>
public static final <A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A> <B>FLEXIBLE</B></PRE>
<DL>
+<DD>Daciuk: flexible FSA encoding.
+<P>
<DL>
</DL>
</DL>
@@ -256,6 +266,8 @@ STOPBIT</H3>
<PRE>
public static final <A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A> <B>STOPBIT</B></PRE>
<DL>
+<DD>Daciuk: stop bit in use.
+<P>
<DL>
</DL>
</DL>
@@ -266,6 +278,8 @@ NEXTBIT</H3>
<PRE>
public static final <A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A> <B>NEXTBIT</B></PRE>
<DL>
+<DD>Daciuk: next bit in use.
+<P>
<DL>
</DL>
</DL>
@@ -276,26 +290,33 @@ TAILS</H3>
<PRE>
public static final <A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A> <B>TAILS</B></PRE>
<DL>
+<DD>Daciuk: tails compression.
+<P>
<DL>
</DL>
</DL>
<HR>
-<A NAME="WEIGHTED"><!-- --></A><H3>
-WEIGHTED</H3>
+<A NAME="NUMBERS"><!-- --></A><H3>
+NUMBERS</H3>
<PRE>
-public static final <A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A> <B>WEIGHTED</B></PRE>
+public static final <A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A> <B>NUMBERS</B></PRE>
<DL>
+<DD>The FSA contains right-language count numbers on states.
+<P>
<DL>
-</DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA.html#getRightLanguageCount(int)"><CODE>FSA.getRightLanguageCount(int)</CODE></A></DL>
</DL>
<HR>
-<A NAME="LARGE_DICTIONARIES"><!-- --></A><H3>
-LARGE_DICTIONARIES</H3>
+<A NAME="SEPARATORS"><!-- --></A><H3>
+SEPARATORS</H3>
<PRE>
-public static final <A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A> <B>LARGE_DICTIONARIES</B></PRE>
+public static final <A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A> <B>SEPARATORS</B></PRE>
<DL>
+<DD>The FSA supports legacy built-in separator and filler characters (Daciuk's FSA package
+ compatibility).
+<P>
<DL>
</DL>
</DL>
@@ -379,8 +400,20 @@ isSet</H3>
public static boolean <B>isSet</B>(int&nbsp;flags,
<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&nbsp;flag)</PRE>
<DL>
-<DD>Returns <code>true</code> if the corresponding flag is set in the
- bit set.
+<DD>Returns <code>true</code> if the corresponding flag is set in the bit set.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="asShort(java.util.Set)"><!-- --></A><H3>
+asShort</H3>
+<PRE>
+public static short <B>asShort</B>(java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt;&nbsp;flags)</PRE>
+<DL>
+<DD>Returns the set of flags encoded in a single short.
<P>
<DD><DL>
</DL>
@@ -417,7 +450,7 @@ public static boolean <B>isSet</B>(int&nbsp;flags,
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;<A HREF="../../morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/fsa/FSAHelpers.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/fsa/FSAFlags.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="FSAFlags.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
diff --git a/doc/api/morfologik/fsa/FSAInfo.html b/doc/api/morfologik/fsa/FSAInfo.html
new file mode 100644
index 0000000..9f08c90
--- /dev/null
+++ b/doc/api/morfologik/fsa/FSAInfo.html
@@ -0,0 +1,399 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
+<TITLE>
+FSAInfo
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="FSAInfo";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSAInfo.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSAInfo.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.fsa</FONT>
+<BR>
+Class FSAInfo</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.FSAInfo</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public final class <B>FSAInfo</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+Compute additional information about an FSA: number of arcs, nodes, etc.
+<P>
+
+<P>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAInfo.html#arcsCount">arcsCount</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Number of arcs in the automaton, excluding an arcs from the zero node
+ (initial) and an arc from the start node to the root node.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAInfo.html#arcsCountTotal">arcsCountTotal</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Total number of arcs, counting arcs that physically overlap due to
+ merging.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAInfo.html#finalStatesCount">finalStatesCount</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Number of final states (number of input sequences stored in the automaton).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAInfo.html#nodeCount">nodeCount</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Number of nodes in the automaton.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAInfo.html#size">size</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Arcs size (in serialized form).</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAInfo.html#FSAInfo(morfologik.fsa.FSA)">FSAInfo</A></B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAInfo.html#FSAInfo(int, int, int, int)">FSAInfo</A></B>(int&nbsp;nodeCount,
+ int&nbsp;arcsCount,
+ int&nbsp;arcsCountTotal,
+ int&nbsp;finalStatesCount)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAInfo.html#toString()">toString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="nodeCount"><!-- --></A><H3>
+nodeCount</H3>
+<PRE>
+public final int <B>nodeCount</B></PRE>
+<DL>
+<DD>Number of nodes in the automaton.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="arcsCount"><!-- --></A><H3>
+arcsCount</H3>
+<PRE>
+public final int <B>arcsCount</B></PRE>
+<DL>
+<DD>Number of arcs in the automaton, excluding an arcs from the zero node
+ (initial) and an arc from the start node to the root node.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="arcsCountTotal"><!-- --></A><H3>
+arcsCountTotal</H3>
+<PRE>
+public final int <B>arcsCountTotal</B></PRE>
+<DL>
+<DD>Total number of arcs, counting arcs that physically overlap due to
+ merging.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="finalStatesCount"><!-- --></A><H3>
+finalStatesCount</H3>
+<PRE>
+public final int <B>finalStatesCount</B></PRE>
+<DL>
+<DD>Number of final states (number of input sequences stored in the automaton).
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="size"><!-- --></A><H3>
+size</H3>
+<PRE>
+public final int <B>size</B></PRE>
+<DL>
+<DD>Arcs size (in serialized form).
+<P>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="FSAInfo(morfologik.fsa.FSA)"><!-- --></A><H3>
+FSAInfo</H3>
+<PRE>
+public <B>FSAInfo</B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa)</PRE>
+<DL>
+</DL>
+<HR>
+
+<A NAME="FSAInfo(int, int, int, int)"><!-- --></A><H3>
+FSAInfo</H3>
+<PRE>
+public <B>FSAInfo</B>(int&nbsp;nodeCount,
+ int&nbsp;arcsCount,
+ int&nbsp;arcsCountTotal,
+ int&nbsp;finalStatesCount)</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="toString()"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public java.lang.String <B>toString</B>()</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>toString</CODE> in class <CODE>java.lang.Object</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSAInfo.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSAInfo.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/fsa/FSASerializer.html b/doc/api/morfologik/fsa/FSASerializer.html
new file mode 100644
index 0000000..5e57fae
--- /dev/null
+++ b/doc/api/morfologik/fsa/FSASerializer.html
@@ -0,0 +1,335 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
+<TITLE>
+FSASerializer
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="FSASerializer";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSASerializer.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSASerializer.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.fsa</FONT>
+<BR>
+Interface FSASerializer</H2>
+<DL>
+<DT><B>All Known Implementing Classes:</B> <DD><A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A>, <A HREF="../../morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public interface <B>FSASerializer</B></DL>
+</PRE>
+
+<P>
+All FSA serializers to binary formats will implement this interface.
+<P>
+
+<P>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSASerializer.html#getFlags()">getFlags</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the set of flags supported by the serializer (and the output automaton).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
+<TR ALIGN="right" VALIGN="">
+<TD NOWRAP><FONT SIZE="-1">
+<CODE>&lt;T extends java.io.OutputStream&gt;
+<BR>
+T</CODE></FONT></TD>
+</TR>
+</TABLE>
+</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSASerializer.html#serialize(morfologik.fsa.FSA, T)">serialize</A></B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ T&nbsp;os)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serialize a finite state automaton to an output stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSASerializer.html#withAnnotationSeparator(byte)">withAnnotationSeparator</A></B>(byte&nbsp;annotationSeparator)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Supports built-in annotation separator.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSASerializer.html#withFiller(byte)">withFiller</A></B>(byte&nbsp;filler)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Supports built-in filler separator.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSASerializer.html#withLogger(morfologik.tools.IMessageLogger)">withLogger</A></B>(<A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A>&nbsp;logger)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log extra messages during construction.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSASerializer.html#withNumbers()">withNumbers</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Supports built-in right language count on nodes, speeding up perfect hash counts.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="serialize(morfologik.fsa.FSA,java.io.OutputStream)"><!-- --></A><A NAME="serialize(morfologik.fsa.FSA, T)"><!-- --></A><H3>
+serialize</H3>
+<PRE>
+&lt;T extends java.io.OutputStream&gt; T <B>serialize</B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ T&nbsp;os)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Serialize a finite state automaton to an output stream.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFlags()"><!-- --></A><H3>
+getFlags</H3>
+<PRE>
+java.util.Set&lt;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A>&gt; <B>getFlags</B>()</PRE>
+<DL>
+<DD>Returns the set of flags supported by the serializer (and the output automaton).
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="withLogger(morfologik.tools.IMessageLogger)"><!-- --></A><H3>
+withLogger</H3>
+<PRE>
+<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A> <B>withLogger</B>(<A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A>&nbsp;logger)</PRE>
+<DL>
+<DD>Log extra messages during construction.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="withFiller(byte)"><!-- --></A><H3>
+withFiller</H3>
+<PRE>
+<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A> <B>withFiller</B>(byte&nbsp;filler)</PRE>
+<DL>
+<DD>Supports built-in filler separator. Only if <A HREF="../../morfologik/fsa/FSASerializer.html#getFlags()"><CODE>getFlags()</CODE></A> returns
+ <A HREF="../../morfologik/fsa/FSAFlags.html#SEPARATORS"><CODE>FSAFlags.SEPARATORS</CODE></A>.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="withAnnotationSeparator(byte)"><!-- --></A><H3>
+withAnnotationSeparator</H3>
+<PRE>
+<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A> <B>withAnnotationSeparator</B>(byte&nbsp;annotationSeparator)</PRE>
+<DL>
+<DD>Supports built-in annotation separator. Only if <A HREF="../../morfologik/fsa/FSASerializer.html#getFlags()"><CODE>getFlags()</CODE></A> returns
+ <A HREF="../../morfologik/fsa/FSAFlags.html#SEPARATORS"><CODE>FSAFlags.SEPARATORS</CODE></A>.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="withNumbers()"><!-- --></A><H3>
+withNumbers</H3>
+<PRE>
+<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A> <B>withNumbers</B>()</PRE>
+<DL>
+<DD>Supports built-in right language count on nodes, speeding up perfect hash counts.
+ Only if <A HREF="../../morfologik/fsa/FSASerializer.html#getFlags()"><CODE>getFlags()</CODE></A> returns <A HREF="../../morfologik/fsa/FSAFlags.html#NUMBERS"><CODE>FSAFlags.NUMBERS</CODE></A>.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSASerializer.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSASerializer.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/fsa/FSATraversal.html b/doc/api/morfologik/fsa/FSATraversal.html
new file mode 100644
index 0000000..65a778d
--- /dev/null
+++ b/doc/api/morfologik/fsa/FSATraversal.html
@@ -0,0 +1,394 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
+<TITLE>
+FSATraversal
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="FSATraversal";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSATraversal.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSATraversal.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.fsa</FONT>
+<BR>
+Class FSATraversal</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.FSATraversal</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public final class <B>FSATraversal</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+This class implements some common matching and scanning operations on a
+ generic FSA.
+<P>
+
+<P>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSATraversal.html#FSATraversal(morfologik.fsa.FSA)">FSATraversal</A></B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Traversals of the given FSA.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSATraversal.html#match(byte[])">match</A></B>(byte[]&nbsp;sequence)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSATraversal.html#match(byte[], int)">match</A></B>(byte[]&nbsp;sequence,
+ int&nbsp;node)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSATraversal.html#match(byte[], int, int, int)">match</A></B>(byte[]&nbsp;sequence,
+ int&nbsp;start,
+ int&nbsp;length,
+ int&nbsp;node)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Finds a matching path in the dictionary for a given sequence of labels
+ from <code>sequence</code> and starting at node <code>node</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSATraversal.html#match(morfologik.fsa.MatchResult, byte[], int, int, int)">match</A></B>(<A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A>&nbsp;result,
+ byte[]&nbsp;sequence,
+ int&nbsp;start,
+ int&nbsp;length,
+ int&nbsp;node)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Same as <A HREF="../../morfologik/fsa/FSATraversal.html#match(byte[], int, int, int)"><CODE>match(byte[], int, int, int)</CODE></A>, but allows passing
+ a reusable <A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa"><CODE>MatchResult</CODE></A> object so that no intermediate garbage is
+ produced.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSATraversal.html#perfectHash(byte[])">perfectHash</A></B>(byte[]&nbsp;sequence)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSATraversal.html#perfectHash(byte[], int, int, int)">perfectHash</A></B>(byte[]&nbsp;sequence,
+ int&nbsp;start,
+ int&nbsp;length,
+ int&nbsp;node)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Calculate perfect hash for a given input sequence of bytes.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="FSATraversal(morfologik.fsa.FSA)"><!-- --></A><H3>
+FSATraversal</H3>
+<PRE>
+public <B>FSATraversal</B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa)</PRE>
+<DL>
+<DD>Traversals of the given FSA.
+<P>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="perfectHash(byte[], int, int, int)"><!-- --></A><H3>
+perfectHash</H3>
+<PRE>
+public int <B>perfectHash</B>(byte[]&nbsp;sequence,
+ int&nbsp;start,
+ int&nbsp;length,
+ int&nbsp;node)</PRE>
+<DL>
+<DD>Calculate perfect hash for a given input sequence of bytes. The perfect hash requires
+ that <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> is built with <A HREF="../../morfologik/fsa/FSAFlags.html#NUMBERS"><CODE>FSAFlags.NUMBERS</CODE></A> and corresponds to the sequential
+ order of input sequences used at automaton construction time.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>start</CODE> - Start index in the sequence array.<DD><CODE>length</CODE> - Length of the byte sequence, must be at least 1.
+<DT><B>Returns:</B><DD>Returns a unique integer assigned to the input sequence in the automaton (reflecting
+ the number of that sequence in the input used to build the automaton). Returns a negative
+ integer if the input sequence was not part of the input from which the automaton was created.
+ The type of mismatch is a constant defined in <A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa"><CODE>MatchResult</CODE></A>.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="perfectHash(byte[])"><!-- --></A><H3>
+perfectHash</H3>
+<PRE>
+public int <B>perfectHash</B>(byte[]&nbsp;sequence)</PRE>
+<DL>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSATraversal.html#perfectHash(byte[], int, int, int)"><CODE>perfectHash(byte[], int, int, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="match(morfologik.fsa.MatchResult, byte[], int, int, int)"><!-- --></A><H3>
+match</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A> <B>match</B>(<A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A>&nbsp;result,
+ byte[]&nbsp;sequence,
+ int&nbsp;start,
+ int&nbsp;length,
+ int&nbsp;node)</PRE>
+<DL>
+<DD>Same as <A HREF="../../morfologik/fsa/FSATraversal.html#match(byte[], int, int, int)"><CODE>match(byte[], int, int, int)</CODE></A>, but allows passing
+ a reusable <A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa"><CODE>MatchResult</CODE></A> object so that no intermediate garbage is
+ produced.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>The same object as <code>result</code>, but with reset internal
+ type and other fields.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="match(byte[], int, int, int)"><!-- --></A><H3>
+match</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A> <B>match</B>(byte[]&nbsp;sequence,
+ int&nbsp;start,
+ int&nbsp;length,
+ int&nbsp;node)</PRE>
+<DL>
+<DD>Finds a matching path in the dictionary for a given sequence of labels
+ from <code>sequence</code> and starting at node <code>node</code>.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sequence</CODE> - An array of labels to follow in the FSA.<DD><CODE>start</CODE> - Starting index in <code>sequence</code>.<DD><CODE>length</CODE> - How many symbols to consider from <code>sequence</code>?<DD><CODE>node</CODE> - Start node identifier in the FSA.<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSATraversal.html#match(byte[], int)"><CODE>match(byte [], int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="match(byte[], int)"><!-- --></A><H3>
+match</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A> <B>match</B>(byte[]&nbsp;sequence,
+ int&nbsp;node)</PRE>
+<DL>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSATraversal.html#match(byte[], int, int, int)"><CODE>match(byte[], int, int, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="match(byte[])"><!-- --></A><H3>
+match</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A> <B>match</B>(byte[]&nbsp;sequence)</PRE>
+<DL>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSATraversal.html#match(byte[], int, int, int)"><CODE>match(byte[], int, int, int)</CODE></A></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSATraversal.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSATraversal.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/fsa/FSATraversalHelper.html b/doc/api/morfologik/fsa/FSATraversalHelper.html
deleted file mode 100644
index e493621..0000000
--- a/doc/api/morfologik/fsa/FSATraversalHelper.html
+++ /dev/null
@@ -1,358 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!--NewPage-->
-<HTML>
-<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
-<TITLE>
-FSATraversalHelper
-</TITLE>
-
-<META NAME="date" CONTENT="2009-09-21">
-
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
-
-<SCRIPT type="text/javascript">
-function windowTitle()
-{
- if (location.href.indexOf('is-external=true') == -1) {
- parent.document.title="FSATraversalHelper";
- }
-}
-</SCRIPT>
-<NOSCRIPT>
-</NOSCRIPT>
-
-</HEAD>
-
-<BODY BGCOLOR="white" onload="windowTitle();">
-<HR>
-
-
-<!-- ========= START OF TOP NAVBAR ======= -->
-<A NAME="navbar_top"><!-- --></A>
-<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
-<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
-<TR>
-<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
-<A NAME="navbar_top_firstrow"><!-- --></A>
-<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
- <TR ALIGN="center" VALIGN="top">
- <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
- <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
- <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
- <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
- <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
- <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
- <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
- </TR>
-</TABLE>
-</TD>
-<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
-</EM>
-</TD>
-</TR>
-
-<TR>
-<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
-<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/fsa/FSATraversalHelper.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="FSATraversalHelper.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
-&nbsp;<SCRIPT type="text/javascript">
- <!--
- if(window==top) {
- document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
- }
- //-->
-</SCRIPT>
-<NOSCRIPT>
- <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
-</NOSCRIPT>
-
-
-</FONT></TD>
-</TR>
-<TR>
-<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
- SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
-<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
-DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
-</TR>
-</TABLE>
-<A NAME="skip-navbar_top"></A>
-<!-- ========= END OF TOP NAVBAR ========= -->
-
-<HR>
-<!-- ======== START OF CLASS DATA ======== -->
-<H2>
-<FONT SIZE="-1">
-morfologik.fsa</FONT>
-<BR>
-Class FSATraversalHelper</H2>
-<PRE>
-java.lang.Object
- <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.FSATraversalHelper</B>
-</PRE>
-<HR>
-<DL>
-<DT><PRE>public final class <B>FSATraversalHelper</B><DT>extends java.lang.Object</DL>
-</PRE>
-
-<P>
-This class implements some common matching and scanning operations on a
- generic FSA.
-
- <p>
- Optimized implementations may be provided my specific versions of FSA,
- therefore objects of this class should be instantiated via
- <A HREF="../../morfologik/fsa/FSA.html#getTraversalHelper()"><CODE>FSA.getTraversalHelper()</CODE></A>.
-<P>
-
-<P>
-<HR>
-
-<P>
-
-<!-- ========== METHOD SUMMARY =========== -->
-
-<A NAME="method_summary"><!-- --></A>
-<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
-<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
-<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
-<B>Method Summary</B></FONT></TH>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;java.util.Iterator&lt;java.nio.ByteBuffer&gt;</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSATraversalHelper.html#getAllSubsequences(int)">getAllSubsequences</A></B>(int&nbsp;node)</CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an <CODE>Iterator</CODE> of all subsequences available from the given
- node to all reachable final states.</TD>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa">FSAFinalStatesIterator</A></CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSATraversalHelper.html#getFinalStatesIterator()">getFinalStatesIterator</A></B>()</CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a new iterator for walking along the final states of this FSA.</TD>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A></CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSATraversalHelper.html#matchSequence(byte[])">matchSequence</A></B>(byte[]&nbsp;sequence)</CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A></CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSATraversalHelper.html#matchSequence(byte[], int)">matchSequence</A></B>(byte[]&nbsp;sequence,
- int&nbsp;node)</CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A></CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSATraversalHelper.html#matchSequence(byte[], int, int, int)">matchSequence</A></B>(byte[]&nbsp;sequence,
- int&nbsp;start,
- int&nbsp;length,
- int&nbsp;node)</CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Finds a matching path in the dictionary for a given sequence of labels
- from <code>sequence</code> and starting at node <code>node</code>.</TD>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A></CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSATraversalHelper.html#matchSequence(morfologik.fsa.FSAMatch, byte[], int, int, int)">matchSequence</A></B>(<A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A>&nbsp;result,
- byte[]&nbsp;sequence,
- int&nbsp;start,
- int&nbsp;length,
- int&nbsp;node)</CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Same as <A HREF="../../morfologik/fsa/FSATraversalHelper.html#matchSequence(byte[], int, int, int)"><CODE>matchSequence(byte[], int, int, int)</CODE></A>, but allows passing
- a reusable <A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><CODE>FSAMatch</CODE></A> object so that no intermediate garbage is
- produced.</TD>
-</TR>
-</TABLE>
-&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
-<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
-<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
-<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
-</TR>
-</TABLE>
-&nbsp;
-<P>
-
-<!-- ============ METHOD DETAIL ========== -->
-
-<A NAME="method_detail"><!-- --></A>
-<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
-<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
-<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
-<B>Method Detail</B></FONT></TH>
-</TR>
-</TABLE>
-
-<A NAME="getAllSubsequences(int)"><!-- --></A><H3>
-getAllSubsequences</H3>
-<PRE>
-public java.util.Iterator&lt;java.nio.ByteBuffer&gt; <B>getAllSubsequences</B>(int&nbsp;node)</PRE>
-<DL>
-<DD>Returns an <CODE>Iterator</CODE> of all subsequences available from the given
- node to all reachable final states.
-<P>
-<DD><DL>
-</DL>
-</DD>
-</DL>
-<HR>
-
-<A NAME="getFinalStatesIterator()"><!-- --></A><H3>
-getFinalStatesIterator</H3>
-<PRE>
-public <A HREF="../../morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa">FSAFinalStatesIterator</A> <B>getFinalStatesIterator</B>()</PRE>
-<DL>
-<DD>Returns a new iterator for walking along the final states of this FSA.
- The iterator is initially set to walk along all final states reachable
- from the root node.
-<P>
-<DD><DL>
-</DL>
-</DD>
-</DL>
-<HR>
-
-<A NAME="matchSequence(morfologik.fsa.FSAMatch, byte[], int, int, int)"><!-- --></A><H3>
-matchSequence</H3>
-<PRE>
-public <A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A> <B>matchSequence</B>(<A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A>&nbsp;result,
- byte[]&nbsp;sequence,
- int&nbsp;start,
- int&nbsp;length,
- int&nbsp;node)</PRE>
-<DL>
-<DD>Same as <A HREF="../../morfologik/fsa/FSATraversalHelper.html#matchSequence(byte[], int, int, int)"><CODE>matchSequence(byte[], int, int, int)</CODE></A>, but allows passing
- a reusable <A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><CODE>FSAMatch</CODE></A> object so that no intermediate garbage is
- produced.
-<P>
-<DD><DL>
-
-<DT><B>Returns:</B><DD>The same object as <code>result</code>, but with reset internal
- type and other fields.</DL>
-</DD>
-</DL>
-<HR>
-
-<A NAME="matchSequence(byte[], int, int, int)"><!-- --></A><H3>
-matchSequence</H3>
-<PRE>
-public <A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A> <B>matchSequence</B>(byte[]&nbsp;sequence,
- int&nbsp;start,
- int&nbsp;length,
- int&nbsp;node)</PRE>
-<DL>
-<DD>Finds a matching path in the dictionary for a given sequence of labels
- from <code>sequence</code> and starting at node <code>node</code>.
-<P>
-<DD><DL>
-<DT><B>Parameters:</B><DD><CODE>sequence</CODE> - An array of labels to follow in the FSA.<DD><CODE>start</CODE> - Starting index in <code>sequence</code>.<DD><CODE>length</CODE> - How many symbols to consider from <code>sequence</code>?<DD><CODE>node</CODE> - Start node identifier in the FSA.<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSATraversalHelper.html#matchSequence(byte[], int)"><CODE>matchSequence(byte [], int)</CODE></A></DL>
-</DD>
-</DL>
-<HR>
-
-<A NAME="matchSequence(byte[], int)"><!-- --></A><H3>
-matchSequence</H3>
-<PRE>
-public <A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A> <B>matchSequence</B>(byte[]&nbsp;sequence,
- int&nbsp;node)</PRE>
-<DL>
-<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSATraversalHelper.html#matchSequence(byte[], int, int, int)"><CODE>matchSequence(byte[], int, int, int)</CODE></A></DL>
-</DD>
-</DL>
-<HR>
-
-<A NAME="matchSequence(byte[])"><!-- --></A><H3>
-matchSequence</H3>
-<PRE>
-public <A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A> <B>matchSequence</B>(byte[]&nbsp;sequence)</PRE>
-<DL>
-<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSATraversalHelper.html#matchSequence(byte[], int, int, int)"><CODE>matchSequence(byte[], int, int, int)</CODE></A></DL>
-</DD>
-</DL>
-<!-- ========= END OF CLASS DATA ========= -->
-<HR>
-
-
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<A NAME="navbar_bottom"><!-- --></A>
-<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
-<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
-<TR>
-<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
-<A NAME="navbar_bottom_firstrow"><!-- --></A>
-<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
- <TR ALIGN="center" VALIGN="top">
- <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
- <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
- <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
- <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
- <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
- <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
- <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
- </TR>
-</TABLE>
-</TD>
-<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
-</EM>
-</TD>
-</TR>
-
-<TR>
-<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
-<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/fsa/FSATraversalHelper.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="FSATraversalHelper.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
-&nbsp;<SCRIPT type="text/javascript">
- <!--
- if(window==top) {
- document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
- }
- //-->
-</SCRIPT>
-<NOSCRIPT>
- <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
-</NOSCRIPT>
-
-
-</FONT></TD>
-</TR>
-<TR>
-<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
- SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
-<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
-DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
-</TR>
-</TABLE>
-<A NAME="skip-navbar_bottom"></A>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-
-<HR>
-
-</BODY>
-</HTML>
diff --git a/doc/api/morfologik/fsa/FSAMatch.html b/doc/api/morfologik/fsa/FSAUtils.IntIntHolder.html
index 9aa0419..871d878 100644
--- a/doc/api/morfologik/fsa/FSAMatch.html
+++ b/doc/api/morfologik/fsa/FSAUtils.IntIntHolder.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
<TITLE>
-FSAMatch
+FSAUtils.IntIntHolder
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -15,7 +15,7 @@ FSAMatch
function windowTitle()
{
if (location.href.indexOf('is-external=true') == -1) {
- parent.document.title="FSAMatch";
+ parent.document.title="FSAUtils.IntIntHolder";
}
}
</SCRIPT>
@@ -54,11 +54,11 @@ function windowTitle()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/fsa/FSAHelpers.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/fsa/FSAMatch.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="FSAMatch.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+ <A HREF="../../index.html?morfologik/fsa/FSAUtils.IntIntHolder.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSAUtils.IntIntHolder.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
@@ -75,9 +75,9 @@ function windowTitle()
</TR>
<TR>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
- SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#methods_inherited_from_class_java.lang.Object">METHOD</A></FONT></TD>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
-DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;METHOD</FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_top"></A>
@@ -89,74 +89,79 @@ DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&n
<FONT SIZE="-1">
morfologik.fsa</FONT>
<BR>
-Class FSAMatch</H2>
+Class FSAUtils.IntIntHolder</H2>
<PRE>
java.lang.Object
- <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.FSAMatch</B>
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.FSAUtils.IntIntHolder</B>
</PRE>
+<DL>
+<DT><B>Enclosing class:</B><DD><A HREF="../../morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa">FSAUtils</A></DD>
+</DL>
<HR>
<DL>
-<DT><PRE>public final class <B>FSAMatch</B><DT>extends java.lang.Object</DL>
+<DT><PRE>public static final class <B>FSAUtils.IntIntHolder</B><DT>extends java.lang.Object</DL>
</PRE>
<P>
-A matching result returned from <A HREF="../../morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa"><CODE>FSATraversalHelper</CODE></A>.
-<P>
-
-<P>
-<DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa"><CODE>FSATraversalHelper</CODE></A></DL>
<HR>
<P>
+<!-- =========== FIELD SUMMARY =========== -->
-<!-- ======== CONSTRUCTOR SUMMARY ======== -->
-
-<A NAME="constructor_summary"><!-- --></A>
+<A NAME="field_summary"><!-- --></A>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
-<B>Constructor Summary</B></FONT></TH>
+<B>Field Summary</B></FONT></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAMatch.html#FSAMatch()">FSAMatch</A></B>()</CODE>
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAUtils.IntIntHolder.html#a">a</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAUtils.IntIntHolder.html#b">b</A></B></CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
</TABLE>
&nbsp;
-<!-- ========== METHOD SUMMARY =========== -->
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
-<A NAME="method_summary"><!-- --></A>
+<A NAME="constructor_summary"><!-- --></A>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
-<B>Method Summary</B></FONT></TH>
+<B>Constructor Summary</B></FONT></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A></CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAMatch.html#getMatchType()">getMatchType</A></B>()</CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAUtils.IntIntHolder.html#FSAUtils.IntIntHolder()">FSAUtils.IntIntHolder</A></B>()</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return match type.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAMatch.html#getMismatchIndex()">getMismatchIndex</A></B>()</CODE>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAUtils.IntIntHolder.html#FSAUtils.IntIntHolder(int, int)">FSAUtils.IntIntHolder</A></B>(int&nbsp;a,
+ int&nbsp;b)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the index at which a mismatch occurred.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAMatch.html#getMismatchNode()">getMismatchNode</A></B>()</CODE>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the node at which mismatch occurred.</TD>
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
</TR>
</TABLE>
&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
@@ -171,69 +176,59 @@ A matching result returned from <A HREF="../../morfologik/fsa/FSATraversalHelper
&nbsp;
<P>
-<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<!-- ============ FIELD DETAIL =========== -->
-<A NAME="constructor_detail"><!-- --></A>
+<A NAME="field_detail"><!-- --></A>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
-<B>Constructor Detail</B></FONT></TH>
+<B>Field Detail</B></FONT></TH>
</TR>
</TABLE>
-<A NAME="FSAMatch()"><!-- --></A><H3>
-FSAMatch</H3>
+<A NAME="a"><!-- --></A><H3>
+a</H3>
<PRE>
-public <B>FSAMatch</B>()</PRE>
+public int <B>a</B></PRE>
+<DL>
<DL>
</DL>
+</DL>
+<HR>
-<!-- ============ METHOD DETAIL ========== -->
+<A NAME="b"><!-- --></A><H3>
+b</H3>
+<PRE>
+public int <B>b</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
-<A NAME="method_detail"><!-- --></A>
+<A NAME="constructor_detail"><!-- --></A>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
-<B>Method Detail</B></FONT></TH>
+<B>Constructor Detail</B></FONT></TH>
</TR>
</TABLE>
-<A NAME="getMatchType()"><!-- --></A><H3>
-getMatchType</H3>
-<PRE>
-public <A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A> <B>getMatchType</B>()</PRE>
-<DL>
-<DD>Return match type.
-<P>
-<DD><DL>
-</DL>
-</DD>
-</DL>
-<HR>
-
-<A NAME="getMismatchIndex()"><!-- --></A><H3>
-getMismatchIndex</H3>
+<A NAME="FSAUtils.IntIntHolder(int, int)"><!-- --></A><H3>
+FSAUtils.IntIntHolder</H3>
<PRE>
-public int <B>getMismatchIndex</B>()</PRE>
+public <B>FSAUtils.IntIntHolder</B>(int&nbsp;a,
+ int&nbsp;b)</PRE>
<DL>
-<DD>Return the index at which a mismatch occurred.
-<P>
-<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa"><CODE>FSAMatchType</CODE></A></DL>
-</DD>
</DL>
<HR>
-<A NAME="getMismatchNode()"><!-- --></A><H3>
-getMismatchNode</H3>
+<A NAME="FSAUtils.IntIntHolder()"><!-- --></A><H3>
+FSAUtils.IntIntHolder</H3>
<PRE>
-public int <B>getMismatchNode</B>()</PRE>
+public <B>FSAUtils.IntIntHolder</B>()</PRE>
<DL>
-<DD>Return the node at which mismatch occurred.
-<P>
-<DD><DL>
-<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa"><CODE>FSAMatchType</CODE></A></DL>
-</DD>
</DL>
<!-- ========= END OF CLASS DATA ========= -->
<HR>
@@ -265,11 +260,11 @@ public int <B>getMismatchNode</B>()</PRE>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/fsa/FSAHelpers.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/fsa/FSAMatch.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="FSAMatch.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+ <A HREF="../../index.html?morfologik/fsa/FSAUtils.IntIntHolder.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSAUtils.IntIntHolder.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
@@ -286,9 +281,9 @@ public int <B>getMismatchNode</B>()</PRE>
</TR>
<TR>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
- SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#methods_inherited_from_class_java.lang.Object">METHOD</A></FONT></TD>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
-DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;METHOD</FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_bottom"></A>
diff --git a/doc/api/morfologik/fsa/FSAUtils.html b/doc/api/morfologik/fsa/FSAUtils.html
new file mode 100644
index 0000000..53b4725
--- /dev/null
+++ b/doc/api/morfologik/fsa/FSAUtils.html
@@ -0,0 +1,379 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
+<TITLE>
+FSAUtils
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="FSAUtils";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSAUtils.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSAUtils.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.fsa</FONT>
+<BR>
+Class FSAUtils</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.FSAUtils</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public final class <B>FSAUtils</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+Other FSA-related utilities not directly associated with the class hierarchy.
+<P>
+
+<P>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+<A NAME="nested_class_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Nested Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa">FSAUtils.IntIntHolder</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAUtils.html#FSAUtils()">FSAUtils</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.util.TreeMap&lt;java.lang.Integer,java.lang.Integer&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAUtils.html#calculateFanOuts(morfologik.fsa.FSA, int)">calculateFanOuts</A></B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ int&nbsp;root)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Calculate fan-out ratio.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.util.ArrayList&lt;byte[]&gt;</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAUtils.html#rightLanguage(morfologik.fsa.FSA, int)">rightLanguage</A></B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ int&nbsp;state)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;All byte sequences generated as the right language of <code>state</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;com.carrotsearch.hppc.IntIntOpenHashMap</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAUtils.html#rightLanguageForAllStates(morfologik.fsa.FSA)">rightLanguageForAllStates</A></B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Calculate the size of right language for each state in an FSA.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAUtils.html#toDot(morfologik.fsa.FSA, int)">toDot</A></B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ int&nbsp;node)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the right-language reachable from a given FSA node, formatted
+ as an input for the graphviz package (expressed in the <code>dot</code>
+ language).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/FSAUtils.html#toDot(java.io.Writer, morfologik.fsa.FSA, int)">toDot</A></B>(java.io.Writer&nbsp;w,
+ <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ int&nbsp;node)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Saves the right-language reachable from a given FSA node, formatted
+ as an input for the graphviz package (expressed in the <code>dot</code>
+ language), to the given writer.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="FSAUtils()"><!-- --></A><H3>
+FSAUtils</H3>
+<PRE>
+public <B>FSAUtils</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="toDot(morfologik.fsa.FSA, int)"><!-- --></A><H3>
+toDot</H3>
+<PRE>
+public static java.lang.String <B>toDot</B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ int&nbsp;node)</PRE>
+<DL>
+<DD>Returns the right-language reachable from a given FSA node, formatted
+ as an input for the graphviz package (expressed in the <code>dot</code>
+ language).
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toDot(java.io.Writer, morfologik.fsa.FSA, int)"><!-- --></A><H3>
+toDot</H3>
+<PRE>
+public static void <B>toDot</B>(java.io.Writer&nbsp;w,
+ <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ int&nbsp;node)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Saves the right-language reachable from a given FSA node, formatted
+ as an input for the graphviz package (expressed in the <code>dot</code>
+ language), to the given writer.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="rightLanguage(morfologik.fsa.FSA, int)"><!-- --></A><H3>
+rightLanguage</H3>
+<PRE>
+public static java.util.ArrayList&lt;byte[]&gt; <B>rightLanguage</B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ int&nbsp;state)</PRE>
+<DL>
+<DD>All byte sequences generated as the right language of <code>state</code>.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="calculateFanOuts(morfologik.fsa.FSA, int)"><!-- --></A><H3>
+calculateFanOuts</H3>
+<PRE>
+public static java.util.TreeMap&lt;java.lang.Integer,java.lang.Integer&gt; <B>calculateFanOuts</B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa,
+ int&nbsp;root)</PRE>
+<DL>
+<DD>Calculate fan-out ratio.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>The returned array: result[outgoing-arcs]</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="rightLanguageForAllStates(morfologik.fsa.FSA)"><!-- --></A><H3>
+rightLanguageForAllStates</H3>
+<PRE>
+public static com.carrotsearch.hppc.IntIntOpenHashMap <B>rightLanguageForAllStates</B>(<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A>&nbsp;fsa)</PRE>
+<DL>
+<DD>Calculate the size of right language for each state in an FSA.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/FSAUtils.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSAUtils.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/fsa/MatchResult.html b/doc/api/morfologik/fsa/MatchResult.html
new file mode 100644
index 0000000..889c378
--- /dev/null
+++ b/doc/api/morfologik/fsa/MatchResult.html
@@ -0,0 +1,397 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
+<TITLE>
+MatchResult
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="MatchResult";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/MatchResult.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="MatchResult.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#methods_inherited_from_class_java.lang.Object">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;METHOD</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.fsa</FONT>
+<BR>
+Class MatchResult</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.MatchResult</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public final class <B>MatchResult</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+A matching result returned from <A HREF="../../morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa"><CODE>FSATraversal</CODE></A>.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa"><CODE>FSATraversal</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/MatchResult.html#AUTOMATON_HAS_PREFIX">AUTOMATON_HAS_PREFIX</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The automaton contains a prefix of the input sequence.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/MatchResult.html#EXACT_MATCH">EXACT_MATCH</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The automaton has exactly one match for the input sequence.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/MatchResult.html#index">index</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Input sequence's index, interpretation depends on <A HREF="../../morfologik/fsa/MatchResult.html#kind"><CODE>kind</CODE></A>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/MatchResult.html#kind">kind</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;One of the match kind constants defined in this class.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/MatchResult.html#NO_MATCH">NO_MATCH</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The automaton has no match for the input sequence.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/MatchResult.html#node">node</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Automaton node, interpretation depends on the <A HREF="../../morfologik/fsa/MatchResult.html#kind"><CODE>kind</CODE></A>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/MatchResult.html#SEQUENCE_IS_A_PREFIX">SEQUENCE_IS_A_PREFIX</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The sequence is a prefix of at least one sequence in the automaton.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/fsa/MatchResult.html#MatchResult()">MatchResult</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="EXACT_MATCH"><!-- --></A><H3>
+EXACT_MATCH</H3>
+<PRE>
+public static final int <B>EXACT_MATCH</B></PRE>
+<DL>
+<DD>The automaton has exactly one match for the input sequence.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.MatchResult.EXACT_MATCH">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="NO_MATCH"><!-- --></A><H3>
+NO_MATCH</H3>
+<PRE>
+public static final int <B>NO_MATCH</B></PRE>
+<DL>
+<DD>The automaton has no match for the input sequence.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.MatchResult.NO_MATCH">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="AUTOMATON_HAS_PREFIX"><!-- --></A><H3>
+AUTOMATON_HAS_PREFIX</H3>
+<PRE>
+public static final int <B>AUTOMATON_HAS_PREFIX</B></PRE>
+<DL>
+<DD>The automaton contains a prefix of the input sequence. That is:
+ one of the input sequences used to build the automaton is a
+ prefix of the input sequence that is shorter than the sequence.
+
+ <p><A HREF="../../morfologik/fsa/MatchResult.html#index"><CODE>index</CODE></A> will contain an index of the
+ first character of the input sequence not present in the
+ dictionary.</p>
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.MatchResult.AUTOMATON_HAS_PREFIX">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="SEQUENCE_IS_A_PREFIX"><!-- --></A><H3>
+SEQUENCE_IS_A_PREFIX</H3>
+<PRE>
+public static final int <B>SEQUENCE_IS_A_PREFIX</B></PRE>
+<DL>
+<DD>The sequence is a prefix of at least one sequence in the automaton.
+ <A HREF="../../morfologik/fsa/MatchResult.html#node"><CODE>node</CODE></A> returns the node from which all sequences
+ with the given prefix start in the automaton.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../constant-values.html#morfologik.fsa.MatchResult.SEQUENCE_IS_A_PREFIX">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="kind"><!-- --></A><H3>
+kind</H3>
+<PRE>
+public int <B>kind</B></PRE>
+<DL>
+<DD>One of the match kind constants defined in this class.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/MatchResult.html#NO_MATCH"><CODE>NO_MATCH</CODE></A>,
+<A HREF="../../morfologik/fsa/MatchResult.html#EXACT_MATCH"><CODE>EXACT_MATCH</CODE></A>,
+<A HREF="../../morfologik/fsa/MatchResult.html#AUTOMATON_HAS_PREFIX"><CODE>AUTOMATON_HAS_PREFIX</CODE></A>,
+<A HREF="../../morfologik/fsa/MatchResult.html#SEQUENCE_IS_A_PREFIX"><CODE>SEQUENCE_IS_A_PREFIX</CODE></A></DL>
+</DL>
+<HR>
+
+<A NAME="index"><!-- --></A><H3>
+index</H3>
+<PRE>
+public int <B>index</B></PRE>
+<DL>
+<DD>Input sequence's index, interpretation depends on <A HREF="../../morfologik/fsa/MatchResult.html#kind"><CODE>kind</CODE></A>.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="node"><!-- --></A><H3>
+node</H3>
+<PRE>
+public int <B>node</B></PRE>
+<DL>
+<DD>Automaton node, interpretation depends on the <A HREF="../../morfologik/fsa/MatchResult.html#kind"><CODE>kind</CODE></A>.
+<P>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="MatchResult()"><!-- --></A><H3>
+MatchResult</H3>
+<PRE>
+public <B>MatchResult</B>()</PRE>
+<DL>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/MatchResult.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="MatchResult.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#methods_inherited_from_class_java.lang.Object">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;METHOD</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/fsa/StateVisitor.html b/doc/api/morfologik/fsa/StateVisitor.html
new file mode 100644
index 0000000..a8bbf0b
--- /dev/null
+++ b/doc/api/morfologik/fsa/StateVisitor.html
@@ -0,0 +1,211 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
+<TITLE>
+StateVisitor
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="StateVisitor";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/StateVisitor.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="StateVisitor.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.fsa</FONT>
+<BR>
+Interface StateVisitor</H2>
+<HR>
+<DL>
+<DT><PRE>public interface <B>StateVisitor</B></DL>
+</PRE>
+
+<P>
+State visitor.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../morfologik/fsa/FSA.html#visitInPostOrder(T)"><CODE>FSA.visitInPostOrder(StateVisitor)</CODE></A>,
+<A HREF="../../morfologik/fsa/FSA.html#visitInPreOrder(T)"><CODE>FSA.visitInPreOrder(StateVisitor)</CODE></A></DL>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/fsa/StateVisitor.html#accept(int)">accept</A></B>(int&nbsp;state)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="accept(int)"><!-- --></A><H3>
+accept</H3>
+<PRE>
+boolean <B>accept</B>(int&nbsp;state)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/fsa/StateVisitor.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="StateVisitor.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/fsa/package-frame.html b/doc/api/morfologik/fsa/package-frame.html
index 94451c6..e4fec52 100644
--- a/doc/api/morfologik/fsa/package-frame.html
+++ b/doc/api/morfologik/fsa/package-frame.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
morfologik.fsa
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -20,20 +20,49 @@ morfologik.fsa
<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
<TR>
<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Interfaces</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="FSASerializer.html" title="interface in morfologik.fsa" target="classFrame"><I>FSASerializer</I></A>
+<BR>
+<A HREF="StateVisitor.html" title="interface in morfologik.fsa" target="classFrame"><I>StateVisitor</I></A></FONT></TD>
+</TR>
+</TABLE>
+
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
Classes</FONT>&nbsp;
<FONT CLASS="FrameItemFont">
<BR>
+<A HREF="CFSA.html" title="class in morfologik.fsa" target="classFrame">CFSA</A>
+<BR>
+<A HREF="CFSA2.html" title="class in morfologik.fsa" target="classFrame">CFSA2</A>
+<BR>
+<A HREF="CFSA2Serializer.html" title="class in morfologik.fsa" target="classFrame">CFSA2Serializer</A>
+<BR>
+<A HREF="ConstantArcSizeFSA.html" title="class in morfologik.fsa" target="classFrame">ConstantArcSizeFSA</A>
+<BR>
<A HREF="FSA.html" title="class in morfologik.fsa" target="classFrame">FSA</A>
<BR>
+<A HREF="FSA5.html" title="class in morfologik.fsa" target="classFrame">FSA5</A>
+<BR>
+<A HREF="FSA5Serializer.html" title="class in morfologik.fsa" target="classFrame">FSA5Serializer</A>
+<BR>
+<A HREF="FSABuilder.html" title="class in morfologik.fsa" target="classFrame">FSABuilder</A>
+<BR>
<A HREF="FSAFinalStatesIterator.html" title="class in morfologik.fsa" target="classFrame">FSAFinalStatesIterator</A>
<BR>
-<A HREF="FSAHelpers.html" title="class in morfologik.fsa" target="classFrame">FSAHelpers</A>
+<A HREF="FSAInfo.html" title="class in morfologik.fsa" target="classFrame">FSAInfo</A>
+<BR>
+<A HREF="FSATraversal.html" title="class in morfologik.fsa" target="classFrame">FSATraversal</A>
<BR>
-<A HREF="FSAMatch.html" title="class in morfologik.fsa" target="classFrame">FSAMatch</A>
+<A HREF="FSAUtils.html" title="class in morfologik.fsa" target="classFrame">FSAUtils</A>
<BR>
-<A HREF="FSATraversalHelper.html" title="class in morfologik.fsa" target="classFrame">FSATraversalHelper</A>
+<A HREF="FSAUtils.IntIntHolder.html" title="class in morfologik.fsa" target="classFrame">FSAUtils.IntIntHolder</A>
<BR>
-<A HREF="FSAVer5Impl.html" title="class in morfologik.fsa" target="classFrame">FSAVer5Impl</A></FONT></TD>
+<A HREF="MatchResult.html" title="class in morfologik.fsa" target="classFrame">MatchResult</A></FONT></TD>
</TR>
</TABLE>
@@ -44,9 +73,9 @@ Classes</FONT>&nbsp;
Enums</FONT>&nbsp;
<FONT CLASS="FrameItemFont">
<BR>
-<A HREF="FSAFlags.html" title="enum in morfologik.fsa" target="classFrame">FSAFlags</A>
+<A HREF="FSABuilder.InfoEntry.html" title="enum in morfologik.fsa" target="classFrame">FSABuilder.InfoEntry</A>
<BR>
-<A HREF="FSAMatchType.html" title="enum in morfologik.fsa" target="classFrame">FSAMatchType</A></FONT></TD>
+<A HREF="FSAFlags.html" title="enum in morfologik.fsa" target="classFrame">FSAFlags</A></FONT></TD>
</TR>
</TABLE>
diff --git a/doc/api/morfologik/fsa/package-summary.html b/doc/api/morfologik/fsa/package-summary.html
index 9f23cfe..aba058d 100644
--- a/doc/api/morfologik/fsa/package-summary.html
+++ b/doc/api/morfologik/fsa/package-summary.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
morfologik.fsa
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -85,38 +85,89 @@ Package morfologik.fsa
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Interface Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></B></TD>
+<TD>All FSA serializers to binary formats will implement this interface.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa">StateVisitor</A></B></TD>
+<TD>State visitor.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
<B>Class Summary</B></FONT></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/CFSA.html" title="class in morfologik.fsa">CFSA</A></B></TD>
+<TD>CFSA (Compact Finite State Automaton) binary format implementation.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/CFSA2.html" title="class in morfologik.fsa">CFSA2</A></B></TD>
+<TD>CFSA (Compact Finite State Automaton) binary format implementation, version 2:
+
+ <A HREF="../../morfologik/fsa/CFSA2.html#BIT_TARGET_NEXT"><CODE>CFSA2.BIT_TARGET_NEXT</CODE></A> applicable on all arcs, not necessarily the last one.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa">CFSA2Serializer</A></B></TD>
+<TD>Serializes in-memory <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> graphs to <A HREF="../../morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><CODE>CFSA2</CODE></A>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa">ConstantArcSizeFSA</A></B></TD>
+<TD>An FSA with constant-size arc representation produced directly
+ by <A HREF="../../morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa"><CODE>FSABuilder</CODE></A>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa">FSA</A></B></TD>
-<TD>This class implements Finite State Automaton traversal as described in Jan
- Daciuk's <i>Incremental Construction of Finite-State Automata and
- Transducers, and Their Use in the Natural Language Processing</i> (PhD
- thesis, Technical University of Gdansk).</TD>
+<TD>This is a top abstract class for handling finite state automata.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa">FSAFinalStatesIterator</A></B></TD>
-<TD>An iterator that traverses all final states reachable from a given
- node and returns byte sequences corresponding to final states.</TD>
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSA5.html" title="class in morfologik.fsa">FSA5</A></B></TD>
+<TD>FSA binary format implementation for version 5.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSAHelpers.html" title="class in morfologik.fsa">FSAHelpers</A></B></TD>
-<TD>This class has several static utility methods for use
- with the FSA package.</TD>
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa">FSA5Serializer</A></B></TD>
+<TD>Serializes in-memory <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A> graphs to a binary format compatible with
+ Jan Daciuk's <code>fsa</code>'s package <code>FSA5</code> format.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa">FSABuilder</A></B></TD>
+<TD>Fast, memory-conservative finite state automaton builder, returning a
+ byte-serialized <A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa"><CODE>ConstantArcSizeFSA</CODE></A> (a tradeoff between construction
+ speed and memory consumption).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa">FSAFinalStatesIterator</A></B></TD>
+<TD>An iterator that traverses the right language of a given node (all sequences
+ reachable from a given node).</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa">FSAMatch</A></B></TD>
-<TD>A matching result returned from <A HREF="../../morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa"><CODE>FSATraversalHelper</CODE></A>.</TD>
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa">FSAInfo</A></B></TD>
+<TD>Compute additional information about an FSA: number of arcs, nodes, etc.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa">FSATraversalHelper</A></B></TD>
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa">FSATraversal</A></B></TD>
<TD>This class implements some common matching and scanning operations on a
generic FSA.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa">FSAVer5Impl</A></B></TD>
-<TD>FSA (Finite State Automaton) dictionary traversal implementation for version
- 5 of the FSA automaton.</TD>
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa">FSAUtils</A></B></TD>
+<TD>Other FSA-related utilities not directly associated with the class hierarchy.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa">FSAUtils.IntIntHolder</A></B></TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa">MatchResult</A></B></TD>
+<TD>A matching result returned from <A HREF="../../morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa"><CODE>FSATraversal</CODE></A>.</TD>
</TR>
</TABLE>
&nbsp;
@@ -129,12 +180,12 @@ Package morfologik.fsa
<B>Enum Summary</B></FONT></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A></B></TD>
-<TD>FSA automaton flags.</TD>
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa">FSABuilder.InfoEntry</A></B></TD>
+<TD>Debug and information constants.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A></B></TD>
-<TD>Type of the match returned as part of <A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><CODE>FSAMatch</CODE></A>.</TD>
+<TD WIDTH="15%"><B><A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa">FSAFlags</A></B></TD>
+<TD>FSA automaton flags.</TD>
</TR>
</TABLE>
&nbsp;
diff --git a/doc/api/morfologik/fsa/package-tree.html b/doc/api/morfologik/fsa/package-tree.html
index 0714763..be565e3 100644
--- a/doc/api/morfologik/fsa/package-tree.html
+++ b/doc/api/morfologik/fsa/package-tree.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
morfologik.fsa Class Hierarchy
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -91,20 +91,27 @@ Class Hierarchy
</H2>
<UL>
<LI TYPE="circle">java.lang.Object<UL>
+<LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa"><B>CFSA2Serializer</B></A> (implements morfologik.fsa.<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A>)
<LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><B>FSA</B></A> (implements java.lang.Iterable&lt;T&gt;)
<UL>
-<LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa"><B>FSAVer5Impl</B></A></UL>
-<LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa"><B>FSAFinalStatesIterator</B></A> (implements java.util.Iterator&lt;E&gt;)
-<LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSAHelpers.html" title="class in morfologik.fsa"><B>FSAHelpers</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><B>FSAMatch</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa"><B>FSATraversalHelper</B></A></UL>
+<LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/CFSA.html" title="class in morfologik.fsa"><B>CFSA</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><B>CFSA2</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa"><B>ConstantArcSizeFSA</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSA5.html" title="class in morfologik.fsa"><B>FSA5</B></A></UL>
+<LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa"><B>FSA5Serializer</B></A> (implements morfologik.fsa.<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A>)
+<LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa"><B>FSABuilder</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa"><B>FSAFinalStatesIterator</B></A> (implements java.util.Iterator&lt;E&gt;)
+<LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa"><B>FSAInfo</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa"><B>FSATraversal</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa"><B>FSAUtils</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa"><B>FSAUtils.IntIntHolder</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/MatchResult.html" title="class in morfologik.fsa"><B>MatchResult</B></A></UL>
</UL>
<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa"><B>FSASerializer</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa"><B>StateVisitor</B></A></UL>
+<H2>
Enum Hierarchy
</H2>
<UL>
<LI TYPE="circle">java.lang.Object<UL>
<LI TYPE="circle">java.lang.Enum&lt;E&gt; (implements java.lang.Comparable&lt;T&gt;, java.io.Serializable)
<UL>
-<LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa"><B>FSAMatchType</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa"><B>FSAFlags</B></A></UL>
+<LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa"><B>FSAFlags</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="../../morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa"><B>FSABuilder.InfoEntry</B></A></UL>
</UL>
</UL>
<HR>
diff --git a/doc/api/morfologik/stemming/Dictionary.html b/doc/api/morfologik/stemming/Dictionary.html
index 50f1f58..9ed04ce 100644
--- a/doc/api/morfologik/stemming/Dictionary.html
+++ b/doc/api/morfologik/stemming/Dictionary.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
<TITLE>
Dictionary
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
diff --git a/doc/api/morfologik/stemming/DictionaryIterator.html b/doc/api/morfologik/stemming/DictionaryIterator.html
index 12f5b74..f857393 100644
--- a/doc/api/morfologik/stemming/DictionaryIterator.html
+++ b/doc/api/morfologik/stemming/DictionaryIterator.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
<TITLE>
DictionaryIterator
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -104,7 +104,8 @@ java.lang.Object
<P>
An iterator over <A HREF="../../morfologik/stemming/WordData.html" title="class in morfologik.stemming"><CODE>WordData</CODE></A> entries of a <A HREF="../../morfologik/stemming/Dictionary.html" title="class in morfologik.stemming"><CODE>Dictionary</CODE></A>. The stems
- can be decoded from compressed format or the compressed form can be preserved.
+ can be decoded from compressed format or the compressed form can be
+ preserved.
<P>
<P>
diff --git a/doc/api/morfologik/stemming/DictionaryLookup.html b/doc/api/morfologik/stemming/DictionaryLookup.html
index 85fe27e..423b6ac 100644
--- a/doc/api/morfologik/stemming/DictionaryLookup.html
+++ b/doc/api/morfologik/stemming/DictionaryLookup.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
<TITLE>
DictionaryLookup
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -117,7 +117,8 @@ This class implements a dictionary lookup over an FSA dictionary. The
<P>
<DL>
-<DT><B>See Also:</B><DD><a href="http://www.eti.pg.gda.pl/~jandac/fsa.html">FSA package Web site</a></DL>
+<DT><B>See Also:</B><DD><a href="http://www.eti.pg.gda.pl/~jandac/fsa.html">FSA package Web
+ site</a></DL>
<HR>
<P>
@@ -175,8 +176,8 @@ This class implements a dictionary lookup over an FSA dictionary. The
<TD><CODE><B><A HREF="../../morfologik/stemming/DictionaryLookup.html#iterator()">iterator</A></B>()</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return an iterator over all <A HREF="../../morfologik/stemming/WordData.html" title="class in morfologik.stemming"><CODE>WordData</CODE></A> entries available in
- the embedded <A HREF="../../morfologik/stemming/Dictionary.html" title="class in morfologik.stemming"><CODE>Dictionary</CODE></A>.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return an iterator over all <A HREF="../../morfologik/stemming/WordData.html" title="class in morfologik.stemming"><CODE>WordData</CODE></A> entries available in the
+ embedded <A HREF="../../morfologik/stemming/Dictionary.html" title="class in morfologik.stemming"><CODE>Dictionary</CODE></A>.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
@@ -285,8 +286,8 @@ iterator</H3>
<PRE>
public java.util.Iterator&lt;<A HREF="../../morfologik/stemming/WordData.html" title="class in morfologik.stemming">WordData</A>&gt; <B>iterator</B>()</PRE>
<DL>
-<DD>Return an iterator over all <A HREF="../../morfologik/stemming/WordData.html" title="class in morfologik.stemming"><CODE>WordData</CODE></A> entries available in
- the embedded <A HREF="../../morfologik/stemming/Dictionary.html" title="class in morfologik.stemming"><CODE>Dictionary</CODE></A>.
+<DD>Return an iterator over all <A HREF="../../morfologik/stemming/WordData.html" title="class in morfologik.stemming"><CODE>WordData</CODE></A> entries available in the
+ embedded <A HREF="../../morfologik/stemming/Dictionary.html" title="class in morfologik.stemming"><CODE>Dictionary</CODE></A>.
<P>
<DD><DL>
<DT><B>Specified by:</B><DD><CODE>iterator</CODE> in interface <CODE>java.lang.Iterable&lt;<A HREF="../../morfologik/stemming/WordData.html" title="class in morfologik.stemming">WordData</A>&gt;</CODE></DL>
diff --git a/doc/api/morfologik/stemming/DictionaryMetadata.html b/doc/api/morfologik/stemming/DictionaryMetadata.html
index 27b6912..63b289f 100644
--- a/doc/api/morfologik/stemming/DictionaryMetadata.html
+++ b/doc/api/morfologik/stemming/DictionaryMetadata.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:37 CET 2011 -->
<TITLE>
DictionaryMetadata
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
diff --git a/doc/api/morfologik/stemming/IStemmer.html b/doc/api/morfologik/stemming/IStemmer.html
index c91fd04..8d901f9 100644
--- a/doc/api/morfologik/stemming/IStemmer.html
+++ b/doc/api/morfologik/stemming/IStemmer.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
IStemmer
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
diff --git a/doc/api/morfologik/stemming/PolishStemmer.html b/doc/api/morfologik/stemming/PolishStemmer.html
index d48276c..ccaa8f4 100644
--- a/doc/api/morfologik/stemming/PolishStemmer.html
+++ b/doc/api/morfologik/stemming/PolishStemmer.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
PolishStemmer
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
diff --git a/doc/api/morfologik/stemming/WordData.html b/doc/api/morfologik/stemming/WordData.html
index 14e07a1..42d956b 100644
--- a/doc/api/morfologik/stemming/WordData.html
+++ b/doc/api/morfologik/stemming/WordData.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
WordData
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -111,8 +111,8 @@ Stem and tag data associated with a given word.
<li>Objects of this class are <i>volatile</i> (their content changes on
subsequent calls to <A HREF="../../morfologik/stemming/DictionaryLookup.html" title="class in morfologik.stemming"><CODE>DictionaryLookup</CODE></A> class. If you need a copy of the
stem or tag data for a given word, you have to create a custom buffer
- yourself and copy the associated data, perform <A HREF="../../morfologik/stemming/WordData.html#clone()"><CODE>clone()</CODE></A> or create strings (they
- are immutable) using <A HREF="../../morfologik/stemming/WordData.html#getStem()"><CODE>getStem()</CODE></A> and then
+ yourself and copy the associated data, perform <A HREF="../../morfologik/stemming/WordData.html#clone()"><CODE>clone()</CODE></A> or create
+ strings (they are immutable) using <A HREF="../../morfologik/stemming/WordData.html#getStem()"><CODE>getStem()</CODE></A> and then
<CODE>CharSequence.toString()</CODE>.</li>
<li>Objects of this class must not be used in any Java collections. In fact
both equals and hashCode methods are overridden and throw exceptions to
@@ -139,8 +139,8 @@ Stem and tag data associated with a given word.
<TD><CODE><B><A HREF="../../morfologik/stemming/WordData.html#clone()">clone</A></B>()</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Declare a covariant of <CODE>Object.clone()</CODE> that returns a deep copy
- of this object.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Declare a covariant of <CODE>Object.clone()</CODE> that returns a deep copy of
+ this object.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
@@ -333,8 +333,8 @@ public java.lang.CharSequence <B>getWord</B>()</PRE>
</DD>
<DD><DL>
-<DT><B>Returns:</B><DD>Return inflected word form data. Usually the parameter
- passed to <A HREF="../../morfologik/stemming/DictionaryLookup.html#lookup(java.lang.CharSequence)"><CODE>DictionaryLookup.lookup(CharSequence)</CODE></A>.</DL>
+<DT><B>Returns:</B><DD>Return inflected word form data. Usually the parameter passed to
+ <A HREF="../../morfologik/stemming/DictionaryLookup.html#lookup(java.lang.CharSequence)"><CODE>DictionaryLookup.lookup(CharSequence)</CODE></A>.</DL>
</DD>
</DL>
<HR>
@@ -372,8 +372,8 @@ clone</H3>
<PRE>
protected <A HREF="../../morfologik/stemming/WordData.html" title="class in morfologik.stemming">WordData</A> <B>clone</B>()</PRE>
<DL>
-<DD>Declare a covariant of <CODE>Object.clone()</CODE> that returns a deep copy
- of this object. The content of all internal buffers is copied.
+<DD>Declare a covariant of <CODE>Object.clone()</CODE> that returns a deep copy of
+ this object. The content of all internal buffers is copied.
<P>
<DD><DL>
<DT><B>Overrides:</B><DD><CODE>clone</CODE> in class <CODE>java.lang.Object</CODE></DL>
diff --git a/doc/api/morfologik/stemming/package-frame.html b/doc/api/morfologik/stemming/package-frame.html
index 62a0afe..b8d12fb 100644
--- a/doc/api/morfologik/stemming/package-frame.html
+++ b/doc/api/morfologik/stemming/package-frame.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
morfologik.stemming
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
diff --git a/doc/api/morfologik/stemming/package-summary.html b/doc/api/morfologik/stemming/package-summary.html
index 613d016..d439020 100644
--- a/doc/api/morfologik/stemming/package-summary.html
+++ b/doc/api/morfologik/stemming/package-summary.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
morfologik.stemming
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
diff --git a/doc/api/morfologik/stemming/package-tree.html b/doc/api/morfologik/stemming/package-tree.html
index 6a7904e..73b3e3d 100644
--- a/doc/api/morfologik/stemming/package-tree.html
+++ b/doc/api/morfologik/stemming/package-tree.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
morfologik.stemming Class Hierarchy
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
diff --git a/doc/api/morfologik/fsa/FSAMatchType.html b/doc/api/morfologik/tools/FSABuildTool.Format.html
index cbee8d4..af79179 100644
--- a/doc/api/morfologik/fsa/FSAMatchType.html
+++ b/doc/api/morfologik/tools/FSABuildTool.Format.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
-FSAMatchType
+FSABuildTool.Format
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -15,7 +15,7 @@ FSAMatchType
function windowTitle()
{
if (location.href.indexOf('is-external=true') == -1) {
- parent.document.title="FSAMatchType";
+ parent.document.title="FSABuildTool.Format";
}
}
</SCRIPT>
@@ -54,11 +54,11 @@ function windowTitle()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/tools/FSABuildTool.html" title="class in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/tools/FSADumpTool.html" title="class in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/fsa/FSAMatchType.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="FSAMatchType.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+ <A HREF="../../index.html?morfologik/tools/FSABuildTool.Format.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSABuildTool.Format.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
@@ -87,24 +87,27 @@ DETAIL:&nbsp;<A HREF="#enum_constant_detail">ENUM CONSTANTS</A>&nbsp;|&nbsp;FIEL
<!-- ======== START OF CLASS DATA ======== -->
<H2>
<FONT SIZE="-1">
-morfologik.fsa</FONT>
+morfologik.tools</FONT>
<BR>
-Enum FSAMatchType</H2>
+Enum FSABuildTool.Format</H2>
<PRE>
java.lang.Object
- <IMG SRC="../../resources/inherit.gif" ALT="extended by ">java.lang.Enum&lt;<A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A>&gt;
- <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.FSAMatchType</B>
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by ">java.lang.Enum&lt;<A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A>&gt;
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.tools.FSABuildTool.Format</B>
</PRE>
<DL>
-<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable, java.lang.Comparable&lt;<A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A>&gt;</DD>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable, java.lang.Comparable&lt;<A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A>&gt;</DD>
+</DL>
+<DL>
+<DT><B>Enclosing class:</B><DD><A HREF="../../morfologik/tools/FSABuildTool.html" title="class in morfologik.tools">FSABuildTool</A></DD>
</DL>
<HR>
<DL>
-<DT><PRE>public enum <B>FSAMatchType</B><DT>extends java.lang.Enum&lt;<A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A>&gt;</DL>
+<DT><PRE>public static enum <B>FSABuildTool.Format</B><DT>extends java.lang.Enum&lt;<A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A>&gt;</DL>
</PRE>
<P>
-Type of the match returned as part of <A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><CODE>FSAMatch</CODE></A>.
+The serialization format to use for the binary output.
<P>
<P>
@@ -120,35 +123,16 @@ Type of the match returned as part of <A HREF="../../morfologik/fsa/FSAMatch.htm
<B>Enum Constant Summary</B></FONT></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAMatchType.html#EXACT_MATCH">EXACT_MATCH</A></B></CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The input sequence ends exactly on the final node.</TD>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAMatchType.html#NO_MATCH">NO_MATCH</A></B></CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;No match for the input sequence of symbols found in the automaton.</TD>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAMatchType.html#PREFIX_FOUND">PREFIX_FOUND</A></B></CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The sequence ends on an intermediate automaton node.</TD>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAMatchType.html#PREMATURE_PATH_END_FOUND">PREMATURE_PATH_END_FOUND</A></B></CODE>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.Format.html#CFSA2">CFSA2</A></B></CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A terminating node occurs in the dictionary before the end of the input
- sequence.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAMatchType.html#PREMATURE_WORD_END_FOUND">PREMATURE_WORD_END_FOUND</A></B></CODE>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.Format.html#FSA5">FSA5</A></B></CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The input sequence ends on an intermediate automaton node.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
</TABLE>
&nbsp;
@@ -162,16 +146,24 @@ Type of the match returned as part of <A HREF="../../morfologik/fsa/FSAMatch.htm
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>static&nbsp;<A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A></CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAMatchType.html#valueOf(java.lang.String)">valueOf</A></B>(java.lang.String&nbsp;name)</CODE>
+<CODE>&nbsp;<A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.Format.html#getSerializer()">getSerializer</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.Format.html#valueOf(java.lang.String)">valueOf</A></B>(java.lang.String&nbsp;name)</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the enum constant of this type with the specified name.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>static&nbsp;<A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A>[]</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAMatchType.html#values()">values</A></B>()</CODE>
+<CODE>static&nbsp;<A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A>[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.Format.html#values()">values</A></B>()</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an array containing the constants of this enum type, in
@@ -209,73 +201,21 @@ the order they are declared.</TD>
</TR>
</TABLE>
-<A NAME="NO_MATCH"><!-- --></A><H3>
-NO_MATCH</H3>
+<A NAME="FSA5"><!-- --></A><H3>
+FSA5</H3>
<PRE>
-public static final <A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A> <B>NO_MATCH</B></PRE>
+public static final <A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A> <B>FSA5</B></PRE>
<DL>
-<DD>No match for the input sequence of symbols found in the automaton.
-<P>
<DL>
</DL>
</DL>
<HR>
-<A NAME="EXACT_MATCH"><!-- --></A><H3>
-EXACT_MATCH</H3>
+<A NAME="CFSA2"><!-- --></A><H3>
+CFSA2</H3>
<PRE>
-public static final <A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A> <B>EXACT_MATCH</B></PRE>
+public static final <A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A> <B>CFSA2</B></PRE>
<DL>
-<DD>The input sequence ends exactly on the final node.
-<P>
-<DL>
-</DL>
-</DL>
-<HR>
-
-<A NAME="PREMATURE_PATH_END_FOUND"><!-- --></A><H3>
-PREMATURE_PATH_END_FOUND</H3>
-<PRE>
-public static final <A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A> <B>PREMATURE_PATH_END_FOUND</B></PRE>
-<DL>
-<DD>A terminating node occurs in the dictionary before the end of the input
- sequence. It effectively means a prefix of the input sequence is stored
- in the dictionary (e.g., an empty sequence is a prefix of all other
- sequences). The result <A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><CODE>FSAMatch</CODE></A> will contain an index of the
- first character not present in the dictionary.
-<P>
-<DL>
-</DL>
-</DL>
-<HR>
-
-<A NAME="PREFIX_FOUND"><!-- --></A><H3>
-PREFIX_FOUND</H3>
-<PRE>
-public static final <A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A> <B>PREFIX_FOUND</B></PRE>
-<DL>
-<DD>The sequence ends on an intermediate automaton node. The sequence is
- therefore a prefix of at least one other sequence stored in the
- dictionary. The result <A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><CODE>FSAMatch</CODE></A> object will contain an index of
- the first character in the input sequence not present in the dictionary
- and a pointer to the <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A>'s <code>node</code> where mismatch
- occurred.
-<P>
-<DL>
-</DL>
-</DL>
-<HR>
-
-<A NAME="PREMATURE_WORD_END_FOUND"><!-- --></A><H3>
-PREMATURE_WORD_END_FOUND</H3>
-<PRE>
-public static final <A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A> <B>PREMATURE_WORD_END_FOUND</B></PRE>
-<DL>
-<DD>The input sequence ends on an intermediate automaton node. This is a
- special case of <A HREF="../../morfologik/fsa/FSAMatchType.html#PREFIX_FOUND"><CODE>PREFIX_FOUND</CODE></A>. A node where the mismatch (missing
- input sequence's characters) occurred is returned in the <A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><CODE>FSAMatch</CODE></A>
- .
-<P>
<DL>
</DL>
</DL>
@@ -293,13 +233,13 @@ public static final <A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum
<A NAME="values()"><!-- --></A><H3>
values</H3>
<PRE>
-public static <A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A>[] <B>values</B>()</PRE>
+public static <A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A>[] <B>values</B>()</PRE>
<DL>
<DD>Returns an array containing the constants of this enum type, in
the order they are declared. This method may be used to iterate
over the constants as follows:
<pre>
-for (FSAMatchType c : FSAMatchType.values())
+for (FSABuildTool.Format c : FSABuildTool.Format.values())
&nbsp; System.out.println(c);
</pre>
<P>
@@ -314,7 +254,7 @@ the order they are declared</DL>
<A NAME="valueOf(java.lang.String)"><!-- --></A><H3>
valueOf</H3>
<PRE>
-public static <A HREF="../../morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa">FSAMatchType</A> <B>valueOf</B>(java.lang.String&nbsp;name)</PRE>
+public static <A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A> <B>valueOf</B>(java.lang.String&nbsp;name)</PRE>
<DL>
<DD>Returns the enum constant of this type with the specified name.
The string must match <I>exactly</I> an identifier used to declare an
@@ -330,6 +270,17 @@ with the specified name
<DD><CODE>java.lang.NullPointerException</CODE> - if the argument is null</DL>
</DD>
</DL>
+<HR>
+
+<A NAME="getSerializer()"><!-- --></A><H3>
+getSerializer</H3>
+<PRE>
+public <A HREF="../../morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A> <B>getSerializer</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
<!-- ========= END OF CLASS DATA ========= -->
<HR>
@@ -360,11 +311,11 @@ with the specified name
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/tools/FSABuildTool.html" title="class in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/tools/FSADumpTool.html" title="class in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/fsa/FSAMatchType.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="FSAMatchType.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+ <A HREF="../../index.html?morfologik/tools/FSABuildTool.Format.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSABuildTool.Format.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
diff --git a/doc/api/morfologik/tools/FSABuildTool.html b/doc/api/morfologik/tools/FSABuildTool.html
new file mode 100644
index 0000000..74a0465
--- /dev/null
+++ b/doc/api/morfologik/tools/FSABuildTool.html
@@ -0,0 +1,522 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
+<TITLE>
+FSABuildTool
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="FSABuildTool";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/tools/FSABuildTool.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSABuildTool.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.tools</FONT>
+<BR>
+Class FSABuildTool</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.tools.FSABuildTool</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public final class <B>FSABuildTool</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+Convert from plain text input to a serialized FSA in any of the
+ available <A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools"><CODE>FSABuildTool.Format</CODE></A>s.
+<P>
+
+<P>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+<A NAME="nested_class_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Nested Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The serialization format to use for the binary output.</TD>
+</TR>
+</TABLE>
+&nbsp;<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;org.apache.commons.cli.Options</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.html#options">options</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Command line options.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.html#FSABuildTool()">FSABuildTool</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.html#checkSingleByte(java.lang.String)">checkSingleByte</A></B>(java.lang.String&nbsp;chr)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Check if the argument is a single byte after conversion using platform-default
+ encoding.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.html#dumpLine(byte[], int)">dumpLine</A></B>(byte[]&nbsp;line,
+ int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dump input line, byte-by-byte.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.html#go(org.apache.commons.cli.CommandLine)">go</A></B>(org.apache.commons.cli.CommandLine&nbsp;line)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Command line entry point after parsing arguments.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.html#go(java.lang.String[])">go</A></B>(java.lang.String[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initializes application context.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.html#initializeOptions(org.apache.commons.cli.Options)">initializeOptions</A></B>(org.apache.commons.cli.Options&nbsp;options)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Override and initialize options.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.html#isAvailable()">isAvailable</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Is the tool available?</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.html#main(java.lang.String[])">main</A></B>(java.lang.String[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Command line entry point.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.html#printError(java.lang.String)">printError</A></B>(java.lang.String&nbsp;msg)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Print an error without an exception.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.html#printError(java.lang.String, java.lang.Throwable)">printError</A></B>(java.lang.String&nbsp;msg,
+ java.lang.Throwable&nbsp;t)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Print an error and an associated exception.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSABuildTool.html#printUsage()">printUsage</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Prints usage (options).</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="options"><!-- --></A><H3>
+options</H3>
+<PRE>
+protected final org.apache.commons.cli.Options <B>options</B></PRE>
+<DL>
+<DD>Command line options.
+<P>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="FSABuildTool()"><!-- --></A><H3>
+FSABuildTool</H3>
+<PRE>
+public <B>FSABuildTool</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="go(org.apache.commons.cli.CommandLine)"><!-- --></A><H3>
+go</H3>
+<PRE>
+protected void <B>go</B>(org.apache.commons.cli.CommandLine&nbsp;line)
+ throws java.lang.Exception</PRE>
+<DL>
+<DD>Command line entry point after parsing arguments.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.Exception</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="dumpLine(byte[], int)"><!-- --></A><H3>
+dumpLine</H3>
+<PRE>
+protected java.lang.String <B>dumpLine</B>(byte[]&nbsp;line,
+ int&nbsp;length)</PRE>
+<DL>
+<DD>Dump input line, byte-by-byte.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="checkSingleByte(java.lang.String)"><!-- --></A><H3>
+checkSingleByte</H3>
+<PRE>
+public static void <B>checkSingleByte</B>(java.lang.String&nbsp;chr)</PRE>
+<DL>
+<DD>Check if the argument is a single byte after conversion using platform-default
+ encoding.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="printUsage()"><!-- --></A><H3>
+printUsage</H3>
+<PRE>
+protected void <B>printUsage</B>()</PRE>
+<DL>
+<DD>Prints usage (options).
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="initializeOptions(org.apache.commons.cli.Options)"><!-- --></A><H3>
+initializeOptions</H3>
+<PRE>
+protected void <B>initializeOptions</B>(org.apache.commons.cli.Options&nbsp;options)</PRE>
+<DL>
+<DD>Override and initialize options.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(java.lang.String[]&nbsp;args)
+ throws java.lang.Exception</PRE>
+<DL>
+<DD>Command line entry point.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.Exception</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="go(java.lang.String[])"><!-- --></A><H3>
+go</H3>
+<PRE>
+protected final void <B>go</B>(java.lang.String[]&nbsp;args)</PRE>
+<DL>
+<DD>Initializes application context.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="printError(java.lang.String, java.lang.Throwable)"><!-- --></A><H3>
+printError</H3>
+<PRE>
+protected void <B>printError</B>(java.lang.String&nbsp;msg,
+ java.lang.Throwable&nbsp;t)</PRE>
+<DL>
+<DD>Print an error and an associated exception.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="printError(java.lang.String)"><!-- --></A><H3>
+printError</H3>
+<PRE>
+protected void <B>printError</B>(java.lang.String&nbsp;msg)</PRE>
+<DL>
+<DD>Print an error without an exception.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isAvailable()"><!-- --></A><H3>
+isAvailable</H3>
+<PRE>
+protected boolean <B>isAvailable</B>()</PRE>
+<DL>
+<DD>Is the tool available? <code>true</code> by default.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/tools/FSABuildTool.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSABuildTool.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/tools/DumpTool.html b/doc/api/morfologik/tools/FSADumpTool.html
index 04cdc03..e7b9098 100644
--- a/doc/api/morfologik/tools/DumpTool.html
+++ b/doc/api/morfologik/tools/FSADumpTool.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
-DumpTool
+FSADumpTool
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -15,7 +15,7 @@ DumpTool
function windowTitle()
{
if (location.href.indexOf('is-external=true') == -1) {
- parent.document.title="DumpTool";
+ parent.document.title="FSADumpTool";
}
}
</SCRIPT>
@@ -54,11 +54,11 @@ function windowTitle()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;PREV CLASS&nbsp;
-&nbsp;<A HREF="../../morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/tools/DumpTool.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="DumpTool.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+ <A HREF="../../index.html?morfologik/tools/FSADumpTool.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSADumpTool.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
@@ -89,14 +89,14 @@ DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor
<FONT SIZE="-1">
morfologik.tools</FONT>
<BR>
-Class DumpTool</H2>
+Class FSADumpTool</H2>
<PRE>
java.lang.Object
- <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.tools.DumpTool</B>
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.tools.FSADumpTool</B>
</PRE>
<HR>
<DL>
-<DT><PRE>public final class <B>DumpTool</B><DT>extends java.lang.Object</DL>
+<DT><PRE>public final class <B>FSADumpTool</B><DT>extends java.lang.Object</DL>
</PRE>
<P>
@@ -120,7 +120,7 @@ This utility will dump the information and contents of a given <A HREF="../../mo
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>protected &nbsp;org.apache.commons.cli.Options</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/tools/DumpTool.html#options">options</A></B></CODE>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSADumpTool.html#options">options</A></B></CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Command line options.</TD>
@@ -136,7 +136,7 @@ This utility will dump the information and contents of a given <A HREF="../../mo
<B>Constructor Summary</B></FONT></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/tools/DumpTool.html#DumpTool()">DumpTool</A></B>()</CODE>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSADumpTool.html#FSADumpTool()">FSADumpTool</A></B>()</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
@@ -154,7 +154,7 @@ This utility will dump the information and contents of a given <A HREF="../../mo
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>protected &nbsp;void</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/tools/DumpTool.html#go(org.apache.commons.cli.CommandLine)">go</A></B>(org.apache.commons.cli.CommandLine&nbsp;line)</CODE>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSADumpTool.html#go(org.apache.commons.cli.CommandLine)">go</A></B>(org.apache.commons.cli.CommandLine&nbsp;line)</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Command line entry point after parsing arguments.</TD>
@@ -162,7 +162,7 @@ This utility will dump the information and contents of a given <A HREF="../../mo
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>protected &nbsp;void</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/tools/DumpTool.html#go(java.lang.String[])">go</A></B>(java.lang.String[]&nbsp;args)</CODE>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSADumpTool.html#go(java.lang.String[])">go</A></B>(java.lang.String[]&nbsp;args)</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initializes application context.</TD>
@@ -170,15 +170,23 @@ This utility will dump the information and contents of a given <A HREF="../../mo
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>protected &nbsp;void</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/tools/DumpTool.html#initializeOptions(org.apache.commons.cli.Options)">initializeOptions</A></B>(org.apache.commons.cli.Options&nbsp;options)</CODE>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSADumpTool.html#initializeOptions(org.apache.commons.cli.Options)">initializeOptions</A></B>(org.apache.commons.cli.Options&nbsp;options)</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Command line options for the tool.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSADumpTool.html#isAvailable()">isAvailable</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Is the tool available?</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>static&nbsp;void</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/tools/DumpTool.html#main(java.lang.String[])">main</A></B>(java.lang.String[]&nbsp;args)</CODE>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSADumpTool.html#main(java.lang.String[])">main</A></B>(java.lang.String[]&nbsp;args)</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Command line entry point.</TD>
@@ -186,7 +194,7 @@ This utility will dump the information and contents of a given <A HREF="../../mo
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>protected &nbsp;void</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/tools/DumpTool.html#printError(java.lang.String)">printError</A></B>(java.lang.String&nbsp;msg)</CODE>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSADumpTool.html#printError(java.lang.String)">printError</A></B>(java.lang.String&nbsp;msg)</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Print an error without an exception.</TD>
@@ -194,7 +202,7 @@ This utility will dump the information and contents of a given <A HREF="../../mo
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>protected &nbsp;void</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/tools/DumpTool.html#printError(java.lang.String, java.lang.Throwable)">printError</A></B>(java.lang.String&nbsp;msg,
+<TD><CODE><B><A HREF="../../morfologik/tools/FSADumpTool.html#printError(java.lang.String, java.lang.Throwable)">printError</A></B>(java.lang.String&nbsp;msg,
java.lang.Throwable&nbsp;t)</CODE>
<BR>
@@ -203,7 +211,7 @@ This utility will dump the information and contents of a given <A HREF="../../mo
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>protected &nbsp;void</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/tools/DumpTool.html#printUsage()">printUsage</A></B>()</CODE>
+<TD><CODE><B><A HREF="../../morfologik/tools/FSADumpTool.html#printUsage()">printUsage</A></B>()</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Prints usage (options).</TD>
@@ -252,10 +260,10 @@ protected final org.apache.commons.cli.Options <B>options</B></PRE>
</TR>
</TABLE>
-<A NAME="DumpTool()"><!-- --></A><H3>
-DumpTool</H3>
+<A NAME="FSADumpTool()"><!-- --></A><H3>
+FSADumpTool</H3>
<PRE>
-public <B>DumpTool</B>()</PRE>
+public <B>FSADumpTool</B>()</PRE>
<DL>
</DL>
@@ -371,6 +379,19 @@ protected void <B>printUsage</B>()</PRE>
</DL>
</DD>
</DL>
+<HR>
+
+<A NAME="isAvailable()"><!-- --></A><H3>
+isAvailable</H3>
+<PRE>
+protected boolean <B>isAvailable</B>()</PRE>
+<DL>
+<DD>Is the tool available? <code>true</code> by default.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
<!-- ========= END OF CLASS DATA ========= -->
<HR>
@@ -401,11 +422,11 @@ protected void <B>printUsage</B>()</PRE>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;PREV CLASS&nbsp;
-&nbsp;<A HREF="../../morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/tools/DumpTool.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="DumpTool.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+ <A HREF="../../index.html?morfologik/tools/FSADumpTool.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FSADumpTool.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
diff --git a/doc/api/morfologik/fsa/FSAHelpers.html b/doc/api/morfologik/tools/IMessageLogger.html
index 7932c50..d84023a 100644
--- a/doc/api/morfologik/fsa/FSAHelpers.html
+++ b/doc/api/morfologik/tools/IMessageLogger.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
-FSAHelpers
+IMessageLogger
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -15,7 +15,7 @@ FSAHelpers
function windowTitle()
{
if (location.href.indexOf('is-external=true') == -1) {
- parent.document.title="FSAHelpers";
+ parent.document.title="IMessageLogger";
}
}
</SCRIPT>
@@ -54,11 +54,11 @@ function windowTitle()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/tools/FSADumpTool.html" title="class in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/fsa/FSAHelpers.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="FSAHelpers.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+ <A HREF="../../index.html?morfologik/tools/IMessageLogger.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IMessageLogger.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
@@ -87,24 +87,18 @@ DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHO
<!-- ======== START OF CLASS DATA ======== -->
<H2>
<FONT SIZE="-1">
-morfologik.fsa</FONT>
+morfologik.tools</FONT>
<BR>
-Class FSAHelpers</H2>
-<PRE>
-java.lang.Object
- <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.fsa.FSAHelpers</B>
-</PRE>
+Interface IMessageLogger</H2>
+<DL>
+<DT><B>All Known Implementing Classes:</B> <DD><A HREF="../../morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools">WriterMessageLogger</A></DD>
+</DL>
<HR>
<DL>
-<DT><PRE>public final class <B>FSAHelpers</B><DT>extends java.lang.Object</DL>
+<DT><PRE>public interface <B>IMessageLogger</B></DL>
</PRE>
<P>
-This class has several static utility methods for use
- with the FSA package.
-<P>
-
-<P>
<HR>
<P>
@@ -119,36 +113,36 @@ This class has several static utility methods for use
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>static&nbsp;java.lang.String</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAHelpers.html#flagsToString(int)">flagsToString</A></B>(int&nbsp;flags)</CODE>
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/IMessageLogger.html#endPart()">endPart</A></B>()</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Converts an integer with FSA flags to a human-readable string.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>static&nbsp;int</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAHelpers.html#getFlags(int)">getFlags</A></B>(int&nbsp;version)</CODE>
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/IMessageLogger.html#log(java.lang.String)">log</A></B>(java.lang.String&nbsp;msg)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns flags as an integer for a given version number.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log progress to the console.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>static&nbsp;byte</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/fsa/FSAHelpers.html#getVersion(int)">getVersion</A></B>(int&nbsp;flags)</CODE>
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/IMessageLogger.html#log(java.lang.String, java.lang.Object)">log</A></B>(java.lang.String&nbsp;header,
+ java.lang.Object&nbsp;v)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a version number for a set of flags.</TD>
-</TR>
-</TABLE>
-&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
-<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
-<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
-<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log a two-part message.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/IMessageLogger.html#startPart(java.lang.String)">startPart</A></B>(java.lang.String&nbsp;header)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log message header and save current time.</TD>
</TR>
</TABLE>
&nbsp;
@@ -164,12 +158,12 @@ This class has several static utility methods for use
</TR>
</TABLE>
-<A NAME="flagsToString(int)"><!-- --></A><H3>
-flagsToString</H3>
+<A NAME="log(java.lang.String)"><!-- --></A><H3>
+log</H3>
<PRE>
-public static java.lang.String <B>flagsToString</B>(int&nbsp;flags)</PRE>
+void <B>log</B>(java.lang.String&nbsp;msg)</PRE>
<DL>
-<DD>Converts an integer with FSA flags to a human-readable string.
+<DD>Log progress to the console.
<P>
<DD><DL>
</DL>
@@ -177,12 +171,12 @@ public static java.lang.String <B>flagsToString</B>(int&nbsp;flags)</PRE>
</DL>
<HR>
-<A NAME="getVersion(int)"><!-- --></A><H3>
-getVersion</H3>
+<A NAME="startPart(java.lang.String)"><!-- --></A><H3>
+startPart</H3>
<PRE>
-public static byte <B>getVersion</B>(int&nbsp;flags)</PRE>
+void <B>startPart</B>(java.lang.String&nbsp;header)</PRE>
<DL>
-<DD>Returns a version number for a set of flags.
+<DD>Log message header and save current time.
<P>
<DD><DL>
</DL>
@@ -190,17 +184,27 @@ public static byte <B>getVersion</B>(int&nbsp;flags)</PRE>
</DL>
<HR>
-<A NAME="getFlags(int)"><!-- --></A><H3>
-getFlags</H3>
+<A NAME="endPart()"><!-- --></A><H3>
+endPart</H3>
<PRE>
-public static int <B>getFlags</B>(int&nbsp;version)</PRE>
+void <B>endPart</B>()</PRE>
<DL>
-<DD>Returns flags as an integer for a given version number.
-<P>
<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
-<DT><B>Throws:</B>
-<DD><CODE>java.lang.RuntimeException</CODE> - if the version number is not recognized.</DL>
+<A NAME="log(java.lang.String, java.lang.Object)"><!-- --></A><H3>
+log</H3>
+<PRE>
+void <B>log</B>(java.lang.String&nbsp;header,
+ java.lang.Object&nbsp;v)</PRE>
+<DL>
+<DD>Log a two-part message.
+<P>
+<DD><DL>
+</DL>
</DD>
</DL>
<!-- ========= END OF CLASS DATA ========= -->
@@ -233,11 +237,11 @@ public static int <B>getFlags</B>(int&nbsp;version)</PRE>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/tools/FSADumpTool.html" title="class in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/fsa/FSAHelpers.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="FSAHelpers.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+ <A HREF="../../index.html?morfologik/tools/IMessageLogger.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="IMessageLogger.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
diff --git a/doc/api/morfologik/tools/InflectionFramesTool.html b/doc/api/morfologik/tools/InflectionFramesTool.html
index 0268184..6d3d792 100644
--- a/doc/api/morfologik/tools/InflectionFramesTool.html
+++ b/doc/api/morfologik/tools/InflectionFramesTool.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
InflectionFramesTool
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -54,7 +54,7 @@ function windowTitle()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/tools/DumpTool.html" title="class in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
&nbsp;<A HREF="../../morfologik/tools/Launcher.html" title="class in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/tools/InflectionFramesTool.html" target="_top"><B>FRAMES</B></A> &nbsp;
@@ -244,7 +244,7 @@ public void <B>inflectionFrames</B>()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/tools/DumpTool.html" title="class in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
&nbsp;<A HREF="../../morfologik/tools/Launcher.html" title="class in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/tools/InflectionFramesTool.html" target="_top"><B>FRAMES</B></A> &nbsp;
diff --git a/doc/api/morfologik/tools/Launcher.html b/doc/api/morfologik/tools/Launcher.html
index 0acdf8e..da29ad9 100644
--- a/doc/api/morfologik/tools/Launcher.html
+++ b/doc/api/morfologik/tools/Launcher.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
Launcher
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -55,7 +55,7 @@ function windowTitle()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;<A HREF="../../morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;NEXT CLASS</FONT></TD>
+&nbsp;<A HREF="../../morfologik/tools/MorphEncoder.html" title="class in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/tools/Launcher.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="Launcher.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
@@ -225,7 +225,7 @@ public static void <B>main</B>(java.lang.String[]&nbsp;args)
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;<A HREF="../../morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;NEXT CLASS</FONT></TD>
+&nbsp;<A HREF="../../morfologik/tools/MorphEncoder.html" title="class in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/tools/Launcher.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="Launcher.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
diff --git a/doc/api/morfologik/tools/MorphEncoder.html b/doc/api/morfologik/tools/MorphEncoder.html
new file mode 100644
index 0000000..fc9fd18
--- /dev/null
+++ b/doc/api/morfologik/tools/MorphEncoder.html
@@ -0,0 +1,584 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
+<TITLE>
+MorphEncoder
+</TITLE>
+
+<META NAME="date" CONTENT="2011-01-26">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="MorphEncoder";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/tools/Launcher.html" title="class in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/tools/MorphEncoder.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="MorphEncoder.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+morfologik.tools</FONT>
+<BR>
+Class MorphEncoder</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.tools.MorphEncoder</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public final class <B>MorphEncoder</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+A class that converts tabular data to fsa morphological format. Three formats
+ are supported:
+ <ul>
+ <li><b>standard</b>, see <A HREF="../../morfologik/tools/MorphEncoder.html#standardEncode(byte[], byte[], byte[])"><CODE>standardEncode(byte[], byte[], byte[])</CODE></A></li>
+ <li><b>prefix</b>, see <A HREF="../../morfologik/tools/MorphEncoder.html#prefixEncode(byte[], byte[], byte[])"><CODE>prefixEncode(byte[], byte[], byte[])</CODE></A></li>
+ <li><b>infix</b>, see <A HREF="../../morfologik/tools/MorphEncoder.html#infixEncode(byte[], byte[], byte[])"><CODE>infixEncode(byte[], byte[], byte[])</CODE></A></li>
+ </ul>
+<P>
+
+<P>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/tools/MorphEncoder.html#MorphEncoder()">MorphEncoder</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../morfologik/tools/MorphEncoder.html#MorphEncoder(byte)">MorphEncoder</A></B>(byte&nbsp;annotationSeparator)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected static&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/MorphEncoder.html#asString(byte[], java.lang.String)">asString</A></B>(byte[]&nbsp;str,
+ java.lang.String&nbsp;encoding)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Converts a byte array to a given encoding.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/MorphEncoder.html#commonPrefix(byte[], byte[])">commonPrefix</A></B>(byte[]&nbsp;s1,
+ byte[]&nbsp;s2)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/MorphEncoder.html#infixEncode(byte[], byte[], byte[])">infixEncode</A></B>(byte[]&nbsp;wordForm,
+ byte[]&nbsp;wordLemma,
+ byte[]&nbsp;wordTag)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method converts wordform, wordLemma and the tag to the form:
+
+ inflected_form + MLKending + tags
+
+
+ where '+' is a separator, M is the position of characters to be deleted
+ towards the beginning of the inflected form ("A" means from the
+ beginning, "B" from the second character, "C" - from the third one, and
+ so on), L is the number of characters to be deleted from the position
+ specified by M ("A" means none, "B" means one, "C" - 2, etc.), K is a
+ character that specifies how many characters should be deleted from the
+ end of the inflected form to produce the lexeme by concatenating the
+ stripped string with the ending ("A" means none, "B' - 1, "C" - 2, and so
+ on).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/MorphEncoder.html#infixEncodeUTF8(java.lang.String, java.lang.String, java.lang.String)">infixEncodeUTF8</A></B>(java.lang.String&nbsp;wordForm,
+ java.lang.String&nbsp;wordLemma,
+ java.lang.String&nbsp;wordTag)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A UTF-8 variant of <A HREF="../../morfologik/tools/MorphEncoder.html#infixEncode(byte[], byte[], byte[])"><CODE>infixEncode(byte[], byte[], byte[])</CODE></A>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/MorphEncoder.html#prefixEncode(byte[], byte[], byte[])">prefixEncode</A></B>(byte[]&nbsp;wordForm,
+ byte[]&nbsp;wordLemma,
+ byte[]&nbsp;wordTag)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method converts wordform, wordLemma and the tag to the form:
+
+
+
+ inflected_form + LKending + tags
+
+
+ where '+' is a separator, L is the number of characters to be deleted
+ from the beginning of the word ("A" means none, "B" means one, "C" - 2,
+ etc.), K is a character that specifies how many characters should be
+ deleted from the end of the inflected form to produce the lexeme by
+ concatenating the stripped string with the ending ("A" means none,
+ "B' - 1, "C" - 2, and so on).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/MorphEncoder.html#prefixEncodeUTF8(java.lang.String, java.lang.String, java.lang.String)">prefixEncodeUTF8</A></B>(java.lang.String&nbsp;wordForm,
+ java.lang.String&nbsp;wordLemma,
+ java.lang.String&nbsp;wordTag)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A UTF-8 variant of <A HREF="../../morfologik/tools/MorphEncoder.html#prefixEncode(byte[], byte[], byte[])"><CODE>prefixEncode(byte[], byte[], byte[])</CODE></A> This
+ method converts wordform, wordLemma and the tag to the form:
+
+ inflected_form + LKending + tags
+
+
+ where '+' is a separator, L is the number of characters to be deleted
+ from the beginning of the word ("A" means none, "B" means one, "C" - 2,
+ etc.), K is a character that specifies how many characters should be
+ deleted from the end of the inflected form to produce the lexeme by
+ concatenating the stripped string with the ending ("A" means none,
+ "B' - 1, "C" - 2, and so on).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/MorphEncoder.html#standardEncode(byte[], byte[], byte[])">standardEncode</A></B>(byte[]&nbsp;wordForm,
+ byte[]&nbsp;wordLemma,
+ byte[]&nbsp;wordTag)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This method converts the wordForm, wordLemma and tag to the form:
+
+
+ wordForm + Kending + tags
+
+
+ where '+' is a separator, K is a character that specifies how many
+ characters should be deleted from the end of the inflected form to
+ produce the lexeme by concatenating the stripped string with the ending.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/MorphEncoder.html#standardEncodeUTF8(java.lang.String, java.lang.String, java.lang.String)">standardEncodeUTF8</A></B>(java.lang.String&nbsp;wordForm,
+ java.lang.String&nbsp;wordLemma,
+ java.lang.String&nbsp;wordTag)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A UTF-8 variant of <A HREF="../../morfologik/tools/MorphEncoder.html#standardEncode(byte[], byte[], byte[])"><CODE>standardEncode(byte[], byte[], byte[])</CODE></A> This
+ method converts the wordForm, wordLemma and tag to the form:
+
+
+ wordForm + Kending + tags
+
+
+ where '+' is a separator, K is a character that specifies how many
+ characters should be deleted from the end of the inflected form to
+ produce the lexeme by concatenating the stripped string with the ending.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="MorphEncoder()"><!-- --></A><H3>
+MorphEncoder</H3>
+<PRE>
+public <B>MorphEncoder</B>()</PRE>
+<DL>
+</DL>
+<HR>
+
+<A NAME="MorphEncoder(byte)"><!-- --></A><H3>
+MorphEncoder</H3>
+<PRE>
+public <B>MorphEncoder</B>(byte&nbsp;annotationSeparator)</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="commonPrefix(byte[], byte[])"><!-- --></A><H3>
+commonPrefix</H3>
+<PRE>
+public static int <B>commonPrefix</B>(byte[]&nbsp;s1,
+ byte[]&nbsp;s2)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="standardEncode(byte[], byte[], byte[])"><!-- --></A><H3>
+standardEncode</H3>
+<PRE>
+public byte[] <B>standardEncode</B>(byte[]&nbsp;wordForm,
+ byte[]&nbsp;wordLemma,
+ byte[]&nbsp;wordTag)</PRE>
+<DL>
+<DD>This method converts the wordForm, wordLemma and tag to the form:
+
+ <pre>
+ wordForm + Kending + tags
+ </pre>
+
+ where '+' is a separator, K is a character that specifies how many
+ characters should be deleted from the end of the inflected form to
+ produce the lexeme by concatenating the stripped string with the ending.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="prefixEncode(byte[], byte[], byte[])"><!-- --></A><H3>
+prefixEncode</H3>
+<PRE>
+public byte[] <B>prefixEncode</B>(byte[]&nbsp;wordForm,
+ byte[]&nbsp;wordLemma,
+ byte[]&nbsp;wordTag)</PRE>
+<DL>
+<DD>This method converts wordform, wordLemma and the tag to the form:
+ <p>
+
+ <pre>
+ inflected_form + LKending + tags
+ </pre>
+ <p>
+ where '+' is a separator, L is the number of characters to be deleted
+ from the beginning of the word ("A" means none, "B" means one, "C" - 2,
+ etc.), K is a character that specifies how many characters should be
+ deleted from the end of the inflected form to produce the lexeme by
+ concatenating the stripped string with the ending ("A" means none,
+ "B' - 1, "C" - 2, and so on).
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>wordForm</CODE> - - inflected word form<DD><CODE>wordLemma</CODE> - - canonical form<DD><CODE>wordTag</CODE> - - tag
+<DT><B>Returns:</B><DD>the encoded string</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="infixEncode(byte[], byte[], byte[])"><!-- --></A><H3>
+infixEncode</H3>
+<PRE>
+public byte[] <B>infixEncode</B>(byte[]&nbsp;wordForm,
+ byte[]&nbsp;wordLemma,
+ byte[]&nbsp;wordTag)</PRE>
+<DL>
+<DD>This method converts wordform, wordLemma and the tag to the form:
+ <pre>
+ inflected_form + MLKending + tags
+ </pre>
+ <p>
+ where '+' is a separator, M is the position of characters to be deleted
+ towards the beginning of the inflected form ("A" means from the
+ beginning, "B" from the second character, "C" - from the third one, and
+ so on), L is the number of characters to be deleted from the position
+ specified by M ("A" means none, "B" means one, "C" - 2, etc.), K is a
+ character that specifies how many characters should be deleted from the
+ end of the inflected form to produce the lexeme by concatenating the
+ stripped string with the ending ("A" means none, "B' - 1, "C" - 2, and so
+ on).
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>wordForm</CODE> - - inflected word form<DD><CODE>wordLemma</CODE> - - canonical form<DD><CODE>wordTag</CODE> - - tag
+<DT><B>Returns:</B><DD>the encoded string</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="asString(byte[], java.lang.String)"><!-- --></A><H3>
+asString</H3>
+<PRE>
+protected static java.lang.String <B>asString</B>(byte[]&nbsp;str,
+ java.lang.String&nbsp;encoding)</PRE>
+<DL>
+<DD>Converts a byte array to a given encoding.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>str</CODE> - Byte-array to be converted.
+<DT><B>Returns:</B><DD>Java String. If decoding is unsuccessful, the string is empty.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="standardEncodeUTF8(java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+standardEncodeUTF8</H3>
+<PRE>
+public java.lang.String <B>standardEncodeUTF8</B>(java.lang.String&nbsp;wordForm,
+ java.lang.String&nbsp;wordLemma,
+ java.lang.String&nbsp;wordTag)
+ throws java.io.UnsupportedEncodingException</PRE>
+<DL>
+<DD>A UTF-8 variant of <A HREF="../../morfologik/tools/MorphEncoder.html#standardEncode(byte[], byte[], byte[])"><CODE>standardEncode(byte[], byte[], byte[])</CODE></A> This
+ method converts the wordForm, wordLemma and tag to the form:
+
+ <pre>
+ wordForm + Kending + tags
+ </pre>
+
+ where '+' is a separator, K is a character that specifies how many
+ characters should be deleted from the end of the inflected form to
+ produce the lexeme by concatenating the stripped string with the ending.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.UnsupportedEncodingException</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="prefixEncodeUTF8(java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+prefixEncodeUTF8</H3>
+<PRE>
+public java.lang.String <B>prefixEncodeUTF8</B>(java.lang.String&nbsp;wordForm,
+ java.lang.String&nbsp;wordLemma,
+ java.lang.String&nbsp;wordTag)
+ throws java.io.UnsupportedEncodingException</PRE>
+<DL>
+<DD>A UTF-8 variant of <A HREF="../../morfologik/tools/MorphEncoder.html#prefixEncode(byte[], byte[], byte[])"><CODE>prefixEncode(byte[], byte[], byte[])</CODE></A> This
+ method converts wordform, wordLemma and the tag to the form:
+ <pre>
+ inflected_form + LKending + tags
+ </pre>
+ <p>
+ where '+' is a separator, L is the number of characters to be deleted
+ from the beginning of the word ("A" means none, "B" means one, "C" - 2,
+ etc.), K is a character that specifies how many characters should be
+ deleted from the end of the inflected form to produce the lexeme by
+ concatenating the stripped string with the ending ("A" means none,
+ "B' - 1, "C" - 2, and so on).
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>wordForm</CODE> - - inflected word form<DD><CODE>wordLemma</CODE> - - canonical form<DD><CODE>wordTag</CODE> - - tag
+<DT><B>Returns:</B><DD>the encoded string
+<DT><B>Throws:</B>
+<DD><CODE>java.io.UnsupportedEncodingException</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="infixEncodeUTF8(java.lang.String, java.lang.String, java.lang.String)"><!-- --></A><H3>
+infixEncodeUTF8</H3>
+<PRE>
+public java.lang.String <B>infixEncodeUTF8</B>(java.lang.String&nbsp;wordForm,
+ java.lang.String&nbsp;wordLemma,
+ java.lang.String&nbsp;wordTag)
+ throws java.io.UnsupportedEncodingException</PRE>
+<DL>
+<DD>A UTF-8 variant of <A HREF="../../morfologik/tools/MorphEncoder.html#infixEncode(byte[], byte[], byte[])"><CODE>infixEncode(byte[], byte[], byte[])</CODE></A>.
+
+ This method converts wordform, wordLemma and the tag to the form:
+ <pre>
+ inflected_form + MLKending + tags
+ </pre>
+ <p>
+ where '+' is a separator, M is the position of characters to be deleted
+ towards the beginning of the inflected form ("A" means from the
+ beginning, "B" from the second character, "C" - from the third one, and
+ so on), L is the number of characters to be deleted from the position
+ specified by M ("A" means none, "B" means one, "C" - 2, etc.), K is a
+ character that specifies how many characters should be deleted from the
+ end of the inflected form to produce the lexeme by concatenating the
+ stripped string with the ending ("A" means none, "B' - 1, "C" - 2, and so
+ on).
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>wordForm</CODE> - - inflected word form<DD><CODE>wordLemma</CODE> - - canonical form<DD><CODE>wordTag</CODE> - - tag
+<DT><B>Returns:</B><DD>the encoded string
+<DT><B>Throws:</B>
+<DD><CODE>java.io.UnsupportedEncodingException</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../morfologik/tools/Launcher.html" title="class in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html?morfologik/tools/MorphEncoder.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="MorphEncoder.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/api/morfologik/util/PerformanceTimer.html b/doc/api/morfologik/tools/WriterMessageLogger.html
index 66d446c..0cd0cf7 100644
--- a/doc/api/morfologik/util/PerformanceTimer.html
+++ b/doc/api/morfologik/tools/WriterMessageLogger.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
-PerformanceTimer
+WriterMessageLogger
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -15,7 +15,7 @@ PerformanceTimer
function windowTitle()
{
if (location.href.indexOf('is-external=true') == -1) {
- parent.document.title="PerformanceTimer";
+ parent.document.title="WriterMessageLogger";
}
}
</SCRIPT>
@@ -54,11 +54,11 @@ function windowTitle()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/util/FileUtils.html" title="class in morfologik.util"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/util/ResourceUtils.html" title="class in morfologik.util"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/tools/MorphEncoder.html" title="class in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/util/PerformanceTimer.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="PerformanceTimer.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+ <A HREF="../../index.html?morfologik/tools/WriterMessageLogger.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="WriterMessageLogger.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
@@ -87,20 +87,23 @@ DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&n
<!-- ======== START OF CLASS DATA ======== -->
<H2>
<FONT SIZE="-1">
-morfologik.util</FONT>
+morfologik.tools</FONT>
<BR>
-Class PerformanceTimer</H2>
+Class WriterMessageLogger</H2>
<PRE>
java.lang.Object
- <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.util.PerformanceTimer</B>
+ <IMG SRC="../../resources/inherit.gif" ALT="extended by "><B>morfologik.tools.WriterMessageLogger</B>
</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A></DD>
+</DL>
<HR>
<DL>
-<DT><PRE>public final class <B>PerformanceTimer</B><DT>extends java.lang.Object</DL>
+<DT><PRE>public class <B>WriterMessageLogger</B><DT>extends java.lang.Object<DT>implements <A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A></DL>
</PRE>
<P>
-Simple, simple performance checking.
+A logger dumping info to <code>System.err</code>.
<P>
<P>
@@ -117,7 +120,7 @@ Simple, simple performance checking.
<B>Constructor Summary</B></FONT></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../morfologik/util/PerformanceTimer.html#PerformanceTimer()">PerformanceTimer</A></B>()</CODE>
+<TD><CODE><B><A HREF="../../morfologik/tools/WriterMessageLogger.html#WriterMessageLogger(java.io.PrintWriter)">WriterMessageLogger</A></B>(java.io.PrintWriter&nbsp;w)</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
@@ -134,30 +137,36 @@ Simple, simple performance checking.
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;long</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/util/PerformanceTimer.html#elemsPerSecond(int)">elemsPerSecond</A></B>(int&nbsp;sequences)</CODE>
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/WriterMessageLogger.html#endPart()">endPart</A></B>()</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>static&nbsp;<A HREF="../../morfologik/util/PerformanceTimer.html" title="class in morfologik.util">PerformanceTimer</A></CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/util/PerformanceTimer.html#run(java.util.concurrent.Callable, int, int)">run</A></B>(java.util.concurrent.Callable&lt;java.lang.Void&gt;&nbsp;task,
- int&nbsp;warmupRounds,
- int&nbsp;cycles)</CODE>
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/WriterMessageLogger.html#log(java.lang.String)">log</A></B>(java.lang.String&nbsp;msg)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Run the task with a given number of warm-up rounds and the given number
- of cycles.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log progress to the console.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/util/PerformanceTimer.html#toString()">toString</A></B>()</CODE>
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/WriterMessageLogger.html#log(java.lang.String, java.lang.Object)">log</A></B>(java.lang.String&nbsp;header,
+ java.lang.Object&nbsp;v)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log a two-part message.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/tools/WriterMessageLogger.html#startPart(java.lang.String)">startPart</A></B>(java.lang.String&nbsp;header)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log message header and save current time.</TD>
</TR>
</TABLE>
&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
@@ -166,7 +175,7 @@ Simple, simple performance checking.
<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
</TR>
</TABLE>
&nbsp;
@@ -182,10 +191,10 @@ Simple, simple performance checking.
</TR>
</TABLE>
-<A NAME="PerformanceTimer()"><!-- --></A><H3>
-PerformanceTimer</H3>
+<A NAME="WriterMessageLogger(java.io.PrintWriter)"><!-- --></A><H3>
+WriterMessageLogger</H3>
<PRE>
-public <B>PerformanceTimer</B>()</PRE>
+public <B>WriterMessageLogger</B>(java.io.PrintWriter&nbsp;w)</PRE>
<DL>
</DL>
@@ -199,29 +208,51 @@ public <B>PerformanceTimer</B>()</PRE>
</TR>
</TABLE>
-<A NAME="run(java.util.concurrent.Callable, int, int)"><!-- --></A><H3>
-run</H3>
+<A NAME="log(java.lang.String)"><!-- --></A><H3>
+log</H3>
+<PRE>
+public void <B>log</B>(java.lang.String&nbsp;msg)</PRE>
+<DL>
+<DD><B>Description copied from interface: <CODE><A HREF="../../morfologik/tools/IMessageLogger.html#log(java.lang.String)">IMessageLogger</A></CODE></B></DD>
+<DD>Log progress to the console.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/tools/IMessageLogger.html#log(java.lang.String)">log</A></CODE> in interface <CODE><A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="log(java.lang.String, java.lang.Object)"><!-- --></A><H3>
+log</H3>
<PRE>
-public static <A HREF="../../morfologik/util/PerformanceTimer.html" title="class in morfologik.util">PerformanceTimer</A> <B>run</B>(java.util.concurrent.Callable&lt;java.lang.Void&gt;&nbsp;task,
- int&nbsp;warmupRounds,
- int&nbsp;cycles)</PRE>
+public void <B>log</B>(java.lang.String&nbsp;header,
+ java.lang.Object&nbsp;v)</PRE>
<DL>
-<DD>Run the task with a given number of warm-up rounds and the given number
- of cycles.
+<DD><B>Description copied from interface: <CODE><A HREF="../../morfologik/tools/IMessageLogger.html#log(java.lang.String, java.lang.Object)">IMessageLogger</A></CODE></B></DD>
+<DD>Log a two-part message.
<P>
<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/tools/IMessageLogger.html#log(java.lang.String, java.lang.Object)">log</A></CODE> in interface <CODE><A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A></CODE></DL>
+</DD>
+<DD><DL>
</DL>
</DD>
</DL>
<HR>
-<A NAME="toString()"><!-- --></A><H3>
-toString</H3>
+<A NAME="startPart(java.lang.String)"><!-- --></A><H3>
+startPart</H3>
<PRE>
-public java.lang.String <B>toString</B>()</PRE>
+public void <B>startPart</B>(java.lang.String&nbsp;header)</PRE>
<DL>
+<DD><B>Description copied from interface: <CODE><A HREF="../../morfologik/tools/IMessageLogger.html#startPart(java.lang.String)">IMessageLogger</A></CODE></B></DD>
+<DD>Log message header and save current time.
+<P>
<DD><DL>
-<DT><B>Overrides:</B><DD><CODE>toString</CODE> in class <CODE>java.lang.Object</CODE></DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/tools/IMessageLogger.html#startPart(java.lang.String)">startPart</A></CODE> in interface <CODE><A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A></CODE></DL>
</DD>
<DD><DL>
</DL>
@@ -229,12 +260,15 @@ public java.lang.String <B>toString</B>()</PRE>
</DL>
<HR>
-<A NAME="elemsPerSecond(int)"><!-- --></A><H3>
-elemsPerSecond</H3>
+<A NAME="endPart()"><!-- --></A><H3>
+endPart</H3>
<PRE>
-public long <B>elemsPerSecond</B>(int&nbsp;sequences)</PRE>
+public void <B>endPart</B>()</PRE>
<DL>
<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../morfologik/tools/IMessageLogger.html#endPart()">endPart</A></CODE> in interface <CODE><A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A></CODE></DL>
+</DD>
+<DD><DL>
</DL>
</DD>
</DL>
@@ -268,11 +302,11 @@ public long <B>elemsPerSecond</B>(int&nbsp;sequences)</PRE>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/util/FileUtils.html" title="class in morfologik.util"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/util/ResourceUtils.html" title="class in morfologik.util"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/tools/MorphEncoder.html" title="class in morfologik.tools"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
- <A HREF="../../index.html?morfologik/util/PerformanceTimer.html" target="_top"><B>FRAMES</B></A> &nbsp;
-&nbsp;<A HREF="PerformanceTimer.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+ <A HREF="../../index.html?morfologik/tools/WriterMessageLogger.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="WriterMessageLogger.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
diff --git a/doc/api/morfologik/tools/package-frame.html b/doc/api/morfologik/tools/package-frame.html
index 10e2408..1648f37 100644
--- a/doc/api/morfologik/tools/package-frame.html
+++ b/doc/api/morfologik/tools/package-frame.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
morfologik.tools
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -20,14 +20,42 @@ morfologik.tools
<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
<TR>
<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Interfaces</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="IMessageLogger.html" title="interface in morfologik.tools" target="classFrame"><I>IMessageLogger</I></A></FONT></TD>
+</TR>
+</TABLE>
+
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
Classes</FONT>&nbsp;
<FONT CLASS="FrameItemFont">
<BR>
-<A HREF="DumpTool.html" title="class in morfologik.tools" target="classFrame">DumpTool</A>
+<A HREF="FSABuildTool.html" title="class in morfologik.tools" target="classFrame">FSABuildTool</A>
+<BR>
+<A HREF="FSADumpTool.html" title="class in morfologik.tools" target="classFrame">FSADumpTool</A>
<BR>
<A HREF="InflectionFramesTool.html" title="class in morfologik.tools" target="classFrame">InflectionFramesTool</A>
<BR>
-<A HREF="Launcher.html" title="class in morfologik.tools" target="classFrame">Launcher</A></FONT></TD>
+<A HREF="Launcher.html" title="class in morfologik.tools" target="classFrame">Launcher</A>
+<BR>
+<A HREF="MorphEncoder.html" title="class in morfologik.tools" target="classFrame">MorphEncoder</A>
+<BR>
+<A HREF="WriterMessageLogger.html" title="class in morfologik.tools" target="classFrame">WriterMessageLogger</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Enums</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="FSABuildTool.Format.html" title="enum in morfologik.tools" target="classFrame">FSABuildTool.Format</A></FONT></TD>
</TR>
</TABLE>
diff --git a/doc/api/morfologik/tools/package-summary.html b/doc/api/morfologik/tools/package-summary.html
index 8150a9e..f926b20 100644
--- a/doc/api/morfologik/tools/package-summary.html
+++ b/doc/api/morfologik/tools/package-summary.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
morfologik.tools
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -85,10 +85,29 @@ Package morfologik.tools
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Interface Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A></B></TD>
+<TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
<B>Class Summary</B></FONT></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD WIDTH="15%"><B><A HREF="../../morfologik/tools/DumpTool.html" title="class in morfologik.tools">DumpTool</A></B></TD>
+<TD WIDTH="15%"><B><A HREF="../../morfologik/tools/FSABuildTool.html" title="class in morfologik.tools">FSABuildTool</A></B></TD>
+<TD>Convert from plain text input to a serialized FSA in any of the
+ available <A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools"><CODE>FSABuildTool.Format</CODE></A>s.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/tools/FSADumpTool.html" title="class in morfologik.tools">FSADumpTool</A></B></TD>
<TD>This utility will dump the information and contents of a given <A HREF="../../morfologik/fsa/FSA.html" title="class in morfologik.fsa"><CODE>FSA</CODE></A>
dictionary.</TD>
</TR>
@@ -100,6 +119,28 @@ Package morfologik.tools
<TD WIDTH="15%"><B><A HREF="../../morfologik/tools/Launcher.html" title="class in morfologik.tools">Launcher</A></B></TD>
<TD>A launcher for other command-line tools.</TD>
</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/tools/MorphEncoder.html" title="class in morfologik.tools">MorphEncoder</A></B></TD>
+<TD>A class that converts tabular data to fsa morphological format.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools">WriterMessageLogger</A></B></TD>
+<TD>A logger dumping info to <code>System.err</code>.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Enum Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools">FSABuildTool.Format</A></B></TD>
+<TD>The serialization format to use for the binary output.</TD>
+</TR>
</TABLE>
&nbsp;
diff --git a/doc/api/morfologik/tools/package-tree.html b/doc/api/morfologik/tools/package-tree.html
index bc41772..d4395e1 100644
--- a/doc/api/morfologik/tools/package-tree.html
+++ b/doc/api/morfologik/tools/package-tree.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
morfologik.tools Class Hierarchy
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -91,7 +91,23 @@ Class Hierarchy
</H2>
<UL>
<LI TYPE="circle">java.lang.Object<UL>
-<LI TYPE="circle">morfologik.tools.<A HREF="../../morfologik/tools/DumpTool.html" title="class in morfologik.tools"><B>DumpTool</B></A><LI TYPE="circle">morfologik.tools.<A HREF="../../morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools"><B>InflectionFramesTool</B></A><LI TYPE="circle">morfologik.tools.<A HREF="../../morfologik/tools/Launcher.html" title="class in morfologik.tools"><B>Launcher</B></A></UL>
+<LI TYPE="circle">morfologik.tools.<A HREF="../../morfologik/tools/FSABuildTool.html" title="class in morfologik.tools"><B>FSABuildTool</B></A><LI TYPE="circle">morfologik.tools.<A HREF="../../morfologik/tools/FSADumpTool.html" title="class in morfologik.tools"><B>FSADumpTool</B></A><LI TYPE="circle">morfologik.tools.<A HREF="../../morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools"><B>InflectionFramesTool</B></A><LI TYPE="circle">morfologik.tools.<A HREF="../../morfologik/tools/Launcher.html" title="class in morfologik.tools"><B>Launcher</B></A><LI TYPE="circle">morfologik.tools.<A HREF="../../morfologik/tools/MorphEncoder.html" title="class in morfologik.tools"><B>MorphEncoder</B></A><LI TYPE="circle">morfologik.tools.<A HREF="../../morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools"><B>WriterMessageLogger</B></A> (implements morfologik.tools.<A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A>)
+</UL>
+</UL>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">morfologik.tools.<A HREF="../../morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools"><B>IMessageLogger</B></A></UL>
+<H2>
+Enum Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">java.lang.Object<UL>
+<LI TYPE="circle">java.lang.Enum&lt;E&gt; (implements java.lang.Comparable&lt;T&gt;, java.io.Serializable)
+<UL>
+<LI TYPE="circle">morfologik.tools.<A HREF="../../morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools"><B>FSABuildTool.Format</B></A></UL>
+</UL>
</UL>
<HR>
diff --git a/doc/api/morfologik/util/Arrays.html b/doc/api/morfologik/util/Arrays.html
index 830904c..9add801 100644
--- a/doc/api/morfologik/util/Arrays.html
+++ b/doc/api/morfologik/util/Arrays.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
Arrays
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -118,54 +118,61 @@ Compatibility layer for JVM 1.5.
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>static&nbsp;byte[]</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/util/Arrays.html#copyOf(byte[], int)">copyOf</A></B>(byte[]&nbsp;original,
- int&nbsp;newLength)</CODE>
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/util/Arrays.html#equals(boolean[], int, boolean[], int, int)">equals</A></B>(boolean[]&nbsp;a1,
+ int&nbsp;a1s,
+ boolean[]&nbsp;a2,
+ int&nbsp;a2s,
+ int&nbsp;length)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Compare two arrays for equality.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>static&nbsp;int[]</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/util/Arrays.html#copyOf(int[], int)">copyOf</A></B>(int[]&nbsp;original,
- int&nbsp;newLength)</CODE>
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/util/Arrays.html#equals(byte[], int, byte[], int, int)">equals</A></B>(byte[]&nbsp;a1,
+ int&nbsp;a1s,
+ byte[]&nbsp;a2,
+ int&nbsp;a2s,
+ int&nbsp;length)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Compare two arrays for equality.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>static
-<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
-<TR ALIGN="right" VALIGN="">
-<TD NOWRAP><FONT SIZE="-1">
-<CODE>&lt;T&gt; T[]</CODE></FONT></TD>
-</TR>
-</TABLE>
-</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/util/Arrays.html#copyOf(T[], int)">copyOf</A></B>(T[]&nbsp;original,
- int&nbsp;newLength)</CODE>
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/util/Arrays.html#equals(int[], int, int[], int, int)">equals</A></B>(int[]&nbsp;a1,
+ int&nbsp;a1s,
+ int[]&nbsp;a2,
+ int&nbsp;a2s,
+ int&nbsp;length)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Compare two arrays for equality.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>static
-<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
-<TR ALIGN="right" VALIGN="">
-<TD NOWRAP><FONT SIZE="-1">
-<CODE>&lt;T,U&gt; T[]</CODE></FONT></TD>
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/util/Arrays.html#referenceEquals(java.lang.Object[], int, java.lang.Object[], int, int)">referenceEquals</A></B>(java.lang.Object[]&nbsp;a1,
+ int&nbsp;a1s,
+ java.lang.Object[]&nbsp;a2,
+ int&nbsp;a2s,
+ int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Compare two lists of objects for reference-equality.</TD>
</TR>
-</TABLE>
-</CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../morfologik/util/Arrays.html#copyOf(U[], int, java.lang.Class)">copyOf</A></B>(U[]&nbsp;original,
- int&nbsp;newLength,
- java.lang.Class&lt;? extends T[]&gt;&nbsp;newType)</CODE>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/util/Arrays.html#toString(byte[], int, int)">toString</A></B>(byte[]&nbsp;bytes,
+ int&nbsp;start,
+ int&nbsp;length)</CODE>
<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convert an array of strings to bytes.</TD>
</TR>
</TABLE>
&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
@@ -190,49 +197,83 @@ Compatibility layer for JVM 1.5.
</TR>
</TABLE>
-<A NAME="copyOf(byte[], int)"><!-- --></A><H3>
-copyOf</H3>
+<A NAME="referenceEquals(java.lang.Object[], int, java.lang.Object[], int, int)"><!-- --></A><H3>
+referenceEquals</H3>
+<PRE>
+public static boolean <B>referenceEquals</B>(java.lang.Object[]&nbsp;a1,
+ int&nbsp;a1s,
+ java.lang.Object[]&nbsp;a2,
+ int&nbsp;a2s,
+ int&nbsp;length)</PRE>
+<DL>
+<DD>Compare two lists of objects for reference-equality.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="equals(byte[], int, byte[], int, int)"><!-- --></A><H3>
+equals</H3>
<PRE>
-public static byte[] <B>copyOf</B>(byte[]&nbsp;original,
- int&nbsp;newLength)</PRE>
+public static boolean <B>equals</B>(byte[]&nbsp;a1,
+ int&nbsp;a1s,
+ byte[]&nbsp;a2,
+ int&nbsp;a2s,
+ int&nbsp;length)</PRE>
<DL>
+<DD>Compare two arrays for equality.
+<P>
<DD><DL>
</DL>
</DD>
</DL>
<HR>
-<A NAME="copyOf(int[], int)"><!-- --></A><H3>
-copyOf</H3>
+<A NAME="equals(boolean[], int, boolean[], int, int)"><!-- --></A><H3>
+equals</H3>
<PRE>
-public static int[] <B>copyOf</B>(int[]&nbsp;original,
- int&nbsp;newLength)</PRE>
+public static boolean <B>equals</B>(boolean[]&nbsp;a1,
+ int&nbsp;a1s,
+ boolean[]&nbsp;a2,
+ int&nbsp;a2s,
+ int&nbsp;length)</PRE>
<DL>
+<DD>Compare two arrays for equality.
+<P>
<DD><DL>
</DL>
</DD>
</DL>
<HR>
-<A NAME="copyOf(java.lang.Object[],int)"><!-- --></A><A NAME="copyOf(T[], int)"><!-- --></A><H3>
-copyOf</H3>
+<A NAME="equals(int[], int, int[], int, int)"><!-- --></A><H3>
+equals</H3>
<PRE>
-public static &lt;T&gt; T[] <B>copyOf</B>(T[]&nbsp;original,
- int&nbsp;newLength)</PRE>
+public static boolean <B>equals</B>(int[]&nbsp;a1,
+ int&nbsp;a1s,
+ int[]&nbsp;a2,
+ int&nbsp;a2s,
+ int&nbsp;length)</PRE>
<DL>
+<DD>Compare two arrays for equality.
+<P>
<DD><DL>
</DL>
</DD>
</DL>
<HR>
-<A NAME="copyOf(java.lang.Object[],int,java.lang.Class)"><!-- --></A><A NAME="copyOf(U[], int, java.lang.Class)"><!-- --></A><H3>
-copyOf</H3>
+<A NAME="toString(byte[], int, int)"><!-- --></A><H3>
+toString</H3>
<PRE>
-public static &lt;T,U&gt; T[] <B>copyOf</B>(U[]&nbsp;original,
- int&nbsp;newLength,
- java.lang.Class&lt;? extends T[]&gt;&nbsp;newType)</PRE>
+public static java.lang.String <B>toString</B>(byte[]&nbsp;bytes,
+ int&nbsp;start,
+ int&nbsp;length)</PRE>
<DL>
+<DD>Convert an array of strings to bytes.
+<P>
<DD><DL>
</DL>
</DD>
diff --git a/doc/api/morfologik/util/BufferUtils.html b/doc/api/morfologik/util/BufferUtils.html
index 29302b4..58d8a88 100644
--- a/doc/api/morfologik/util/BufferUtils.html
+++ b/doc/api/morfologik/util/BufferUtils.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:36 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
BufferUtils
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -134,6 +134,14 @@ Utility functions for buffers.
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ensure the char buffer's capacity.</TD>
</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/util/BufferUtils.html#toString(java.nio.ByteBuffer)">toString</A></B>(java.nio.ByteBuffer&nbsp;sequence)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convert a byte buffer to a string in platform default encoding.</TD>
+</TR>
</TABLE>
&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
@@ -187,6 +195,19 @@ public static java.nio.CharBuffer <B>ensureCapacity</B>(java.nio.CharBuffer&nbsp
should be allocated.</DL>
</DD>
</DL>
+<HR>
+
+<A NAME="toString(java.nio.ByteBuffer)"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public static java.lang.String <B>toString</B>(java.nio.ByteBuffer&nbsp;sequence)</PRE>
+<DL>
+<DD>Convert a byte buffer to a string in platform default encoding.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
<!-- ========= END OF CLASS DATA ========= -->
<HR>
diff --git a/doc/api/morfologik/util/FileUtils.html b/doc/api/morfologik/util/FileUtils.html
index 13e41a6..438e851 100644
--- a/doc/api/morfologik/util/FileUtils.html
+++ b/doc/api/morfologik/util/FileUtils.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
FileUtils
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -55,7 +55,7 @@ function windowTitle()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;<A HREF="../../morfologik/util/BufferUtils.html" title="class in morfologik.util"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/util/PerformanceTimer.html" title="class in morfologik.util"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/util/ResourceUtils.html" title="class in morfologik.util"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/util/FileUtils.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="FileUtils.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
@@ -134,6 +134,66 @@ Utility functions.
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Force any non-null closeables.</TD>
</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;byte</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/util/FileUtils.html#readByte(java.io.InputStream)">readByte</A></B>(java.io.InputStream&nbsp;in)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Read exactly one byte from the input stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;byte[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/util/FileUtils.html#readFully(java.io.InputStream)">readFully</A></B>(java.io.InputStream&nbsp;stream)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reads all bytes from an input stream (until EOF).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/util/FileUtils.html#readFully(java.io.InputStream, byte[])">readFully</A></B>(java.io.InputStream&nbsp;in,
+ byte[]&nbsp;array)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Read enough bytes to fill <code>array</code> If there are not enough
+ bytes, throw an exception.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/util/FileUtils.html#readInt(java.io.InputStream)">readInt</A></B>(java.io.InputStream&nbsp;in)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Read exactly 4 bytes from the input stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;short</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/util/FileUtils.html#readShort(java.io.InputStream)">readShort</A></B>(java.io.InputStream&nbsp;in)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Read exactly 2 bytes from the input stream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/util/FileUtils.html#writeInt(java.io.OutputStream, int)">writeInt</A></B>(java.io.OutputStream&nbsp;os,
+ int&nbsp;v)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../morfologik/util/FileUtils.html#writeShort(java.io.OutputStream, short)">writeShort</A></B>(java.io.OutputStream&nbsp;os,
+ short&nbsp;v)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
</TABLE>
&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
@@ -186,6 +246,119 @@ public static void <B>close</B>(java.io.Closeable...&nbsp;closeables)</PRE>
</DL>
</DD>
</DL>
+<HR>
+
+<A NAME="readFully(java.io.InputStream)"><!-- --></A><H3>
+readFully</H3>
+<PRE>
+public static byte[] <B>readFully</B>(java.io.InputStream&nbsp;stream)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Reads all bytes from an input stream (until EOF).
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="readFully(java.io.InputStream, byte[])"><!-- --></A><H3>
+readFully</H3>
+<PRE>
+public static void <B>readFully</B>(java.io.InputStream&nbsp;in,
+ byte[]&nbsp;array)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Read enough bytes to fill <code>array</code> If there are not enough
+ bytes, throw an exception.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="readInt(java.io.InputStream)"><!-- --></A><H3>
+readInt</H3>
+<PRE>
+public static int <B>readInt</B>(java.io.InputStream&nbsp;in)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Read exactly 4 bytes from the input stream.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="writeInt(java.io.OutputStream, int)"><!-- --></A><H3>
+writeInt</H3>
+<PRE>
+public static void <B>writeInt</B>(java.io.OutputStream&nbsp;os,
+ int&nbsp;v)
+ throws java.io.IOException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="readShort(java.io.InputStream)"><!-- --></A><H3>
+readShort</H3>
+<PRE>
+public static short <B>readShort</B>(java.io.InputStream&nbsp;in)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Read exactly 2 bytes from the input stream.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="readByte(java.io.InputStream)"><!-- --></A><H3>
+readByte</H3>
+<PRE>
+public static byte <B>readByte</B>(java.io.InputStream&nbsp;in)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Read exactly one byte from the input stream.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.EOFException</CODE> - if EOF is reached.
+<DD><CODE>java.io.IOException</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="writeShort(java.io.OutputStream, short)"><!-- --></A><H3>
+writeShort</H3>
+<PRE>
+public static void <B>writeShort</B>(java.io.OutputStream&nbsp;os,
+ short&nbsp;v)
+ throws java.io.IOException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DD>
+</DL>
<!-- ========= END OF CLASS DATA ========= -->
<HR>
@@ -217,7 +390,7 @@ public static void <B>close</B>(java.io.Closeable...&nbsp;closeables)</PRE>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;<A HREF="../../morfologik/util/BufferUtils.html" title="class in morfologik.util"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../morfologik/util/PerformanceTimer.html" title="class in morfologik.util"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../morfologik/util/ResourceUtils.html" title="class in morfologik.util"><B>NEXT CLASS</B></A></FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/util/FileUtils.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="FileUtils.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
diff --git a/doc/api/morfologik/util/ResourceUtils.html b/doc/api/morfologik/util/ResourceUtils.html
index 95d56b9..b924071 100644
--- a/doc/api/morfologik/util/ResourceUtils.html
+++ b/doc/api/morfologik/util/ResourceUtils.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
ResourceUtils
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -54,7 +54,7 @@ function windowTitle()
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/util/PerformanceTimer.html" title="class in morfologik.util"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/util/FileUtils.html" title="class in morfologik.util"><B>PREV CLASS</B></A>&nbsp;
&nbsp;NEXT CLASS</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/util/ResourceUtils.html" target="_top"><B>FRAMES</B></A> &nbsp;
@@ -157,7 +157,7 @@ public static java.io.InputStream <B>openInputStream</B>(java.lang.String&nbsp;r
<P>
<DD><DL>
<DT><B>Parameters:</B><DD><CODE>resource</CODE> - The path leading to the resource. Can be an URL, a path
- leading to a class resource or a <CODE>File</CODE>.
+ leading to a class resource or a <CODE>File</CODE>.
<DT><B>Returns:</B><DD>InputStream instance.
<DT><B>Throws:</B>
<DD><CODE>java.io.IOException</CODE> - If the resource could not be found or opened.</DL>
@@ -193,7 +193,7 @@ public static java.io.InputStream <B>openInputStream</B>(java.lang.String&nbsp;r
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../morfologik/util/PerformanceTimer.html" title="class in morfologik.util"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../morfologik/util/FileUtils.html" title="class in morfologik.util"><B>PREV CLASS</B></A>&nbsp;
&nbsp;NEXT CLASS</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../index.html?morfologik/util/ResourceUtils.html" target="_top"><B>FRAMES</B></A> &nbsp;
diff --git a/doc/api/morfologik/util/package-frame.html b/doc/api/morfologik/util/package-frame.html
index 0f210df..1803ab0 100644
--- a/doc/api/morfologik/util/package-frame.html
+++ b/doc/api/morfologik/util/package-frame.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
morfologik.util
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -29,8 +29,6 @@ Classes</FONT>&nbsp;
<BR>
<A HREF="FileUtils.html" title="class in morfologik.util" target="classFrame">FileUtils</A>
<BR>
-<A HREF="PerformanceTimer.html" title="class in morfologik.util" target="classFrame">PerformanceTimer</A>
-<BR>
<A HREF="ResourceUtils.html" title="class in morfologik.util" target="classFrame">ResourceUtils</A></FONT></TD>
</TR>
</TABLE>
diff --git a/doc/api/morfologik/util/package-summary.html b/doc/api/morfologik/util/package-summary.html
index d50d2bd..c3ce8cb 100644
--- a/doc/api/morfologik/util/package-summary.html
+++ b/doc/api/morfologik/util/package-summary.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
morfologik.util
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -100,10 +100,6 @@ Package morfologik.util
<TD>Utility functions.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
-<TD WIDTH="15%"><B><A HREF="../../morfologik/util/PerformanceTimer.html" title="class in morfologik.util">PerformanceTimer</A></B></TD>
-<TD>Simple, simple performance checking.</TD>
-</TR>
-<TR BGCOLOR="white" CLASS="TableRowColor">
<TD WIDTH="15%"><B><A HREF="../../morfologik/util/ResourceUtils.html" title="class in morfologik.util">ResourceUtils</A></B></TD>
<TD>Resource management utilities.</TD>
</TR>
diff --git a/doc/api/morfologik/util/package-tree.html b/doc/api/morfologik/util/package-tree.html
index 5095a1d..c34d1a1 100644
--- a/doc/api/morfologik/util/package-tree.html
+++ b/doc/api/morfologik/util/package-tree.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
morfologik.util Class Hierarchy
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
@@ -91,7 +91,7 @@ Class Hierarchy
</H2>
<UL>
<LI TYPE="circle">java.lang.Object<UL>
-<LI TYPE="circle">morfologik.util.<A HREF="../../morfologik/util/Arrays.html" title="class in morfologik.util"><B>Arrays</B></A><LI TYPE="circle">morfologik.util.<A HREF="../../morfologik/util/BufferUtils.html" title="class in morfologik.util"><B>BufferUtils</B></A><LI TYPE="circle">morfologik.util.<A HREF="../../morfologik/util/FileUtils.html" title="class in morfologik.util"><B>FileUtils</B></A><LI TYPE="circle">morfologik.util.<A HREF="../../morfologik/util/PerformanceTimer.html" title="class in morfologik.util"><B>PerformanceTimer</B></A><LI TYPE="circle">morfologik.util.<A HREF="../../morfologik/util/ResourceUtils.html" title="class in morfologik.util"><B>ResourceUtils</B></A></UL>
+<LI TYPE="circle">morfologik.util.<A HREF="../../morfologik/util/Arrays.html" title="class in morfologik.util"><B>Arrays</B></A><LI TYPE="circle">morfologik.util.<A HREF="../../morfologik/util/BufferUtils.html" title="class in morfologik.util"><B>BufferUtils</B></A><LI TYPE="circle">morfologik.util.<A HREF="../../morfologik/util/FileUtils.html" title="class in morfologik.util"><B>FileUtils</B></A><LI TYPE="circle">morfologik.util.<A HREF="../../morfologik/util/ResourceUtils.html" title="class in morfologik.util"><B>ResourceUtils</B></A></UL>
</UL>
<HR>
diff --git a/doc/api/overview-frame.html b/doc/api/overview-frame.html
index 6ddde96..3e3c6be 100644
--- a/doc/api/overview-frame.html
+++ b/doc/api/overview-frame.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
Overview List
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
diff --git a/doc/api/overview-summary.html b/doc/api/overview-summary.html
index 0590a41..250077d 100644
--- a/doc/api/overview-summary.html
+++ b/doc/api/overview-summary.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
Overview
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
diff --git a/doc/api/overview-tree.html b/doc/api/overview-tree.html
index b73fe4b..4d068a8 100644
--- a/doc/api/overview-tree.html
+++ b/doc/api/overview-tree.html
@@ -2,12 +2,12 @@
<!--NewPage-->
<HTML>
<HEAD>
-<!-- Generated by javadoc (build 1.6.0_14) on Mon Sep 21 12:09:37 CEST 2009 -->
+<!-- Generated by javadoc (build 1.6.0_14) on Wed Jan 26 18:49:38 CET 2011 -->
<TITLE>
Class Hierarchy
</TITLE>
-<META NAME="date" CONTENT="2009-09-21">
+<META NAME="date" CONTENT="2011-01-26">
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
@@ -90,21 +90,24 @@ Class Hierarchy
</H2>
<UL>
<LI TYPE="circle">java.lang.Object<UL>
-<LI TYPE="circle">morfologik.util.<A HREF="morfologik/util/Arrays.html" title="class in morfologik.util"><B>Arrays</B></A><LI TYPE="circle">morfologik.util.<A HREF="morfologik/util/BufferUtils.html" title="class in morfologik.util"><B>BufferUtils</B></A><LI TYPE="circle">morfologik.stemming.<A HREF="morfologik/stemming/Dictionary.html" title="class in morfologik.stemming"><B>Dictionary</B></A><LI TYPE="circle">morfologik.stemming.<A HREF="morfologik/stemming/DictionaryIterator.html" title="class in morfologik.stemming"><B>DictionaryIterator</B></A> (implements java.util.Iterator&lt;E&gt;)
+<LI TYPE="circle">morfologik.util.<A HREF="morfologik/util/Arrays.html" title="class in morfologik.util"><B>Arrays</B></A><LI TYPE="circle">morfologik.util.<A HREF="morfologik/util/BufferUtils.html" title="class in morfologik.util"><B>BufferUtils</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/CFSA2Serializer.html" title="class in morfologik.fsa"><B>CFSA2Serializer</B></A> (implements morfologik.fsa.<A HREF="morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A>)
+<LI TYPE="circle">morfologik.stemming.<A HREF="morfologik/stemming/Dictionary.html" title="class in morfologik.stemming"><B>Dictionary</B></A><LI TYPE="circle">morfologik.stemming.<A HREF="morfologik/stemming/DictionaryIterator.html" title="class in morfologik.stemming"><B>DictionaryIterator</B></A> (implements java.util.Iterator&lt;E&gt;)
<LI TYPE="circle">morfologik.stemming.<A HREF="morfologik/stemming/DictionaryLookup.html" title="class in morfologik.stemming"><B>DictionaryLookup</B></A> (implements morfologik.stemming.<A HREF="morfologik/stemming/IStemmer.html" title="interface in morfologik.stemming">IStemmer</A>, java.lang.Iterable&lt;T&gt;)
-<LI TYPE="circle">morfologik.stemming.<A HREF="morfologik/stemming/DictionaryMetadata.html" title="class in morfologik.stemming"><B>DictionaryMetadata</B></A><LI TYPE="circle">morfologik.tools.<A HREF="morfologik/tools/DumpTool.html" title="class in morfologik.tools"><B>DumpTool</B></A><LI TYPE="circle">morfologik.util.<A HREF="morfologik/util/FileUtils.html" title="class in morfologik.util"><B>FileUtils</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSA.html" title="class in morfologik.fsa"><B>FSA</B></A> (implements java.lang.Iterable&lt;T&gt;)
+<LI TYPE="circle">morfologik.stemming.<A HREF="morfologik/stemming/DictionaryMetadata.html" title="class in morfologik.stemming"><B>DictionaryMetadata</B></A><LI TYPE="circle">morfologik.util.<A HREF="morfologik/util/FileUtils.html" title="class in morfologik.util"><B>FileUtils</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSA.html" title="class in morfologik.fsa"><B>FSA</B></A> (implements java.lang.Iterable&lt;T&gt;)
<UL>
-<LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSAVer5Impl.html" title="class in morfologik.fsa"><B>FSAVer5Impl</B></A></UL>
-<LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa"><B>FSAFinalStatesIterator</B></A> (implements java.util.Iterator&lt;E&gt;)
-<LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSAHelpers.html" title="class in morfologik.fsa"><B>FSAHelpers</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSAMatch.html" title="class in morfologik.fsa"><B>FSAMatch</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSATraversalHelper.html" title="class in morfologik.fsa"><B>FSATraversalHelper</B></A><LI TYPE="circle">morfologik.tools.<A HREF="morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools"><B>InflectionFramesTool</B></A><LI TYPE="circle">morfologik.tools.<A HREF="morfologik/tools/Launcher.html" title="class in morfologik.tools"><B>Launcher</B></A><LI TYPE="circle">morfologik.util.<A HREF="morfologik/util/PerformanceTimer.html" title="class in morfologik.util"><B>PerformanceTimer</B></A><LI TYPE="circle">morfologik.stemming.<A HREF="morfologik/stemming/PolishStemmer.html" title="class in morfologik.stemming"><B>PolishStemmer</B></A> (implements morfologik.stemming.<A HREF="morfologik/stemming/IStemmer.html" title="interface in morfologik.stemming">IStemmer</A>, java.lang.Iterable&lt;T&gt;)
+<LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/CFSA.html" title="class in morfologik.fsa"><B>CFSA</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/CFSA2.html" title="class in morfologik.fsa"><B>CFSA2</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/ConstantArcSizeFSA.html" title="class in morfologik.fsa"><B>ConstantArcSizeFSA</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSA5.html" title="class in morfologik.fsa"><B>FSA5</B></A></UL>
+<LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSA5Serializer.html" title="class in morfologik.fsa"><B>FSA5Serializer</B></A> (implements morfologik.fsa.<A HREF="morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa">FSASerializer</A>)
+<LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSABuilder.html" title="class in morfologik.fsa"><B>FSABuilder</B></A><LI TYPE="circle">morfologik.tools.<A HREF="morfologik/tools/FSABuildTool.html" title="class in morfologik.tools"><B>FSABuildTool</B></A><LI TYPE="circle">morfologik.tools.<A HREF="morfologik/tools/FSADumpTool.html" title="class in morfologik.tools"><B>FSADumpTool</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSAFinalStatesIterator.html" title="class in morfologik.fsa"><B>FSAFinalStatesIterator</B></A> (implements java.util.Iterator&lt;E&gt;)
+<LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSAInfo.html" title="class in morfologik.fsa"><B>FSAInfo</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSATraversal.html" title="class in morfologik.fsa"><B>FSATraversal</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSAUtils.html" title="class in morfologik.fsa"><B>FSAUtils</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSAUtils.IntIntHolder.html" title="class in morfologik.fsa"><B>FSAUtils.IntIntHolder</B></A><LI TYPE="circle">morfologik.tools.<A HREF="morfologik/tools/InflectionFramesTool.html" title="class in morfologik.tools"><B>InflectionFramesTool</B></A><LI TYPE="circle">morfologik.tools.<A HREF="morfologik/tools/Launcher.html" title="class in morfologik.tools"><B>Launcher</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/MatchResult.html" title="class in morfologik.fsa"><B>MatchResult</B></A><LI TYPE="circle">morfologik.tools.<A HREF="morfologik/tools/MorphEncoder.html" title="class in morfologik.tools"><B>MorphEncoder</B></A><LI TYPE="circle">morfologik.stemming.<A HREF="morfologik/stemming/PolishStemmer.html" title="class in morfologik.stemming"><B>PolishStemmer</B></A> (implements morfologik.stemming.<A HREF="morfologik/stemming/IStemmer.html" title="interface in morfologik.stemming">IStemmer</A>, java.lang.Iterable&lt;T&gt;)
<LI TYPE="circle">morfologik.util.<A HREF="morfologik/util/ResourceUtils.html" title="class in morfologik.util"><B>ResourceUtils</B></A><LI TYPE="circle">morfologik.stemming.<A HREF="morfologik/stemming/WordData.html" title="class in morfologik.stemming"><B>WordData</B></A> (implements java.lang.Cloneable)
+<LI TYPE="circle">morfologik.tools.<A HREF="morfologik/tools/WriterMessageLogger.html" title="class in morfologik.tools"><B>WriterMessageLogger</B></A> (implements morfologik.tools.<A HREF="morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools">IMessageLogger</A>)
</UL>
</UL>
<H2>
Interface Hierarchy
</H2>
<UL>
-<LI TYPE="circle">morfologik.stemming.<A HREF="morfologik/stemming/IStemmer.html" title="interface in morfologik.stemming"><B>IStemmer</B></A></UL>
+<LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSASerializer.html" title="interface in morfologik.fsa"><B>FSASerializer</B></A><LI TYPE="circle">morfologik.tools.<A HREF="morfologik/tools/IMessageLogger.html" title="interface in morfologik.tools"><B>IMessageLogger</B></A><LI TYPE="circle">morfologik.stemming.<A HREF="morfologik/stemming/IStemmer.html" title="interface in morfologik.stemming"><B>IStemmer</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/StateVisitor.html" title="interface in morfologik.fsa"><B>StateVisitor</B></A></UL>
<H2>
Enum Hierarchy
</H2>
@@ -112,7 +115,7 @@ Enum Hierarchy
<LI TYPE="circle">java.lang.Object<UL>
<LI TYPE="circle">java.lang.Enum&lt;E&gt; (implements java.lang.Comparable&lt;T&gt;, java.io.Serializable)
<UL>
-<LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSAMatchType.html" title="enum in morfologik.fsa"><B>FSAMatchType</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa"><B>FSAFlags</B></A></UL>
+<LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSAFlags.html" title="enum in morfologik.fsa"><B>FSAFlags</B></A><LI TYPE="circle">morfologik.fsa.<A HREF="morfologik/fsa/FSABuilder.InfoEntry.html" title="enum in morfologik.fsa"><B>FSABuilder.InfoEntry</B></A><LI TYPE="circle">morfologik.tools.<A HREF="morfologik/tools/FSABuildTool.Format.html" title="enum in morfologik.tools"><B>FSABuildTool.Format</B></A></UL>
</UL>
</UL>
<HR>
diff --git a/lib/commons-cli-1.2.LICENSE b/lib/commons-cli-1.2.LICENSE
new file mode 100644
index 0000000..57bc88a
--- /dev/null
+++ b/lib/commons-cli-1.2.LICENSE
@@ -0,0 +1,202 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
diff --git a/lib/commons-cli-1.2.jar b/lib/commons-cli-1.2.jar
new file mode 100644
index 0000000..ce4b9ff
--- /dev/null
+++ b/lib/commons-cli-1.2.jar
Binary files differ
diff --git a/lib/hppc-0.3.2.jar b/lib/hppc-0.3.2.jar
new file mode 100644
index 0000000..2392b00
--- /dev/null
+++ b/lib/hppc-0.3.2.jar
Binary files differ
diff --git a/lib/hppc.LICENSE b/lib/hppc.LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/lib/hppc.LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/lib/junit-4.7.jar b/lib/junit-4.7.jar
new file mode 100644
index 0000000..700ad69
--- /dev/null
+++ b/lib/junit-4.7.jar
Binary files differ
diff --git a/lib/junit-benchmarks-0.1.0.jar b/lib/junit-benchmarks-0.1.0.jar
new file mode 100644
index 0000000..225c2a6
--- /dev/null
+++ b/lib/junit-benchmarks-0.1.0.jar
Binary files differ
diff --git a/lib/junit-benchmarks.LICENSE b/lib/junit-benchmarks.LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/lib/junit-benchmarks.LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/lib/junit.LICENSE b/lib/junit.LICENSE
new file mode 100644
index 0000000..4d42e47
--- /dev/null
+++ b/lib/junit.LICENSE
@@ -0,0 +1,88 @@
+Common Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+ a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+ b) in the case of each subsequent Contributor:
+
+ i) changes to the Program, and
+
+ ii) additions to the Program;
+
+ where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+ a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+
+ b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+
+ c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+
+ d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+ a) it complies with the terms and conditions of this Agreement; and
+
+ b) its license agreement:
+
+ i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+
+ ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+
+ iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+
+ iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+ a) it must be made available under this Agreement; and
+
+ b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
+
+
diff --git a/lib/thirdparty.LICENSE b/lib/thirdparty.LICENSE
new file mode 100644
index 0000000..10c50fe
--- /dev/null
+++ b/lib/thirdparty.LICENSE
@@ -0,0 +1,5 @@
+
+HPPC library integrates the following classes from other open-source projects:
+
+- fast BitSets from Apache Lucene (Apache license; same as HPPC).
+
diff --git a/src-test/morfologik/fsa/CFSA2SerializerTest.java b/src-test/morfologik/fsa/CFSA2SerializerTest.java
new file mode 100644
index 0000000..332bbcc
--- /dev/null
+++ b/src-test/morfologik/fsa/CFSA2SerializerTest.java
@@ -0,0 +1,27 @@
+package morfologik.fsa;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ *
+ */
+public class CFSA2SerializerTest extends SerializerTestBase {
+ protected CFSA2Serializer createSerializer() {
+ return new CFSA2Serializer();
+ }
+
+ @Test
+ public void testVIntCoding() {
+ byte [] scratch = new byte [5];
+
+ int [] values = {0, 1, 128, 256, 0x1000, Integer.MAX_VALUE };
+
+ for (int v : values) {
+ int len = CFSA2.writeVInt(scratch, 0, v);
+ assertEquals(v, CFSA2.readVInt(scratch, 0));
+ assertEquals(len, CFSA2.vIntLength(v));
+ }
+ }
+}
diff --git a/src-test/morfologik/fsa/FSA5SerializerTest.java b/src-test/morfologik/fsa/FSA5SerializerTest.java
new file mode 100644
index 0000000..1d05cfc
--- /dev/null
+++ b/src-test/morfologik/fsa/FSA5SerializerTest.java
@@ -0,0 +1,10 @@
+package morfologik.fsa;
+
+/**
+ *
+ */
+public class FSA5SerializerTest extends SerializerTestBase {
+ protected FSA5Serializer createSerializer() {
+ return new FSA5Serializer();
+ }
+}
diff --git a/src-test/morfologik/fsa/FSA5Test.java b/src-test/morfologik/fsa/FSA5Test.java
new file mode 100644
index 0000000..869dfeb
--- /dev/null
+++ b/src-test/morfologik/fsa/FSA5Test.java
@@ -0,0 +1,117 @@
+package morfologik.fsa;
+
+import static morfologik.fsa.FSAFlags.NEXTBIT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import morfologik.stemming.Dictionary;
+
+import org.junit.Test;
+
+/**
+ * Additional tests for {@link FSA5}.
+ */
+public final class FSA5Test {
+ public ArrayList<String> expected = new ArrayList<String>(Arrays.asList(
+ "a", "aba", "ac", "b", "ba", "c"));
+
+ @Test
+ public void testVersion5() throws IOException {
+ final FSA fsa = FSA.read(this.getClass().getResourceAsStream("abc.fsa"));
+ assertFalse(fsa.getFlags().contains(FSAFlags.NUMBERS));
+ verifyContent(expected, fsa);
+ }
+
+ @Test
+ public void testVersion5WithNumbers() throws IOException {
+ final FSA fsa = FSA.read(this.getClass().getResourceAsStream("abc-numbers.fsa"));
+
+ verifyContent(expected, fsa);
+ assertTrue(fsa.getFlags().contains(FSAFlags.NUMBERS));
+ }
+
+ @Test
+ public void testArcsAndNodes() throws IOException {
+ final FSA fsa1 = FSA.read(this.getClass().getResourceAsStream(
+ "abc.fsa"));
+ final FSA fsa2 = FSA.read(this.getClass().getResourceAsStream(
+ "abc-numbers.fsa"));
+
+ FSAInfo info1 = new FSAInfo(fsa1);
+ FSAInfo info2 = new FSAInfo(fsa2);
+
+ assertEquals(info1.arcsCount, info2.arcsCount);
+ assertEquals(info1.nodeCount, info2.nodeCount);
+
+ assertEquals(4, info2.nodeCount);
+ assertEquals(7, info2.arcsCount);
+ }
+
+ @Test
+ public void testArcsAndNodesLarge() throws IOException {
+ final FSA fsa3 = Dictionary.getForLanguage("pl").fsa;
+ FSAInfo info3 = new FSAInfo(fsa3);
+
+ assertEquals(293329, info3.nodeCount);
+ assertEquals(679676, info3.arcsCount);
+ assertEquals(3672200, info3.finalStatesCount);
+ }
+
+ @Test
+ public void testNumbers() throws IOException {
+ final FSA5 fsa = FSA.read(this.getClass().getResourceAsStream("abc-numbers.fsa"));
+
+ assertTrue(fsa.getFlags().contains(NEXTBIT));
+
+ // Get all numbers for nodes.
+ byte[] buffer = new byte[128];
+ final ArrayList<String> result = new ArrayList<String>();
+ walkNode(buffer, 0, fsa, fsa.getRootNode(), 0, result);
+
+ Collections.sort(result);
+ assertEquals(Arrays
+ .asList("0 c", "1 b", "2 ba", "3 a", "4 ac", "5 aba"), result);
+ }
+
+ public static void walkNode(byte[] buffer, int depth, FSA fsa, int node,
+ int cnt, List<String> result) throws IOException {
+ for (int arc = fsa.getFirstArc(node); arc != 0; arc = fsa.getNextArc(arc)) {
+ buffer[depth] = fsa.getArcLabel(arc);
+
+ if (fsa.isArcFinal(arc) || fsa.isArcTerminal(arc)) {
+ result.add(cnt + " " + new String(buffer, 0, depth + 1, "UTF-8"));
+ }
+
+ if (fsa.isArcFinal(arc))
+ cnt++;
+
+ if (!fsa.isArcTerminal(arc)) {
+ walkNode(buffer, depth + 1, fsa, fsa.getEndNode(arc), cnt, result);
+ cnt += fsa.getRightLanguageCount(fsa.getEndNode(arc));
+ }
+ }
+ }
+
+ private static void verifyContent(List<String> expected, FSA fsa) throws IOException {
+ final ArrayList<String> actual = new ArrayList<String>();
+
+ int count = 0;
+ for (ByteBuffer bb : fsa.getSequences()) {
+ assertEquals(0, bb.arrayOffset());
+ assertEquals(0, bb.position());
+ actual.add(new String(bb.array(), 0, bb.remaining(), "UTF-8"));
+ count++;
+ }
+ assertEquals(expected.size(), count);
+ Collections.sort(actual);
+ assertEquals(expected, actual);
+ }
+}
diff --git a/src-test/morfologik/fsa/FSABuilderTest.java b/src-test/morfologik/fsa/FSABuilderTest.java
new file mode 100644
index 0000000..d2e1bad
--- /dev/null
+++ b/src-test/morfologik/fsa/FSABuilderTest.java
@@ -0,0 +1,112 @@
+package morfologik.fsa;
+
+import static morfologik.fsa.FSATestUtils.*;
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import morfologik.fsa.FSA;
+import morfologik.fsa.FSABuilder;
+import morfologik.util.MinMax;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class FSABuilderTest {
+ private static byte[][] input;
+ private static byte[][] input2;
+
+ @BeforeClass
+ public static void prepareByteInput() {
+ input = generateRandom(25000, new MinMax(1, 20), new MinMax(0, 255));
+ input2 = generateRandom(40, new MinMax(1, 20), new MinMax(0, 3));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testEmptyInput() {
+ byte[][] input = {};
+ checkCorrect(input, FSABuilder.build(input));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testHashResizeBug() throws Exception {
+ byte[][] input = {
+ {0, 1 },
+ {0, 2 },
+ {1, 1 },
+ {2, 1 },
+ };
+
+ FSA fsa = FSABuilder.build(input);
+ checkCorrect(input, FSABuilder.build(input));
+ checkMinimal(fsa);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testSmallInput() throws Exception {
+ byte[][] input = {
+ "abc".getBytes("UTF-8"),
+ "bbc".getBytes("UTF-8"),
+ "d".getBytes("UTF-8"),
+ };
+ checkCorrect(input, FSABuilder.build(input));
+ }
+
+ /**
+ * Verify absolute byte-value ordering in the comparators and serialized automaton.
+ */
+ @Test
+ public void testLexicographicOrder() throws IOException {
+ byte[][] input = {
+ {0},
+ {1},
+ {(byte) 0xff},
+ };
+ Arrays.sort(input, FSABuilder.LEXICAL_ORDERING);
+
+ // Check if lexical ordering is consistent with absolute byte value.
+ assertEquals(0, input[0][0]);
+ assertEquals(1, input[1][0]);
+ assertEquals((byte) 0xff, input[2][0]);
+
+ final FSA fsa;
+ checkCorrect(input, fsa = FSABuilder.build(input));
+
+ int arc = fsa.getFirstArc(fsa.getRootNode());
+ assertEquals(0, fsa.getArcLabel(arc));
+ arc = fsa.getNextArc(arc);
+ assertEquals(1, fsa.getArcLabel(arc));
+ arc = fsa.getNextArc(arc);
+ assertEquals((byte) 0xff, fsa.getArcLabel(arc));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testRandom25000_largerAlphabet() {
+ FSA fsa = FSABuilder.build(input);
+ checkCorrect(input, fsa);
+ checkMinimal(fsa);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testRandom25000_smallAlphabet() throws IOException {
+ FSA fsa = FSABuilder.build(input2);
+ checkCorrect(input2, fsa);
+ checkMinimal(fsa);
+ }
+}
diff --git a/src-test/morfologik/fsa/FSATestUtils.java b/src-test/morfologik/fsa/FSATestUtils.java
new file mode 100644
index 0000000..d6cfeee
--- /dev/null
+++ b/src-test/morfologik/fsa/FSATestUtils.java
@@ -0,0 +1,179 @@
+package morfologik.fsa;
+
+import java.nio.ByteBuffer;
+import java.util.*;
+
+import morfologik.util.BufferUtils;
+import morfologik.util.MinMax;
+
+import org.junit.Assert;
+
+public class FSATestUtils {
+ /**
+ * Generate a sorted list of random sequences.
+ */
+ public static byte[][] generateRandom(int count, MinMax length,
+ MinMax alphabet) {
+ final byte[][] input = new byte[count][];
+ final Random rnd = new Random(0x11223344);
+ for (int i = 0; i < count; i++) {
+ input[i] = randomByteSequence(rnd, length, alphabet);
+ }
+ Arrays.sort(input, FSABuilder.LEXICAL_ORDERING);
+ return input;
+ }
+
+ /**
+ * Generate a random string.
+ */
+ private static byte[] randomByteSequence(Random rnd, MinMax length,
+ MinMax alphabet) {
+ byte[] bytes = new byte[length.min + rnd.nextInt(length.range())];
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[i] = (byte) (alphabet.min + rnd.nextInt(alphabet.range()));
+ }
+ return bytes;
+ }
+
+ /**
+ * Check if the DFSA is correct with respect to the given input.
+ */
+ public static void checkCorrect(byte[][] input, FSA fsa) {
+ // (1) All input sequences are in the right language.
+ HashSet<ByteBuffer> rl = new HashSet<ByteBuffer>();
+ for (ByteBuffer bb : fsa) {
+ rl.add(ByteBuffer.wrap(Arrays.copyOf(bb.array(), bb.remaining())));
+ }
+
+ HashSet<ByteBuffer> uniqueInput = new HashSet<ByteBuffer>();
+ for (byte[] sequence : input) {
+ uniqueInput.add(ByteBuffer.wrap(sequence));
+ }
+
+ for (ByteBuffer sequence : uniqueInput) {
+ Assert.assertTrue("Not present in the right language: "
+ + BufferUtils.toString(sequence), rl.remove(sequence));
+ }
+
+ // (2) No other sequence _other_ than the input is in the right language.
+ Assert.assertEquals(0, rl.size());
+ }
+
+ /**
+ * Check if the DFSA reachable from a given state is minimal. This means no
+ * two states have the same right language.
+ */
+ public static void checkMinimal(final FSA fsa) {
+ final HashMap<String, Integer> stateLanguages = new HashMap<String, Integer>();
+
+ fsa.visitInPostOrder(new StateVisitor() {
+ private StringBuilder b = new StringBuilder();
+
+ public boolean accept(int state) {
+ List<byte[]> rightLanguage = allSequences(fsa, state);
+ Collections.sort(rightLanguage, FSABuilder.LEXICAL_ORDERING);
+
+ b.setLength(0);
+ for (byte[] seq : rightLanguage) {
+ b.append(Arrays.toString(seq));
+ b.append(',');
+ }
+
+ String full = b.toString();
+ Assert.assertFalse("State exists: " + state + " "
+ + full + " " + stateLanguages.get(full), stateLanguages.containsKey(full));
+ stateLanguages.put(full, state);
+
+ return true;
+ }
+ });
+ }
+
+ static List<byte[]> allSequences(FSA fsa, int state) {
+ ArrayList<byte[]> seq = new ArrayList<byte[]>();
+ for (ByteBuffer bb : fsa.getSequences(state)) {
+ seq.add(Arrays.copyOf(bb.array(), bb.remaining()));
+ }
+ return seq;
+ }
+
+ /**
+ * Check if two FSAs are identical.
+ */
+ public static void checkIdentical(FSA fsa1, FSA fsa2) {
+ ArrayDeque<String> fromRoot = new ArrayDeque<String>();
+ checkIdentical(fromRoot,
+ fsa1, fsa1.getRootNode(), new BitSet(),
+ fsa2, fsa2.getRootNode(), new BitSet());
+ }
+
+ /*
+ *
+ */
+ static void checkIdentical(ArrayDeque<String> fromRoot,
+ FSA fsa1, int node1, BitSet visited1,
+ FSA fsa2, int node2, BitSet visited2) {
+ int arc1 = fsa1.getFirstArc(node1);
+ int arc2 = fsa2.getFirstArc(node2);
+
+ if (visited1.get(node1) != visited2.get(node2)) {
+ throw new RuntimeException("Two nodes should either be visited or not visited: "
+ + Arrays.toString(fromRoot.toArray()) + " "
+ + " node1: " + node1 + " "
+ + " node2: " + node2);
+ }
+ visited1.set(node1);
+ visited2.set(node2);
+
+ TreeSet<Character> labels1 = new TreeSet<Character>();
+ TreeSet<Character> labels2 = new TreeSet<Character>();
+ while (true) {
+ labels1.add((char) fsa1.getArcLabel(arc1));
+ labels2.add((char) fsa2.getArcLabel(arc2));
+
+ arc1 = fsa1.getNextArc(arc1);
+ arc2 = fsa2.getNextArc(arc2);
+
+ if (arc1 == 0 || arc2 == 0) {
+ if (arc1 != arc2) {
+ throw new RuntimeException("Different number of labels at path: "
+ + Arrays.toString(fromRoot.toArray()));
+ }
+ break;
+ }
+ }
+
+ if (!labels1.equals(labels2)) {
+ throw new RuntimeException("Different sets of labels at path: "
+ + Arrays.toString(fromRoot.toArray()) + ":\n"
+ + labels1 + "\n" + labels2);
+ }
+
+ // recurse.
+ for (char chr : labels1) {
+ byte label = (byte) chr;
+ fromRoot.push(Character.isLetterOrDigit(chr) ? Character.toString(chr) : Integer.toString(chr));
+
+ arc1 = fsa1.getArc(node1, label);
+ arc2 = fsa2.getArc(node2, label);
+
+ if (fsa1.isArcFinal(arc1) != fsa2.isArcFinal(arc2)) {
+ throw new RuntimeException("Different final flag on arcs at: "
+ + Arrays.toString(fromRoot.toArray()) + ", label: " + label);
+ }
+
+ if (fsa1.isArcTerminal(arc1) != fsa2.isArcTerminal(arc2)) {
+ throw new RuntimeException("Different terminal flag on arcs at: "
+ + Arrays.toString(fromRoot.toArray()) + ", label: " + label);
+ }
+
+ if (!fsa1.isArcTerminal(arc1)) {
+ checkIdentical(fromRoot,
+ fsa1, fsa1.getEndNode(arc1), visited1,
+ fsa2, fsa2.getEndNode(arc2), visited2);
+ }
+
+ fromRoot.pop();
+ }
+ }
+}
diff --git a/src-test/morfologik/fsa/FSATraversalTest.java b/src-test/morfologik/fsa/FSATraversalTest.java
new file mode 100644
index 0000000..ddafb6d
--- /dev/null
+++ b/src-test/morfologik/fsa/FSATraversalTest.java
@@ -0,0 +1,160 @@
+package morfologik.fsa;
+
+import static org.junit.Assert.*;
+import static morfologik.fsa.MatchResult.*;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.HashSet;
+
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link FSATraversal}.
+ */
+public final class FSATraversalTest {
+ private FSA fsa;
+
+ /**
+ *
+ */
+ @Before
+ public void setUp() throws Exception {
+ fsa = FSA.read(this.getClass().getResourceAsStream("en_tst.dict"));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testTraversalWithIterable() {
+ int count = 0;
+ for (ByteBuffer bb : fsa.getSequences()) {
+ assertEquals(0, bb.arrayOffset());
+ assertEquals(0, bb.position());
+ count++;
+ }
+ assertEquals(346773, count);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testPerfectHash() throws IOException {
+ byte[][] input = new byte[][] {
+ { 'a' },
+ { 'a', 'b', 'a' },
+ { 'a', 'c' },
+ { 'b' },
+ { 'b', 'a' },
+ { 'c' },
+ };
+
+ Arrays.sort(input, FSABuilder.LEXICAL_ORDERING);
+ FSA s = FSABuilder.build(input);
+
+ final byte[] fsaData =
+ new FSA5Serializer()
+ .withNumbers()
+ .serialize(s, new ByteArrayOutputStream())
+ .toByteArray();
+
+ final FSA5 fsa = (FSA5) FSA.read(new ByteArrayInputStream(fsaData));
+ final FSATraversal traversal = new FSATraversal(fsa);
+
+ int i = 0;
+ for (byte [] seq : input)
+ {
+ assertEquals(new String(seq), i++, traversal.perfectHash(seq));
+ }
+
+ // Check if the total number of sequences is encoded at the root node.
+ assertEquals(6, fsa.getRightLanguageCount(fsa.getRootNode()));
+
+ // Check sub/super sequence scenarios.
+ assertEquals(AUTOMATON_HAS_PREFIX, traversal.perfectHash("abax".getBytes("UTF-8")));
+ assertEquals(SEQUENCE_IS_A_PREFIX, traversal.perfectHash("ab".getBytes("UTF-8")));
+ assertEquals(NO_MATCH, traversal.perfectHash("d".getBytes("UTF-8")));
+ assertEquals(NO_MATCH, traversal.perfectHash(new byte [] {0}));
+
+ assertTrue(AUTOMATON_HAS_PREFIX < 0);
+ assertTrue(SEQUENCE_IS_A_PREFIX < 0);
+ assertTrue(NO_MATCH < 0);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testRecursiveTraversal() {
+ final int[] counter = new int[] { 0 };
+
+ class Recursion {
+ public void dumpNode(final int node) {
+ int arc = fsa.getFirstArc(node);
+ do {
+ if (fsa.isArcFinal(arc)) {
+ counter[0]++;
+ }
+
+ if (!fsa.isArcTerminal(arc)) {
+ dumpNode(fsa.getEndNode(arc));
+ }
+
+ arc = fsa.getNextArc(arc);
+ } while (arc != 0);
+ }
+ }
+
+ new Recursion().dumpNode(fsa.getRootNode());
+
+ assertEquals(346773, counter[0]);
+ }
+
+ /**
+ * Test {@link FSATraversal} and matching results.
+ */
+ @Test
+ public void testMatch() throws IOException {
+ final FSA5 fsa = FSA.read(this.getClass().getResourceAsStream("abc.fsa"));
+ final FSATraversal traversalHelper = new FSATraversal(fsa);
+
+ MatchResult m = traversalHelper.match("ax".getBytes());
+ assertEquals(NO_MATCH, m.kind);
+ assertEquals(1, m.index);
+ assertEquals(new HashSet<String>(Arrays.asList("ba", "c")),
+ suffixes(fsa, m.node));
+
+ assertEquals(EXACT_MATCH,
+ traversalHelper.match("aba".getBytes()).kind);
+
+ m = traversalHelper.match("abalonger".getBytes());
+ assertEquals(AUTOMATON_HAS_PREFIX, m.kind);
+ assertEquals("longer", "abalonger".substring(m.index));
+
+ m = traversalHelper.match("ab".getBytes());
+ assertEquals(SEQUENCE_IS_A_PREFIX, m.kind);
+ assertEquals(new HashSet<String>(Arrays.asList("a")),
+ suffixes(fsa, m.node));
+ }
+
+ /**
+ * Return all sequences reachable from a given node, as strings.
+ */
+ private HashSet<String> suffixes(FSA fsa, int node) {
+ HashSet<String> result = new HashSet<String>();
+ for (ByteBuffer bb : fsa.getSequences(node))
+ {
+ try {
+ result.add(new String(bb.array(), bb.position(), bb.remaining(), "UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return result;
+ }
+}
diff --git a/src-test/morfologik/fsa/SerializerTestBase.java b/src-test/morfologik/fsa/SerializerTestBase.java
new file mode 100644
index 0000000..ce373ba
--- /dev/null
+++ b/src-test/morfologik/fsa/SerializerTestBase.java
@@ -0,0 +1,256 @@
+package morfologik.fsa;
+
+import static morfologik.fsa.FSAFlags.NUMBERS;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.util.*;
+
+import morfologik.util.BufferUtils;
+
+import org.junit.*;
+
+public abstract class SerializerTestBase {
+ @Test
+ public void testA() throws IOException {
+ byte[][] input = new byte[][] {
+ { 'a' },
+ };
+
+ Arrays.sort(input, FSABuilder.LEXICAL_ORDERING);
+ FSA s = FSABuilder.build(input);
+
+ checkSerialization(input, s);
+ }
+
+ @Test
+ public void testArcsSharing() throws IOException {
+ byte[][] input = new byte[][] {
+ { 'a', 'c', 'f' },
+ { 'a', 'd', 'g' },
+ { 'a', 'e', 'h' },
+ { 'b', 'd', 'g' },
+ { 'b', 'e', 'h' },
+ };
+
+ Arrays.sort(input, FSABuilder.LEXICAL_ORDERING);
+ FSA s = FSABuilder.build(input);
+
+ checkSerialization(input, s);
+ }
+
+ @Test
+ public void testFSA5SerializerSimple() throws IOException {
+ byte[][] input = new byte[][] {
+ { 'a' },
+ { 'a', 'b', 'a' },
+ { 'a', 'c' },
+ { 'b' },
+ { 'b', 'a' },
+ { 'c' },
+ };
+
+ Arrays.sort(input, FSABuilder.LEXICAL_ORDERING);
+ FSA s = FSABuilder.build(input);
+
+ checkSerialization(input, s);
+ }
+
+ @Test
+ public void testNotMinimal() throws IOException {
+ byte[][] input = new byte[][] {
+ { 'a', 'b', 'a' },
+ { 'b' },
+ { 'b', 'a' }
+ };
+
+ Arrays.sort(input, FSABuilder.LEXICAL_ORDERING);
+ FSA s = FSABuilder.build(input);
+
+ checkSerialization(input, s);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testFSA5Bug0() throws IOException {
+ checkCorrect(new String[] {
+ "3-D+A+JJ",
+ "3-D+A+NN",
+ "4-F+A+NN",
+ "z+A+NN", });
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testFSA5Bug1() throws IOException {
+ checkCorrect(new String[] { "+NP", "n+N", "n+NP", });
+ }
+
+ private void checkCorrect(String[] strings) throws IOException {
+ byte[][] input = new byte[strings.length][];
+ for (int i = 0; i < strings.length; i++) {
+ input[i] = strings[i].getBytes("ISO8859-1");
+ }
+
+ Arrays.sort(input, FSABuilder.LEXICAL_ORDERING);
+ FSA s = FSABuilder.build(input);
+
+ checkSerialization(input, s);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testEmptyInput() throws IOException {
+ byte[][] input = new byte[][] {};
+ FSA s = FSABuilder.build(input);
+
+ checkSerialization(input, s);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void test_abc() throws IOException {
+ testBuiltIn(FSA.read(FSA5Test.class.getResourceAsStream("abc.fsa")));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void test_minimal() throws IOException {
+ testBuiltIn(FSA.read(FSA5Test.class.getResourceAsStream("minimal.fsa")));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void test_minimal2() throws IOException {
+ testBuiltIn(FSA.read(FSA5Test.class.getResourceAsStream("minimal2.fsa")));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void test_en_tst() throws IOException {
+ testBuiltIn(FSA.read(FSA5Test.class.getResourceAsStream("en_tst.dict")));
+ }
+
+ private void testBuiltIn(FSA fsa) throws IOException {
+ final ArrayList<byte[]> sequences = new ArrayList<byte[]>();
+
+ sequences.clear();
+ for (ByteBuffer bb : fsa) {
+ sequences.add(Arrays.copyOf(bb.array(), bb.remaining()));
+ }
+
+ Collections.sort(sequences, FSABuilder.LEXICAL_ORDERING);
+
+ final byte[][] in = sequences.toArray(new byte[sequences.size()][]);
+ FSA root = FSABuilder.build(in);
+
+ // Check if the DFSA is correct first.
+ FSATestUtils.checkCorrect(in, root);
+
+ // Check serialization.
+ checkSerialization(in, root);
+ }
+
+ /** */
+ private void checkSerialization(byte[][] input, FSA root)
+ throws IOException {
+ checkSerialization0(createSerializer(), input, root);
+ if (createSerializer().getFlags().contains(FSAFlags.NUMBERS)) {
+ checkSerialization0(createSerializer().withNumbers(), input, root);
+ }
+ }
+
+ /** */
+ private void checkSerialization0(FSASerializer serializer,
+ final byte[][] in, FSA root) throws IOException {
+ final byte[] fsaData = serializer.serialize(root,
+ new ByteArrayOutputStream()).toByteArray();
+
+ FSA fsa = FSA.read(new ByteArrayInputStream(fsaData));
+ checkCorrect(in, fsa);
+ }
+
+ /**
+ * Check if the FSA is correct with respect to the given input.
+ */
+ protected void checkCorrect(byte[][] input, FSA fsa) {
+ // (1) All input sequences are in the right language.
+ HashSet<ByteBuffer> rl = new HashSet<ByteBuffer>();
+ for (ByteBuffer bb : fsa) {
+ byte[] array = bb.array();
+ int length = bb.remaining();
+ rl.add(ByteBuffer.wrap(Arrays.copyOf(array, length)));
+ }
+
+ HashSet<ByteBuffer> uniqueInput = new HashSet<ByteBuffer>();
+ for (byte[] sequence : input) {
+ uniqueInput.add(ByteBuffer.wrap(sequence));
+ }
+
+ for (ByteBuffer sequence : uniqueInput) {
+ Assert.assertTrue("Not present in the right language: "
+ + BufferUtils.toString(sequence), rl.remove(sequence));
+ }
+
+ // (2) No other sequence _other_ than the input is in the right
+ // language.
+ Assert.assertEquals(0, rl.size());
+ }
+
+ @Test
+ public void testAutomatonWithNodeNumbers() throws IOException {
+ Assume.assumeTrue(createSerializer().getFlags().contains(FSAFlags.NUMBERS));
+
+ byte[][] input = new byte[][] {
+ { 'a' },
+ { 'a', 'b', 'a' },
+ { 'a', 'c' },
+ { 'b' },
+ { 'b', 'a' },
+ { 'c' }, };
+
+ Arrays.sort(input, FSABuilder.LEXICAL_ORDERING);
+ FSA s = FSABuilder.build(input);
+
+ final byte[] fsaData =
+ createSerializer()
+ .withNumbers()
+ .serialize(s, new ByteArrayOutputStream()).toByteArray();
+
+ FSA fsa = FSA.read(new ByteArrayInputStream(fsaData));
+
+ // Ensure we have the NUMBERS flag set.
+ assertTrue(fsa.getFlags().contains(NUMBERS));
+
+ // Get all numbers from nodes.
+ byte[] buffer = new byte[128];
+ final ArrayList<String> result = new ArrayList<String>();
+ FSA5Test.walkNode(buffer, 0, fsa, fsa.getRootNode(), 0, result);
+
+ Collections.sort(result);
+ assertEquals(
+ Arrays.asList("0 a", "1 aba", "2 ac", "3 b", "4 ba", "5 c"),
+ result);
+ }
+
+ /**
+ *
+ */
+ protected abstract FSASerializer createSerializer();
+}
diff --git a/src-test/morfologik/fsa/abc-numbers.fsa b/src-test/morfologik/fsa/abc-numbers.fsa
new file mode 100644
index 0000000..d97091d
--- /dev/null
+++ b/src-test/morfologik/fsa/abc-numbers.fsa
Binary files differ
diff --git a/src-test/morfologik/fsa/abc.fsa b/src-test/morfologik/fsa/abc.fsa
new file mode 100644
index 0000000..68c0b96
--- /dev/null
+++ b/src-test/morfologik/fsa/abc.fsa
Binary files differ
diff --git a/src-test/morfologik/fsa/abc.in b/src-test/morfologik/fsa/abc.in
new file mode 100644
index 0000000..7bb8744
--- /dev/null
+++ b/src-test/morfologik/fsa/abc.in
@@ -0,0 +1,6 @@
+a
+aba
+ac
+b
+ba
+c
diff --git a/src-test/morfologik/fsa/en_tst.dict b/src-test/morfologik/fsa/en_tst.dict
new file mode 100644
index 0000000..09cc22b
--- /dev/null
+++ b/src-test/morfologik/fsa/en_tst.dict
Binary files differ
diff --git a/src-test/morfologik/fsa/minimal.fsa b/src-test/morfologik/fsa/minimal.fsa
new file mode 100644
index 0000000..9d667b7
--- /dev/null
+++ b/src-test/morfologik/fsa/minimal.fsa
Binary files differ
diff --git a/src-test/morfologik/fsa/minimal.in b/src-test/morfologik/fsa/minimal.in
new file mode 100644
index 0000000..7ae8d81
--- /dev/null
+++ b/src-test/morfologik/fsa/minimal.in
@@ -0,0 +1,3 @@
++NP
+n+N
+n+NP
diff --git a/src-test/morfologik/fsa/minimal2.fsa b/src-test/morfologik/fsa/minimal2.fsa
new file mode 100644
index 0000000..e81f6d0
--- /dev/null
+++ b/src-test/morfologik/fsa/minimal2.fsa
Binary files differ
diff --git a/src-test/morfologik/fsa/minimal2.in b/src-test/morfologik/fsa/minimal2.in
new file mode 100644
index 0000000..d28708d
--- /dev/null
+++ b/src-test/morfologik/fsa/minimal2.in
@@ -0,0 +1,24 @@
+3-D+A+JJ
+3-D+A+NN
+4-F+A+NN
+4-H+A+JJ
+z+A+NN
+z-axis+A+NN
+zB+A+NN
+zZt+A+NNP
+za-zen+A+NN
+zabaglione+A+NN
+zabagliones+B+NNS
+zabajone+A+NN
+zabajones+B+NNS
+zabaione+A+NN
+zabaiones+B+NNS
+zabra+A+NN
+zabras+B+NNS
+zack+A+NN
+zacaton+A+NN
+zacatons+B+NNS
+zacatun+A+NN
+zaddik+A+NN
+zaddiks+B+NNS
+zaffar+A+NN \ No newline at end of file
diff --git a/src-test/morfologik/stemming/DictionaryLookupTest.java b/src-test/morfologik/stemming/DictionaryLookupTest.java
new file mode 100644
index 0000000..e5c5204
--- /dev/null
+++ b/src-test/morfologik/stemming/DictionaryLookupTest.java
@@ -0,0 +1,250 @@
+package morfologik.stemming;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.util.*;
+
+import org.junit.Test;
+
+/*
+ *
+ */
+public class DictionaryLookupTest {
+ /* */
+ @Test
+ public void testPrefixDictionaries() throws IOException {
+ final URL url = this.getClass().getResource("test-prefix.dict");
+ final IStemmer s = new DictionaryLookup(Dictionary.read(url));
+
+ assertArrayEquals(new String[] { "Rzeczpospolita", "subst:irreg" },
+ stem(s, "Rzeczypospolitej"));
+ assertArrayEquals(new String[] { "Rzeczpospolita", "subst:irreg" },
+ stem(s, "RzeczÄ…pospolitÄ…"));
+
+ // This word is not in the dictionary.
+ assertNoStemFor(s, "martygalski");
+ }
+
+ /* */
+ @Test
+ public void testInfixDictionaries() throws IOException {
+ final URL url = this.getClass().getResource("test-infix.dict");
+ final IStemmer s = new DictionaryLookup(Dictionary.read(url));
+
+ assertArrayEquals(new String[] { "Rzeczpospolita", "subst:irreg" },
+ stem(s, "Rzeczypospolitej"));
+ assertArrayEquals(new String[] { "Rzeczycki", "adj:pl:nom:m" }, stem(s,
+ "Rzeczyccy"));
+ assertArrayEquals(new String[] { "Rzeczpospolita", "subst:irreg" },
+ stem(s, "RzeczÄ…pospolitÄ…"));
+
+ // This word is not in the dictionary.
+ assertNoStemFor(s, "martygalski");
+ }
+
+ /* */
+ @Test
+ public void testWordDataIterator() throws IOException {
+ final URL url = this.getClass().getResource("test-infix.dict");
+ final DictionaryLookup s = new DictionaryLookup(Dictionary.read(url));
+
+ final HashSet<String> entries = new HashSet<String>();
+ for (WordData wd : s) {
+ entries.add(wd.getWord() + " " + wd.getStem() + " " + wd.getTag());
+ }
+
+ // Make sure a sample of the entries is present.
+ assertTrue(entries.contains("Rzekunia Rzekuń subst:sg:gen:m"));
+ assertTrue(entries
+ .contains("Rzeczkowskie Rzeczkowski adj:sg:nom.acc.voc:n+adj:pl:acc.nom.voc:f.n"));
+ assertTrue(entries
+ .contains("RzeczÄ…pospolitÄ… Rzeczpospolita subst:irreg"));
+ assertTrue(entries
+ .contains("Rzeczypospolita Rzeczpospolita subst:irreg"));
+ assertTrue(entries
+ .contains("Rzeczypospolitych Rzeczpospolita subst:irreg"));
+ assertTrue(entries
+ .contains("Rzeczyckiej Rzeczycki adj:sg:gen.dat.loc:f"));
+ }
+
+ /* */
+ @Test
+ public void testWordDataCloning() throws IOException {
+ final URL url = this.getClass().getResource("test-infix.dict");
+ final DictionaryLookup s = new DictionaryLookup(Dictionary.read(url));
+
+ ArrayList<WordData> words = new ArrayList<WordData>();
+ for (WordData wd : s) {
+ WordData clone = wd.clone();
+ words.add(clone);
+ }
+
+ // Reiterate and verify that we have the same entries.
+ final DictionaryLookup s2 = new DictionaryLookup(Dictionary.read(url));
+ int i = 0;
+ for (WordData wd : s2) {
+ WordData clone = words.get(i++);
+ assertEqualSequences(clone.getStem(), wd.getStem());
+ assertEqualSequences(clone.getTag(), wd.getTag());
+ assertEqualSequences(clone.getWord(), wd.getWord());
+ assertEqualSequences(clone.wordCharSequence, wd.wordCharSequence);
+ }
+
+ // Check collections contract.
+ final HashSet<WordData> entries = new HashSet<WordData>();
+ try {
+ entries.add(words.get(0));
+ fail();
+ } catch (RuntimeException e) {
+ // Expected.
+ }
+ }
+
+ private void assertEqualSequences(CharSequence s1, CharSequence s2) {
+ assertEquals(s1.toString(), s2.toString());
+ }
+
+ /* */
+ @Test
+ public void testWordDataFields() throws IOException {
+ final IStemmer s = new PolishStemmer();
+
+ final String word = "liga";
+ final List<WordData> response = s.lookup(word);
+ assertEquals(2, response.size());
+
+ final HashSet<String> stems = new HashSet<String>();
+ final HashSet<String> tags = new HashSet<String>();
+ for (WordData wd : response) {
+ stems.add(wd.getStem().toString());
+ tags.add(wd.getTag().toString());
+ assertSame(word, wd.getWord());
+ }
+ assertTrue(stems.contains("ligać"));
+ assertTrue(stems.contains("liga"));
+ assertTrue(tags.contains("subst:sg:nom:f"));
+ assertTrue(tags.contains("verb:fin:sg:ter:imperf"));
+
+ // Repeat to make sure we get the same values consistently.
+ for (WordData wd : response) {
+ stems.contains(wd.getStem().toString());
+ tags.contains(wd.getTag().toString());
+ }
+
+ // Run the same consistency check for the returned buffers.
+ final ByteBuffer temp = ByteBuffer.allocate(100);
+ for (WordData wd : response) {
+ // Buffer should be copied.
+ final ByteBuffer copy = wd.getStemBytes(null);
+ final String stem = new String(copy.array(), copy.arrayOffset()
+ + copy.position(), copy.remaining(), "iso-8859-2");
+ // The buffer should be present in stems set.
+ assertTrue(stem, stems.contains(stem));
+ // Buffer large enough to hold the contents.
+ temp.clear();
+ assertSame(temp, wd.getStemBytes(temp));
+ // The copy and the clone should be identical.
+ assertEquals(0, copy.compareTo(temp));
+ }
+
+ for (WordData wd : response) {
+ // Buffer should be copied.
+ final ByteBuffer copy = wd.getTagBytes(null);
+ final String tag = new String(copy.array(), copy.arrayOffset()
+ + copy.position(), copy.remaining(), "iso-8859-2");
+ // The buffer should be present in tags set.
+ assertTrue(tag, tags.contains(tag));
+ // Buffer large enough to hold the contents.
+ temp.clear();
+ assertSame(temp, wd.getTagBytes(temp));
+ // The copy and the clone should be identical.
+ assertEquals(0, copy.compareTo(temp));
+ }
+
+ for (WordData wd : response) {
+ // Buffer should be copied.
+ final ByteBuffer copy = wd.getWordBytes(null);
+ assertNotNull(copy);
+ assertEquals(0, copy.compareTo(ByteBuffer.wrap(word
+ .getBytes("iso-8859-2"))));
+ }
+ }
+
+ /* */
+ @Test
+ public void testMultibyteEncodingUTF8() throws IOException {
+ final URL url = this.getClass()
+ .getResource("test-diacritics-utf8.dict");
+ final IStemmer s = new DictionaryLookup(Dictionary.read(url));
+
+ assertArrayEquals(new String[] { "merge", "001" }, stem(s, "mergeam"));
+ assertArrayEquals(new String[] { "merge", "002" },
+ stem(s, "merseserăm"));
+ }
+
+ /* */
+ @Test
+ public void testSynthesis() throws IOException {
+ final URL url = this.getClass().getResource("test-synth.dict");
+ final IStemmer s = new DictionaryLookup(Dictionary.read(url));
+
+ assertArrayEquals(new String[] { "miała", null }, stem(s,
+ "mieć|verb:praet:sg:ter:f:?perf"));
+ assertArrayEquals(new String[] { "a", null }, stem(s, "a|conj"));
+ assertArrayEquals(new String[] {}, stem(s, "dziecko|subst:sg:dat:n"));
+
+ // This word is not in the dictionary.
+ assertNoStemFor(s, "martygalski");
+ }
+
+ /* */
+ @Test
+ public void testInputWithSeparators() throws IOException {
+ final URL url = this.getClass().getResource("test-separators.dict");
+ final DictionaryLookup s = new DictionaryLookup(Dictionary.read(url));
+
+ /*
+ * Attemp to reconstruct input sequences using WordData iterator.
+ */
+ ArrayList<String> sequences = new ArrayList<String>();
+ for (WordData wd : s) {
+ sequences.add("" + wd.getWord() + " " + wd.getStem() + " "
+ + wd.getTag());
+ }
+ Collections.sort(sequences);
+
+ assertEquals("token1 null null", sequences.get(0));
+ assertEquals("token2 null null", sequences.get(1));
+ assertEquals("token3 null +", sequences.get(2));
+ assertEquals("token4 token2 null", sequences.get(3));
+ assertEquals("token5 token2 null", sequences.get(4));
+ assertEquals("token6 token2 +", sequences.get(5));
+ assertEquals("token7 token2 token3+", sequences.get(6));
+ assertEquals("token8 token2 token3++", sequences.get(7));
+ }
+
+ /* */
+ public static String[] stem(IStemmer s, String word) {
+ ArrayList<String> result = new ArrayList<String>();
+ for (WordData wd : s.lookup(word)) {
+ result.add(asString(wd.getStem()));
+ result.add(asString(wd.getTag()));
+ }
+ return result.toArray(new String[result.size()]);
+ }
+
+ /* */
+ public static String asString(CharSequence s) {
+ if (s == null)
+ return null;
+ return s.toString();
+ }
+
+ /* */
+ public static void assertNoStemFor(IStemmer s, String word) {
+ assertArrayEquals(new String[] {}, stem(s, word));
+ }
+}
diff --git a/src-test/morfologik/stemming/PerformanceTest.java b/src-test/morfologik/stemming/PerformanceTest.java
new file mode 100644
index 0000000..3676d7d
--- /dev/null
+++ b/src-test/morfologik/stemming/PerformanceTest.java
@@ -0,0 +1,73 @@
+package morfologik.stemming;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.carrotsearch.junitbenchmarks.AbstractBenchmark;
+import com.carrotsearch.junitbenchmarks.BenchmarkOptions;
+
+/**
+ * Simple performance micro-benchmarks.
+ */
+@BenchmarkOptions(callgc = false, warmupRounds = 5, benchmarkRounds = 10)
+public class PerformanceTest extends AbstractBenchmark {
+ /* Guard against escape analysis and HotSpot opts. */
+ public volatile int guard;
+
+ /* Test data. */
+ static final int sequences = 100000;
+ static final String[] testWords = new String[sequences];
+ static final PolishStemmer stemmer = new PolishStemmer();
+
+ /**
+ * Prepare test data.
+ */
+ @BeforeClass
+ public static void prepare() throws UnsupportedEncodingException
+ {
+ final Dictionary dict = Dictionary.getForLanguage("pl");
+ int i = 0;
+ for (ByteBuffer sequence : dict.fsa) {
+ testWords[i] = new String(sequence.array(), 0,
+ sequence.remaining(), dict.metadata.encoding);
+ testWords[i] = testWords[i].substring(0, testWords[i]
+ .indexOf(dict.metadata.separator));
+ i++;
+
+ if (i == testWords.length)
+ break;
+ }
+ }
+
+ @Test
+ public void traversal_100000() throws IOException {
+ final Dictionary dict = Dictionary.getForLanguage("pl");
+
+ int max = sequences;
+ int guard = 0;
+ for (ByteBuffer sequence : dict.fsa) {
+ guard += sequence.remaining();
+ if (--max == 0)
+ break;
+ }
+
+ this.guard = guard;
+ }
+
+ @Test
+ public void stemming_100000() throws IOException {
+ int guard = 0;
+ for (String word : testWords) {
+ for (WordData dta : stemmer.lookup(word))
+ {
+ guard += dta.getStem().length();
+ guard += dta.getTag().length();
+ }
+ }
+ this.guard = guard;
+ }
+}
diff --git a/src-test/morfologik/stemming/PolishStemmerTest.java b/src-test/morfologik/stemming/PolishStemmerTest.java
new file mode 100644
index 0000000..b3230ac
--- /dev/null
+++ b/src-test/morfologik/stemming/PolishStemmerTest.java
@@ -0,0 +1,54 @@
+package morfologik.stemming;
+
+import static morfologik.stemming.DictionaryLookupTest.assertNoStemFor;
+import static morfologik.stemming.DictionaryLookupTest.stem;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.TreeSet;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+/*
+ *
+ */
+public class PolishStemmerTest {
+ /* */
+ @Test
+ public void testLexemes() throws IOException {
+ PolishStemmer s = new PolishStemmer();
+
+ assertEquals("żywotopisarstwo", stem(s, "żywotopisarstwie")[0]);
+ assertEquals("abradować", stem(s, "abradowałoby")[0]);
+
+ assertArrayEquals(new String[] { "żywotopisarstwo", "subst:sg:loc:n" },
+ stem(s, "żywotopisarstwie"));
+ assertArrayEquals(new String[] { "bazia", "subst:pl:inst:f" }, stem(s,
+ "baziami"));
+
+ // This word is not in the dictionary.
+ assertNoStemFor(s, "martygalski");
+ }
+
+ /* */
+ @Test
+ @Ignore
+ public void listUniqueTags() throws IOException {
+ HashSet<String> forms = new HashSet<String>();
+ for (WordData wd : new PolishStemmer()) {
+ final CharSequence chs = wd.getTag();
+ if (chs == null) {
+ System.err.println("Missing tag for: " + wd.getWord());
+ continue;
+ }
+ forms.add(chs.toString());
+ }
+
+ for (String s : new TreeSet<String>(forms)) {
+ System.out.println(s);
+ }
+ }
+}
diff --git a/src-test/morfologik/stemming/StringDecoderBenchmarkTest.java b/src-test/morfologik/stemming/StringDecoderBenchmarkTest.java
new file mode 100644
index 0000000..e8c6c17
--- /dev/null
+++ b/src-test/morfologik/stemming/StringDecoderBenchmarkTest.java
@@ -0,0 +1,62 @@
+package morfologik.stemming;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.carrotsearch.junitbenchmarks.AbstractBenchmark;
+import com.carrotsearch.junitbenchmarks.BenchmarkOptions;
+
+@BenchmarkOptions(callgc = false, warmupRounds = 5, benchmarkRounds = 20)
+@Ignore
+public class StringDecoderBenchmarkTest extends AbstractBenchmark {
+ /* Guard against escape analysis and HotSpot opts. */
+ public volatile int guard;
+
+ private final int sequences = 1000000;
+
+ final String input = "dbaoidbhoei";
+ final CharBuffer chars = CharBuffer.allocate(100);
+ final ByteBuffer bytes = ByteBuffer.allocate(100);
+ final CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
+
+ /**
+ * This is a simple comparison of performance converting a string to bytes
+ * using String.getBytes and CharsetEncoder (which String.getBytes uses
+ * internally in SUN's JDK).
+ */
+ @Test
+ public void stringGetBytes() throws Exception {
+ int guard = 0;
+ for (int i = 0; i < sequences; i++) {
+ guard += input.getBytes("UTF-8").length;
+ }
+ this.guard = guard;
+ }
+
+ @Test
+ public void charsetEncoder() throws Exception {
+ int guard = 0;
+ for (int i = 0; i < sequences; i++) {
+ chars.clear();
+ for (int j = 0; j < input.length(); j++) {
+ chars.put(input.charAt(j));
+ }
+ chars.flip();
+
+ bytes.clear();
+ chars.mark();
+ encoder.encode(chars, bytes, true);
+ bytes.flip();
+ chars.reset();
+
+ guard += chars.remaining();
+ }
+
+ this.guard = guard;
+ }
+}
diff --git a/src-test/morfologik/stemming/test-diacritics-utf8.dict b/src-test/morfologik/stemming/test-diacritics-utf8.dict
new file mode 100644
index 0000000..2a62f21
--- /dev/null
+++ b/src-test/morfologik/stemming/test-diacritics-utf8.dict
Binary files differ
diff --git a/src-test/morfologik/stemming/test-diacritics-utf8.info b/src-test/morfologik/stemming/test-diacritics-utf8.info
new file mode 100644
index 0000000..ec3a98e
--- /dev/null
+++ b/src-test/morfologik/stemming/test-diacritics-utf8.info
@@ -0,0 +1,10 @@
+#
+# Dictionary properties.
+#
+
+fsa.dict.separator=+
+fsa.dict.encoding=UTF-8
+
+fsa.dict.uses-prefixes=false
+fsa.dict.uses-infixes=false
+
diff --git a/src-test/morfologik/stemming/test-infix.dict b/src-test/morfologik/stemming/test-infix.dict
new file mode 100644
index 0000000..cc91f70
--- /dev/null
+++ b/src-test/morfologik/stemming/test-infix.dict
Binary files differ
diff --git a/src-test/morfologik/stemming/test-infix.info b/src-test/morfologik/stemming/test-infix.info
new file mode 100644
index 0000000..30e68ba
--- /dev/null
+++ b/src-test/morfologik/stemming/test-infix.info
@@ -0,0 +1,9 @@
+#
+# Dictionary properties.
+#
+
+fsa.dict.separator=+
+fsa.dict.encoding=iso-8859-2
+
+fsa.dict.uses-prefixes=true
+fsa.dict.uses-infixes=true \ No newline at end of file
diff --git a/src-test/morfologik/stemming/test-prefix.dict b/src-test/morfologik/stemming/test-prefix.dict
new file mode 100644
index 0000000..d0bed4c
--- /dev/null
+++ b/src-test/morfologik/stemming/test-prefix.dict
Binary files differ
diff --git a/src-test/morfologik/stemming/test-prefix.info b/src-test/morfologik/stemming/test-prefix.info
new file mode 100644
index 0000000..59b5376
--- /dev/null
+++ b/src-test/morfologik/stemming/test-prefix.info
@@ -0,0 +1,9 @@
+#
+# Dictionary properties.
+#
+
+fsa.dict.separator=+
+fsa.dict.encoding=iso-8859-2
+
+fsa.dict.uses-prefixes=true
+fsa.dict.uses-infixes=false \ No newline at end of file
diff --git a/src-test/morfologik/stemming/test-separators.dict b/src-test/morfologik/stemming/test-separators.dict
new file mode 100644
index 0000000..a71b9e7
--- /dev/null
+++ b/src-test/morfologik/stemming/test-separators.dict
Binary files differ
diff --git a/src-test/morfologik/stemming/test-separators.info b/src-test/morfologik/stemming/test-separators.info
new file mode 100644
index 0000000..c4a260f
--- /dev/null
+++ b/src-test/morfologik/stemming/test-separators.info
@@ -0,0 +1,9 @@
+#
+# Dictionary properties.
+#
+
+fsa.dict.separator=+
+fsa.dict.encoding=iso8859-1
+
+fsa.dict.uses-prefixes=false
+fsa.dict.uses-infixes=false \ No newline at end of file
diff --git a/src-test/morfologik/stemming/test-separators.txt b/src-test/morfologik/stemming/test-separators.txt
new file mode 100644
index 0000000..cd77945
--- /dev/null
+++ b/src-test/morfologik/stemming/test-separators.txt
@@ -0,0 +1,8 @@
+token1+
+token2++
+token3+++
+token4+token2
+token5+token2+
+token6+token2++
+token7+token2+token3+
+token8+token2+token3++ \ No newline at end of file
diff --git a/src-test/morfologik/stemming/test-synth.dict b/src-test/morfologik/stemming/test-synth.dict
new file mode 100644
index 0000000..6890253
--- /dev/null
+++ b/src-test/morfologik/stemming/test-synth.dict
Binary files differ
diff --git a/src-test/morfologik/stemming/test-synth.info b/src-test/morfologik/stemming/test-synth.info
new file mode 100644
index 0000000..ffce33e
--- /dev/null
+++ b/src-test/morfologik/stemming/test-synth.info
@@ -0,0 +1,6 @@
+#
+# Dictionary properties.
+#
+
+fsa.dict.separator=+
+fsa.dict.encoding=iso-8859-2 \ No newline at end of file
diff --git a/src-test/morfologik/tools/LauncherTest.java b/src-test/morfologik/tools/LauncherTest.java
new file mode 100644
index 0000000..da94df7
--- /dev/null
+++ b/src-test/morfologik/tools/LauncherTest.java
@@ -0,0 +1,26 @@
+package morfologik.tools;
+
+import java.util.Map;
+
+import morfologik.tools.Launcher.ToolInfo;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/*
+ *
+ */
+public class LauncherTest {
+ /* */
+ @Test
+ public void testTools() throws Exception {
+ for (Map.Entry<String, ToolInfo> e : Launcher.initTools().entrySet()) {
+ try {
+ e.getValue().invoke(new String[] {});
+ } catch (Throwable t) {
+ Assert.fail("Unable to launch " + e.getKey() + ": "
+ + t.getMessage());
+ }
+ }
+ }
+}
diff --git a/src-test/morfologik/tools/MorphEncoderTest.java b/src-test/morfologik/tools/MorphEncoderTest.java
new file mode 100644
index 0000000..a9b8f0d
--- /dev/null
+++ b/src-test/morfologik/tools/MorphEncoderTest.java
@@ -0,0 +1,125 @@
+package morfologik.tools;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.UnsupportedEncodingException;
+
+import morfologik.tools.MorphEncoder;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static morfologik.tools.MorphEncoder.*;
+
+/*
+ *
+ */
+public class MorphEncoderTest {
+ private MorphEncoder encoder;
+
+ @Before
+ public void setUp() {
+ encoder = new MorphEncoder();
+ }
+
+ @Test
+ public void testCommonPrefix() {
+ assertEquals(3, commonPrefix("abc".getBytes(), "abcd".getBytes()));
+ assertEquals(0, commonPrefix("abc".getBytes(), "cba".getBytes()));
+ }
+
+ @Test
+ public void testStandardEncode() throws UnsupportedEncodingException {
+ assertEquals("abc+Ad+tag",
+ asString(encoder.standardEncode(
+ "abc".getBytes("UTF-8"),
+ "abcd".getBytes("UTF-8"),
+ "tag".getBytes("UTF-8")), "UTF-8"));
+
+ assertEquals("abc+Dxyz+tag", encoder.standardEncodeUTF8("abc", "xyz", "tag"));
+ assertEquals("abc+Bć+tag", encoder.standardEncodeUTF8("abc", "abć", "tag"));
+ }
+
+ @Test
+ public void testSeparatorChange() throws UnsupportedEncodingException {
+ assertEquals("abc+Ad+tag",
+ asString(encoder.standardEncode(
+ "abc".getBytes("UTF-8"),
+ "abcd".getBytes("UTF-8"),
+ "tag".getBytes("UTF-8")), "UTF-8"));
+
+ encoder = new MorphEncoder((byte) '_');
+ assertEquals("abc_Ad_tag",
+ asString(encoder.standardEncode(
+ "abc".getBytes("UTF-8"),
+ "abcd".getBytes("UTF-8"),
+ "tag".getBytes("UTF-8")), "UTF-8"));
+
+ encoder = new MorphEncoder((byte) '\t');
+ assertEquals("abc\tAd\ttag",
+ asString(encoder.standardEncode(
+ "abc".getBytes("UTF-8"),
+ "abcd".getBytes("UTF-8"),
+ "tag".getBytes("UTF-8")), "UTF-8"));
+ }
+
+ @Test
+ public void testPrefixEncode() throws UnsupportedEncodingException {
+ assertEquals("abc+AAd+tag", asString(
+ encoder.prefixEncode(
+ "abc".getBytes("UTF-8"),
+ "abcd".getBytes("UTF-8"),
+ "tag".getBytes("UTF-8")), "UTF-8"));
+
+ assertEquals("abcd+AB+tag", asString(
+ encoder.prefixEncode(
+ "abcd".getBytes("UTF-8"),
+ "abc".getBytes("UTF-8"),
+ "tag".getBytes("UTF-8")), "US-ASCII"));
+
+ assertEquals("abc+ADxyz+tag",
+ encoder.prefixEncodeUTF8("abc", "xyz", "tag"));
+ assertEquals("abc+ABć+tag",
+ encoder.prefixEncodeUTF8("abc", "abć", "tag"));
+ assertEquals("postmodernizm+AAu+xyz",
+ encoder.prefixEncodeUTF8("postmodernizm", "postmodernizmu", "xyz"));
+ assertEquals("postmodernizmu+AB+xyz",
+ encoder.prefixEncodeUTF8("postmodernizmu", "postmodernizm", "xyz"));
+ assertEquals("nieduży+DA+adj",
+ encoder.prefixEncodeUTF8("nieduży", "duży", "adj"));
+ assertEquals("postmodernizm+ANmodernizm+xyz",
+ encoder.prefixEncodeUTF8("postmodernizm", "modernizm", "xyz"));
+ }
+
+ @Test
+ public void testInfixEncode() throws UnsupportedEncodingException {
+ assertEquals("abc+AAAd+tag", encoder.infixEncodeUTF8("abc", "abcd", "tag"));
+ assertEquals("abcd+AAB+tag", encoder.infixEncodeUTF8("abcd", "abc", "tag"));
+ assertEquals("abc+AADxyz+tag", encoder.infixEncodeUTF8("abc", "xyz", "tag"));
+ assertEquals("abc+AABć+tag", encoder.infixEncodeUTF8("abc", "abć", "tag"));
+ assertEquals("postmodernizm+AAAu+xyz",
+ encoder.infixEncodeUTF8("postmodernizm", "postmodernizmu", "xyz"));
+ assertEquals("postmodernizmu+AAB+xyz",
+ encoder.infixEncodeUTF8("postmodernizmu", "postmodernizm", "xyz"));
+ assertEquals("nieduży+ADA+adj",
+ encoder.infixEncodeUTF8("nieduży", "duży", "adj"));
+
+ // real infix cases
+ assertEquals("kcal+ABA+xyz", encoder.infixEncodeUTF8("kcal", "cal", "xyz"));
+ assertEquals("aillent+BBCr+xyz", encoder.infixEncodeUTF8("aillent", "aller", "xyz"));
+ assertEquals("laquelle+AAHequel+D f s", encoder.infixEncodeUTF8("laquelle", "lequel", "D f s"));
+ assertEquals("ccal+ABA+test", encoder.infixEncodeUTF8("ccal", "cal", "test"));
+ }
+
+ @Test
+ public void testUTF8Boundary() throws UnsupportedEncodingException {
+ assertEquals("passagère+Eer+tag", encoder.standardEncodeUTF8("passagère", "passager", "tag"));
+ assertEquals("passagère+AAEer+tag", encoder.infixEncodeUTF8("passagère", "passager", "tag"));
+ assertEquals("passagère+AEer+tag", encoder.prefixEncodeUTF8("passagère", "passager", "tag"));
+ }
+
+ @Test
+ public void testAsString() throws UnsupportedEncodingException {
+ assertEquals("passagère", asString("passagère".getBytes("UTF-8"), "UTF-8"));
+ }
+}
diff --git a/src-test/morfologik/tools/MorphEncodingToolTest.java b/src-test/morfologik/tools/MorphEncodingToolTest.java
new file mode 100644
index 0000000..c3d2559
--- /dev/null
+++ b/src-test/morfologik/tools/MorphEncodingToolTest.java
@@ -0,0 +1,110 @@
+package morfologik.tools;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/*
+ *
+ */
+public class MorphEncodingToolTest {
+
+ @Test
+ public void testTool() throws Exception {
+ // Create a simple plain text file.
+ File input = File.createTempFile("input", "in");
+ File output = File.createTempFile("output", "fsa.txt");
+ input.deleteOnExit();
+ output.deleteOnExit();
+
+ // Populate the file with data.
+ PrintWriter w = new PrintWriter(new OutputStreamWriter(
+ new FileOutputStream(input), "UTF-8"));
+ w.println("passagère\tpassager\ttag");
+ w.println("nieduży\tduży\ttest");
+ w.println("abcd\tabc\txyz");
+ w.close();
+
+ // suffix
+ MorphEncodingTool.main(new String[] {
+ "--input", input.getAbsolutePath(),
+ "--output", output.getAbsolutePath(),
+ "-suf" });
+
+ BufferedReader testOutput = new BufferedReader(new InputStreamReader(
+ new FileInputStream(output.getAbsolutePath()), "UTF-8"));
+ Assert.assertEquals("passagère+Eer+tag", testOutput.readLine());
+ Assert.assertEquals("nieduży+Iduży+test", testOutput.readLine());
+ Assert.assertEquals("abcd+B+xyz", testOutput.readLine());
+
+ testOutput.close();
+
+ // prefix
+ MorphEncodingTool.main(new String[] {
+ "--input", input.getAbsolutePath(),
+ "--output", output.getAbsolutePath(),
+ "-pre" });
+
+ testOutput = new BufferedReader(new InputStreamReader(
+ new FileInputStream(output.getAbsolutePath()), "UTF-8"));
+ Assert.assertEquals("passagère+AEer+tag", testOutput.readLine());
+ Assert.assertEquals("nieduży+DA+test", testOutput.readLine());
+ Assert.assertEquals("abcd+AB+xyz", testOutput.readLine());
+
+ testOutput.close();
+
+ // infix
+ MorphEncodingTool.main(new String[] {
+ "--input", input.getAbsolutePath(),
+ "--output", output.getAbsolutePath(),
+ "-inf" });
+
+ testOutput = new BufferedReader(new InputStreamReader(
+ new FileInputStream(output.getAbsolutePath()), "UTF-8"));
+ Assert.assertEquals("passagère+AAEer+tag", testOutput.readLine());
+ Assert.assertEquals("nieduży+ADA+test", testOutput.readLine());
+ Assert.assertEquals("abcd+AAB+xyz", testOutput.readLine());
+
+ testOutput.close();
+
+ }
+
+ /* */
+ @Test
+ public void testStemmingFile() throws Exception {
+ // Create a simple plain text file.
+ File input = File.createTempFile("input", "in");
+ File output = File.createTempFile("output", "fsa.txt");
+ input.deleteOnExit();
+ output.deleteOnExit();
+
+ // Populate the file with data.
+
+ // stemming only
+ PrintWriter w = new PrintWriter(new OutputStreamWriter(
+ new FileOutputStream(input), "UTF-8"));
+ w.println("passagère\tpassager");
+ w.println("nieduży\tduży");
+ w.println("abcd\tabc");
+ w.close();
+
+ MorphEncodingTool.main(new String[] { "--input",
+ input.getAbsolutePath(), "--output", output.getAbsolutePath(),
+ "-suf" });
+
+ BufferedReader testOutput = new BufferedReader(new InputStreamReader(
+ new FileInputStream(output.getAbsolutePath()), "UTF-8"));
+ Assert.assertEquals("passagère+Eer+", testOutput.readLine());
+ Assert.assertEquals("nieduży+Iduży+", testOutput.readLine());
+ Assert.assertEquals("abcd+B+", testOutput.readLine());
+
+ testOutput.close();
+ }
+}
diff --git a/src-test/morfologik/tools/Text2FSA5Test.java b/src-test/morfologik/tools/Text2FSA5Test.java
new file mode 100644
index 0000000..573c5da
--- /dev/null
+++ b/src-test/morfologik/tools/Text2FSA5Test.java
@@ -0,0 +1,37 @@
+package morfologik.tools;
+
+import java.io.*;
+
+import morfologik.fsa.*;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/*
+ *
+ */
+public class Text2FSA5Test {
+ @Test
+ public void testTool() throws Exception {
+ // Create a simple plain text file.
+ File input = File.createTempFile("input", "in");
+ File output = File.createTempFile("output", "fsa");
+ input.deleteOnExit();
+ output.deleteOnExit();
+
+ // Populate the file with data.
+ PrintWriter w = new PrintWriter(new OutputStreamWriter(new FileOutputStream(input), "UTF-8"));
+ w.println("b");
+ w.println("cab");
+ w.println("ab");
+ w.close();
+
+ FSABuildTool.main(new String [] {
+ "--input", input.getAbsolutePath(),
+ "--output", output.getAbsolutePath()
+ });
+
+ FSA5 fsa = FSA.read(new FileInputStream(output));
+ Assert.assertEquals(3, new FSAInfo(fsa).finalStatesCount);
+ }
+}
diff --git a/src-test/morfologik/util/MinMax.java b/src-test/morfologik/util/MinMax.java
new file mode 100644
index 0000000..4af6118
--- /dev/null
+++ b/src-test/morfologik/util/MinMax.java
@@ -0,0 +1,21 @@
+package morfologik.util;
+
+/**
+ * Minimum/maximum and range.
+ */
+public final class MinMax
+{
+ public final int min;
+ public final int max;
+
+ public MinMax(int min, int max)
+ {
+ this.min = Math.min(min, max);
+ this.max = Math.max(min, max);
+ }
+
+ public int range()
+ {
+ return max - min;
+ }
+} \ No newline at end of file
diff --git a/src/morfologik/dictionaries/pl.LICENSE b/src/morfologik/dictionaries/pl.LICENSE
new file mode 100644
index 0000000..8529618
--- /dev/null
+++ b/src/morfologik/dictionaries/pl.LICENSE
@@ -0,0 +1,8 @@
+LICENCE
+
+The dictionary comes from Morfologik project. Morfologik uses data from
+Polish ispell/myspell dictionary hosted at http://www.sjp.pl/slownik/en/ and
+is licenced on the terms of (inter alia) LGPL and Creative Commons
+ShareAlike. The part-of-speech tags were added in Morfologik project and
+are not found in the data from sjp.pl. The tagset is similar to IPI PAN
+tagset.
diff --git a/src/morfologik/dictionaries/pl.dict b/src/morfologik/dictionaries/pl.dict
new file mode 100644
index 0000000..1ebd28a
--- /dev/null
+++ b/src/morfologik/dictionaries/pl.dict
Binary files differ
diff --git a/src/morfologik/dictionaries/pl.info b/src/morfologik/dictionaries/pl.info
new file mode 100644
index 0000000..0c933c9
--- /dev/null
+++ b/src/morfologik/dictionaries/pl.info
@@ -0,0 +1,13 @@
+#
+# Dictionary metadata.
+#
+
+fsa.dict.author=morfologik.blogspot.com
+fsa.dict.created=19.11.2010
+fsa.dict.license=LGPL or Creative Commons ShareAlike license (pick any suitable). http://morfologik.blogspot.com
+
+fsa.dict.separator=+
+fsa.dict.encoding=iso-8859-2
+
+fsa.dict.uses-prefixes=true
+fsa.dict.uses-infixes=true
diff --git a/src/morfologik/fsa/CFSA.java b/src/morfologik/fsa/CFSA.java
new file mode 100644
index 0000000..695664d
--- /dev/null
+++ b/src/morfologik/fsa/CFSA.java
@@ -0,0 +1,364 @@
+package morfologik.fsa;
+
+import static morfologik.fsa.FSAFlags.*;
+import static morfologik.util.FileUtils.readFully;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * CFSA (Compact Finite State Automaton) binary format implementation. This is a
+ * slightly reorganized version of {@link FSA5} offering smaller automata size
+ * at some (minor) performance penalty.
+ *
+ * <p><b>Note:</b> Serialize to {@link CFSA2} for new code.</p>
+ *
+ * <p>The encoding of automaton body is as follows.</p>
+ *
+ * <pre>
+ * ---- FSA header (standard)
+ * Byte Description
+ * +-+-+-+-+-+-+-+-+\
+ * 0 | | | | | | | | | +------ '\'
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 1 | | | | | | | | | +------ 'f'
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 2 | | | | | | | | | +------ 's'
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 3 | | | | | | | | | +------ 'a'
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 4 | | | | | | | | | +------ version (fixed 0xc5)
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 5 | | | | | | | | | +------ filler character
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 6 | | | | | | | | | +------ annot character
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 7 |C|C|C|C|G|G|G|G| +------ C - node data size (ctl), G - address size (gotoLength)
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 8-32 | | | | | | | | | +------ labels mapped for type (1) of arc encoding.
+ * : : : : : : : : : |
+ * +-+-+-+-+-+-+-+-+/
+ *
+ * ---- Start of a node; only if automaton was compiled with NUMBERS option.
+ *
+ * Byte
+ * +-+-+-+-+-+-+-+-+\
+ * 0 | | | | | | | | | \ LSB
+ * +-+-+-+-+-+-+-+-+ +
+ * 1 | | | | | | | | | | number of strings recognized
+ * +-+-+-+-+-+-+-+-+ +----- by the automaton starting
+ * : : : : : : : : : | from this node.
+ * +-+-+-+-+-+-+-+-+ +
+ * ctl-1 | | | | | | | | | / MSB
+ * +-+-+-+-+-+-+-+-+/
+ *
+ * ---- A vector of node's arcs. Conditional format, depending on flags.
+ *
+ * 1) NEXT bit set, mapped arc label.
+ *
+ * +--------------- arc's label mapped in M bits if M's field value > 0
+ * | +------------- node pointed to is next
+ * | | +----------- the last arc of the node
+ * _______| | | +--------- the arc is final
+ * / | | | |
+ * +-+-+-+-+-+-+-+-+\
+ * 0 |M|M|M|M|M|1|L|F| +------ flags + (M) index of the mapped label.
+ * +-+-+-+-+-+-+-+-+/
+ *
+ * 2) NEXT bit set, label separate.
+ *
+ * +--------------- arc's label stored separately (M's field is zero).
+ * | +------------- node pointed to is next
+ * | | +----------- the last arc of the node
+ * | | | +--------- the arc is final
+ * | | | |
+ * +-+-+-+-+-+-+-+-+\
+ * 0 |0|0|0|0|0|1|L|F| +------ flags
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 1 | | | | | | | | | +------ label
+ * +-+-+-+-+-+-+-+-+/
+ *
+ * 3) NEXT bit not set. Full arc.
+ *
+ * +------------- node pointed to is next
+ * | +----------- the last arc of the node
+ * | | +--------- the arc is final
+ * | | |
+ * +-+-+-+-+-+-+-+-+\
+ * 0 |A|A|A|A|A|0|L|F| +------ flags + (A) address field, lower bits
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 1 | | | | | | | | | +------ label
+ * +-+-+-+-+-+-+-+-+/
+ * : : : : : : : : :
+ * +-+-+-+-+-+-+-+-+\
+ * gtl-1 |A|A|A|A|A|A|A|A| +------ address, continuation (MSB)
+ * +-+-+-+-+-+-+-+-+/
+ * </pre>
+ */
+public final class CFSA extends FSA {
+ /**
+ * Automaton header version value.
+ */
+ public static final byte VERSION = (byte) 0xC5;
+
+ /**
+ * Bitmask indicating that an arc corresponds to the last character of a
+ * sequence available when building the automaton.
+ */
+ public static final int BIT_FINAL_ARC = 1 << 0;
+
+ /**
+ * Bitmask indicating that an arc is the last one of the node's list and the
+ * following one belongs to another node.
+ */
+ public static final int BIT_LAST_ARC = 1 << 1;
+
+ /**
+ * Bitmask indicating that the target node of this arc follows it in the
+ * compressed automaton structure (no goto field).
+ */
+ public static final int BIT_TARGET_NEXT = 1 << 2;
+
+ /**
+ * An array of bytes with the internal representation of the automaton.
+ * Please see the documentation of this class for more information on how
+ * this structure is organized.
+ */
+ public byte[] arcs;
+
+ /**
+ * The length of the node header structure (if the automaton was compiled with
+ * <code>NUMBERS</code> option). Otherwise zero.
+ */
+ public final int nodeDataLength;
+
+ /**
+ * Flags for this automaton version.
+ */
+ private final Set<FSAFlags> flags;
+
+ /**
+ * Number of bytes each address takes in full, expanded form (goto length).
+ */
+ public final int gtl;
+
+ /**
+ * Label mapping for arcs of type (1) (see class documentation). The array
+ * is indexed by mapped label's value and contains the original label.
+ */
+ public final byte[] labelMapping;
+
+ /**
+ * Creates a new automaton, reading it from a file in FSA format, version 5.
+ */
+ public CFSA(InputStream fsaStream) throws IOException {
+ // Read the header first.
+ final FSAHeader header = FSAHeader.read(fsaStream);
+
+ // Ensure we have the correct version.
+ if (header.version != VERSION) {
+ throw new IOException("This class can read FSA version 5 only: " + header.version);
+ }
+
+ /*
+ * Determine if the automaton was compiled with NUMBERS. If so, modify
+ * ctl and goto fields accordingly.
+ */
+ flags = EnumSet.of(FLEXIBLE, STOPBIT, NEXTBIT);
+ if ((header.gtl & 0xf0) != 0) {
+ this.nodeDataLength = (header.gtl >>> 4) & 0x0f;
+ this.gtl = header.gtl & 0x0f;
+ flags.add(NUMBERS);
+ } else {
+ this.nodeDataLength = 0;
+ this.gtl = header.gtl & 0x0f;
+ }
+
+ /*
+ * Read mapping dictionary.
+ */
+ labelMapping = new byte[1 << 5];
+ readFully(fsaStream, labelMapping);
+
+ /*
+ * Read arcs' data.
+ */
+ arcs = readFully(fsaStream);
+ }
+
+ /**
+ * Returns the start node of this automaton. May return <code>0</code> if
+ * the start node is also an end node.
+ */
+ @Override
+ public int getRootNode() {
+ // Skip dummy node marking terminating state.
+ final int epsilonNode = skipArc(getFirstArc(0));
+
+ // And follow the epsilon node's first (and only) arc.
+ return getDestinationNodeOffset(getFirstArc(epsilonNode));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final int getFirstArc(int node) {
+ return nodeDataLength + node;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final int getNextArc(int arc) {
+ if (isArcLast(arc))
+ return 0;
+ else
+ return skipArc(arc);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getArc(int node, byte label) {
+ for (int arc = getFirstArc(node); arc != 0; arc = getNextArc(arc)) {
+ if (getArcLabel(arc) == label)
+ return arc;
+ }
+
+ // An arc labeled with "label" not found.
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getEndNode(int arc) {
+ final int nodeOffset = getDestinationNodeOffset(arc);
+ if (0 == nodeOffset) {
+ throw new RuntimeException("This is a terminal arc [" + arc + "]");
+ }
+ return nodeOffset;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public byte getArcLabel(int arc) {
+ if (isNextSet(arc) && isLabelCompressed(arc)) {
+ return this.labelMapping[(arcs[arc] >>> 3) & 0x1f];
+ } else {
+ return arcs[arc + 1];
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getRightLanguageCount(int node) {
+ assert getFlags().contains(FSAFlags.NUMBERS): "This FSA was not compiled with NUMBERS.";
+ return FSA5.decodeFromBytes(arcs, node, nodeDataLength);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isArcFinal(int arc) {
+ return (arcs[arc] & BIT_FINAL_ARC) != 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isArcTerminal(int arc) {
+ return (0 == getDestinationNodeOffset(arc));
+ }
+
+ /**
+ * Returns <code>true</code> if this arc has <code>NEXT</code> bit set.
+ *
+ * @see #BIT_LAST_ARC
+ */
+ public boolean isArcLast(int arc) {
+ return (arcs[arc] & BIT_LAST_ARC) != 0;
+ }
+
+ /**
+ * @see #BIT_TARGET_NEXT
+ */
+ public boolean isNextSet(int arc) {
+ return (arcs[arc] & BIT_TARGET_NEXT) != 0;
+ }
+
+ /**
+ * Returns <code>true</code> if the label is compressed inside flags byte.
+ */
+ public boolean isLabelCompressed(int arc) {
+ assert isNextSet(arc) : "Only applicable to arcs with NEXT bit.";
+ return (arcs[arc] & (-1 << 3)) != 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>For this automaton version, an additional {@link FSAFlags#NUMBERS} flag
+ * may be set to indicate the automaton contains extra fields for each node.</p>
+ */
+ public Set<FSAFlags> getFlags() {
+ return Collections.unmodifiableSet(flags);
+ }
+
+ /**
+ * Returns the address of the node pointed to by this arc.
+ */
+ final int getDestinationNodeOffset(int arc) {
+ if (isNextSet(arc)) {
+ /* The destination node follows this arc in the array. */
+ return skipArc(arc);
+ } else {
+ /*
+ * The destination node address has to be extracted from the arc's
+ * goto field.
+ */
+ int r = 0;
+ for (int i = gtl; --i >= 1;) {
+ r = r << 8 | (arcs[arc + 1 + i] & 0xff);
+ }
+ r = r << 8 | (arcs[arc] & 0xff);
+ return r >>> 3;
+ }
+ }
+
+ /**
+ * Read the arc's layout and skip as many bytes, as needed, to skip it.
+ */
+ private int skipArc(int offset) {
+ if (isNextSet(offset)) {
+ if (isLabelCompressed(offset)) {
+ offset++;
+ } else {
+ offset += 1 + 1;
+ }
+ } else {
+ offset += 1 + gtl;
+ }
+ return offset;
+ }
+} \ No newline at end of file
diff --git a/src/morfologik/fsa/CFSA2.java b/src/morfologik/fsa/CFSA2.java
new file mode 100644
index 0000000..6955da4
--- /dev/null
+++ b/src/morfologik/fsa/CFSA2.java
@@ -0,0 +1,404 @@
+package morfologik.fsa;
+
+import static morfologik.util.FileUtils.readFully;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.EnumSet;
+import java.util.Set;
+
+import morfologik.util.FileUtils;
+
+/**
+ * CFSA (Compact Finite State Automaton) binary format implementation, version 2:
+ * <ul>
+ * <li>{@link #BIT_TARGET_NEXT} applicable on all arcs, not necessarily the last one.</li>
+ * <li>v-coded goto field</li>
+ * <li>v-coded perfect hashing numbers, if any</li>
+ * <li>31 most frequent labels integrated with flags byte</li>
+ * </ul>
+ *
+ * <p>The encoding of automaton body is as follows.</p>
+ *
+ * <pre>
+ * ---- CFSA header
+ * Byte Description
+ * +-+-+-+-+-+-+-+-+\
+ * 0 | | | | | | | | | +------ '\'
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 1 | | | | | | | | | +------ 'f'
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 2 | | | | | | | | | +------ 's'
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 3 | | | | | | | | | +------ 'a'
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 4 | | | | | | | | | +------ version (fixed 0xc6)
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 5 | | | | | | | | | +----\
+ * +-+-+-+-+-+-+-+-+/ \ flags [MSB first]
+ * +-+-+-+-+-+-+-+-+\ /
+ * 6 | | | | | | | | | +----/
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 7 | | | | | | | | | +------ label lookup table size
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 8-32 | | | | | | | | | +------ label value lookup table
+ * : : : : : : : : : |
+ * +-+-+-+-+-+-+-+-+/
+ *
+ * ---- Start of a node; only if automaton was compiled with NUMBERS option.
+ *
+ * Byte
+ * +-+-+-+-+-+-+-+-+\
+ * 0 | | | | | | | | | \
+ * +-+-+-+-+-+-+-+-+ +
+ * 1 | | | | | | | | | | number of strings recognized
+ * +-+-+-+-+-+-+-+-+ +----- by the automaton starting
+ * : : : : : : : : : | from this node. v-coding
+ * +-+-+-+-+-+-+-+-+ +
+ * | | | | | | | | | /
+ * +-+-+-+-+-+-+-+-+/
+ *
+ * ---- A vector of this node's arcs. An arc's layout depends on the combination of flags.
+ *
+ * 1) NEXT bit set, mapped arc label.
+ *
+ * +----------------------- node pointed to is next
+ * | +--------------------- the last arc of the node
+ * | | +------------------- this arc leads to a final state (acceptor)
+ * | | | _______+--------- arc's label; indexed if M > 0, otherwise explicit label follows
+ * | | | / | | | |
+ * +-+-+-+-+-+-+-+-+\
+ * 0 |N|L|F|M|M|M|M|M| +------ flags + (M) index of the mapped label.
+ * +-+-+-+-+-+-+-+-+/
+ * +-+-+-+-+-+-+-+-+\
+ * 1 | | | | | | | | | +------ optional label if M == 0
+ * +-+-+-+-+-+-+-+-+/
+ * : : : : : : : : :
+ * +-+-+-+-+-+-+-+-+\
+ * |A|A|A|A|A|A|A|A| +------ v-coded goto address
+ * +-+-+-+-+-+-+-+-+/
+ * </pre>
+ */
+public final class CFSA2 extends FSA {
+ /**
+ * Automaton header version value.
+ */
+ public static final byte VERSION = (byte) 0xc6;
+
+ /**
+ * The target node of this arc follows the last arc of the current state
+ * (no goto field).
+ */
+ public static final int BIT_TARGET_NEXT = 1 << 7;
+
+ /**
+ * The arc is the last one from the current node's arcs list.
+ */
+ public static final int BIT_LAST_ARC = 1 << 6;
+
+ /**
+ * The arc corresponds to the last character of a sequence
+ * available when building the automaton (acceptor transition).
+ */
+ public static final int BIT_FINAL_ARC = 1 << 5;
+
+ /**
+ * The count of bits assigned to storing an indexed label.
+ */
+ static final int LABEL_INDEX_BITS = 5;
+
+ /**
+ * Masks only the M bits of a flag byte.
+ */
+ static final int LABEL_INDEX_MASK = (1 << LABEL_INDEX_BITS) - 1;
+
+ /**
+ * Maximum size of the labels index.
+ */
+ static final int LABEL_INDEX_SIZE = (1 << LABEL_INDEX_BITS) - 1;
+
+ /**
+ * An array of bytes with the internal representation of the automaton.
+ * Please see the documentation of this class for more information on how
+ * this structure is organized.
+ */
+ public byte[] arcs;
+
+ /**
+ * Flags for this automaton version.
+ */
+ private final EnumSet<FSAFlags> flags;
+
+ /**
+ * Label mapping for M-indexed labels.
+ */
+ public final byte[] labelMapping;
+
+ /**
+ * If <code>true</code> states are prepended with numbers.
+ */
+ private final boolean hasNumbers;
+
+ /**
+ * Epsilon node's offset.
+ */
+ private final int epsilon = 0;
+
+ /**
+ * Reads an automaton from a byte stream.
+ */
+ public CFSA2(InputStream in) throws IOException {
+ // Read the header first.
+ if (FSAHeader.FSA_MAGIC != FileUtils.readInt(in))
+ throw new IOException("Invalid file header magic bytes.");
+
+ // Ensure we have the correct version.
+ final int version = FileUtils.readByte(in);
+ if (version != VERSION) {
+ throw new IOException("This class can only read FSA version: " + VERSION);
+ }
+
+ // Read flags.
+ short flagBits = FileUtils.readShort(in);
+ flags = EnumSet.noneOf(FSAFlags.class);
+ for (FSAFlags f : FSAFlags.values()) {
+ if (FSAFlags.isSet(flagBits, f))
+ flags.add(f);
+ }
+
+ if (flagBits != FSAFlags.asShort(flags))
+ throw new IOException("Unrecognized flags remained: 0x" + Integer.toHexString(flagBits));
+
+ this.hasNumbers = flags.contains(FSAFlags.NUMBERS);
+
+ /*
+ * Read mapping dictionary.
+ */
+ int labelMappingSize = FileUtils.readByte(in) & 0xff;
+ labelMapping = new byte[labelMappingSize];
+ readFully(in, labelMapping);
+
+ /*
+ * Read arcs' data.
+ */
+ arcs = readFully(in);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getRootNode() {
+ // Skip dummy node marking terminating state.
+ return getDestinationNodeOffset(getFirstArc(epsilon));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final int getFirstArc(int node) {
+ if (hasNumbers) {
+ return skipVInt(node);
+ } else {
+ return node;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final int getNextArc(int arc) {
+ if (isArcLast(arc))
+ return 0;
+ else
+ return skipArc(arc);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getArc(int node, byte label) {
+ for (int arc = getFirstArc(node); arc != 0; arc = getNextArc(arc)) {
+ if (getArcLabel(arc) == label)
+ return arc;
+ }
+
+ // An arc labeled with "label" not found.
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getEndNode(int arc) {
+ final int nodeOffset = getDestinationNodeOffset(arc);
+ assert nodeOffset != 0 : "Can't follow a terminal arc: " + arc;
+ assert nodeOffset < arcs.length : "Node out of bounds.";
+ return nodeOffset;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public byte getArcLabel(int arc) {
+ int index = arcs[arc] & LABEL_INDEX_MASK;
+ if (index > 0) {
+ return this.labelMapping[index];
+ } else {
+ return arcs[arc + 1];
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getRightLanguageCount(int node) {
+ assert getFlags().contains(FSAFlags.NUMBERS): "This FSA was not compiled with NUMBERS.";
+ return readVInt(arcs, node);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isArcFinal(int arc) {
+ return (arcs[arc] & BIT_FINAL_ARC) != 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isArcTerminal(int arc) {
+ return (0 == getDestinationNodeOffset(arc));
+ }
+
+ /**
+ * Returns <code>true</code> if this arc has <code>NEXT</code> bit set.
+ *
+ * @see #BIT_LAST_ARC
+ */
+ public boolean isArcLast(int arc) {
+ return (arcs[arc] & BIT_LAST_ARC) != 0;
+ }
+
+ /**
+ * @see #BIT_TARGET_NEXT
+ */
+ public boolean isNextSet(int arc) {
+ return (arcs[arc] & BIT_TARGET_NEXT) != 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<FSAFlags> getFlags() {
+ return flags;
+ }
+
+ /**
+ * Returns the address of the node pointed to by this arc.
+ */
+ final int getDestinationNodeOffset(int arc) {
+ if (isNextSet(arc)) {
+ /* Follow until the last arc of this state. */
+ while (!isArcLast(arc)) {
+ arc = getNextArc(arc);
+ }
+
+ /* And return the byte right after it. */
+ return skipArc(arc);
+ } else {
+ /*
+ * The destination node address is v-coded. v-code starts either
+ * at the next byte (label indexed) or after the next byte (label explicit).
+ */
+ return readVInt(arcs, arc + ((arcs[arc] & LABEL_INDEX_MASK) == 0 ? 2 : 1));
+ }
+ }
+
+ /**
+ * Read the arc's layout and skip as many bytes, as needed, to skip it.
+ */
+ private int skipArc(int offset) {
+ int flag = arcs[offset++];
+
+ // Explicit label?
+ if ((flag & LABEL_INDEX_MASK) == 0) {
+ offset++;
+ }
+
+ // Explicit goto?
+ if ((flag & BIT_TARGET_NEXT) == 0) {
+ offset = skipVInt(offset);
+ }
+
+ assert offset < this.arcs.length;
+ return offset;
+ }
+
+ /**
+ * Read a v-int.
+ */
+ static int readVInt(byte[] array, int offset) {
+ byte b = array[offset];
+ int value = b & 0x7F;
+
+ for (int shift = 7; b < 0; shift += 7) {
+ b = array[++offset];
+ value |= (b & 0x7F) << shift;
+ }
+
+ return value;
+ }
+
+ /**
+ * Write a v-int to a byte array.
+ */
+ static int writeVInt(byte[] array, int offset, int value) {
+ assert value >= 0 : "Can't v-code negative ints.";
+
+ while (value > 0x7F) {
+ array[offset++] = (byte) (0x80 | (value & 0x7F));
+ value >>= 7;
+ }
+ array[offset++] = (byte) value;
+
+ return offset;
+ }
+
+ /**
+ * Return the byte-length of a v-coded int.
+ */
+ static int vIntLength(int value) {
+ assert value >= 0 : "Can't v-code negative ints.";
+
+ int bytes;
+ for (bytes = 1; value >= 0x80; bytes++) {
+ value >>= 7;
+ }
+
+ return bytes;
+ }
+
+ /**
+ * Skip a v-int.
+ */
+ private int skipVInt(int offset) {
+ while (arcs[offset++] < 0);
+ return offset;
+ }
+} \ No newline at end of file
diff --git a/src/morfologik/fsa/CFSA2Serializer.java b/src/morfologik/fsa/CFSA2Serializer.java
new file mode 100644
index 0000000..11c7b13
--- /dev/null
+++ b/src/morfologik/fsa/CFSA2Serializer.java
@@ -0,0 +1,536 @@
+package morfologik.fsa;
+
+import static morfologik.fsa.CFSA2.BIT_FINAL_ARC;
+import static morfologik.fsa.CFSA2.BIT_LAST_ARC;
+import static morfologik.fsa.CFSA2.BIT_TARGET_NEXT;
+import static morfologik.fsa.FSAFlags.FLEXIBLE;
+import static morfologik.fsa.FSAFlags.NEXTBIT;
+import static morfologik.fsa.FSAFlags.NUMBERS;
+import static morfologik.fsa.FSAFlags.STOPBIT;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayDeque;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.PriorityQueue;
+import java.util.Set;
+
+import morfologik.fsa.FSAUtils.IntIntHolder;
+import morfologik.tools.IMessageLogger;
+import morfologik.util.FileUtils;
+
+import com.carrotsearch.hppc.BitSet;
+import com.carrotsearch.hppc.BoundedProportionalArraySizingStrategy;
+import com.carrotsearch.hppc.IntArrayList;
+import com.carrotsearch.hppc.IntIntOpenHashMap;
+import com.carrotsearch.hppc.IntStack;
+import com.carrotsearch.hppc.cursors.IntCursor;
+import com.carrotsearch.hppc.cursors.IntIntCursor;
+
+/**
+ * Serializes in-memory {@link FSA} graphs to {@link CFSA2}.
+ *
+ * <p>
+ * It is possible to serialize the automaton with numbers required for perfect
+ * hashing. See {@link #withNumbers()} method.
+ * </p>
+ *
+ * @see CFSA2
+ * @see FSA#read(java.io.InputStream)
+ */
+public final class CFSA2Serializer implements FSASerializer {
+ /**
+ * Supported flags.
+ */
+ private final static EnumSet<FSAFlags> flags = EnumSet.of(NUMBERS, FLEXIBLE, STOPBIT, NEXTBIT);
+
+ /**
+ * No-state id.
+ */
+ private final static int NO_STATE = -1;
+
+ /**
+ * <code>true</code> if we should serialize with numbers.
+ *
+ * @see #withNumbers()
+ */
+ private boolean withNumbers;
+
+ /**
+ * A hash map of [state, offset] pairs.
+ */
+ private IntIntOpenHashMap offsets = new IntIntOpenHashMap();
+
+ /**
+ * A hash map of [state, right-language-count] pairs.
+ */
+ private IntIntOpenHashMap numbers = new IntIntOpenHashMap();
+
+ /**
+ * Scratch array for serializing vints.
+ */
+ private final byte [] scratch = new byte [5];
+
+ /**
+ * The most frequent labels for integrating with the flags field.
+ */
+ private byte [] labelsIndex;
+
+ /**
+ * Inverted index of labels to be integrated with flags field. A label
+ * at index <code>i<code> has the index or zero (no integration).
+ */
+ private int [] labelsInvIndex;
+
+ /**
+ * Logger for progress.
+ */
+ private IMessageLogger logger = new NullMessageLogger();
+
+ /**
+ * Serialize the automaton with the number of right-language sequences in
+ * each node. This is required to implement perfect hashing. The numbering
+ * also preserves the order of input sequences.
+ *
+ * @return Returns the same object for easier call chaining.
+ */
+ public CFSA2Serializer withNumbers() {
+ withNumbers = true;
+ return this;
+ }
+
+ /**
+ * Serializes any {@link FSA} to {@link CFSA2} stream.
+ *
+ * @see #withNumbers
+ * @return Returns <code>os</code> for chaining.
+ */
+ @Override
+ public <T extends OutputStream> T serialize(final FSA fsa, T os) throws IOException {
+ /*
+ * Calculate the most frequent labels and build indexed labels dictionary.
+ */
+ computeLabelsIndex(fsa);
+
+ /*
+ * Calculate the number of bytes required for the node data, if
+ * serializing with numbers.
+ */
+ if (withNumbers) {
+ this.numbers = FSAUtils.rightLanguageForAllStates(fsa);
+ }
+
+ /*
+ * Linearize all the states, optimizing their layout.
+ */
+ IntArrayList linearized = linearize(fsa);
+
+ /*
+ * Emit the header.
+ */
+ FileUtils.writeInt(os, FSAHeader.FSA_MAGIC);
+ os.write(CFSA2.VERSION);
+
+ EnumSet<FSAFlags> fsaFlags = EnumSet.of(FLEXIBLE, STOPBIT, NEXTBIT);
+ if (withNumbers) fsaFlags.add(NUMBERS);
+ FileUtils.writeShort(os, FSAFlags.asShort(fsaFlags));
+
+ /*
+ * Emit labels index.
+ */
+ os.write(labelsIndex.length);
+ os.write(labelsIndex);
+
+ /*
+ * Emit the automaton.
+ */
+ int size = emitNodes(fsa, os, linearized);
+ assert size == 0 : "Size changed in the final pass?";
+
+ return os;
+ }
+
+ /**
+ * Compute a set of labels to be integrated with the flags field.
+ */
+ private void computeLabelsIndex(final FSA fsa) {
+ // Compute labels count.
+ final int [] countByValue = new int [256];
+
+ fsa.visitAllStates(new StateVisitor() {
+ public boolean accept(int state) {
+ for (int arc = fsa.getFirstArc(state); arc != 0; arc = fsa.getNextArc(arc))
+ countByValue[fsa.getArcLabel(arc) & 0xff]++;
+ return true;
+ }
+ });
+
+ // Order by descending frequency of counts and increasing label value.
+ Comparator<IntIntHolder> comparator = new Comparator<IntIntHolder>() {
+ public int compare(IntIntHolder o1, IntIntHolder o2) {
+ int countDiff = o2.b - o1.b;
+ if (countDiff == 0) {
+ countDiff = o1.a - o2.a;
+ }
+ return countDiff;
+ }
+ };
+
+ PriorityQueue<IntIntHolder> labelAndCount = new PriorityQueue<IntIntHolder>(countByValue.length, comparator);
+ for (int label = 0; label < countByValue.length; label++) {
+ if (countByValue[label] > 0) {
+ labelAndCount.add(new IntIntHolder(label, countByValue[label]));
+ }
+ }
+
+ labelsIndex = new byte [1 + Math.min(labelAndCount.size(), CFSA2.LABEL_INDEX_SIZE)];
+ labelsInvIndex = new int [256];
+ for (int i = labelsIndex.length - 1; i > 0 && !labelAndCount.isEmpty(); i--) {
+ IntIntHolder p = labelAndCount.remove();
+ labelsInvIndex[p.a] = i;
+ labelsIndex[i] = (byte) p.a;
+ }
+ }
+
+ /**
+ * Return supported flags.
+ */
+ @Override
+ public Set<FSAFlags> getFlags() {
+ return flags;
+ }
+
+ /**
+ * Linearization of states.
+ */
+ private IntArrayList linearize(final FSA fsa) throws IOException {
+ /*
+ * Compute the states with most inlinks. These should be placed as close to the
+ * start of the automaton, as possible so that v-coded addresses are tiny.
+ */
+ final IntIntOpenHashMap inlinkCount = computeInlinkCount(fsa);
+
+ /*
+ * An array of ordered states for serialization.
+ */
+ final IntArrayList linearized = new IntArrayList(0,
+ new BoundedProportionalArraySizingStrategy(1000, 10000, 1.5f));
+
+ /*
+ * Determine which states should be linearized first (at fixed positions) so as to
+ * minimize the place occupied by goto fields.
+ */
+ int maxStates = Integer.MAX_VALUE;
+ int minInlinkCount = 2;
+ ArrayDeque<Integer> statesQueue = computeFirstStates(inlinkCount, maxStates, minInlinkCount);
+ IntArrayList states = new IntArrayList();
+ while (!statesQueue.isEmpty())
+ states.add(statesQueue.pop());
+
+ /*
+ * Compute initial addresses, without node rearrangements.
+ */
+ int serializedSize = linearizeAndCalculateOffsets(fsa, new IntArrayList(), linearized, offsets);
+
+ /*
+ * Probe for better node arrangements by selecting between [lower, upper]
+ * nodes from the potential candidate nodes list.
+ */
+ IntArrayList sublist = new IntArrayList();
+ sublist.buffer = states.buffer;
+ sublist.elementsCount = states.elementsCount;
+
+ /*
+ * Probe the initial region a little bit, looking for optimal cut. It can't be binary search
+ * because the result isn't monotonic.
+ */
+ logger.startPart("Compacting");
+ logger.log("Initial output size", serializedSize);
+ int cutAt = 0;
+ for (int cut = Math.min(25, states.size()); cut <= Math.min(150, states.size()); cut += 25) {
+ sublist.elementsCount = cut;
+ int newSize = linearizeAndCalculateOffsets(fsa, sublist, linearized, offsets);
+ logger.log("Moved " + sublist.size() + " states, output size", newSize);
+ if (newSize >= serializedSize) {
+ break;
+ }
+ cutAt = cut;
+ }
+
+ /*
+ * Cut at the calculated point and repeat linearization.
+ */
+ sublist.elementsCount = cutAt;
+ int size = linearizeAndCalculateOffsets(fsa, sublist, linearized, offsets);
+
+ logger.log("Will move " + sublist.size() + " states, final size", size);
+ logger.endPart();
+
+ return linearized;
+ }
+
+ /**
+ * Linearize all states, putting <code>states</code> in front of the automaton and
+ * calculating stable state offsets.
+ */
+ private int linearizeAndCalculateOffsets(FSA fsa, IntArrayList states,
+ IntArrayList linearized, IntIntOpenHashMap offsets) throws IOException
+ {
+ final BitSet visited = new BitSet();
+ final IntStack nodes = new IntStack();
+ linearized.clear();
+
+ /*
+ * Linearize states with most inlinks first.
+ */
+ for (int i = 0; i < states.size(); i++) {
+ linearizeState(fsa, nodes, linearized, visited, states.get(i));
+ }
+
+ /*
+ * Linearize the remaining states by chaining them one after another, in depth-order.
+ */
+ nodes.push(fsa.getRootNode());
+ while (!nodes.isEmpty()) {
+ final int node = nodes.pop();
+ if (visited.get(node))
+ continue;
+
+ linearizeState(fsa, nodes, linearized, visited, node);
+ }
+
+ /*
+ * Calculate new state offsets. This is iterative. We start with
+ * maximum potential offsets and recalculate until converged.
+ */
+ int MAX_OFFSET = Integer.MAX_VALUE;
+ for (IntCursor c : linearized) {
+ offsets.put(c.value, MAX_OFFSET);
+ }
+
+ int i, j = 0;
+ while ((i = emitNodes(fsa, null, linearized)) > 0) {
+ j = i;
+ }
+ return j;
+ }
+
+ /**
+ * Add a state to linearized list.
+ */
+ private void linearizeState(final FSA fsa,
+ IntStack nodes,
+ IntArrayList linearized,
+ BitSet visited, int node)
+ {
+ linearized.add(node);
+ visited.set(node);
+ for (int arc = fsa.getFirstArc(node); arc != 0; arc = fsa.getNextArc(arc)) {
+ if (!fsa.isArcTerminal(arc)) {
+ final int target = fsa.getEndNode(arc);
+ if (!visited.get(target))
+ nodes.push(target);
+ }
+ }
+ }
+
+ /**
+ * Compute the set of states that should be linearized first to minimize other
+ * states goto length.
+ */
+ private ArrayDeque<Integer> computeFirstStates(IntIntOpenHashMap inlinkCount,
+ int maxStates,
+ int minInlinkCount)
+ {
+ Comparator<IntIntHolder> comparator = new Comparator<FSAUtils.IntIntHolder>() {
+ public int compare(IntIntHolder o1, IntIntHolder o2) {
+ int v = o1.a - o2.a;
+ return v == 0 ? (o1.b - o2.b) : v;
+ }
+ };
+
+ PriorityQueue<IntIntHolder> stateInlink = new PriorityQueue<IntIntHolder>(1, comparator);
+ IntIntHolder scratch = new IntIntHolder();
+ for (IntIntCursor c : inlinkCount) {
+ if (c.value > minInlinkCount) {
+ scratch.a = c.value;
+ scratch.b = c.key;
+
+ if (stateInlink.size() < maxStates || comparator.compare(scratch, stateInlink.peek()) > 0) {
+ stateInlink.add(new IntIntHolder(c.value, c.key));
+ if (stateInlink.size() > maxStates) stateInlink.remove();
+ }
+ }
+ }
+
+ ArrayDeque<Integer> states = new ArrayDeque<Integer>();
+ while (!stateInlink.isEmpty()) {
+ IntIntHolder i = stateInlink.remove();
+ states.addFirst(i.b);
+ }
+ return states;
+ }
+
+ /**
+ * Compute in-link count for each state.
+ */
+ private IntIntOpenHashMap computeInlinkCount(final FSA fsa) {
+ IntIntOpenHashMap inlinkCount = new IntIntOpenHashMap();
+ BitSet visited = new BitSet();
+ IntStack nodes = new IntStack();
+ nodes.push(fsa.getRootNode());
+
+ while (!nodes.isEmpty()) {
+ final int node = nodes.pop();
+ if (visited.get(node))
+ continue;
+
+ visited.set(node);
+
+ for (int arc = fsa.getFirstArc(node); arc != 0; arc = fsa.getNextArc(arc)) {
+ if (!fsa.isArcTerminal(arc)) {
+ final int target = fsa.getEndNode(arc);
+ inlinkCount.putOrAdd(target, 1, 1);
+ if (!visited.get(target))
+ nodes.push(target);
+ }
+ }
+ }
+
+ return inlinkCount;
+ }
+
+ /**
+ * Update arc offsets assuming the given goto length.
+ */
+ private int emitNodes(FSA fsa, OutputStream os, IntArrayList linearized) throws IOException {
+ int offset = 0;
+
+ // Add epsilon state.
+ offset += emitNodeData(os, 0);
+ if (fsa.getRootNode() != 0)
+ offset += emitArc(os, BIT_LAST_ARC, (byte) '^', offsets.get(fsa.getRootNode()));
+ else
+ offset += emitArc(os, BIT_LAST_ARC, (byte) '^', 0);
+
+ boolean offsetsChanged = false;
+ final int max = linearized.size();
+ for (IntCursor c : linearized) {
+ final int state = c.value;
+ final int nextState = c.index + 1 < max ? linearized.get(c.index + 1) : NO_STATE;
+
+ if (os == null) {
+ offsetsChanged |= (offsets.get(state) != offset);
+ offsets.put(state, offset);
+ } else {
+ assert offsets.get(state) == offset : state + " " + offsets.get(state) + " " + offset;
+ }
+
+ offset += emitNodeData(os, withNumbers ? numbers.get(state) : 0);
+ offset += emitNodeArcs(fsa, os, state, nextState);
+ }
+
+ return offsetsChanged ? offset : 0;
+ }
+
+ /**
+ * Emit all arcs of a single node.
+ */
+ private int emitNodeArcs(FSA fsa, OutputStream os,
+ final int state, final int nextState) throws IOException {
+ int offset = 0;
+ for (int arc = fsa.getFirstArc(state); arc != 0; arc = fsa.getNextArc(arc)) {
+ int targetOffset;
+ final int target;
+
+ if (fsa.isArcTerminal(arc)) {
+ target = 0;
+ targetOffset = 0;
+ } else {
+ target = fsa.getEndNode(arc);
+ targetOffset = offsets.get(target);
+ }
+
+ int flags = 0;
+
+ if (fsa.isArcFinal(arc)) {
+ flags |= BIT_FINAL_ARC;
+ }
+
+ if (fsa.getNextArc(arc) == 0) {
+ flags |= BIT_LAST_ARC;
+ }
+
+ if (targetOffset != 0 && target == nextState) {
+ flags |= BIT_TARGET_NEXT;
+ targetOffset = 0;
+ }
+
+ offset += emitArc(os, flags, fsa.getArcLabel(arc), targetOffset);
+ }
+
+ return offset;
+ }
+
+ /** */
+ private int emitArc(OutputStream os, int flags, byte label, int targetOffset)
+ throws IOException
+ {
+ int length = 0;
+
+ int labelIndex = labelsInvIndex[label & 0xff];
+ if (labelIndex > 0) {
+ if (os != null) os.write(flags | labelIndex);
+ length++;
+ } else {
+ if (os != null) {
+ os.write(flags);
+ os.write(label);
+ }
+ length += 2;
+ }
+
+ if ((flags & BIT_TARGET_NEXT) == 0) {
+ int len = CFSA2.writeVInt(scratch, 0, targetOffset);
+ if (os != null) {
+ os.write(scratch, 0, len);
+ }
+ length += len;
+ }
+
+ return length;
+ }
+
+ /** */
+ private int emitNodeData(OutputStream os, int number) throws IOException {
+ int size = 0;
+
+ if (withNumbers) {
+ size = CFSA2.writeVInt(scratch, 0, number);
+ if (os != null) {
+ os.write(scratch, 0, size);
+ }
+ }
+
+ return size;
+ }
+
+ /** */
+ @Override
+ public CFSA2Serializer withFiller(byte filler) {
+ throw new UnsupportedOperationException("CFSA2 does not support filler. Use .info file.");
+ }
+
+ /** */
+ @Override
+ public CFSA2Serializer withAnnotationSeparator(byte annotationSeparator) {
+ throw new UnsupportedOperationException("CFSA2 does not support separator. Use .info file.");
+ }
+
+ @Override
+ public CFSA2Serializer withLogger(IMessageLogger logger) {
+ this.logger = logger;
+ return this;
+ }
+}
diff --git a/src/morfologik/fsa/ConstantArcSizeFSA.java b/src/morfologik/fsa/ConstantArcSizeFSA.java
new file mode 100644
index 0000000..2f6d412
--- /dev/null
+++ b/src/morfologik/fsa/ConstantArcSizeFSA.java
@@ -0,0 +1,134 @@
+package morfologik.fsa;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * An FSA with constant-size arc representation produced directly
+ * by {@link FSABuilder}.
+ *
+ * @see FSABuilder
+ */
+public final class ConstantArcSizeFSA extends FSA {
+ /** Size of the target address field (constant for the builder). */
+ public final static int TARGET_ADDRESS_SIZE = 4;
+
+ /** Size of the flags field (constant for the builder). */
+ public final static int FLAGS_SIZE = 1;
+
+ /** Size of the label field (constant for the builder). */
+ public final static int LABEL_SIZE = 1;
+
+ /**
+ * Size of a single arc structure.
+ */
+ public final static int ARC_SIZE = FLAGS_SIZE + LABEL_SIZE + TARGET_ADDRESS_SIZE;
+
+ /** Offset of the flags field inside an arc. */
+ public final static int FLAGS_OFFSET = 0;
+
+ /** Offset of the label field inside an arc. */
+ public final static int LABEL_OFFSET = FLAGS_SIZE;
+
+ /** Offset of the address field inside an arc. */
+ public final static int ADDRESS_OFFSET = LABEL_OFFSET + LABEL_SIZE;
+
+ /** A dummy address of the terminal state. */
+ final static int TERMINAL_STATE = 0;
+
+ /**
+ * An arc flag indicating the target node of an arc corresponds to a final
+ * state.
+ */
+ public final static int BIT_ARC_FINAL = 1 << 1;
+
+ /** An arc flag indicating the arc is last within its state. */
+ public final static int BIT_ARC_LAST = 1 << 0;
+
+ /**
+ * An epsilon state. The first and only arc of this state points either
+ * to the root or to the terminal state, indicating an empty automaton.
+ */
+ private final int epsilon;
+
+ /**
+ * FSA data, serialized as a byte array.
+ */
+ private final byte[] data;
+
+ /**
+ * @param data FSA data. There must be no trailing bytes after the last state.
+ */
+ ConstantArcSizeFSA(byte[] data, int epsilon) {
+ assert epsilon == 0 : "Epsilon is not zero?";
+
+ this.epsilon = epsilon;
+ this.data = data;
+ }
+
+ @Override
+ public int getRootNode() {
+ return getEndNode(getFirstArc(epsilon));
+ }
+
+ @Override
+ public int getFirstArc(int node) {
+ return node;
+ }
+
+ @Override
+ public int getArc(int node, byte label) {
+ for (int arc = getFirstArc(node); arc != 0; arc = getNextArc(arc)) {
+ if (getArcLabel(arc) == label)
+ return arc;
+ }
+ return 0;
+ }
+
+ @Override
+ public int getNextArc(int arc) {
+ if (isArcLast(arc))
+ return 0;
+ return arc + ARC_SIZE;
+ }
+
+ @Override
+ public byte getArcLabel(int arc) {
+ return data[arc + LABEL_OFFSET];
+ }
+
+ /**
+ * Fills the target state address of an arc.
+ */
+ private int getArcTarget(int arc) {
+ arc += ADDRESS_OFFSET;
+ return (data[arc]) << 24 |
+ (data[arc + 1] & 0xff) << 16 |
+ (data[arc + 2] & 0xff) << 8 |
+ (data[arc + 3] & 0xff);
+ }
+
+ @Override
+ public boolean isArcFinal(int arc) {
+ return (data[arc + FLAGS_OFFSET] & BIT_ARC_FINAL) != 0;
+ }
+
+ @Override
+ public boolean isArcTerminal(int arc) {
+ return getArcTarget(arc) == 0;
+ }
+
+ private boolean isArcLast(int arc) {
+ return (data[arc + FLAGS_OFFSET] & BIT_ARC_LAST) != 0;
+ }
+
+ @Override
+ public int getEndNode(int arc) {
+ return getArcTarget(arc);
+ }
+
+ @Override
+ public Set<FSAFlags> getFlags() {
+ return Collections.emptySet();
+ }
+}
diff --git a/src/morfologik/fsa/FSA.java b/src/morfologik/fsa/FSA.java
index 04deeee..28b44a2 100644
--- a/src/morfologik/fsa/FSA.java
+++ b/src/morfologik/fsa/FSA.java
@@ -1,361 +1,270 @@
package morfologik.fsa;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInput;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-import java.io.UnsupportedEncodingException;
+import java.io.*;
import java.nio.ByteBuffer;
-import java.util.Iterator;
-
-import morfologik.util.FileUtils;
+import java.util.*;
/**
- * This class implements Finite State Automaton traversal as described in Jan
- * Daciuk's <i>Incremental Construction of Finite-State Automata and
- * Transducers, and Their Use in the Natural Language Processing</i> (PhD
- * thesis, Technical University of Gdansk).
+ * This is a top abstract class for handling finite state automata. These
+ * automata are arc-based, a design described in Jan Daciuk's <i>Incremental
+ * Construction of Finite-State Automata and Transducers, and Their Use in the
+ * Natural Language Processing</i> (PhD thesis, Technical University of Gdansk).
*
* <p>
- * This is an abstract base class for all forms of binary storage present in Jan
- * Daciuk's FSA package.
+ * Concrete subclasses (implementations) provide varying tradeoffs and features:
+ * traversal speed vs. memory size, for example.
+ * </p>
+ *
+ * @see FSABuilder
*/
public abstract class FSA implements Iterable<ByteBuffer> {
/**
- * Version number for version 5 of the automaton.
- */
- public final static byte VERSION_5 = 5;
-
- /**
- * Dictionary version (derived from the combination of flags).
- */
- protected byte version;
-
- /**
- * The meaning of this field is not clear (check the FSA documentation).
- */
- protected byte filler;
-
- /**
- * Size of transition's destination node "address". This field may also have
- * different interpretation, or may not be used at all. It depends on the
- * combination of flags used for building FSA.
+ * @return Returns the identifier of the root node of this automaton.
+ * Returns 0 if the start node is also the end node (the automaton
+ * is empty).
*/
- protected byte gotoLength;
-
- /**
- * Annotation separator is a special character used for separating "tokens"
- * in a FSA. For instance an inflected form of a word may be separated from
- * the base form.
- */
- private byte annotationSeparator;
+ public abstract int getRootNode();
/**
- * The encoding (codepage) in which the dictionary has been compiled;
- * byte-to-character conversion scheme.
+ * @return Returns the identifier of the first arc leaving <code>node</code>
+ * or 0 if the node has no outgoing arcs.
*/
- private String dictionaryEncoding;
+ public abstract int getFirstArc(int node);
/**
- * Creates a new automaton reading the FSA automaton from an input stream.
- *
- * @param fsaStream
- * An input stream with FSA automaton.
- * @throws IOException
- * if the dictionary file cannot be read, or version of the file
- * is not supported.
+ * @return Returns the identifier of the next arc after <code>arc</code> and
+ * leaving <code>node</code>. Zero is returned if no more arcs are
+ * available for the node.
*/
- protected FSA(InputStream fsaStream, String dictionaryEncoding)
- throws IOException {
- if (fsaStream == null) {
- throw new IllegalArgumentException(
- "The input stream must not be null.");
- }
-
- if (dictionaryEncoding == null) {
- throw new IllegalArgumentException(
- "Dictionary encoding must not be null.");
- }
- this.dictionaryEncoding = dictionaryEncoding;
-
- /*
- * This implementation requires the length of stream to be known in
- * advance. Preload the dictionary entirely.
- */
- final byte[] fsa = readFully(fsaStream);
- DataInputStream input = null;
- try {
- input = new DataInputStream(new ByteArrayInputStream(fsa));
- readHeader(input, fsa.length);
- } finally {
- FileUtils.close(input);
- }
- }
+ public abstract int getNextArc(int arc);
/**
- * Returns the version number of the binary representation of this FSA.
- *
- * <p>
- * The version number is a derivation of combination of flags and is exactly
- * the same as in Jan Daciuk's FSA package.
+ * @return Returns the identifier of an arc leaving <code>node</code> and
+ * labeled with <code>label</code>. An identifier equal to 0 means
+ * the node has no outgoing arc labeled <code>label</code>.
*/
- public final int getVersion() {
- return version;
- }
+ public abstract int getArc(int node, byte label);
/**
- * Returns a set of flags for this FSA instance. Each flag is represented by
- * a unique bit in the integer returned. Therefore to check whether the
- * dictionary has been built using {@link FSAFlags#FLEXIBLE} flag, one must
- * perform a bitwise AND:
- * <code>boolean isFlexible = ((dict.getFlags() &amp; FSA.FSA_FLEXIBLE ) != 0)</code>
+ * Return the label associated with a given <code>arc</code>.
*/
- public final int getFlags() {
- return FSAHelpers.getFlags(version);
- }
+ public abstract byte getArcLabel(int arc);
/**
- * Return the annotation separator character, converted to a character
- * according to the encoding scheme passed in in the constructor of this
- * class.
+ * Returns <code>true</code> if the destination node at the end of this
+ * <code>arc</code> corresponds to an input sequence created when building
+ * this automaton.
*/
- public final char getAnnotationSeparator() {
- try {
- final String annotationChar = new String(
- new byte[] { this.annotationSeparator },
- this.dictionaryEncoding);
- if (annotationChar.length() != 1) {
- throw new RuntimeException(
- "Unexpected annotation character length (should be 1): "
- + annotationChar.length());
- }
- return annotationChar.charAt(0);
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- }
+ public abstract boolean isArcFinal(int arc);
/**
- * Return the filler character, converted to a character according to the
- * encoding scheme passed in in the constructor of this class.
+ * Returns <code>true</code> if this <code>arc</code> does not have a
+ * terminating node (@link {@link #getEndNode(int)} will throw an
+ * exception). Implies {@link #isArcFinal(int)}.
*/
- public final char getFillerCharacter() {
- try {
- final String fillerChar = new String(new byte[] { this.filler },
- this.dictionaryEncoding);
- if (fillerChar.length() != 1) {
- throw new RuntimeException(
- "Unexpected filler character length (should be 1): "
- + fillerChar.length());
- }
- return fillerChar.charAt(0);
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- }
+ public abstract boolean isArcTerminal(int arc);
/**
- * Returns the number of arcs in this automaton. <b>Depending on the
- * representation of the automaton, this method may take a long time to
- * finish.</b>
+ * Return the end node pointed to by a given <code>arc</code>. Terminal arcs
+ * (those that point to a terminal state) have no end node representation
+ * and throw a runtime exception.
*/
- public abstract int getNumberOfArcs();
+ public abstract int getEndNode(int arc);
/**
- * Returns the number of nodes in this automaton. <b>Depending on the
- * representation of the automaton, this method may take a long time to
- * finish.</b>
+ * Returns a set of flags for this FSA instance.
*/
- public abstract int getNumberOfNodes();
+ public abstract Set<FSAFlags> getFlags();
/**
- * Returns an object which can be used to walk the edges of this finite
- * state automaton and match arbitrary sequences against its states.
+ * Calculates the number of arcs of a given node. Unless really required,
+ * use the following idiom for looping through all arcs:
+ * <pre>
+ * for (int arc = fsa.getFirstArc(node); arc != 0; arc = fsa.getNextArc(arc)) {
+ * }
+ * </pre>
*/
- public FSATraversalHelper getTraversalHelper() {
- return new FSATraversalHelper(this);
+ public int getArcCount(int node) {
+ int count = 0;
+ for (int arc = getFirstArc(node); arc != 0; arc = getNextArc(arc)) {
+ count++;
+ }
+ return count;
}
/**
- * This static method will attempt to instantiate an appropriate
- * implementation of the FSA for the version found in file given in the
- * input argument.
+ * @return Returns the number of sequences reachable from the given state if
+ * the automaton was compiled with {@link FSAFlags#NUMBERS}. The size of
+ * the right language of the state, in other words.
*
- * @throws IOException
- * An exception is thrown if no corresponding FSA parser is
- * found or if the input file cannot be opened.
+ * @throws UnsupportedOperationException If the automaton was not compiled with
+ * {@link FSAFlags#NUMBERS}. The value can then be computed by manual count
+ * of {@link #getSequences(int)}.
*/
- public static FSA getInstance(File fsaFile, String dictionaryEncoding)
- throws IOException {
- if (!fsaFile.exists()) {
- throw new IOException("File does not exist: "
- + fsaFile.getAbsolutePath());
- }
-
- return getInstance(new FileInputStream(fsaFile), dictionaryEncoding);
+ public int getRightLanguageCount(int node) {
+ throw new UnsupportedOperationException("Automaton not compiled with " + FSAFlags.NUMBERS);
}
/**
- * This static method will attempt to instantiate an appropriate
- * implementation of the FSA for the version found in file given in the
- * input argument.
+ * Returns an iterator over all binary sequences starting at the given FSA
+ * state (node) and ending in final nodes. This corresponds to a set of
+ * suffixes of a given prefix from all sequences stored in the automaton.
*
- * @throws IOException
- * An exception is thrown if no corresponding FSA parser is
- * found or if the input file cannot be opened.
- */
- public static FSA getInstance(InputStream fsaStream,
- String dictionaryEncoding) throws IOException {
- if (fsaStream == null)
- throw new IllegalArgumentException("FSA stream cannot be null.");
-
- final PushbackInputStream stream = new PushbackInputStream(fsaStream, 5);
- final byte[] header = new byte[5];
- for (int bytesRead = 0; bytesRead < header.length;) {
- bytesRead += stream.read(header, bytesRead, header.length
- - bytesRead);
- }
-
- if (header[0] == '\\' && header[1] == 'f' && header[2] == 's'
- && header[3] == 'a') {
- // Read FSA version
- final byte version = header[4];
-
- // put back header info
- stream.unread(header);
-
- switch (version) {
- case 0x05:
- return new FSAVer5Impl(stream, dictionaryEncoding);
- }
-
- // No supporting implementation found.
- throw new IOException("Cannot read FSA: support for version "
- + version + " ("
- + FSAHelpers.flagsToString(FSAHelpers.getFlags(version))
- + ") not implemented.");
- } else {
- throw new IOException(
- "Cannot read FSA: file does not begin with a valid magic number.");
- }
- }
-
- /**
- * Reads a FSA header from a stream.
+ * <p>
+ * The returned iterator is a {@link ByteBuffer} whose contents changes on
+ * each call to {@link Iterator#next()}. The keep the contents between calls
+ * to {@link Iterator#next()}, one must copy the buffer to some other
+ * location.
+ * </p>
+ *
+ * <p>
+ * <b>Important.</b> It is guaranteed that the returned byte buffer is
+ * backed by a byte array and that the content of the byte buffer starts at
+ * the array's index 0.
+ * </p>
*
- * @throws IOException
- * If the stream is not a dictionary, or if the version is not
- * supported.
+ * @see Iterable
*/
- protected void readHeader(DataInput in, long fileSize) throws IOException {
- final byte[] magic = new byte[4];
- in.readFully(magic);
-
- if (magic[0] == '\\' && magic[1] == 'f' && magic[2] == 's'
- && magic[3] == 'a') {
- version = in.readByte();
- filler = in.readByte();
- annotationSeparator = in.readByte();
- gotoLength = in.readByte();
- } else {
- throw new IOException(
- "Cannot read FSA: File does not begin with a valid magic number.");
- }
+ public Iterable<ByteBuffer> getSequences(final int node) {
+ if (node == 0) {
+ return Collections.<ByteBuffer> emptyList();
+ }
+
+ return new Iterable<ByteBuffer>() {
+ public Iterator<ByteBuffer> iterator() {
+ return new FSAFinalStatesIterator(FSA.this, node);
+ }
+ };
}
/**
- * Reads all bytes from an input stream.
- *
- * @param stream
- * @return Returns an array of read bytes.
+ * An alias of calling {@link #iterator} directly ({@link FSA} is also
+ * {@link Iterable}).
*/
- protected byte[] readFully(InputStream stream) throws IOException {
- final ByteArrayOutputStream baos = new ByteArrayOutputStream(1024 * 16);
- final byte[] buffer = new byte[1024 * 8];
- int bytesCount;
- while ((bytesCount = stream.read(buffer)) > 0) {
- baos.write(buffer, 0, bytesCount);
- }
- return baos.toByteArray();
+ public final Iterable<ByteBuffer> getSequences() {
+ return getSequences(getRootNode());
}
/**
* Returns an iterator over all binary sequences starting from the initial
- * FSA state and ending in final nodes. The returned iterator is a
- * {@link ByteBuffer} that changes on each call to {@link Iterator#next()},
- * so if the content should be preserved, it must be copied somewhere else.
+ * FSA state (node) and ending in final nodes. The returned iterator is a
+ * {@link ByteBuffer} whose contents changes on each call to
+ * {@link Iterator#next()}. The keep the contents between calls to
+ * {@link Iterator#next()}, one must copy the buffer to some other location.
*
* <p>
- * It is guaranteed that the returned byte buffer is backed by a byte array
- * and that the content of the byte buffer starts at the array's index 0.
+ * <b>Important.</b> It is guaranteed that the returned byte buffer is
+ * backed by a byte array and that the content of the byte buffer starts at
+ * the array's index 0.
+ * </p>
+ *
+ * @see Iterable
*/
- public Iterator<ByteBuffer> iterator() {
- return getTraversalHelper().getAllSubsequences(getRootNode());
+ public final Iterator<ByteBuffer> iterator() {
+ return getSequences().iterator();
}
/**
- * Returns the identifier of the root node of this automaton. May return 0
- * if the start node is also the end node.
- *
- * @see #getTraversalHelper()
+ * Visit all states. The order of visiting is undefined. This method may be faster
+ * than traversing the automaton in post or preorder since it can scan states
+ * linearly. Returning false from {@link StateVisitor#accept(int)}
+ * immediately terminates the traversal.
*/
- public abstract int getRootNode();
+ public <T extends StateVisitor> T visitAllStates(T v) {
+ return visitInPostOrder(v);
+ }
/**
- * Returns the identifier of the first arc leaving <code>node</code> or 0 if
- * the node has no outgoing arcs.
- *
- * @see #getTraversalHelper()
+ * Same as {@link #visitInPostOrder(StateVisitor, int)},
+ * starting from root automaton node.
*/
- public abstract int getFirstArc(int node);
+ public <T extends StateVisitor> T visitInPostOrder(T v) {
+ return visitInPostOrder(v, getRootNode());
+ }
/**
- * Returns the identifier of an arc leaving <code>node</code> and labeled
- * with <code>label</code>. An identifier equal to 0 means the node has no
- * outgoing arc labeled <code>label</code>.
- *
- * @see #getTraversalHelper()
+ * Visits all states reachable from <code>node</code> in postorder.
+ * Returning false from {@link StateVisitor#accept(int)}
+ * immediately terminates the traversal.
*/
- public abstract int getArc(int node, byte label);
+ public <T extends StateVisitor> T visitInPostOrder(T v, int node) {
+ visitInPostOrder(v, node, new BitSet());
+ return v;
+ }
- /**
- * Returns the identifier of the next arc after <code>arc</code> and leaving
- * <code>node</code>. Zero is returned if no more arcs are available for the
- * node.
- *
- * @see #getTraversalHelper()
- */
- public abstract int getNextArc(int node, int arc);
+ /** Private recursion. */
+ private boolean visitInPostOrder(StateVisitor v, int node, BitSet visited) {
+ if (visited.get(node))
+ return true;
+ visited.set(node);
- /**
- * Return the end node pointed to by a given <code>arc</code>. Terminal arcs
- * (those that point to a terminal state) have no end node representation
- * and throw a runtime exception.
- *
- * @see #getTraversalHelper()
- */
- public abstract int getEndNode(int arc);
+ for (int arc = getFirstArc(node); arc != 0; arc = getNextArc(arc)) {
+ if (!isArcTerminal(arc)) {
+ if (!visitInPostOrder(v, getEndNode(arc), visited))
+ return false;
+ }
+ }
+
+ return v.accept(node);
+ }
/**
- * Return the label associated with a given <code>arc</code>.
+ * Same as {@link #visitInPreOrder(StateVisitor, int)}, starting from root automaton node.
*/
- public abstract byte getArcLabel(int arc);
+ public <T extends StateVisitor> T visitInPreOrder(T v) {
+ return visitInPreOrder(v, getRootNode());
+ }
/**
- * Returns <code>true</code> if the destination node at the end of this
- * <code>arc</code> corresponds to an input sequence created when building
- * this automaton.
+ * Visits all states in preorder. Returning false from {@link StateVisitor#accept(int)}
+ * skips traversal of all sub-states of a given state.
*/
- public abstract boolean isArcFinal(int arc);
+ public <T extends StateVisitor> T visitInPreOrder(T v, int node) {
+ visitInPreOrder(v, node, new BitSet());
+ return v;
+ }
+
+ /** Private recursion. */
+ private void visitInPreOrder(StateVisitor v, int node, BitSet visited) {
+ if (visited.get(node))
+ return;
+ visited.set(node);
+
+ if (v.accept(node)) {
+ for (int arc = getFirstArc(node); arc != 0; arc = getNextArc(arc)) {
+ if (!isArcTerminal(arc)) {
+ visitInPreOrder(v, getEndNode(arc), visited);
+ }
+ }
+ }
+ }
/**
- * Returns <code>true</code> if this <code>arc</code> does not have a
- * terminating node.
+ * A factory for reading automata in any of the supported versions. If
+ * possible, explicit constructors should be used.
+ *
+ * @see FSA5#FSA5(InputStream)
*/
- public abstract boolean isArcTerminal(int arc);
+ @SuppressWarnings("unchecked")
+ public static <T extends FSA> T read(InputStream in) throws IOException {
+ if (!in.markSupported()) {
+ in = new BufferedInputStream(in, Math.max(FSAHeader.MAX_HEADER_LENGTH + 1, 1024));
+ }
+
+ in.mark(FSAHeader.MAX_HEADER_LENGTH);
+ FSAHeader header = FSAHeader.read(in);
+ in.reset();
+
+ if (header.version == FSA5.VERSION)
+ return (T) new FSA5(in);
+
+ if (header.version == CFSA.VERSION)
+ return (T) new CFSA(in);
+
+ if (header.version == CFSA2.VERSION)
+ return (T) new CFSA2(in);
+
+ throw new IOException("Unsupported automaton version: "
+ + header.version);
+ }
} \ No newline at end of file
diff --git a/src/morfologik/fsa/FSA5.java b/src/morfologik/fsa/FSA5.java
new file mode 100644
index 0000000..d43f4d8
--- /dev/null
+++ b/src/morfologik/fsa/FSA5.java
@@ -0,0 +1,323 @@
+package morfologik.fsa;
+
+import static morfologik.fsa.FSAFlags.FLEXIBLE;
+import static morfologik.fsa.FSAFlags.NEXTBIT;
+import static morfologik.fsa.FSAFlags.NUMBERS;
+import static morfologik.fsa.FSAFlags.STOPBIT;
+import static morfologik.util.FileUtils.readFully;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * FSA binary format implementation for version 5.
+ *
+ * <p>
+ * Version 5 indicates the dictionary was built with these flags:
+ * {@link FSAFlags#FLEXIBLE}, {@link FSAFlags#STOPBIT} and
+ * {@link FSAFlags#NEXTBIT}. The internal representation of the FSA must
+ * therefore follow this description (please note this format describes only a
+ * single transition (arc), not the entire dictionary file).
+ *
+ * <pre>
+ * ---- this node header present only if automaton was compiled with NUMBERS option.
+ * Byte
+ * +-+-+-+-+-+-+-+-+\
+ * 0 | | | | | | | | | \ LSB
+ * +-+-+-+-+-+-+-+-+ +
+ * 1 | | | | | | | | | | number of strings recognized
+ * +-+-+-+-+-+-+-+-+ +----- by the automaton starting
+ * : : : : : : : : : | from this node.
+ * +-+-+-+-+-+-+-+-+ +
+ * ctl-1 | | | | | | | | | / MSB
+ * +-+-+-+-+-+-+-+-+/
+ *
+ * ---- remaining part of the node
+ *
+ * Byte
+ * +-+-+-+-+-+-+-+-+\
+ * 0 | | | | | | | | | +------ label
+ * +-+-+-+-+-+-+-+-+/
+ *
+ * +------------- node pointed to is next
+ * | +----------- the last arc of the node
+ * | | +--------- the arc is final
+ * | | |
+ * +-----------+
+ * | | | | |
+ * ___+___ | | | |
+ * / \ | | | |
+ * MSB LSB |
+ * 7 6 5 4 3 2 1 0 |
+ * +-+-+-+-+-+-+-+-+ |
+ * 1 | | | | | | | | | \ \
+ * +-+-+-+-+-+-+-+-+ \ \ LSB
+ * +-+-+-+-+-+-+-+-+ +
+ * 2 | | | | | | | | | |
+ * +-+-+-+-+-+-+-+-+ |
+ * 3 | | | | | | | | | +----- target node address (in bytes)
+ * +-+-+-+-+-+-+-+-+ | (not present except for the byte
+ * : : : : : : : : : | with flags if the node pointed to
+ * +-+-+-+-+-+-+-+-+ + is next)
+ * gtl | | | | | | | | | / MSB
+ * +-+-+-+-+-+-+-+-+ /
+ * gtl+1 (gtl = gotoLength)
+ * </pre>
+ */
+public final class FSA5 extends FSA {
+ /**
+ * Default filler byte.
+ */
+ public final static byte DEFAULT_FILLER = '_';
+
+ /**
+ * Default annotation byte.
+ */
+ public final static byte DEFAULT_ANNOTATION = '+';
+
+ /**
+ * Automaton version as in the file header.
+ */
+ public static final byte VERSION = 5;
+
+ /**
+ * Bit indicating that an arc corresponds to the last character of a
+ * sequence available when building the automaton.
+ */
+ public static final int BIT_FINAL_ARC = 1 << 0;
+
+ /**
+ * Bit indicating that an arc is the last one of the node's list and the
+ * following one belongs to another node.
+ */
+ public static final int BIT_LAST_ARC = 1 << 1;
+
+ /**
+ * Bit indicating that the target node of this arc follows it in the
+ * compressed automaton structure (no goto field).
+ */
+ public static final int BIT_TARGET_NEXT = 1 << 2;
+
+ /**
+ * An offset in the arc structure, where the address and flags field begins.
+ * In version 5 of FSA automata, this value is constant (1, skip label).
+ */
+ public final static int ADDRESS_OFFSET = 1;
+
+ /**
+ * An array of bytes with the internal representation of the automaton.
+ * Please see the documentation of this class for more information on how
+ * this structure is organized.
+ */
+ public final byte[] arcs;
+
+ /**
+ * The length of the node header structure (if the automaton was compiled with
+ * <code>NUMBERS</code> option). Otherwise zero.
+ */
+ public final int nodeDataLength;
+
+ /**
+ * Flags for this automaton version.
+ */
+ private final Set<FSAFlags> flags;
+
+ /**
+ * Number of bytes each address takes in full, expanded form (goto length).
+ */
+ public final int gtl;
+
+ /** Filler character. */
+ public final byte filler;
+
+ /** Annotation character. */
+ public final byte annotation;
+
+ /**
+ * Read and wrap a binary automaton in FSA version 5.
+ */
+ public FSA5(InputStream fsaStream) throws IOException {
+ // Read the header first.
+ final FSAHeader header = FSAHeader.read(fsaStream);
+
+ // Ensure we have version 5.
+ if (header.version != VERSION) {
+ throw new IOException("This class can read FSA version 5 only: " + header.version);
+ }
+
+ /*
+ * Determine if the automaton was compiled with NUMBERS. If so, modify
+ * ctl and goto fields accordingly.
+ */
+ flags = EnumSet.of(FLEXIBLE, STOPBIT, NEXTBIT);
+ if ((header.gtl & 0xf0) != 0) {
+ flags.add(NUMBERS);
+ }
+
+ this.nodeDataLength = (header.gtl >>> 4) & 0x0f;
+ this.gtl = header.gtl & 0x0f;
+
+ this.filler = header.filler;
+ this.annotation = header.annotation;
+
+ arcs = readFully(fsaStream);
+ }
+
+ /**
+ * Returns the start node of this automaton.
+ */
+ @Override
+ public int getRootNode() {
+ // Skip dummy node marking terminating state.
+ final int epsilonNode = skipArc(getFirstArc(0));
+
+ // And follow the epsilon node's first (and only) arc.
+ return getDestinationNodeOffset(getFirstArc(epsilonNode));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final int getFirstArc(int node) {
+ return nodeDataLength + node;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final int getNextArc(int arc) {
+ if (isArcLast(arc))
+ return 0;
+ else
+ return skipArc(arc);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getArc(int node, byte label) {
+ for (int arc = getFirstArc(node); arc != 0; arc = getNextArc(arc)) {
+ if (getArcLabel(arc) == label)
+ return arc;
+ }
+
+ // An arc labeled with "label" not found.
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getEndNode(int arc) {
+ final int nodeOffset = getDestinationNodeOffset(arc);
+ assert nodeOffset != 0 : "No target node for terminal arcs.";
+ return nodeOffset;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public byte getArcLabel(int arc) {
+ return arcs[arc];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isArcFinal(int arc) {
+ return (arcs[arc + ADDRESS_OFFSET] & BIT_FINAL_ARC) != 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isArcTerminal(int arc) {
+ return (0 == getDestinationNodeOffset(arc));
+ }
+
+ /**
+ * Returns the number encoded at the given node. The number equals the count
+ * of the set of suffixes reachable from <code>node</code> (called its right
+ * language).
+ */
+ @Override
+ public int getRightLanguageCount(int node) {
+ assert getFlags().contains(FSAFlags.NUMBERS): "This FSA was not compiled with NUMBERS.";
+ return decodeFromBytes(arcs, node, nodeDataLength);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>For this automaton version, an additional {@link FSAFlags#NUMBERS} flag
+ * may be set to indicate the automaton contains extra fields for each node.</p>
+ */
+ @Override
+ public Set<FSAFlags> getFlags() {
+ return Collections.unmodifiableSet(flags);
+ }
+
+ /**
+ * Returns <code>true</code> if this arc has <code>LAST</code> bit set.
+ *
+ * @see #BIT_LAST_ARC
+ */
+ public boolean isArcLast(int arc) {
+ return (arcs[arc + ADDRESS_OFFSET] & BIT_LAST_ARC) != 0;
+ }
+
+ /**
+ * @see #BIT_TARGET_NEXT
+ */
+ public boolean isNextSet(int arc) {
+ return (arcs[arc + ADDRESS_OFFSET] & BIT_TARGET_NEXT) != 0;
+ }
+
+ /**
+ * Returns an n-byte integer encoded in byte-packed representation.
+ */
+ static final int decodeFromBytes(
+ final byte[] arcs, final int start, final int n)
+ {
+ int r = 0;
+ for (int i = n; --i >= 0;) {
+ r = r << 8 | (arcs[start + i] & 0xff);
+ }
+ return r;
+ }
+
+ /**
+ * Returns the address of the node pointed to by this arc.
+ */
+ final int getDestinationNodeOffset(int arc) {
+ if (isNextSet(arc)) {
+ /* The destination node follows this arc in the array. */
+ return skipArc(arc);
+ } else {
+ /*
+ * The destination node address has to be extracted from the arc's
+ * goto field.
+ */
+ return decodeFromBytes(arcs, arc + ADDRESS_OFFSET, gtl) >>> 3;
+ }
+ }
+
+ /**
+ * Read the arc's layout and skip as many bytes, as needed.
+ */
+ private int skipArc(int offset) {
+ return offset + (isNextSet(offset)
+ ? 1 + 1 /* label + flags */
+ : 1 + gtl /* label + flags/address */);
+ }
+} \ No newline at end of file
diff --git a/src/morfologik/fsa/FSA5Serializer.java b/src/morfologik/fsa/FSA5Serializer.java
new file mode 100644
index 0000000..be017a4
--- /dev/null
+++ b/src/morfologik/fsa/FSA5Serializer.java
@@ -0,0 +1,334 @@
+package morfologik.fsa;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.*;
+
+import morfologik.tools.IMessageLogger;
+
+import com.carrotsearch.hppc.*;
+import com.carrotsearch.hppc.BitSet;
+
+import static morfologik.fsa.FSAFlags.*;
+
+/**
+ * Serializes in-memory {@link FSA} graphs to a binary format compatible with
+ * Jan Daciuk's <code>fsa</code>'s package <code>FSA5</code> format.
+ *
+ * <p>
+ * It is possible to serialize the automaton with numbers required for perfect
+ * hashing. See {@link #withNumbers()} method.
+ * </p>
+ *
+ * @see FSA5
+ * @see FSA#read(java.io.InputStream)
+ */
+public final class FSA5Serializer implements FSASerializer {
+ /**
+ * Maximum number of bytes for a serialized arc.
+ */
+ private final static int MAX_ARC_SIZE = 1 + 5;
+
+ /**
+ * Maximum number of bytes for per-node data.
+ */
+ private final static int MAX_NODE_DATA_SIZE = 16;
+
+ /**
+ * Number of bytes for the arc's flags header (arc representation without
+ * the goto address).
+ */
+ private final static int SIZEOF_FLAGS = 1;
+
+ /**
+ * Supported flags.
+ */
+ private final static EnumSet<FSAFlags> flags = EnumSet.of(NUMBERS, SEPARATORS, FLEXIBLE, STOPBIT, NEXTBIT);
+
+ /**
+ * @see FSA5#filler
+ */
+ public byte fillerByte = FSA5.DEFAULT_FILLER;
+
+ /**
+ * @see FSA5#annotation
+ */
+ public byte annotationByte = FSA5.DEFAULT_ANNOTATION;
+
+ /**
+ * <code>true</code> if we should serialize with numbers.
+ *
+ * @see #withNumbers()
+ */
+ private boolean withNumbers;
+
+ /**
+ * A hash map of [state, offset] pairs.
+ */
+ private IntIntOpenHashMap offsets = new IntIntOpenHashMap();
+
+ /**
+ * A hash map of [state, right-language-count] pairs.
+ */
+ private IntIntOpenHashMap numbers = new IntIntOpenHashMap();
+
+ /**
+ * Serialize the automaton with the number of right-language sequences in
+ * each node. This is required to implement perfect hashing. The numbering
+ * also preserves the order of input sequences.
+ *
+ * @return Returns the same object for easier call chaining.
+ */
+ public FSA5Serializer withNumbers() {
+ withNumbers = true;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public FSA5Serializer withFiller(byte filler) {
+ this.fillerByte = filler;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public FSA5Serializer withAnnotationSeparator(byte annotationSeparator) {
+ this.annotationByte = annotationSeparator;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public FSASerializer withLogger(IMessageLogger logger) {
+ return this;
+ }
+
+ /**
+ * Serialize root state <code>s</code> to an output stream in
+ * <code>FSA5</code> format.
+ *
+ * @see #withNumbers
+ * @return Returns <code>os</code> for chaining.
+ */
+ @Override
+ public <T extends OutputStream> T serialize(final FSA fsa, T os)
+ throws IOException {
+
+ // Prepare space for arc offsets and linearize all the states.
+ int[] linearized = linearize(fsa);
+
+ /*
+ * Calculate the number of bytes required for the node data, if
+ * serializing with numbers.
+ */
+ int nodeDataLength = 0;
+ if (withNumbers) {
+ this.numbers = FSAUtils.rightLanguageForAllStates(fsa);
+ int maxNumber = numbers.get(fsa.getRootNode());
+ while (maxNumber > 0) {
+ nodeDataLength++;
+ maxNumber >>>= 8;
+ }
+ }
+
+ // Calculate minimal goto length.
+ int gtl = 1;
+ while (true) {
+ // First pass: calculate offsets of states.
+ if (!emitArcs(fsa, null, linearized, gtl, nodeDataLength)) {
+ gtl++;
+ continue;
+ }
+
+ // Second pass: check if goto overflows anywhere.
+ if (emitArcs(fsa, null, linearized, gtl, nodeDataLength))
+ break;
+
+ gtl++;
+ }
+
+ /*
+ * Emit the header.
+ */
+ os.write(new byte[] { '\\', 'f', 's', 'a' });
+ os.write(FSA5.VERSION);
+ os.write(fillerByte);
+ os.write(annotationByte);
+ os.write((nodeDataLength << 4) | gtl);
+
+ /*
+ * Emit the automaton.
+ */
+ boolean gtlUnchanged = emitArcs(fsa, os, linearized, gtl, nodeDataLength);
+ assert gtlUnchanged : "gtl changed in the final pass.";
+
+ return os;
+ }
+
+ /**
+ * Return supported flags.
+ */
+ @Override
+ public Set<FSAFlags> getFlags() {
+ return flags;
+ }
+
+ /**
+ * Linearization of states.
+ */
+ private int[] linearize(final FSA fsa) {
+ int[] linearized = new int[0];
+ int last = 0;
+
+ BitSet visited = new BitSet();
+ IntStack nodes = new IntStack();
+ nodes.push(fsa.getRootNode());
+
+ while (!nodes.isEmpty()) {
+ final int node = nodes.pop();
+ if (visited.get(node))
+ continue;
+
+ if (last >= linearized.length) {
+ linearized = Arrays.copyOf(linearized, linearized.length + 100000);
+ }
+
+ visited.set(node);
+ linearized[last++] = node;
+
+ for (int arc = fsa.getFirstArc(node); arc != 0; arc = fsa.getNextArc(arc)) {
+ if (!fsa.isArcTerminal(arc)) {
+ int target = fsa.getEndNode(arc);
+ if (!visited.get(target))
+ nodes.push(target);
+ }
+ }
+ }
+
+ return Arrays.copyOf(linearized, last);
+ }
+
+ /**
+ * Update arc offsets assuming the given goto length.
+ */
+ private boolean emitArcs(FSA fsa, OutputStream os, int[] linearized,
+ int gtl, int nodeDataLength) throws IOException {
+ final ByteBuffer bb = ByteBuffer.allocate(Math.max(MAX_NODE_DATA_SIZE,
+ MAX_ARC_SIZE));
+
+ int offset = 0;
+
+ // Add dummy terminal state.
+ offset += emitNodeData(bb, os, nodeDataLength, 0);
+ offset += emitArc(bb, os, gtl, 0, (byte) 0, 0);
+
+ // Add epsilon state.
+ offset += emitNodeData(bb, os, nodeDataLength, 0);
+ if (fsa.getRootNode() != 0)
+ offset += emitArc(bb, os, gtl, FSA5.BIT_LAST_ARC | FSA5.BIT_TARGET_NEXT, (byte) '^', 0);
+ else
+ offset += emitArc(bb, os, gtl, FSA5.BIT_LAST_ARC , (byte) '^', 0);
+
+ int maxStates = linearized.length;
+ for (int j = 0; j < maxStates; j++) {
+ final int s = linearized[j];
+
+ if (os == null) {
+ offsets.put(s, offset);
+ } else {
+ assert offsets.get(s) == offset : s + " " + offsets.get(s) + " " + offset;
+ }
+
+ offset += emitNodeData(bb, os, nodeDataLength, withNumbers ? numbers.get(s) : 0);
+
+ for (int arc = fsa.getFirstArc(s); arc != 0; arc = fsa.getNextArc(arc)) {
+ int targetOffset;
+ final int target;
+ if (fsa.isArcTerminal(arc)) {
+ targetOffset = 0;
+ target = 0;
+ } else {
+ target = fsa.getEndNode(arc);
+ targetOffset = offsets.get(target);
+ }
+
+ int flags = 0;
+ if (fsa.isArcFinal(arc)) {
+ flags |= FSA5.BIT_FINAL_ARC;
+ }
+
+ if (fsa.getNextArc(arc) == 0) {
+ flags |= FSA5.BIT_LAST_ARC;
+
+ if (j + 1 < maxStates && target == linearized[j + 1]
+ && targetOffset != 0) {
+ flags |= FSA5.BIT_TARGET_NEXT;
+ targetOffset = 0;
+ }
+ }
+
+ int bytes = emitArc(bb, os, gtl, flags, fsa.getArcLabel(arc), targetOffset);
+ if (bytes < 0)
+ // gtl too small. interrupt eagerly.
+ return false;
+
+ offset += bytes;
+ }
+ }
+
+ return true;
+ }
+
+ /** */
+ private int emitArc(ByteBuffer bb, OutputStream os, int gtl, int flags, byte label, int targetOffset)
+ throws IOException
+ {
+ int arcBytes = (flags & FSA5.BIT_TARGET_NEXT) != 0 ? SIZEOF_FLAGS : gtl;
+
+ flags |= (targetOffset << 3);
+ bb.put(label);
+ for (int b = 0; b < arcBytes; b++) {
+ bb.put((byte) flags);
+ flags >>>= 8;
+ }
+
+ if (flags != 0) {
+ // gtl too small. interrupt eagerly.
+ return -1;
+ }
+
+ bb.flip();
+ int bytes = bb.remaining();
+ if (os != null) {
+ os.write(bb.array(), bb.position(), bb.remaining());
+ }
+ bb.clear();
+
+ return bytes;
+ }
+
+ /** */
+ private int emitNodeData(ByteBuffer bb, OutputStream os,
+ int nodeDataLength, int number) throws IOException {
+ if (nodeDataLength > 0 && os != null) {
+ for (int i = 0; i < nodeDataLength; i++) {
+ bb.put((byte) number);
+ number >>>= 8;
+ }
+
+ bb.flip();
+ os.write(bb.array(), bb.position(), bb.remaining());
+ bb.clear();
+ }
+
+ return nodeDataLength;
+ }
+}
diff --git a/src/morfologik/fsa/FSABuilder.java b/src/morfologik/fsa/FSABuilder.java
new file mode 100644
index 0000000..0cf7cc0
--- /dev/null
+++ b/src/morfologik/fsa/FSABuilder.java
@@ -0,0 +1,486 @@
+package morfologik.fsa;
+
+import java.util.*;
+
+import morfologik.util.Arrays;
+
+import static morfologik.fsa.ConstantArcSizeFSA.*;
+
+/**
+ * Fast, memory-conservative finite state automaton builder, returning a
+ * byte-serialized {@link ConstantArcSizeFSA} (a tradeoff between construction
+ * speed and memory consumption).
+ */
+public final class FSABuilder {
+ /**
+ * Debug and information constants.
+ *
+ * @see FSABuilder#getInfo()
+ */
+ public enum InfoEntry {
+ SERIALIZATION_BUFFER_SIZE("Serialization buffer size"),
+ SERIALIZATION_BUFFER_REALLOCATIONS("Serialization buffer reallocs"),
+ CONSTANT_ARC_AUTOMATON_SIZE("Constant arc FSA size"),
+ MAX_ACTIVE_PATH_LENGTH("Max active path"),
+ STATE_REGISTRY_TABLE_SLOTS("Registry hash slots"),
+ STATE_REGISTRY_SIZE("Registry hash entries"),
+ ESTIMATED_MEMORY_CONSUMPTION_MB("Estimated mem consumption (MB)");
+
+ private final String stringified;
+
+ InfoEntry(String stringified) {
+ this.stringified = stringified;
+ }
+
+ @Override
+ public String toString() {
+ return stringified;
+ }
+ }
+
+ /** A megabyte. */
+ private final static int MB = 1024 * 1024;
+
+ /**
+ * Internal serialized FSA buffer expand ratio.
+ */
+ private final static int BUFFER_GROWTH_SIZE = 5 * MB;
+
+ /**
+ * Maximum number of labels from a single state.
+ */
+ private final static int MAX_LABELS = 256;
+
+ /**
+ * Comparator comparing full byte arrays consistently with
+ * {@link #compare(byte[], int, int, byte[], int, int)}.
+ */
+ public static final Comparator<byte[]> LEXICAL_ORDERING = new Comparator<byte[]>() {
+ public int compare(byte[] o1, byte[] o2) {
+ return FSABuilder.compare(o1, 0, o1.length, o2, 0, o2.length);
+ }
+ };
+
+ /**
+ * Internal serialized FSA buffer expand ratio.
+ */
+ private final int bufferGrowthSize;
+
+ /**
+ * Holds serialized and mutable states. Each state is a sequential list of
+ * arcs, the last arc is marked with {@link #BIT_ARC_LAST}.
+ */
+ private byte[] serialized = new byte[0];
+
+ /**
+ * Number of bytes already taken in {@link #serialized}. Start from 1 to
+ * keep 0 a sentinel value (for the hash set and final state).
+ */
+ private int size;
+
+ /**
+ * States on the "active path" (still mutable). Values are addresses of each
+ * state's first arc.
+ */
+ private int[] activePath = new int[0];
+
+ /**
+ * Current length of the active path.
+ */
+ private int activePathLen;
+
+ /**
+ * The next offset at which an arc will be added to the given state on
+ * {@link #activePath}.
+ */
+ private int[] nextArcOffset = new int[0];
+
+ /**
+ * Root state. If negative, the automaton has been built already and cannot be extended.
+ */
+ private int root;
+
+ /**
+ * An epsilon state. The first and only arc of this state points either
+ * to the root or to the terminal state, indicating an empty automaton.
+ */
+ private int epsilon;
+
+ /**
+ * Hash set of state addresses in {@link #serialized}, hashed by
+ * {@link #hash(int, int)}. Zero reserved for an unoccupied slot.
+ */
+ private int[] hashSet = new int[2];
+
+ /**
+ * Number of entries currently stored in {@link #hashSet}.
+ */
+ private int hashSize = 0;
+
+ /**
+ * Previous sequence added to the automaton in {@link #add(byte[], int, int)}. Used in assertions only.
+ */
+ private byte [] previous;
+
+ /**
+ * Information about the automaton and its compilation.
+ */
+ private TreeMap<InfoEntry, Object> info;
+
+ /**
+ * {@link #previous} sequence's length, used in assertions only.
+ */
+ private int previousLength;
+
+ /** */
+ public FSABuilder() {
+ this(BUFFER_GROWTH_SIZE);
+ }
+
+ /** */
+ public FSABuilder(int bufferGrowthSize) {
+ this.bufferGrowthSize = Math.max(bufferGrowthSize, ARC_SIZE * MAX_LABELS);
+
+ // Allocate epsilon state.
+ epsilon = allocateState(1);
+ serialized[epsilon + FLAGS_OFFSET] |= BIT_ARC_LAST;
+
+ // Allocate root, with an initial empty set of output arcs.
+ expandActivePath(1);
+ root = activePath[0];
+ }
+
+ /**
+ * Add a single sequence of bytes to the FSA. The input must be lexicographically greater
+ * than any previously added sequence.
+ */
+ public void add(byte[] sequence, int start, int len) {
+ assert serialized != null : "Automaton already built.";
+ assert previous == null || len == 0 || compare(previous, 0, previousLength, sequence, start, len) <= 0 :
+ "Input must be sorted: "
+ + Arrays.toString(previous, 0, previousLength) + " >= "
+ + Arrays.toString(sequence, start, len);
+ assert setPrevious(sequence, start, len);
+
+ // Determine common prefix length.
+ final int commonPrefix = commonPrefix(sequence, start, len);
+
+ // Make room for extra states on active path, if needed.
+ expandActivePath(len);
+
+ // Freeze all the states after the common prefix.
+ for (int i = activePathLen - 1; i > commonPrefix; i--) {
+ final int frozenState = freezeState(i);
+ setArcTarget(nextArcOffset[i - 1] - ARC_SIZE, frozenState);
+ nextArcOffset[i] = activePath[i];
+ }
+
+ // Create arcs to new suffix states.
+ for (int i = commonPrefix + 1, j = start + commonPrefix; i <= len; i++) {
+ final int p = nextArcOffset[i - 1];
+
+ serialized[p + FLAGS_OFFSET] = (byte) (i == len ? BIT_ARC_FINAL : 0);
+ serialized[p + LABEL_OFFSET] = sequence[j++];
+ setArcTarget(p, i == len ? TERMINAL_STATE : activePath[i]);
+
+ nextArcOffset[i - 1] = p + ARC_SIZE;
+ }
+
+ // Save last sequence's length so that we don't need to calculate it again.
+ this.activePathLen = len;
+ }
+
+ /** Number of serialization buffer reallocations. */
+ private int serializationBufferReallocations;
+
+ /**
+ * Complete the automaton.
+ */
+ public FSA complete() {
+ add(new byte[0], 0, 0);
+
+ if (nextArcOffset[0] - activePath[0] == 0) {
+ // An empty FSA.
+ setArcTarget(epsilon, TERMINAL_STATE);
+ } else {
+ // An automaton with at least a single arc from root.
+ root = freezeState(0);
+ setArcTarget(epsilon, root);
+ }
+
+ info = new TreeMap<InfoEntry, Object>();
+ info.put(InfoEntry.SERIALIZATION_BUFFER_SIZE, serialized.length);
+ info.put(InfoEntry.SERIALIZATION_BUFFER_REALLOCATIONS, serializationBufferReallocations);
+ info.put(InfoEntry.CONSTANT_ARC_AUTOMATON_SIZE, size);
+ info.put(InfoEntry.MAX_ACTIVE_PATH_LENGTH, activePath.length);
+ info.put(InfoEntry.STATE_REGISTRY_TABLE_SLOTS, hashSet.length);
+ info.put(InfoEntry.STATE_REGISTRY_SIZE, hashSize);
+ info.put(InfoEntry.ESTIMATED_MEMORY_CONSUMPTION_MB,
+ (this.serialized.length + this.hashSet.length * 4) / (double) MB);
+
+ final FSA fsa = new ConstantArcSizeFSA(java.util.Arrays.copyOf(this.serialized, this.size), epsilon);
+ this.serialized = null;
+ this.hashSet = null;
+ return fsa;
+ }
+
+ /**
+ * Build a minimal, deterministic automaton from a sorted list of byte sequences.
+ */
+ public static FSA build(byte[][] input) {
+ final FSABuilder builder = new FSABuilder();
+
+ for (byte [] chs : input)
+ builder.add(chs, 0, chs.length);
+
+ return builder.complete();
+ }
+
+ /**
+ * Build a minimal, deterministic automaton from an iterable list of byte sequences.
+ */
+ public static FSA build(Iterable<byte[]> input) {
+ final FSABuilder builder = new FSABuilder();
+
+ for (byte [] chs : input)
+ builder.add(chs, 0, chs.length);
+
+ return builder.complete();
+ }
+
+ /**
+ * Return various statistics concerning the FSA and its compilation.
+ */
+ public Map<InfoEntry, Object> getInfo() {
+ return info;
+ }
+
+ /** Is this arc the state's last? */
+ private boolean isArcLast(int arc) {
+ return (serialized[arc + FLAGS_OFFSET] & BIT_ARC_LAST) != 0;
+ }
+
+ /** Is this arc final? */
+ private boolean isArcFinal(int arc) {
+ return (serialized[arc + FLAGS_OFFSET] & BIT_ARC_FINAL) != 0;
+ }
+
+ /** Get label's arc. */
+ private byte getArcLabel(int arc) {
+ return serialized[arc + LABEL_OFFSET];
+ }
+
+ /**
+ * Fills the target state address of an arc.
+ */
+ private void setArcTarget(int arc, int state) {
+ arc += ADDRESS_OFFSET + TARGET_ADDRESS_SIZE;
+ for (int i = 0; i < TARGET_ADDRESS_SIZE; i++) {
+ serialized[--arc] = (byte) state;
+ state >>>= 8;
+ }
+ }
+
+ /**
+ * Returns the address of an arc.
+ */
+ private int getArcTarget(int arc) {
+ arc += ADDRESS_OFFSET;
+ return (serialized[arc]) << 24 |
+ (serialized[arc + 1] & 0xff) << 16 |
+ (serialized[arc + 2] & 0xff) << 8 |
+ (serialized[arc + 3] & 0xff);
+ }
+
+ /**
+ * @return The number of common prefix characters with the previous
+ * sequence.
+ */
+ private int commonPrefix(byte[] sequence, int start, int len) {
+ // Empty root state case.
+ final int max = Math.min(len, activePathLen);
+ int i;
+ for (i = 0; i < max; i++) {
+ final int lastArc = nextArcOffset[i] - ARC_SIZE;
+ if (sequence[start++] != getArcLabel(lastArc)) {
+ break;
+ }
+ }
+
+ return i;
+ }
+
+ /**
+ * Freeze a state: try to find an equivalent state in the interned states
+ * dictionary first, if found, return it, otherwise, serialize the mutable
+ * state at <code>activePathIndex</code> and return it.
+ */
+ private int freezeState(final int activePathIndex) {
+ final int start = activePath[activePathIndex];
+ final int end = nextArcOffset[activePathIndex];
+ final int len = end - start;
+
+ // Set the last arc flag on the current active path's state.
+ serialized[end - ARC_SIZE + FLAGS_OFFSET] |= BIT_ARC_LAST;
+
+ // Try to locate a state with an identical content in the hash set.
+ final int bucketMask = (hashSet.length - 1);
+ int slot = hash(start, len) & bucketMask;
+ for (int i = 0;;) {
+ int state = hashSet[slot];
+ if (state == 0) {
+ state = hashSet[slot] = serialize(activePathIndex);
+ if (++hashSize > hashSet.length / 2)
+ expandAndRehash();
+ return state;
+ } else if (equivalent(state, start, len)) {
+ return state;
+ }
+
+ slot = (slot + (++i)) & bucketMask;
+ }
+ }
+
+ /**
+ * Reallocate and rehash the hash set.
+ */
+ private void expandAndRehash() {
+ final int[] newHashSet = new int[hashSet.length * 2];
+ final int bucketMask = (newHashSet.length - 1);
+
+ for (int j = 0; j < hashSet.length; j++) {
+ final int state = hashSet[j];
+ if (state > 0) {
+ int slot = hash(state, stateLength(state)) & bucketMask;
+ for (int i = 0; newHashSet[slot] > 0;) {
+ slot = (slot + (++i)) & bucketMask;
+ }
+ newHashSet[slot] = state;
+ }
+ }
+ this.hashSet = newHashSet;
+ }
+
+ /**
+ * The total length of the serialized state data (all arcs).
+ */
+ private int stateLength(int state) {
+ int arc = state;
+ while (!isArcLast(arc)) {
+ arc += ARC_SIZE;
+ }
+ return arc - state + ARC_SIZE;
+ }
+
+ /** Return <code>true</code> if two regions in {@link #serialized} are identical. */
+ private boolean equivalent(int start1, int start2, int len) {
+ if (start1 + len > size || start2 + len > size)
+ return false;
+
+ while (len-- > 0)
+ if (serialized[start1++] != serialized[start2++])
+ return false;
+
+ return true;
+ }
+
+ /**
+ * Serialize a given state on the active path.
+ */
+ private int serialize(final int activePathIndex) {
+ expandBuffers();
+
+ final int newState = size;
+ final int start = activePath[activePathIndex];
+ final int len = nextArcOffset[activePathIndex] - start;
+ System.arraycopy(serialized, start, serialized, newState, len);
+
+ size += len;
+ return newState;
+ }
+
+ /**
+ * Hash code of a fragment of {@link #serialized} array.
+ */
+ private int hash(int start, int byteCount) {
+ assert byteCount % ARC_SIZE == 0 : "Not an arc multiply?";
+
+ int h = 0;
+ for (int arcs = byteCount / ARC_SIZE; --arcs >= 0; start += ARC_SIZE) {
+ h = 17 * h + getArcLabel(start);
+ h = 17 * h + getArcTarget(start);
+ if (isArcFinal(start)) h += 17;
+ }
+
+ return h;
+ }
+
+ /**
+ * Append a new mutable state to the active path.
+ */
+ private void expandActivePath(int size) {
+ if (activePath.length < size) {
+ final int p = activePath.length;
+ activePath = java.util.Arrays.copyOf(activePath, size);
+ nextArcOffset = java.util.Arrays.copyOf(nextArcOffset, size);
+
+ for (int i = p; i < size; i++) {
+ nextArcOffset[i] = activePath[i] =
+ allocateState(/* assume max labels count */ MAX_LABELS);
+ }
+ }
+ }
+
+ /**
+ * Expand internal buffers for the next state.
+ */
+ private void expandBuffers() {
+ if (this.serialized.length < size + ARC_SIZE * MAX_LABELS) {
+ serialized = java.util.Arrays.copyOf(serialized, serialized.length + bufferGrowthSize);
+ serializationBufferReallocations++;
+ }
+ }
+
+ /**
+ * Allocate space for a state with the given number of outgoing labels.
+ *
+ * @return state offset
+ */
+ private int allocateState(int labels) {
+ expandBuffers();
+ final int state = size;
+ size += labels * ARC_SIZE;
+ return state;
+ }
+
+ /**
+ * Copy <code>current</code> into an internal buffer.
+ */
+ private boolean setPrevious(byte [] sequence, int start, int length) {
+ if (previous == null || previous.length < length) {
+ previous = new byte [length];
+ }
+
+ System.arraycopy(sequence, start, previous, 0, length);
+ previousLength = length;
+ return true;
+ }
+
+ /**
+ * Lexicographic order of input sequences. By default, consistent with the "C" sort
+ * (absolute value of bytes, 0-255).
+ */
+ public static int compare(byte [] s1, int start1, int lens1,
+ byte [] s2, int start2, int lens2) {
+ final int max = Math.min(lens1, lens2);
+
+ for (int i = 0; i < max; i++) {
+ final byte c1 = s1[start1++];
+ final byte c2 = s2[start2++];
+ if (c1 != c2)
+ return (c1 & 0xff) - (c2 & 0xff);
+ }
+
+ return lens1 - lens2;
+ }
+}
diff --git a/src/morfologik/fsa/FSAFinalStatesIterator.java b/src/morfologik/fsa/FSAFinalStatesIterator.java
index 6078771..9e381f4 100644
--- a/src/morfologik/fsa/FSAFinalStatesIterator.java
+++ b/src/morfologik/fsa/FSAFinalStatesIterator.java
@@ -1,14 +1,11 @@
package morfologik.fsa;
import java.nio.ByteBuffer;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import morfologik.util.Arrays;
+import java.util.*;
/**
- * An iterator that traverses all final states reachable from a given
- * node and returns byte sequences corresponding to final states.
+ * An iterator that traverses the right language of a given node (all sequences
+ * reachable from a given node).
*/
public final class FSAFinalStatesIterator implements Iterator<ByteBuffer> {
/**
@@ -32,129 +29,126 @@ public final class FSAFinalStatesIterator implements Iterator<ByteBuffer> {
/** Reusable byte buffer wrapper around {@link #buffer}. */
private ByteBuffer bufferWrapper = ByteBuffer.wrap(buffer);
- /** A node stack for DFS when processing the automaton. */
- private int [] nodes = new int [EXPECTED_MAX_STATES];
-
/** An arc stack for DFS when processing the automaton. */
- private int [] arcs = new int [EXPECTED_MAX_STATES];
+ private int[] arcs = new int[EXPECTED_MAX_STATES];
- /** Current processing depth in {@link #nodes} and {@link #arcs}. */
+ /** Current processing depth in {@link #arcs}. */
private int position;
/**
* Create an instance of the iterator for a given node.
*/
- FSAFinalStatesIterator(FSA fsa, int node) {
- this.fsa = fsa;
+ public FSAFinalStatesIterator(FSA fsa, int node) {
+ this.fsa = fsa;
- if (fsa.getFirstArc(node) != 0) {
- restartFrom(node);
- }
+ if (fsa.getFirstArc(node) != 0) {
+ restartFrom(node);
+ }
}
/**
- * Restart walking from <code>node</code>.
+ * Restart walking from <code>node</code>. Allows iterator reuse.
*/
public void restartFrom(int node) {
- position = 0;
- bufferWrapper.clear();
- nextElement = null;
+ position = 0;
+ bufferWrapper.clear();
+ nextElement = null;
- pushNode(node);
+ pushNode(node);
}
-
+
/** Returns <code>true</code> if there are still elements in this iterator. */
+ @Override
public boolean hasNext() {
- if (nextElement == null) {
- nextElement = advance();
- }
+ if (nextElement == null) {
+ nextElement = advance();
+ }
- return nextElement != null;
+ return nextElement != null;
}
/**
- * @return Returns a {@link ByteBuffer} with the sequence corresponding
- * to the next final state in the automaton.
+ * @return Returns a {@link ByteBuffer} with the sequence corresponding to
+ * the next final state in the automaton.
*/
+ @Override
public ByteBuffer next() {
- if (nextElement != null) {
- final ByteBuffer cache = nextElement;
- nextElement = null;
- return cache;
- } else {
- final ByteBuffer cache = advance();
- if (cache == null) {
- throw new NoSuchElementException();
- }
- return cache;
- }
+ if (nextElement != null) {
+ final ByteBuffer cache = nextElement;
+ nextElement = null;
+ return cache;
+ } else {
+ final ByteBuffer cache = advance();
+ if (cache == null) {
+ throw new NoSuchElementException();
+ }
+ return cache;
+ }
}
/**
* Advances to the next available final state.
*/
private final ByteBuffer advance() {
- if (position == 0) {
- return null;
- }
-
- while (position > 0) {
- final int lastIndex = position - 1;
- final int arc = arcs[lastIndex];
- final int node = nodes[lastIndex];
-
- if (arc == 0) {
- // Remove the current node from the queue.
- position--;
- continue;
- }
-
- // Go to the next arc, but leave it on the stack
- // so that we keep the recursion depth level accurate.
- arcs[lastIndex] = fsa.getNextArc(node, arc);
-
- // Expand buffer if needed.
- final int bufferLength = this.buffer.length;
- if (lastIndex >= bufferLength) {
- this.buffer = Arrays.copyOf(buffer, bufferLength + EXPECTED_MAX_STATES);
- this.bufferWrapper = ByteBuffer.wrap(buffer);
- }
- buffer[lastIndex] = fsa.getArcLabel(arc);
-
- if (!fsa.isArcTerminal(arc)) {
- // Recursively descend into the arc's node.
- pushNode(fsa.getEndNode(arc));
- }
-
- if (fsa.isArcFinal(arc)) {
- bufferWrapper.clear();
- bufferWrapper.limit(lastIndex + 1);
- return bufferWrapper;
- }
- }
-
- return null;
+ if (position == 0) {
+ return null;
+ }
+
+ while (position > 0) {
+ final int lastIndex = position - 1;
+ final int arc = arcs[lastIndex];
+
+ if (arc == 0) {
+ // Remove the current node from the queue.
+ position--;
+ continue;
+ }
+
+ // Go to the next arc, but leave it on the stack
+ // so that we keep the recursion depth level accurate.
+ arcs[lastIndex] = fsa.getNextArc(arc);
+
+ // Expand buffer if needed.
+ final int bufferLength = this.buffer.length;
+ if (lastIndex >= bufferLength) {
+ this.buffer = Arrays.copyOf(buffer, bufferLength
+ + EXPECTED_MAX_STATES);
+ this.bufferWrapper = ByteBuffer.wrap(buffer);
+ }
+ buffer[lastIndex] = fsa.getArcLabel(arc);
+
+ if (!fsa.isArcTerminal(arc)) {
+ // Recursively descend into the arc's node.
+ pushNode(fsa.getEndNode(arc));
+ }
+
+ if (fsa.isArcFinal(arc)) {
+ bufferWrapper.clear();
+ bufferWrapper.limit(lastIndex + 1);
+ return bufferWrapper;
+ }
+ }
+
+ return null;
}
/**
* Not implemented in this iterator.
*/
- public final void remove() {
- throw new UnsupportedOperationException("Read-only iterator.");
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Read-only iterator.");
}
/**
* Descends to a given node, adds its arcs to the stack to be traversed.
*/
private void pushNode(int node) {
- // Expand buffers if needed.
- if (position == arcs.length) {
- nodes = Arrays.copyOf(nodes, nodes.length + EXPECTED_MAX_STATES);
- arcs = Arrays.copyOf(arcs, arcs.length + EXPECTED_MAX_STATES);
- }
-
- nodes[position] = node;
- arcs[position] = fsa.getFirstArc(node);
- position++;
+ // Expand buffers if needed.
+ if (position == arcs.length) {
+ arcs = Arrays.copyOf(arcs, arcs.length + EXPECTED_MAX_STATES);
+ }
+
+ arcs[position++] = fsa.getFirstArc(node);
}
} \ No newline at end of file
diff --git a/src/morfologik/fsa/FSAFlags.java b/src/morfologik/fsa/FSAFlags.java
index 9f6fd0e..7b9a730 100644
--- a/src/morfologik/fsa/FSAFlags.java
+++ b/src/morfologik/fsa/FSAFlags.java
@@ -1,33 +1,64 @@
package morfologik.fsa;
+import java.util.Set;
+
/**
- * FSA automaton flags.
+ * FSA automaton flags. Where applicable, flags follow Daciuk's <code>fsa</code> package.
*/
public enum FSAFlags {
- FLEXIBLE(1 << 0),
- STOPBIT(1 << 1),
- NEXTBIT(1 << 2),
- TAILS(1 << 3),
- WEIGHTED(1 << 4),
- LARGE_DICTIONARIES(1 << 5);
-
- /**
- * Bit mask for the corresponding flag.
- */
- public final int bits;
-
- /*
- *
- */
- private FSAFlags(int bits) {
- this.bits = bits;
- }
+ /** Daciuk: flexible FSA encoding. */
+ FLEXIBLE(1 << 0),
+
+ /** Daciuk: stop bit in use. */
+ STOPBIT(1 << 1),
+
+ /** Daciuk: next bit in use. */
+ NEXTBIT(1 << 2),
+
+ /** Daciuk: tails compression. */
+ TAILS(1 << 3),
+
+ /*
+ * These flags are outside of byte range (never occur in Daciuk's FSA).
+ */
+
+ /**
+ * The FSA contains right-language count numbers on states.
+ *
+ * @see FSA#getRightLanguageCount(int)
+ */
+ NUMBERS(1 << 8),
+
+ /**
+ * The FSA supports legacy built-in separator and filler characters (Daciuk's FSA package
+ * compatibility).
+ */
+ SEPARATORS(1 << 9);
+
+ /**
+ * Bit mask for the corresponding flag.
+ */
+ public final int bits;
+
+ /** */
+ private FSAFlags(int bits) {
+ this.bits = bits;
+ }
+
+ /**
+ * Returns <code>true</code> if the corresponding flag is set in the bit set.
+ */
+ public static boolean isSet(int flags, FSAFlags flag) {
+ return (flags & flag.bits) != 0;
+ }
- /**
- * Returns <code>true</code> if the corresponding flag is set in the
- * bit set.
- */
- public static boolean isSet(int flags, FSAFlags flag) {
- return (flags & flag.bits) != 0;
+ /**
+ * Returns the set of flags encoded in a single short.
+ */
+ public static short asShort(Set<FSAFlags> flags) {
+ short value = 0;
+ for (FSAFlags f : flags)
+ value |= f.bits;
+ return value;
}
} \ No newline at end of file
diff --git a/src/morfologik/fsa/FSAHeader.java b/src/morfologik/fsa/FSAHeader.java
new file mode 100644
index 0000000..76fd6ff
--- /dev/null
+++ b/src/morfologik/fsa/FSAHeader.java
@@ -0,0 +1,52 @@
+package morfologik.fsa;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import morfologik.util.FileUtils;
+import static morfologik.util.FileUtils.*;
+
+/**
+ * Standard FSA file header, as described in <code>fsa</code> package documentation.
+ */
+final class FSAHeader {
+ /**
+ * FSA magic (4 bytes).
+ */
+ public final static int FSA_MAGIC = ('\\' << 24) | ('f' << 16) | ('s' << 8) | ('a');
+
+ /**
+ * Maximum length of the header block.
+ */
+ public static final int MAX_HEADER_LENGTH = 4 + 8;
+
+ /** FSA version number. */
+ public byte version;
+
+ /** Filler character. */
+ public byte filler;
+
+ /** Annotation character. */
+ public byte annotation;
+
+ /** Goto field (may be a compound, depending on the automaton version). */
+ public byte gtl;
+
+ /**
+ * Read FSA header from a stream, consuming its bytes.
+ *
+ * @throws IOException If the stream ends prematurely or if it contains invalid data.
+ */
+ public static FSAHeader read(InputStream in) throws IOException {
+ if (FSA_MAGIC != FileUtils.readInt(in))
+ throw new IOException("Invalid file header magic bytes.");
+
+ final FSAHeader h = new FSAHeader();
+ h.version = readByte(in);
+ h.filler = readByte(in);
+ h.annotation = readByte(in);
+ h.gtl = readByte(in);
+
+ return h;
+ }
+}
diff --git a/src/morfologik/fsa/FSAHelpers.java b/src/morfologik/fsa/FSAHelpers.java
deleted file mode 100644
index 1a189e1..0000000
--- a/src/morfologik/fsa/FSAHelpers.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package morfologik.fsa;
-
-import static morfologik.fsa.FSAFlags.*;
-
-/**
- * This class has several static utility methods for use
- * with the FSA package.
- */
-public final class FSAHelpers
-{
- /** Prevent instantiation. */
- private FSAHelpers() {/* empty */}
-
- /**
- * Converts an integer with FSA flags to a human-readable string.
- */
- public static String flagsToString(int flags) {
- final StringBuilder res = new StringBuilder();
-
- for (FSAFlags flag : FSAFlags.values()) {
- if ((flags & flag.bits) != 0) {
- flags = flags & ~flag.bits;
- if (res.length() > 0) res.append(',');
- res.append(flag.toString());
- }
- }
-
- if (flags != 0) {
- if (res.length() > 0) {
- res.append(' ');
- }
- res.append("(Some flags were not recognized: "
- + Integer.toBinaryString(flags) + ")");
- }
-
- return res.toString();
- }
-
-
- /**
- * Returns a version number for a set of flags.
- */
- public static byte getVersion(int flags) {
- final byte version;
-
- if (FSAFlags.isSet(flags, FLEXIBLE)) {
- if (FSAFlags.isSet(flags, STOPBIT)) {
- if (FSAFlags.isSet(flags, NEXTBIT)) {
- if (FSAFlags.isSet(flags, TAILS)) {
- version = 7;
- } else {
- if (FSAFlags.isSet(flags, WEIGHTED))
- version = 8;
- else
- version = 5;
- }
- } else {
- if (FSAFlags.isSet(flags, TAILS))
- version = 6;
- else
- version = 4;
- }
- } else {
- if (FSAFlags.isSet(flags, NEXTBIT))
- version = 2;
- else
- version = 1;
- }
- } else {
- if (FSAFlags.isSet(flags, LARGE_DICTIONARIES))
- version = (byte) 0x80;
- else
- version = 0;
- }
-
- return version;
- }
-
-
- /**
- * Returns flags as an integer for a given version number.
- *
- * @throws RuntimeException if the version number is not recognized.
- */
- public static int getFlags(int version) {
- final int flags;
- switch (version) {
- case 0:
- flags = 0; break;
- case (byte) 0x80:
- flags = LARGE_DICTIONARIES.bits; break;
- case 1:
- flags = FLEXIBLE.bits; break;
- case 2:
- flags = FLEXIBLE.bits | NEXTBIT.bits; break;
- case 4:
- flags = FLEXIBLE.bits | STOPBIT.bits; break;
- case FSA.VERSION_5:
- flags = FLEXIBLE.bits | STOPBIT.bits | NEXTBIT.bits; break;
- case 6:
- flags = FLEXIBLE.bits | STOPBIT.bits | TAILS.bits; break;
- case 7:
- flags = FLEXIBLE.bits | STOPBIT.bits | NEXTBIT.bits | TAILS.bits; break;
- default:
- throw new RuntimeException("Unknown version number. FSA created with unknown options.");
- }
-
- return flags;
- }
-} \ No newline at end of file
diff --git a/src/morfologik/fsa/FSAInfo.java b/src/morfologik/fsa/FSAInfo.java
new file mode 100644
index 0000000..dc5cb27
--- /dev/null
+++ b/src/morfologik/fsa/FSAInfo.java
@@ -0,0 +1,157 @@
+package morfologik.fsa;
+
+import java.util.BitSet;
+import java.util.HashMap;
+
+/**
+ * Compute additional information about an FSA: number of arcs, nodes, etc.
+ */
+public final class FSAInfo {
+ /**
+ * Computes the exact number of states and nodes by recursively traversing
+ * the FSA.
+ */
+ private static class NodeVisitor {
+ final BitSet visitedArcs = new BitSet();
+ final BitSet visitedNodes = new BitSet();
+
+ int nodes;
+ int arcs;
+ int totalArcs;
+
+ private final FSA fsa;
+
+ NodeVisitor(FSA fsa) {
+ this.fsa = fsa;
+ }
+
+ public void visitNode(final int node) {
+ if (visitedNodes.get(node)) {
+ return;
+ }
+ visitedNodes.set(node);
+
+ nodes++;
+ for (int arc = fsa.getFirstArc(node); arc != 0; arc = fsa
+ .getNextArc(arc)) {
+ if (!visitedArcs.get(arc)) {
+ arcs++;
+ }
+ totalArcs++;
+ visitedArcs.set(arc);
+
+ if (!fsa.isArcTerminal(arc)) {
+ visitNode(fsa.getEndNode(arc));
+ }
+ }
+ }
+ }
+
+ /**
+ * Computes the exact number of final states.
+ */
+ private static class FinalStateVisitor {
+ final HashMap<Integer, Integer> visitedNodes
+ = new HashMap<Integer, Integer>();
+
+ private final FSA fsa;
+
+ FinalStateVisitor(FSA fsa) {
+ this.fsa = fsa;
+ }
+
+ public int visitNode(int node) {
+ Integer cached = visitedNodes.get(node);
+ if (cached != null)
+ return cached;
+
+ int fromHere = 0;
+ for (int arc = fsa.getFirstArc(node);
+ arc != 0; arc = fsa.getNextArc(arc))
+ {
+ if (fsa.isArcFinal(arc))
+ fromHere++;
+
+ if (!fsa.isArcTerminal(arc)) {
+ fromHere += visitNode(fsa.getEndNode(arc));
+ }
+ }
+ visitedNodes.put(node, fromHere);
+ return fromHere;
+ }
+ }
+
+ /**
+ * Number of nodes in the automaton.
+ */
+ public final int nodeCount;
+
+ /**
+ * Number of arcs in the automaton, excluding an arcs from the zero node
+ * (initial) and an arc from the start node to the root node.
+ */
+ public final int arcsCount;
+
+ /**
+ * Total number of arcs, counting arcs that physically overlap due to
+ * merging.
+ */
+ public final int arcsCountTotal;
+
+ /**
+ * Number of final states (number of input sequences stored in the automaton).
+ */
+ public final int finalStatesCount;
+
+ /**
+ * Arcs size (in serialized form).
+ */
+ public final int size;
+
+ /*
+ *
+ */
+ public FSAInfo(FSA fsa) {
+ final NodeVisitor w = new NodeVisitor(fsa);
+ int root = fsa.getRootNode();
+ if (root > 0) {
+ w.visitNode(root);
+ }
+
+ this.nodeCount = 1 + w.nodes;
+ this.arcsCount = 1 + w.arcs;
+ this.arcsCountTotal = 1 + w.totalArcs;
+
+ final FinalStateVisitor fsv = new FinalStateVisitor(fsa);
+ this.finalStatesCount = fsv.visitNode(fsa.getRootNode());
+
+ if (fsa instanceof FSA5) {
+ this.size = ((FSA5) fsa).arcs.length;
+ } else {
+ this.size = 0;
+ }
+ }
+
+ /*
+ *
+ */
+ public FSAInfo(int nodeCount, int arcsCount, int arcsCountTotal, int finalStatesCount) {
+ this.nodeCount = nodeCount;
+ this.arcsCount = arcsCount;
+ this.arcsCountTotal = arcsCountTotal;
+ this.finalStatesCount = finalStatesCount;
+ this.size = 0;
+ }
+
+ /*
+ *
+ */
+ @Override
+ public String toString() {
+ return "Nodes: " + nodeCount
+ + ", arcs visited: " + arcsCount
+ + ", arcs total: " + arcsCountTotal
+ + ", final states: " + finalStatesCount
+ + ", size: " + size;
+ }
+}
diff --git a/src/morfologik/fsa/FSAMatch.java b/src/morfologik/fsa/FSAMatch.java
deleted file mode 100644
index aec1d61..0000000
--- a/src/morfologik/fsa/FSAMatch.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package morfologik.fsa;
-
-/**
- * A matching result returned from {@link FSATraversalHelper}.
- *
- * @see FSATraversalHelper
- */
-public final class FSAMatch {
- private FSAMatchType matchType;
- private int mismatchAtIndex;
- private int mismatchAtNode;
-
- /*
- *
- */
- FSAMatch(FSAMatchType type, int mismatchAtIndex, int mismatchAtNode) {
- reset(type, mismatchAtIndex, mismatchAtNode);
- }
-
- /*
- *
- */
- FSAMatch(FSAMatchType type) {
- this(type, 0, 0);
- }
-
- /*
- *
- */
- public FSAMatch() {
- this(FSAMatchType.NO_MATCH, 0, 0);
- }
-
- /**
- * Return match type.
- */
- public FSAMatchType getMatchType() {
- return matchType;
- }
-
- /**
- * Return the index at which a mismatch occurred.
- *
- * @see FSAMatchType
- */
- public int getMismatchIndex() {
- return mismatchAtIndex;
- }
-
- /**
- * Return the node at which mismatch occurred.
- *
- * @see FSAMatchType
- */
- public int getMismatchNode() {
- return mismatchAtNode;
- }
-
- /*
- *
- */
- void reset(FSAMatchType type, int mismatchAtIndex, int mismatchAtNode) {
- this.matchType = type;
- this.mismatchAtIndex = mismatchAtIndex;
- this.mismatchAtNode = mismatchAtNode;
- }
-
- /*
- *
- */
- void reset(FSAMatchType type) {
- this.matchType = type;
- this.mismatchAtIndex = 0;
- this.mismatchAtNode = 0;
- }
-}
diff --git a/src/morfologik/fsa/FSAMatchType.java b/src/morfologik/fsa/FSAMatchType.java
deleted file mode 100644
index 426d3df..0000000
--- a/src/morfologik/fsa/FSAMatchType.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package morfologik.fsa;
-
-/**
- * Type of the match returned as part of {@link FSAMatch}.
- */
-public enum FSAMatchType {
- /**
- * No match for the input sequence of symbols found in the automaton.
- */
- NO_MATCH,
-
- /**
- * The input sequence ends exactly on the final node.
- */
- EXACT_MATCH,
-
- /**
- * A terminating node occurs in the dictionary before the end of the input
- * sequence. It effectively means a prefix of the input sequence is stored
- * in the dictionary (e.g., an empty sequence is a prefix of all other
- * sequences). The result {@link FSAMatch} will contain an index of the
- * first character not present in the dictionary.
- */
- PREMATURE_PATH_END_FOUND,
-
- /**
- * The sequence ends on an intermediate automaton node. The sequence is
- * therefore a prefix of at least one other sequence stored in the
- * dictionary. The result {@link FSAMatch} object will contain an index of
- * the first character in the input sequence not present in the dictionary
- * and a pointer to the {@link FSA}'s <code>node</code> where mismatch
- * occurred.
- */
- PREFIX_FOUND,
-
- /**
- * The input sequence ends on an intermediate automaton node. This is a
- * special case of {@link #PREFIX_FOUND}. A node where the mismatch (missing
- * input sequence's characters) occurred is returned in the {@link FSAMatch}
- * .
- */
- PREMATURE_WORD_END_FOUND;
-}
diff --git a/src/morfologik/fsa/FSASerializer.java b/src/morfologik/fsa/FSASerializer.java
new file mode 100644
index 0000000..414640e
--- /dev/null
+++ b/src/morfologik/fsa/FSASerializer.java
@@ -0,0 +1,45 @@
+package morfologik.fsa;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Set;
+
+import morfologik.tools.IMessageLogger;
+
+/**
+ * All FSA serializers to binary formats will implement this interface.
+ */
+public interface FSASerializer {
+ /**
+ * Serialize a finite state automaton to an output stream.
+ */
+ public <T extends OutputStream> T serialize(FSA fsa, T os) throws IOException;
+
+ /**
+ * Returns the set of flags supported by the serializer (and the output automaton).
+ */
+ public Set<FSAFlags> getFlags();
+
+ /**
+ * Log extra messages during construction.
+ */
+ public FSASerializer withLogger(IMessageLogger logger);
+
+ /**
+ * Supports built-in filler separator. Only if {@link #getFlags()} returns
+ * {@link FSAFlags#SEPARATORS}.
+ */
+ public FSASerializer withFiller(byte filler);
+
+ /**
+ * Supports built-in annotation separator. Only if {@link #getFlags()} returns
+ * {@link FSAFlags#SEPARATORS}.
+ */
+ public FSASerializer withAnnotationSeparator(byte annotationSeparator);
+
+ /**
+ * Supports built-in right language count on nodes, speeding up perfect hash counts.
+ * Only if {@link #getFlags()} returns {@link FSAFlags#NUMBERS}.
+ */
+ public FSASerializer withNumbers();
+}
diff --git a/src/morfologik/fsa/FSATraversal.java b/src/morfologik/fsa/FSATraversal.java
new file mode 100644
index 0000000..9e59003
--- /dev/null
+++ b/src/morfologik/fsa/FSATraversal.java
@@ -0,0 +1,169 @@
+package morfologik.fsa;
+
+import static morfologik.fsa.MatchResult.*;
+
+/**
+ * This class implements some common matching and scanning operations on a
+ * generic FSA.
+ */
+public final class FSATraversal {
+ /**
+ * Target automaton.
+ */
+ private final FSA fsa;
+
+ /**
+ * Traversals of the given FSA.
+ */
+ public FSATraversal(FSA fsa) {
+ this.fsa = fsa;
+ }
+
+ /**
+ * Calculate perfect hash for a given input sequence of bytes. The perfect hash requires
+ * that {@link FSA} is built with {@link FSAFlags#NUMBERS} and corresponds to the sequential
+ * order of input sequences used at automaton construction time.
+ *
+ * @param start Start index in the sequence array.
+ * @param length Length of the byte sequence, must be at least 1.
+ *
+ * @return Returns a unique integer assigned to the input sequence in the automaton (reflecting
+ * the number of that sequence in the input used to build the automaton). Returns a negative
+ * integer if the input sequence was not part of the input from which the automaton was created.
+ * The type of mismatch is a constant defined in {@link MatchResult}.
+ */
+ public int perfectHash(byte[] sequence, int start, int length, int node) {
+ assert fsa.getFlags().contains(FSAFlags.NUMBERS) : "FSA not built with NUMBERS option.";
+ assert length > 0 : "Must be a non-empty sequence.";
+
+ int hash = 0;
+ final int end = start + length - 1;
+
+ int seqIndex = start;
+ byte label = sequence[seqIndex];
+
+ // Seek through the current node's labels, looking for 'label', update hash.
+ for (int arc = fsa.getFirstArc(node); arc != 0;) {
+ if (fsa.getArcLabel(arc) == label) {
+ if (fsa.isArcFinal(arc)) {
+ if (seqIndex == end)
+ return hash;
+
+ hash++;
+ }
+
+ if (fsa.isArcTerminal(arc)) {
+ /* The automaton contains a prefix of the input sequence. */
+ return AUTOMATON_HAS_PREFIX;
+ }
+
+ // The sequence is a prefix of one of the sequences stored in the automaton.
+ if (seqIndex == end) {
+ return SEQUENCE_IS_A_PREFIX;
+ }
+
+ // Make a transition along the arc, go the target node's first arc.
+ arc = fsa.getFirstArc(fsa.getEndNode(arc));
+ label = sequence[++seqIndex];
+ continue;
+ } else {
+ if (fsa.isArcFinal(arc))
+ hash++;
+ if (!fsa.isArcTerminal(arc))
+ hash += fsa.getRightLanguageCount(fsa.getEndNode(arc));
+ }
+
+ arc = fsa.getNextArc(arc);
+ }
+
+ // Labels of this node ended without a match on the sequence.
+ // Perfect hash does not exist.
+ return NO_MATCH;
+ }
+
+ /**
+ * @see #perfectHash(byte[], int, int, int)
+ */
+ public int perfectHash(byte[] sequence) {
+ return perfectHash(sequence, 0, sequence.length, fsa.getRootNode());
+ }
+
+ /**
+ * Same as {@link #match(byte[], int, int, int)}, but allows passing
+ * a reusable {@link MatchResult} object so that no intermediate garbage is
+ * produced.
+ *
+ * @return The same object as <code>result</code>, but with reset internal
+ * type and other fields.
+ */
+ public MatchResult match(MatchResult result,
+ byte[] sequence, int start, int length, int node)
+ {
+ if (node == 0) {
+ result.reset(NO_MATCH, start, node);
+ return result;
+ }
+
+ final FSA fsa = this.fsa;
+ final int end = start + length;
+ for (int i = start; i < end; i++) {
+ final int arc = fsa.getArc(node, sequence[i]);
+ if (arc != 0) {
+ if (fsa.isArcFinal(arc) && i + 1 == end) {
+ /* The automaton has an exact match of the input sequence. */
+ result.reset(EXACT_MATCH, i, node);
+ return result;
+ }
+
+ if (fsa.isArcTerminal(arc)) {
+ /* The automaton contains a prefix of the input sequence. */
+ result.reset(AUTOMATON_HAS_PREFIX, i + 1, 0);
+ return result;
+ }
+
+ // Make a transition along the arc.
+ node = fsa.getEndNode(arc);
+ } else {
+ result.reset(NO_MATCH, i, node);
+ return result;
+ }
+ }
+
+ /* The sequence is a prefix of at least one sequence in the automaton. */
+ result.reset(SEQUENCE_IS_A_PREFIX, 0, node);
+ return result;
+ }
+
+ /**
+ * Finds a matching path in the dictionary for a given sequence of labels
+ * from <code>sequence</code> and starting at node <code>node</code>.
+ *
+ * @param sequence
+ * An array of labels to follow in the FSA.
+ * @param start
+ * Starting index in <code>sequence</code>.
+ * @param length
+ * How many symbols to consider from <code>sequence</code>?
+ * @param node
+ * Start node identifier in the FSA.
+ *
+ * @see #match(byte [], int)
+ */
+ public MatchResult match(byte[] sequence, int start, int length, int node) {
+ return match(new MatchResult(), sequence, start, length, node);
+ }
+
+ /**
+ * @see #match(byte[], int, int, int)
+ */
+ public MatchResult match(byte[] sequence, int node) {
+ return match(sequence, 0, sequence.length, node);
+ }
+
+ /**
+ * @see #match(byte[], int, int, int)
+ */
+ public MatchResult match(byte[] sequence) {
+ return match(sequence, fsa.getRootNode());
+ }
+} \ No newline at end of file
diff --git a/src/morfologik/fsa/FSATraversalHelper.java b/src/morfologik/fsa/FSATraversalHelper.java
deleted file mode 100644
index 8685d46..0000000
--- a/src/morfologik/fsa/FSATraversalHelper.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package morfologik.fsa;
-
-import java.nio.ByteBuffer;
-import java.util.Iterator;
-import static morfologik.fsa.FSAMatchType.*;
-
-/**
- * This class implements some common matching and scanning operations on a
- * generic FSA.
- *
- * <p>
- * Optimized implementations may be provided my specific versions of FSA,
- * therefore objects of this class should be instantiated via
- * {@link FSA#getTraversalHelper()}.
- */
-public final class FSATraversalHelper {
- /**
- * Target automaton.
- */
- private final FSA fsa;
-
- /**
- * Only allow new instances from within the package.
- */
- FSATraversalHelper(FSA fsa) {
- this.fsa = fsa;
- }
-
- /**
- * Returns an {@link Iterator} of all subsequences available from the given
- * node to all reachable final states.
- */
- public Iterator<ByteBuffer> getAllSubsequences(final int node) {
- if (node == 0) {
- throw new IllegalArgumentException("Node cannot be zero.");
- }
-
- // Create a custom iterator in the FSA
- return new FSAFinalStatesIterator(fsa, node);
- }
-
- /**
- * Returns a new iterator for walking along the final states of this FSA.
- * The iterator is initially set to walk along all final states reachable
- * from the root node.
- */
- public FSAFinalStatesIterator getFinalStatesIterator() {
- return new FSAFinalStatesIterator(fsa, fsa.getRootNode());
- }
-
- /**
- * Same as {@link #matchSequence(byte[], int, int, int)}, but allows passing
- * a reusable {@link FSAMatch} object so that no intermediate garbage is
- * produced.
- *
- * @return The same object as <code>result</code>, but with reset internal
- * type and other fields.
- */
- public FSAMatch matchSequence(FSAMatch result, byte[] sequence, int start,
- int length, int node) {
- if (node == 0) {
- result.reset(NO_MATCH);
- return result;
- }
-
- final int end = start + length;
- for (int i = start; i < end; i++) {
- final int arc = fsa.getArc(node, sequence[i]);
- if (arc != 0) {
- if (fsa.isArcFinal(arc)) {
- if (i + 1 == end) {
- // The word has been found (exact match).
- result.reset(EXACT_MATCH);
- return result;
- } else {
- /*
- * A prefix of the word has been found (there are still
- * characters in the word, but the path is over)
- */
- result.reset(PREMATURE_PATH_END_FOUND, i + 1, 0);
- return result;
- }
- } else {
- // make a transition along the arc.
- node = fsa.getEndNode(arc);
- }
- } else {
- // The label was not found. i.e. there possibly are prefixes
- // of the word in the dictionary, but an exact match does not
- // exist.
- // [an empty string is also considered a prefix!]
- result.reset(PREFIX_FOUND, i, node);
- return result;
- }
- }
-
- // The word is a prefix of some other sequence(s) present in the
- // dictionary.
- result.reset(PREMATURE_WORD_END_FOUND, 0, node);
- return result;
- }
-
- /**
- * Finds a matching path in the dictionary for a given sequence of labels
- * from <code>sequence</code> and starting at node <code>node</code>.
- *
- * @param sequence
- * An array of labels to follow in the FSA.
- * @param start
- * Starting index in <code>sequence</code>.
- * @param length
- * How many symbols to consider from <code>sequence</code>?
- * @param node
- * Start node identifier in the FSA.
- *
- * @see #matchSequence(byte [], int)
- */
- public FSAMatch matchSequence(byte[] sequence, int start, int length,
- int node) {
- return matchSequence(new FSAMatch(), sequence, start, length, node);
- }
-
- /**
- * @see #matchSequence(byte[], int, int, int)
- */
- public FSAMatch matchSequence(byte[] sequence, int node) {
- return matchSequence(sequence, 0, sequence.length, node);
- }
-
- /**
- * @see #matchSequence(byte[], int, int, int)
- */
- public FSAMatch matchSequence(byte[] sequence) {
- return matchSequence(sequence, fsa.getRootNode());
- }
-} \ No newline at end of file
diff --git a/src/morfologik/fsa/FSAUtils.java b/src/morfologik/fsa/FSAUtils.java
new file mode 100644
index 0000000..cad611e
--- /dev/null
+++ b/src/morfologik/fsa/FSAUtils.java
@@ -0,0 +1,202 @@
+package morfologik.fsa;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.TreeMap;
+
+import com.carrotsearch.hppc.IntIntOpenHashMap;
+
+/**
+ * Other FSA-related utilities not directly associated with the class hierarchy.
+ */
+public final class FSAUtils {
+ public final static class IntIntHolder {
+ public int a;
+ public int b;
+
+ public IntIntHolder(int a, int b) {
+ this.a = a;
+ this.b = b;
+ }
+
+ public IntIntHolder() {
+ }
+ }
+
+ /**
+ * Returns the right-language reachable from a given FSA node, formatted
+ * as an input for the graphviz package (expressed in the <code>dot</code>
+ * language).
+ */
+ public static String toDot(FSA fsa, int node) {
+ try {
+ StringWriter w = new StringWriter();
+ toDot(w, fsa, node);
+ return w.toString();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Saves the right-language reachable from a given FSA node, formatted
+ * as an input for the graphviz package (expressed in the <code>dot</code>
+ * language), to the given writer.
+ */
+ public static void toDot(Writer w, FSA fsa, int node) throws IOException {
+ w.write("digraph Automaton {\n");
+ w.write(" rankdir = LR;\n");
+
+ final BitSet visited = new BitSet();
+
+ w.write(" stop [shape=doublecircle,label=\"\"];\n");
+ w.write(" initial [shape=plaintext,label=\"\"];\n");
+ w.write(" initial -> " + node + "\n\n");
+
+ visitNode(w, 0, fsa, node, visited);
+ w.write("}\n");
+ }
+
+ private static void visitNode(Writer w, int d, FSA fsa, int s, BitSet visited) throws IOException {
+ visited.set(s);
+ w.write(" "); w.write(Integer.toString(s));
+
+ if (fsa.getFlags().contains(FSAFlags.NUMBERS)) {
+ int nodeNumber = fsa.getRightLanguageCount(s);
+ w.write(" [shape=circle,label=\"" + nodeNumber + "\"];\n");
+ } else {
+ w.write(" [shape=circle,label=\"\"];\n");
+ }
+
+ for (int arc = fsa.getFirstArc(s); arc != 0; arc = fsa.getNextArc(arc)) {
+ w.write(" ");
+ w.write(Integer.toString(s));
+ w.write(" -> ");
+ if (fsa.isArcTerminal(arc)) {
+ w.write("stop");
+ } else {
+ w.write(Integer.toString(fsa.getEndNode(arc)));
+ }
+
+ final byte label = fsa.getArcLabel(arc);
+ w.write(" [label=\"");
+ if (Character.isLetterOrDigit(label))
+ w.write((char) label);
+ else {
+ w.write("0x");
+ w.write(Integer.toHexString(label & 0xFF));
+ }
+ w.write("\"");
+ if (fsa.isArcFinal(arc)) w.write(" arrowhead=\"tee\"");
+ if (fsa instanceof FSA5) {
+ if (((FSA5) fsa).isNextSet(arc)) {
+ w.write(" color=\"blue\"");
+ }
+ }
+
+ w.write("]\n");
+ }
+
+ for (int arc = fsa.getFirstArc(s); arc != 0; arc = fsa.getNextArc(arc)) {
+ if (!fsa.isArcTerminal(arc)) {
+ int endNode = fsa.getEndNode(arc);
+ if (!visited.get(endNode)) {
+ visitNode(w, d + 1, fsa, endNode, visited);
+ }
+ }
+ }
+ }
+
+ /**
+ * All byte sequences generated as the right language of <code>state</code>.
+ */
+ public static ArrayList<byte[]> rightLanguage(FSA fsa, int state) {
+ final ArrayList<byte[]> rl = new ArrayList<byte[]>();
+ final byte [] buffer = new byte [0];
+
+ descend(fsa, state, buffer, 0, rl);
+
+ return rl;
+ }
+
+ /**
+ * Recursive descend and collection of the right language.
+ */
+ private static byte [] descend(FSA fsa, int state, byte [] b, int position, ArrayList<byte[]> rl) {
+
+ if (b.length <= position) {
+ b = Arrays.copyOf(b, position + 1);
+ }
+
+ for (int arc = fsa.getFirstArc(state); arc != 0; arc = fsa.getNextArc(arc)) {
+ b[position] = fsa.getArcLabel(arc);
+
+ if (fsa.isArcFinal(arc)) {
+ rl.add(Arrays.copyOf(b, position + 1));
+ }
+
+ if (!fsa.isArcTerminal(arc))
+ b = descend(fsa, fsa.getEndNode(arc), b, position + 1, rl);
+ }
+
+ return b;
+ }
+
+ /**
+ * Calculate fan-out ratio.
+ * @return The returned array: result[outgoing-arcs]
+ */
+ public static TreeMap<Integer, Integer> calculateFanOuts(final FSA fsa, int root) {
+ final int [] result = new int [256];
+ fsa.visitInPreOrder(new StateVisitor() {
+ public boolean accept(int state) {
+ int count = 0;
+ for (int arc = fsa.getFirstArc(state); arc != 0; arc = fsa.getNextArc(arc))
+ count++;
+ result[count]++;
+ return true;
+ }
+ });
+
+ TreeMap<Integer, Integer> output = new TreeMap<Integer, Integer>();
+
+ int low = 1; // Omit #0, there is always a single node like that (dummy).
+ while (low < result.length && result[low] == 0) low++;
+
+ int high = result.length - 1;
+ while (high >= 0 && result[high] == 0) high--;
+
+ for (int i = low; i <= high; i++) {
+ output.put(i, result[i]);
+ }
+
+ return output;
+ }
+
+ /**
+ * Calculate the size of right language for each state in an FSA.
+ */
+ public static IntIntOpenHashMap rightLanguageForAllStates(final FSA fsa) {
+ final IntIntOpenHashMap numbers = new IntIntOpenHashMap();
+
+ fsa.visitInPostOrder(new StateVisitor() {
+ public boolean accept(int state) {
+ int thisNodeNumber = 0;
+ for (int arc = fsa.getFirstArc(state); arc != 0; arc = fsa.getNextArc(arc)) {
+ thisNodeNumber +=
+ (fsa.isArcFinal(arc) ? 1 : 0) +
+ (fsa.isArcTerminal(arc) ? 0 : numbers.get(fsa.getEndNode(arc)));
+ }
+ numbers.put(state, thisNodeNumber);
+
+ return true;
+ }
+ });
+
+ return numbers;
+ }
+}
diff --git a/src/morfologik/fsa/FSAVer5Impl.java b/src/morfologik/fsa/FSAVer5Impl.java
deleted file mode 100644
index 538017e..0000000
--- a/src/morfologik/fsa/FSAVer5Impl.java
+++ /dev/null
@@ -1,272 +0,0 @@
-package morfologik.fsa;
-
-import java.io.*;
-
-/**
- * FSA (Finite State Automaton) dictionary traversal implementation for version
- * 5 of the FSA automaton.
- *
- * <p>
- * Version 5 indicates the dictionary was built with these flags:
- * {@link FSAFlags#FLEXIBLE}, {@link FSAFlags#STOPBIT} and
- * {@link FSAFlags#NEXTBIT}. The internal representation of the FSA must
- * therefore follow this description (please note this format describes only a
- * single transition (arc), not the entire dictionary file).
- *
- * <pre>
- * Byte
- * +-+-+-+-+-+-+-+-+\
- * 0 | | | | | | | | | +------ label
- * +-+-+-+-+-+-+-+-+/
- *
- * +------------- node pointed to is next
- * | +----------- the last arc of the node
- * | | +--------- the arc is final
- * | | |
- * +-----------+
- * | | | | |
- * ___+___ | | | |
- * / \ | | | |
- * MSB LSB |
- * 7 6 5 4 3 2 1 0 |
- * +-+-+-+-+-+-+-+-+ |
- * 1 | | | | | | | | | \ \
- * +-+-+-+-+-+-+-+-+ \ \ LSB
- * +-+-+-+-+-+-+-+-+ +
- * 2 | | | | | | | | | |
- * +-+-+-+-+-+-+-+-+ |
- * 3 | | | | | | | | | +----- target node address (in bytes)
- * +-+-+-+-+-+-+-+-+ | (not present except for the byte
- * : : : : : : : : : | with flags if the node pointed to
- * +-+-+-+-+-+-+-+-+ + is next)
- * gtl | | | | | | | | | / MSB
- * +-+-+-+-+-+-+-+-+ /
- * gtl+1 (gtl = gotoLength)
- * </pre>
- */
-public final class FSAVer5Impl extends FSA {
- /**
- * Bitmask indicating that an arc is the last one of the node's list and the
- * following one belongs to another node.
- */
- private static final int BITMASK_LASTARC = 1 << 1;
-
- /**
- * Bitmask indicating that an arc corresponds to the last character of a
- * sequence available when building the automaton.
- */
- private static final int BITMASK_FINALARC = 1 << 0;
-
- /**
- * Bitmask indicating that the next node follows this arc in the compressed
- * automaton structure.
- */
- private static final int BITMASK_NEXTBIT = 1 << 2;
-
- /**
- * Size of a single arc (in bytes).
- */
- protected int arcSize;
-
- /**
- * An offset in the arc structure, where the address field begins. For this
- * version of the automaton, this is a constant value.
- */
- protected final static int gotoOffset = 1;
-
- /**
- * An array of bytes with the internal representation of the automaton.
- * Please see the documentation of this class for more information on how
- * this structure is organized.
- */
- protected byte[] arcs;
-
- /**
- * Returns the number of arcs in this automaton. This method performs a full
- * scan of all arcs in this automaton.
- */
- public int getNumberOfArcs() {
- final int startNode = getRootNode();
-
- int arcOffset = getFirstArc(startNode);
- int arcsNumber = 0;
- while (arcOffset < arcs.length) {
- arcsNumber++;
-
- // go to next arc.
- if ((arcs[arcOffset + gotoOffset] & BITMASK_NEXTBIT) != 0) {
- /* the next arc is right after this one. */
- arcOffset = arcOffset + gotoOffset + 1;
- } else {
- /*
- * the destination node address has to be extracted from the
- * arc's goto field.
- */
- arcOffset = arcOffset + gotoOffset + gotoLength;
- }
- }
-
- return arcsNumber;
- }
-
- /**
- * Returns the number of nodes in this automaton. This method performs a
- * full scan of all arcs in this automaton.
- */
- public int getNumberOfNodes() {
- int offset = gotoOffset;
- int nodes = 0;
- while (offset < arcs.length) {
- // This arc marks an end of the list of node's arrays.
- if ((arcs[offset] & BITMASK_LASTARC) != 0)
- nodes++;
- offset += arcSize;
- }
-
- return nodes;
- }
-
- /**
- * Creates a new automaton reading it from a file in FSA format, version 5.
- */
- public FSAVer5Impl(InputStream fsaStream, String dictionaryEncoding)
- throws IOException {
- super(fsaStream, dictionaryEncoding);
- }
-
- /**
- * Returns the start node of this automaton. May return <code>0</code> if
- * the start node is also an end node.
- */
- public int getRootNode() {
- return getEndNode(getFirstArc(arcSize));
- }
-
- /**
- * {@inheritDoc}
- */
- protected void readHeader(DataInput in, long fileSize) throws IOException {
- super.readHeader(in, fileSize);
-
- // Check if we support such version of the automata.
- if (version != FSA.VERSION_5) {
- throw new IOException("Cannot read FSA in version "
- + version
- + " (built with flags: "
- + FSAHelpers.flagsToString(FSAHelpers.getFlags(version))
- + ")."
- + " Class "
- + this.getClass().getName()
- + " supports version "
- + FSA.VERSION_5
- + " only ("
- + FSAHelpers.flagsToString(FSAHelpers
- .getFlags(FSA.VERSION_5)) + ").");
- }
-
- // Read transitions data.
- gotoLength = (byte) (gotoLength & 0x0f);
- arcSize = gotoLength + 1;
-
- final int numberOfArcs = (int) fileSize - /* header size */8;
- arcs = new byte[numberOfArcs];
- in.readFully(arcs);
- }
-
- /*
- *
- */
- public final int getFirstArc(int node) {
- return node;
- }
-
- /*
- *
- */
- public final int getNextArc(int node, int arc) {
- if (isArcLast(arc))
- return 0;
- else
- return arc + arcSize;
- }
-
- /*
- *
- */
- public int getArc(int node, byte label) {
- for (int arc = getFirstArc(node); arc != 0; arc = getNextArc(node, arc)) {
- if (getArcLabel(arc) == label)
- return arc;
- }
-
- // An arc labeled with "label" not found.
- return 0;
- }
-
- /*
- *
- */
- public int getEndNode(int arc) {
- final int nodeOffset = getDestinationNodeOffset(arc);
- if (0 == nodeOffset) {
- throw new RuntimeException("This is a terminal arc [" + arc + "]");
- }
- return nodeOffset;
- }
-
- /*
- *
- */
- public byte getArcLabel(int arc) {
- return arcs[arc];
- }
-
- /*
- *
- */
- public boolean isArcFinal(int arc) {
- return (arcs[arc + gotoOffset] & BITMASK_FINALARC) != 0;
- }
-
- /*
- *
- */
- public boolean isArcTerminal(int arc) {
- return (0 == getDestinationNodeOffset(arc));
- }
-
- /*
- *
- */
- private boolean isArcLast(int arc) {
- return (arcs[arc + gotoOffset] & BITMASK_LASTARC) != 0;
- }
-
- /**
- * Returns an integer offset from bit-packed representation.
- */
- private final int gotoFieldToOffset(final int start, final int n) {
- int r = 0;
- for (int i = n - 1; i >= 0; --i) {
- r <<= 8;
- r = r | (arcs[start + i] & 0xff);
- }
- return r;
- }
-
- /**
- * Returns the address of the node pointed to by this arc.
- */
- private final int getDestinationNodeOffset(int arc) {
- if ((arcs[arc + gotoOffset] & BITMASK_NEXTBIT) != 0) {
- /* the destination node follows this arc in the array */
- return arc + gotoOffset + 1;
- } else {
- /*
- * the destination node address has to be extracted from the arc's
- * goto field.
- */
- return gotoFieldToOffset(arc + gotoOffset, gotoLength) >>> 3;
- }
- }
-} \ No newline at end of file
diff --git a/src/morfologik/fsa/MatchResult.java b/src/morfologik/fsa/MatchResult.java
new file mode 100644
index 0000000..2f5cbd7
--- /dev/null
+++ b/src/morfologik/fsa/MatchResult.java
@@ -0,0 +1,86 @@
+package morfologik.fsa;
+
+/**
+ * A matching result returned from {@link FSATraversal}.
+ *
+ * @see FSATraversal
+ */
+public final class MatchResult {
+ /**
+ * The automaton has exactly one match for the input sequence.
+ */
+ public static final int EXACT_MATCH = 0;
+
+ /**
+ * The automaton has no match for the input sequence.
+ */
+ public static final int NO_MATCH = -1;
+
+ /**
+ * The automaton contains a prefix of the input sequence. That is:
+ * one of the input sequences used to build the automaton is a
+ * prefix of the input sequence that is shorter than the sequence.
+ *
+ * <p>{@link MatchResult#index} will contain an index of the
+ * first character of the input sequence not present in the
+ * dictionary.</p>
+ */
+ public static final int AUTOMATON_HAS_PREFIX = -3;
+
+ /**
+ * The sequence is a prefix of at least one sequence in the automaton.
+ * {@link MatchResult#node} returns the node from which all sequences
+ * with the given prefix start in the automaton.
+ */
+ public static final int SEQUENCE_IS_A_PREFIX = -4;
+
+ /**
+ * One of the match kind constants defined in this class.
+ *
+ * @see #NO_MATCH
+ * @see #EXACT_MATCH
+ * @see #AUTOMATON_HAS_PREFIX
+ * @see #SEQUENCE_IS_A_PREFIX
+ */
+ public int kind;
+
+ /**
+ * Input sequence's index, interpretation depends on {@link #kind}.
+ */
+ public int index;
+
+ /**
+ * Automaton node, interpretation depends on the {@link #kind}.
+ */
+ public int node;
+
+ /*
+ *
+ */
+ MatchResult(int kind, int index, int node) {
+ reset(kind, index, node);
+ }
+
+ /*
+ *
+ */
+ MatchResult(int kind) {
+ reset(kind, 0, 0);
+ }
+
+ /*
+ *
+ */
+ public MatchResult() {
+ reset(NO_MATCH, 0, 0);
+ }
+
+ /*
+ *
+ */
+ final void reset(int kind, int index, int node) {
+ this.kind = kind;
+ this.index = index;
+ this.node = node;
+ }
+}
diff --git a/src/morfologik/fsa/NullMessageLogger.java b/src/morfologik/fsa/NullMessageLogger.java
new file mode 100644
index 0000000..6d326d9
--- /dev/null
+++ b/src/morfologik/fsa/NullMessageLogger.java
@@ -0,0 +1,24 @@
+package morfologik.fsa;
+
+import morfologik.tools.IMessageLogger;
+
+/*
+ * Do-nothing logger.
+ */
+final class NullMessageLogger implements IMessageLogger {
+ @Override
+ public void log(String msg) {
+ }
+
+ @Override
+ public void startPart(String header) {
+ }
+
+ @Override
+ public void endPart() {
+ }
+
+ @Override
+ public void log(String header, Object v) {
+ }
+}
diff --git a/src/morfologik/fsa/StateVisitor.java b/src/morfologik/fsa/StateVisitor.java
new file mode 100644
index 0000000..8ced239
--- /dev/null
+++ b/src/morfologik/fsa/StateVisitor.java
@@ -0,0 +1,11 @@
+package morfologik.fsa;
+
+/**
+ * State visitor.
+ *
+ * @see FSA#visitInPostOrder(StateVisitor)
+ * @see FSA#visitInPreOrder(StateVisitor)
+ */
+public interface StateVisitor {
+ public boolean accept(int state);
+} \ No newline at end of file
diff --git a/src/morfologik/stemming/ArrayViewList.java b/src/morfologik/stemming/ArrayViewList.java
index 1b446b2..230aef6 100644
--- a/src/morfologik/stemming/ArrayViewList.java
+++ b/src/morfologik/stemming/ArrayViewList.java
@@ -6,104 +6,106 @@ import java.util.*;
* A view over a range of an array.
*/
@SuppressWarnings("serial")
-final class ArrayViewList<E> extends AbstractList<E> implements RandomAccess,
- java.io.Serializable {
- /** Backing array. */
- private E[] a;
- private int start;
- private int length;
+final class ArrayViewList<E> extends AbstractList<E>
+ implements RandomAccess, java.io.Serializable
+{
+ /** Backing array. */
+ private E[] a;
+ private int start;
+ private int length;
- /*
+ /*
*
*/
- ArrayViewList(E[] array, int start, int length) {
- if (array == null)
- throw new IllegalArgumentException();
- wrap(a, start, length);
- }
+ ArrayViewList(E[] array, int start, int length) {
+ if (array == null)
+ throw new IllegalArgumentException();
+ wrap(a, start, length);
+ }
- /*
+ /*
*
*/
- public int size() {
- return length;
- }
+ public int size() {
+ return length;
+ }
- /*
+ /*
*
*/
- public E get(int index) {
- return a[start + index];
- }
+ public E get(int index) {
+ return a[start + index];
+ }
- /*
+ /*
*
*/
- public E set(int index, E element) {
- throw new UnsupportedOperationException();
- }
+ public E set(int index, E element) {
+ throw new UnsupportedOperationException();
+ }
- /*
+ /*
*
*/
- public void add(int index, E element) {
- throw new UnsupportedOperationException();
- }
+ public void add(int index, E element) {
+ throw new UnsupportedOperationException();
+ }
- /*
+ /*
*
*/
- public E remove(int index) {
- throw new UnsupportedOperationException();
- }
+ public E remove(int index) {
+ throw new UnsupportedOperationException();
+ }
- /*
+ /*
*
*/
- public boolean addAll(int index, Collection<? extends E> c) {
- throw new UnsupportedOperationException();
- }
+ public boolean addAll(int index, Collection<? extends E> c) {
+ throw new UnsupportedOperationException();
+ }
- /*
+ /*
*
*/
- public int indexOf(Object o) {
- if (o == null) {
- for (int i = start; i < start + length; i++)
- if (a[i] == null)
- return i - start;
- } else {
- for (int i = start; i < start + length; i++)
- if (o.equals(a[i]))
- return i - start;
+ public int indexOf(Object o) {
+ if (o == null) {
+ for (int i = start; i < start + length; i++)
+ if (a[i] == null)
+ return i - start;
+ } else {
+ for (int i = start; i < start + length; i++)
+ if (o.equals(a[i]))
+ return i - start;
+ }
+ return -1;
}
- return -1;
- }
- public ListIterator<E> listIterator() {
- return listIterator(0);
- }
+ public ListIterator<E> listIterator() {
+ return listIterator(0);
+ }
- /*
+ /*
*
*/
- public ListIterator<E> listIterator(final int index) {
- return Arrays.asList(a).subList(start, start + length).listIterator(index);
- }
+ public ListIterator<E> listIterator(final int index) {
+ return Arrays.asList(a).subList(start, start + length).listIterator(
+ index);
+ }
- /*
+ /*
*
*/
- public boolean contains(Object o) {
- return indexOf(o) != -1;
- }
+ public boolean contains(Object o) {
+ return indexOf(o) != -1;
+ }
- /*
+ /*
*
*/
- public void wrap(E[] array, int start, int length) {
- this.a = array;
- this.start = start;
- this.length = length;
- }
+ void wrap(E[] array, int start, int length) {
+ this.a = array;
+ this.start = start;
+ this.length = length;
+ }
}
diff --git a/src/morfologik/stemming/Dictionary.java b/src/morfologik/stemming/Dictionary.java
index bb21c36..7441d5e 100644
--- a/src/morfologik/stemming/Dictionary.java
+++ b/src/morfologik/stemming/Dictionary.java
@@ -21,150 +21,149 @@ import morfologik.util.ResourceUtils;
* Use static methods in this class to read dictionaries and their metadata.
*/
public final class Dictionary {
- /**
- * Expected metadata file extension.
- */
- public final static String METADATA_FILE_EXTENSION = "info";
-
- /**
- * {@link FSA} automaton with the compiled dictionary data.
- */
- public final FSA fsa;
-
- /**
- * Metadata associated with the dictionary.
- */
- public final DictionaryMetadata metadata;
-
- /**
- * Default loaded dictionaries.
- */
- public static final WeakHashMap<String, Dictionary> defaultDictionaries = new WeakHashMap<String, Dictionary>();
-
- /**
- * It is strongly recommended to use static methods in this class for
- * reading dictionaries.
- *
- * @param fsa
- * An instantiated {@link FSA} instance.
- *
- * @param metadata
- * A map of attributes describing the compression format and
- * other settings not contained in the FSA automaton. For an
- * explanation of available attributes and their possible values,
- * see {@link DictionaryMetadata}.
- */
- public Dictionary(FSA fsa, DictionaryMetadata metadata) {
- this.fsa = fsa;
- this.metadata = metadata;
- }
-
- /**
- * Attempts to load a dictionary using the path to the FSA file and the
- * expected metadata extension.
- */
- public static Dictionary read(File fsaFile) throws IOException {
- final File featuresFile = new File(fsaFile.getParent(),
- getExpectedFeaturesName(fsaFile.getName()));
-
- FileUtils.assertExists(featuresFile, true, false);
-
- return readAndClose(new FileInputStream(fsaFile), new FileInputStream(
- featuresFile));
- }
-
- /**
- * <p>
- * Attempts to load a dictionary using the URL to the FSA file and the
- * expected metadata extension.
- *
- * <p>
- * This method can be used to load resource-based dictionaries, but be aware
- * of JAR resource-locking issues that arise from resource URLs.
- */
- public static Dictionary read(URL fsaURL) throws IOException {
- final String fsa = fsaURL.toExternalForm();
- final String features = getExpectedFeaturesName(fsa);
-
- return readAndClose(ResourceUtils.openInputStream(fsa), ResourceUtils
- .openInputStream(features));
- }
-
- /**
- * Attempts to load a dictionary from opened streams of FSA dictionary data
- * and associated metadata.
- */
- public static Dictionary readAndClose(InputStream fsaData,
- InputStream featuresData) throws IOException {
- try {
- final Properties properties = new Properties();
- properties.load(featuresData);
-
- final DictionaryMetadata features = DictionaryMetadata
- .fromMap(properties);
- final FSA fsa = FSA.getInstance(fsaData, features.encoding);
-
- return new Dictionary(fsa, features);
- } finally {
- FileUtils.close(fsaData, featuresData);
+ /**
+ * Expected metadata file extension.
+ */
+ public final static String METADATA_FILE_EXTENSION = "info";
+
+ /**
+ * {@link FSA} automaton with the compiled dictionary data.
+ */
+ public final FSA fsa;
+
+ /**
+ * Metadata associated with the dictionary.
+ */
+ public final DictionaryMetadata metadata;
+
+ /**
+ * Default loaded dictionaries.
+ */
+ public static final WeakHashMap<String, Dictionary> defaultDictionaries = new WeakHashMap<String, Dictionary>();
+
+ /**
+ * It is strongly recommended to use static methods in this class for
+ * reading dictionaries.
+ *
+ * @param fsa
+ * An instantiated {@link FSA} instance.
+ *
+ * @param metadata
+ * A map of attributes describing the compression format and
+ * other settings not contained in the FSA automaton. For an
+ * explanation of available attributes and their possible values,
+ * see {@link DictionaryMetadata}.
+ */
+ public Dictionary(FSA fsa, DictionaryMetadata metadata) {
+ this.fsa = fsa;
+ this.metadata = metadata;
}
- }
-
- /**
- * Returns the expected name of the metadata file, based on the name of the
- * FSA dictionary file. The expected name is resolved by truncating any
- * suffix of <code>name</code> and appending
- * {@link #METADATA_FILE_EXTENSION}.
- */
- public static String getExpectedFeaturesName(String name) {
- final int dotIndex = name.lastIndexOf('.');
- final String featuresName;
- if (dotIndex >= 0) {
- featuresName = name.substring(0, dotIndex) + "."
- + METADATA_FILE_EXTENSION;
- } else {
- featuresName = name + "." + METADATA_FILE_EXTENSION;
+
+ /**
+ * Attempts to load a dictionary using the path to the FSA file and the
+ * expected metadata extension.
+ */
+ public static Dictionary read(File fsaFile) throws IOException {
+ final File featuresFile = new File(fsaFile.getParent(),
+ getExpectedFeaturesName(fsaFile.getName()));
+
+ FileUtils.assertExists(featuresFile, true, false);
+
+ return readAndClose(new FileInputStream(fsaFile), new FileInputStream(
+ featuresFile));
+ }
+
+ /**
+ * <p>
+ * Attempts to load a dictionary using the URL to the FSA file and the
+ * expected metadata extension.
+ *
+ * <p>
+ * This method can be used to load resource-based dictionaries, but be aware
+ * of JAR resource-locking issues that arise from resource URLs.
+ */
+ public static Dictionary read(URL fsaURL) throws IOException {
+ final String fsa = fsaURL.toExternalForm();
+ final String features = getExpectedFeaturesName(fsa);
+
+ return readAndClose(ResourceUtils.openInputStream(fsa), ResourceUtils
+ .openInputStream(features));
+ }
+
+ /**
+ * Attempts to load a dictionary from opened streams of FSA dictionary data
+ * and associated metadata.
+ */
+ public static Dictionary readAndClose(InputStream fsaData,
+ InputStream featuresData) throws IOException {
+ try {
+ final Properties properties = new Properties();
+ properties.load(featuresData);
+
+ final DictionaryMetadata features = DictionaryMetadata
+ .fromMap(properties);
+ final FSA fsa = FSA.read(fsaData);
+
+ return new Dictionary(fsa, features);
+ } finally {
+ FileUtils.close(fsaData, featuresData);
+ }
}
- return featuresName;
- }
-
- /**
- * Return a built-in dictionary for a given ISO language code. Dictionaries
- * are cached internally for potential reuse.
- *
- * @throws RuntimeException
- * Throws a {@link RuntimeException} if the dictionary is not
- * bundled with the library.
- */
- public static Dictionary getForLanguage(String languageCode) {
- if (languageCode == null || "".equals(languageCode)) {
- throw new IllegalArgumentException(
- "Language code must not be empty.");
+ /**
+ * Returns the expected name of the metadata file, based on the name of the
+ * FSA dictionary file. The expected name is resolved by truncating any
+ * suffix of <code>name</code> and appending
+ * {@link #METADATA_FILE_EXTENSION}.
+ */
+ public static String getExpectedFeaturesName(String name) {
+ final int dotIndex = name.lastIndexOf('.');
+ final String featuresName;
+ if (dotIndex >= 0) {
+ featuresName = name.substring(0, dotIndex) + "."
+ + METADATA_FILE_EXTENSION;
+ } else {
+ featuresName = name + "." + METADATA_FILE_EXTENSION;
+ }
+
+ return featuresName;
}
- synchronized (defaultDictionaries) {
- Dictionary dict = defaultDictionaries.get(languageCode);
- if (dict != null)
- return dict;
-
- try {
- final String dictPath = "/morfologik/dictionaries/"
- + languageCode + ".dict";
- final String metaPath = Dictionary
- .getExpectedFeaturesName(dictPath);
-
- dict = Dictionary.readAndClose(ResourceUtils
- .openInputStream(dictPath), ResourceUtils
- .openInputStream(metaPath));
-
- defaultDictionaries.put(languageCode, dict);
- return dict;
- } catch (IOException e) {
- throw new RuntimeException(
- "Default dictionary resource for language '"
- + languageCode + "not found.", e);
- }
+ /**
+ * Return a built-in dictionary for a given ISO language code. Dictionaries
+ * are cached internally for potential reuse.
+ *
+ * @throws RuntimeException
+ * Throws a {@link RuntimeException} if the dictionary is not
+ * bundled with the library.
+ */
+ public static Dictionary getForLanguage(String languageCode) {
+ if (languageCode == null || "".equals(languageCode)) {
+ throw new IllegalArgumentException(
+ "Language code must not be empty.");
+ }
+
+ synchronized (defaultDictionaries) {
+ Dictionary dict = defaultDictionaries.get(languageCode);
+ if (dict != null)
+ return dict;
+
+ try {
+ final String dictPath = "morfologik/dictionaries/" + languageCode + ".dict";
+ final String metaPath = Dictionary
+ .getExpectedFeaturesName(dictPath);
+
+ dict = Dictionary.readAndClose(
+ ResourceUtils.openInputStream(dictPath),
+ ResourceUtils.openInputStream(metaPath));
+
+ defaultDictionaries.put(languageCode, dict);
+ return dict;
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Default dictionary resource for language '"
+ + languageCode + "not found.", e);
+ }
+ }
}
- }
}
diff --git a/src/morfologik/stemming/DictionaryIterator.java b/src/morfologik/stemming/DictionaryIterator.java
index ee26d12..19b6dad 100644
--- a/src/morfologik/stemming/DictionaryIterator.java
+++ b/src/morfologik/stemming/DictionaryIterator.java
@@ -9,132 +9,136 @@ import morfologik.util.BufferUtils;
/**
* An iterator over {@link WordData} entries of a {@link Dictionary}. The stems
- * can be decoded from compressed format or the compressed form can be preserved.
+ * can be decoded from compressed format or the compressed form can be
+ * preserved.
*/
public final class DictionaryIterator implements Iterator<WordData> {
- private final CharsetDecoder decoder;
- private final Iterator<ByteBuffer> entriesIter;
- private final WordData entry;
- private final byte separator;
- private final DictionaryMetadata dictionaryMetadata;
- private final boolean decodeStems;
-
- private ByteBuffer inflectedBuffer = ByteBuffer.allocate(0);
- private CharBuffer inflectedCharBuffer = CharBuffer.allocate(0);
- private ByteBuffer temp = ByteBuffer.allocate(0);
-
- public DictionaryIterator(Dictionary dictionary, CharsetDecoder decoder, boolean decodeStems) {
- this.entriesIter = dictionary.fsa.iterator();
- this.separator = dictionary.metadata.separator;
- this.dictionaryMetadata = dictionary.metadata;
- this.decoder = decoder;
- this.entry = new WordData(decoder);
- this.decodeStems = decodeStems;
- }
-
- public boolean hasNext() {
- return entriesIter.hasNext();
- }
-
- public WordData next() {
- final ByteBuffer entryBuffer = entriesIter.next();
- entry.reset();
-
- /*
- * Entries are typically: inflected<SEP>codedBase<SEP>tag so try to find
- * this split.
- */
- byte[] ba = entryBuffer.array();
- int bbSize = entryBuffer.remaining();
-
- int sepPos;
- for (sepPos = 0; sepPos < bbSize; sepPos++) {
- if (ba[sepPos] == separator)
- break;
+ private final CharsetDecoder decoder;
+ private final Iterator<ByteBuffer> entriesIter;
+ private final WordData entry;
+ private final byte separator;
+ private final DictionaryMetadata dictionaryMetadata;
+ private final boolean decodeStems;
+
+ private ByteBuffer inflectedBuffer = ByteBuffer.allocate(0);
+ private CharBuffer inflectedCharBuffer = CharBuffer.allocate(0);
+ private ByteBuffer temp = ByteBuffer.allocate(0);
+
+ public DictionaryIterator(Dictionary dictionary, CharsetDecoder decoder,
+ boolean decodeStems) {
+ this.entriesIter = dictionary.fsa.iterator();
+ this.separator = dictionary.metadata.separator;
+ this.dictionaryMetadata = dictionary.metadata;
+ this.decoder = decoder;
+ this.entry = new WordData(decoder);
+ this.decodeStems = decodeStems;
}
- if (sepPos == bbSize) {
- throw new RuntimeException("Invalid dictionary "
- + "entry format (missing separator).");
+ public boolean hasNext() {
+ return entriesIter.hasNext();
}
- inflectedBuffer.clear();
- inflectedBuffer = BufferUtils.ensureCapacity(inflectedBuffer, sepPos);
- inflectedBuffer.put(ba, 0, sepPos);
- inflectedBuffer.flip();
-
- inflectedCharBuffer = bytesToChars(inflectedBuffer, inflectedCharBuffer);
- entry.wordBuffer = inflectedBuffer;
- entry.wordCharSequence = inflectedCharBuffer;
-
- temp.clear();
- temp = BufferUtils.ensureCapacity(temp, bbSize - sepPos);
- sepPos++;
- temp.put(ba, sepPos, bbSize - sepPos);
- temp.flip();
-
- ba = temp.array();
- bbSize = temp.remaining();
-
- /*
- * Find the next separator byte's position splitting word form and tag.
- */
- sepPos = 0;
- for (; sepPos < bbSize; sepPos++) {
- if (ba[sepPos] == separator)
- break;
+ public WordData next() {
+ final ByteBuffer entryBuffer = entriesIter.next();
+ entry.reset();
+
+ /*
+ * Entries are typically: inflected<SEP>codedBase<SEP>tag so try to find
+ * this split.
+ */
+ byte[] ba = entryBuffer.array();
+ int bbSize = entryBuffer.remaining();
+
+ int sepPos;
+ for (sepPos = 0; sepPos < bbSize; sepPos++) {
+ if (ba[sepPos] == separator)
+ break;
+ }
+
+ if (sepPos == bbSize) {
+ throw new RuntimeException("Invalid dictionary "
+ + "entry format (missing separator).");
+ }
+
+ inflectedBuffer.clear();
+ inflectedBuffer = BufferUtils.ensureCapacity(inflectedBuffer, sepPos);
+ inflectedBuffer.put(ba, 0, sepPos);
+ inflectedBuffer.flip();
+
+ inflectedCharBuffer = bytesToChars(inflectedBuffer, inflectedCharBuffer);
+ entry.wordBuffer = inflectedBuffer;
+ entry.wordCharSequence = inflectedCharBuffer;
+
+ temp.clear();
+ temp = BufferUtils.ensureCapacity(temp, bbSize - sepPos);
+ sepPos++;
+ temp.put(ba, sepPos, bbSize - sepPos);
+ temp.flip();
+
+ ba = temp.array();
+ bbSize = temp.remaining();
+
+ /*
+ * Find the next separator byte's position splitting word form and tag.
+ */
+ sepPos = 0;
+ for (; sepPos < bbSize; sepPos++) {
+ if (ba[sepPos] == separator)
+ break;
+ }
+
+ /*
+ * Decode the stem into stem buffer.
+ */
+ entry.stemBuffer.clear();
+ if (decodeStems) {
+ entry.stemBuffer = DictionaryLookup.decodeStem(entry.stemBuffer,
+ ba, sepPos, inflectedBuffer, dictionaryMetadata);
+ } else {
+ entry.stemBuffer = BufferUtils.ensureCapacity(entry.stemBuffer,
+ sepPos);
+ entry.stemBuffer.put(ba, 0, sepPos);
+ }
+ entry.stemBuffer.flip();
+
+ // Skip separator character, if present.
+ if (sepPos + 1 <= bbSize) {
+ sepPos++;
+ }
+
+ /*
+ * Decode the tag data.
+ */
+ entry.tagBuffer = BufferUtils.ensureCapacity(entry.tagBuffer, bbSize
+ - sepPos);
+ entry.tagBuffer.clear();
+ entry.tagBuffer.put(ba, sepPos, bbSize - sepPos);
+ entry.tagBuffer.flip();
+
+ return entry;
}
- /*
- * Decode the stem into stem buffer.
+ /**
+ * Decode the byte buffer, optionally expanding the char buffer.
*/
- entry.stemBuffer.clear();
- if (decodeStems) {
- entry.stemBuffer = DictionaryLookup.decodeStem(entry.stemBuffer, ba,
- sepPos, inflectedBuffer, dictionaryMetadata);
- } else {
- entry.stemBuffer = BufferUtils.ensureCapacity(entry.stemBuffer, sepPos);
- entry.stemBuffer.put(ba, 0, sepPos);
+ private CharBuffer bytesToChars(ByteBuffer bytes, CharBuffer chars) {
+ chars.clear();
+ final int maxCapacity = (int) (bytes.remaining() * decoder
+ .maxCharsPerByte());
+ if (chars.capacity() <= maxCapacity) {
+ chars = CharBuffer.allocate(maxCapacity);
+ }
+
+ bytes.mark();
+ decoder.reset();
+ decoder.decode(bytes, chars, true);
+ chars.flip();
+ bytes.reset();
+
+ return chars;
}
- entry.stemBuffer.flip();
- // Skip separator character, if present.
- if (sepPos + 1 <= bbSize) {
- sepPos++;
+ public void remove() {
+ throw new UnsupportedOperationException();
}
-
- /*
- * Decode the tag data.
- */
- entry.tagBuffer = BufferUtils.ensureCapacity(entry.tagBuffer, bbSize
- - sepPos);
- entry.tagBuffer.clear();
- entry.tagBuffer.put(ba, sepPos, bbSize - sepPos);
- entry.tagBuffer.flip();
-
- return entry;
- }
-
- /**
- * Decode the byte buffer, optionally expanding the char buffer.
- */
- private CharBuffer bytesToChars(ByteBuffer bytes, CharBuffer chars) {
- chars.clear();
- final int maxCapacity = (int) (bytes.remaining() * decoder.maxCharsPerByte());
- if (chars.capacity() <= maxCapacity) {
- chars = CharBuffer.allocate(maxCapacity);
- }
-
- bytes.mark();
- decoder.reset();
- decoder.decode(bytes, chars, true);
- chars.flip();
- bytes.reset();
-
- return chars;
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
}
diff --git a/src/morfologik/stemming/DictionaryLookup.java b/src/morfologik/stemming/DictionaryLookup.java
index 719f6b9..ac90107 100644
--- a/src/morfologik/stemming/DictionaryLookup.java
+++ b/src/morfologik/stemming/DictionaryLookup.java
@@ -1,12 +1,13 @@
package morfologik.stemming;
+import static morfologik.fsa.MatchResult.*;
+
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.*;
import java.util.*;
import morfologik.fsa.*;
-import morfologik.util.Arrays;
import morfologik.util.BufferUtils;
/**
@@ -21,332 +22,334 @@ import morfologik.util.BufferUtils;
* arrays and the other way around. You <b>can</b> use UTF-8 encoding, as it
* should not conflict with any control sequences and separator characters.
*
- * @see <a href="http://www.eti.pg.gda.pl/~jandac/fsa.html">FSA package Web site</a>
+ * @see <a href="http://www.eti.pg.gda.pl/~jandac/fsa.html">FSA package Web
+ * site</a>
*/
public final class DictionaryLookup implements IStemmer, Iterable<WordData> {
- /** A Finite State Automaton used for look ups. */
- private final FSATraversalHelper matcher;
-
- /** An iterator for walking along the final states of {@link #fsa}. */
- private final FSAFinalStatesIterator finalStatesIterator;
-
- /** FSA's root node. */
- private final int rootNode;
-
- /** Expand buffers and arrays by this constant. */
- private final static int EXPAND_SIZE = 10;
-
- /** Private internal array of reusable word data objects. */
- private WordData[] forms = new WordData[0];
-
- /** A "view" over an array implementing */
- private ArrayViewList<WordData> formsList = new ArrayViewList<WordData>(
- forms, 0, forms.length);
-
- /**
- * Features of the compiled dictionary.
- *
- * @see DictionaryMetadata
- */
- private final DictionaryMetadata dictionaryMetadata;
-
- /**
- * Charset encoder for the FSA.
- */
- private final CharsetEncoder encoder;
-
- /**
- * Charset decoder for the FSA.
- */
- private final CharsetDecoder decoder;
-
- /**
- * The FSA we are using.
- */
- private final FSA fsa;
-
- /**
- * Internal reusable buffer for encoding words into byte arrays using
- * {@link #encoder}.
- */
- private ByteBuffer byteBuffer = ByteBuffer.allocate(0);
-
- /**
- * Internal reusable buffer for encoding words into byte arrays using
- * {@link #encoder}.
- */
- private CharBuffer charBuffer = CharBuffer.allocate(0);
-
- /**
- * Reusable match result.
- */
- private final FSAMatch matchResult = new FSAMatch();
-
- /**
- * The {@link Dictionary} this lookup is using.
- */
- private final Dictionary dictionary;
-
- /**
- * <p>
- * Creates a new object of this class using the given FSA for word lookups
- * and encoding for converting characters to bytes.
- *
- * @throws IllegalArgumentException
- * if FSA's root node cannot be acquired (dictionary is empty).
- */
- public DictionaryLookup(Dictionary dictionary) throws IllegalArgumentException
- {
- this.dictionary = dictionary;
- this.dictionaryMetadata = dictionary.metadata;
- this.rootNode = dictionary.fsa.getRootNode();
- this.matcher = dictionary.fsa.getTraversalHelper();
- this.finalStatesIterator = matcher.getFinalStatesIterator();
- this.fsa = dictionary.fsa;
-
- if (rootNode == 0) {
- throw new IllegalArgumentException(
- "Dictionary must have at least the root node.");
- }
+ /** An FSA used for lookups. */
+ private final FSATraversal matcher;
- if (dictionaryMetadata == null) {
- throw new IllegalArgumentException(
- "Dictionary metadata must not be null.");
- }
+ /** An iterator for walking along the final states of {@link #fsa}. */
+ private final FSAFinalStatesIterator finalStatesIterator;
+
+ /** FSA's root node. */
+ private final int rootNode;
+
+ /** Expand buffers and arrays by this constant. */
+ private final static int EXPAND_SIZE = 10;
+
+ /** Private internal array of reusable word data objects. */
+ private WordData[] forms = new WordData[0];
+
+ /** A "view" over an array implementing */
+ private ArrayViewList<WordData> formsList = new ArrayViewList<WordData>(
+ forms, 0, forms.length);
+
+ /**
+ * Features of the compiled dictionary.
+ *
+ * @see DictionaryMetadata
+ */
+ private final DictionaryMetadata dictionaryMetadata;
+
+ /**
+ * Charset encoder for the FSA.
+ */
+ private final CharsetEncoder encoder;
+
+ /**
+ * Charset decoder for the FSA.
+ */
+ private final CharsetDecoder decoder;
+
+ /**
+ * The FSA we are using.
+ */
+ private final FSA fsa;
+
+ /**
+ * Internal reusable buffer for encoding words into byte arrays using
+ * {@link #encoder}.
+ */
+ private ByteBuffer byteBuffer = ByteBuffer.allocate(0);
+
+ /**
+ * Internal reusable buffer for encoding words into byte arrays using
+ * {@link #encoder}.
+ */
+ private CharBuffer charBuffer = CharBuffer.allocate(0);
+
+ /**
+ * Reusable match result.
+ */
+ private final MatchResult matchResult = new MatchResult();
- try {
- Charset charset = Charset.forName(dictionaryMetadata.encoding);
- encoder = charset.newEncoder();
- decoder = charset.newDecoder().onMalformedInput(
- CodingErrorAction.REPORT).onUnmappableCharacter(
- CodingErrorAction.REPORT);
- } catch (UnsupportedCharsetException e) {
- throw new RuntimeException(
- "FSA's encoding charset is not supported: "
- + dictionaryMetadata.encoding);
+ /**
+ * The {@link Dictionary} this lookup is using.
+ */
+ private final Dictionary dictionary;
+
+ /**
+ * <p>
+ * Creates a new object of this class using the given FSA for word lookups
+ * and encoding for converting characters to bytes.
+ *
+ * @throws IllegalArgumentException
+ * if FSA's root node cannot be acquired (dictionary is empty).
+ */
+ public DictionaryLookup(Dictionary dictionary)
+ throws IllegalArgumentException {
+ this.dictionary = dictionary;
+ this.dictionaryMetadata = dictionary.metadata;
+ this.rootNode = dictionary.fsa.getRootNode();
+ this.fsa = dictionary.fsa;
+ this.matcher = new FSATraversal(fsa);
+ this.finalStatesIterator = new FSAFinalStatesIterator(fsa, fsa.getRootNode());
+
+ if (rootNode == 0) {
+ throw new IllegalArgumentException(
+ "Dictionary must have at least the root node.");
+ }
+
+ if (dictionaryMetadata == null) {
+ throw new IllegalArgumentException(
+ "Dictionary metadata must not be null.");
+ }
+
+ try {
+ Charset charset = Charset.forName(dictionaryMetadata.encoding);
+ encoder = charset.newEncoder();
+ decoder = charset.newDecoder().onMalformedInput(
+ CodingErrorAction.REPORT).onUnmappableCharacter(
+ CodingErrorAction.REPORT);
+ } catch (UnsupportedCharsetException e) {
+ throw new RuntimeException(
+ "FSA's encoding charset is not supported: "
+ + dictionaryMetadata.encoding);
+ }
}
- }
-
- /**
- * Searches the automaton for a symbol sequence equal to <code>word</code>,
- * followed by a separator. The result is a stem (decompressed accordingly
- * to the dictionary's specification) and an optional tag data.
- */
- public List<WordData> lookup(CharSequence word) {
- final byte separator = dictionaryMetadata.separator;
-
- // Encode word characters into bytes in the same encoding as the FSA's.
- charBuffer.clear();
- charBuffer = BufferUtils.ensureCapacity(charBuffer, word.length());
- for (int i = 0; i < word.length(); i++)
- charBuffer.put(word.charAt(i));
- charBuffer.flip();
- byteBuffer = charsToBytes(charBuffer, byteBuffer);
-
- // Try to find a partial match in the dictionary.
- final FSAMatch match = matcher.matchSequence(
- matchResult, byteBuffer.array(), 0, byteBuffer.remaining(), rootNode);
-
- if (match.getMatchType() == FSAMatchType.PREMATURE_WORD_END_FOUND) {
- /*
- * The entire sequence exists in the dictionary. A separator
- * should be the next symbol.
- */
- final int arc = fsa.getArc(match.getMismatchNode(), separator);
-
- /*
- * The situation when the arc points to a final node should NEVER
- * happen. After all, we want the word to have SOME base form.
- */
- if (arc != 0 && !fsa.isArcFinal(arc)) {
- // There is such word in the dictionary. Return its base
- // forms.
- int formsCount = 0;
-
- finalStatesIterator.restartFrom(fsa.getEndNode(arc));
- while (finalStatesIterator.hasNext()) {
- final ByteBuffer bb = finalStatesIterator.next();
- final byte[] ba = bb.array();
- final int bbSize = bb.remaining();
-
- if (formsCount >= forms.length) {
- forms = Arrays.copyOf(forms, forms.length + EXPAND_SIZE);
- for (int k = 0; k < forms.length; k++) {
- if (forms[k] == null)
- forms[k] = new WordData(decoder);
+
+ /**
+ * Searches the automaton for a symbol sequence equal to <code>word</code>,
+ * followed by a separator. The result is a stem (decompressed accordingly
+ * to the dictionary's specification) and an optional tag data.
+ */
+ public List<WordData> lookup(CharSequence word) {
+ final byte separator = dictionaryMetadata.separator;
+
+ // Encode word characters into bytes in the same encoding as the FSA's.
+ charBuffer.clear();
+ charBuffer = BufferUtils.ensureCapacity(charBuffer, word.length());
+ for (int i = 0; i < word.length(); i++)
+ charBuffer.put(word.charAt(i));
+ charBuffer.flip();
+ byteBuffer = charsToBytes(charBuffer, byteBuffer);
+
+ // Try to find a partial match in the dictionary.
+ final MatchResult match = matcher.match(matchResult, byteBuffer
+ .array(), 0, byteBuffer.remaining(), rootNode);
+
+ if (match.kind == SEQUENCE_IS_A_PREFIX) {
+ /*
+ * The entire sequence exists in the dictionary. A separator should
+ * be the next symbol.
+ */
+ final int arc = fsa.getArc(match.node, separator);
+
+ /*
+ * The situation when the arc points to a final node should NEVER
+ * happen. After all, we want the word to have SOME base form.
+ */
+ if (arc != 0 && !fsa.isArcFinal(arc)) {
+ // There is such a word in the dictionary. Return its base forms.
+ int formsCount = 0;
+
+ finalStatesIterator.restartFrom(fsa.getEndNode(arc));
+ while (finalStatesIterator.hasNext()) {
+ final ByteBuffer bb = finalStatesIterator.next();
+ final byte[] ba = bb.array();
+ final int bbSize = bb.remaining();
+
+ if (formsCount >= forms.length) {
+ forms = Arrays.copyOf(forms, forms.length + EXPAND_SIZE);
+ for (int k = 0; k < forms.length; k++) {
+ if (forms[k] == null)
+ forms[k] = new WordData(decoder);
+ }
+ }
+
+ /*
+ * Now, expand the prefix/ suffix 'compression' and store
+ * the base form.
+ */
+ final WordData wordData = forms[formsCount++];
+ wordData.reset();
+
+ wordData.wordBuffer = byteBuffer;
+ wordData.wordCharSequence = word;
+
+ /*
+ * Find the separator byte's position splitting word form
+ * and tag.
+ */
+ int sepPos;
+ for (sepPos = 0; sepPos < bbSize; sepPos++) {
+ if (ba[sepPos] == separator)
+ break;
+ }
+
+ /*
+ * Decode the stem into stem buffer.
+ */
+ wordData.stemBuffer.clear();
+ wordData.stemBuffer = decodeStem(wordData.stemBuffer, ba,
+ sepPos, byteBuffer, dictionaryMetadata);
+ wordData.stemBuffer.flip();
+
+ // Skip separator character.
+ sepPos++;
+
+ /*
+ * Decode the tag data.
+ */
+ wordData.tagBuffer = BufferUtils.ensureCapacity(
+ wordData.tagBuffer, bbSize - sepPos);
+ wordData.tagBuffer.clear();
+ wordData.tagBuffer.put(ba, sepPos, bbSize - sepPos);
+ wordData.tagBuffer.flip();
+ }
+
+ formsList.wrap(forms, 0, formsCount);
+ return formsList;
}
- }
-
- /*
- * Now, expand the prefix/ suffix 'compression' and store
- * the base form.
- */
- final WordData wordData = forms[formsCount++];
- wordData.reset();
-
- wordData.wordBuffer = byteBuffer;
- wordData.wordCharSequence = word;
-
- /*
- * Find the separator byte's position splitting word form and tag.
- */
- int sepPos;
- for (sepPos = 0; sepPos < bbSize; sepPos++) {
- if (ba[sepPos] == separator)
- break;
- }
-
- /*
- * Decode the stem into stem buffer.
- */
- wordData.stemBuffer.clear();
- wordData.stemBuffer = decodeStem(wordData.stemBuffer, ba, sepPos,
- byteBuffer, dictionaryMetadata);
- wordData.stemBuffer.flip();
-
- // Skip separator character.
- sepPos++;
-
- /*
- * Decode the tag data.
- */
- wordData.tagBuffer = BufferUtils.ensureCapacity(
- wordData.tagBuffer, bbSize - sepPos);
- wordData.tagBuffer.clear();
- wordData.tagBuffer.put(ba, sepPos, bbSize - sepPos);
- wordData.tagBuffer.flip();
+ } else {
+ /*
+ * this case is somewhat confusing: we should have hit the separator
+ * first... I don't really know how to deal with it at the time
+ * being.
+ */
}
- formsList.wrap(forms, 0, formsCount);
- return formsList;
- }
- } else {
- /*
- * this case is somewhat confusing: we should have hit the separator
- * first... I don't really know how to deal with it at the time
- * being.
- */
+ return Collections.emptyList();
}
- return Collections.emptyList();
- }
-
- /**
- * Decode the base form of an inflected word and save its decoded form into
- * a byte buffer.
- *
- * @param bb
- * The byte buffer to save the result to. A new buffer may be
- * allocated if the capacity of <code>bb</code> is not large
- * enough to store the result. The buffer is not flipped upon
- * return.
- *
- * @param inflectedBuffer
- * Inflected form's bytes (decoded properly).
- *
- * @param bytes
- * Bytes of the encoded base form, starting at 0 index.
- *
- * @param len
- * Length of the encode base form.
- *
- * @return Returns either <code>bb</code> or a new buffer whose capacity is
- * large enough to store the output of the decoded data.
- */
- public static ByteBuffer decodeStem(ByteBuffer bb, byte[] bytes, int len,
- ByteBuffer inflectedBuffer, DictionaryMetadata metadata) {
- bb.clear();
-
- // Empty length? Weird, but return an empty buffer.
- if (len == 0) {
- return bb;
- }
+ /**
+ * Decode the base form of an inflected word and save its decoded form into
+ * a byte buffer.
+ *
+ * @param bb
+ * The byte buffer to save the result to. A new buffer may be
+ * allocated if the capacity of <code>bb</code> is not large
+ * enough to store the result. The buffer is not flipped upon
+ * return.
+ *
+ * @param inflectedBuffer
+ * Inflected form's bytes (decoded properly).
+ *
+ * @param bytes
+ * Bytes of the encoded base form, starting at 0 index.
+ *
+ * @param len
+ * Length of the encode base form.
+ *
+ * @return Returns either <code>bb</code> or a new buffer whose capacity is
+ * large enough to store the output of the decoded data.
+ */
+ public static ByteBuffer decodeStem(ByteBuffer bb, byte[] bytes, int len,
+ ByteBuffer inflectedBuffer, DictionaryMetadata metadata) {
+ bb.clear();
- // Determine inflected string's length in bytes, in the same encoding.
- final byte[] infBytes = inflectedBuffer.array();
- final int infLen = inflectedBuffer.remaining();
- final int code0 = bytes[0] - 'A';
+ // Empty length? Weird, but return an empty buffer.
+ if (len == 0) {
+ return bb;
+ }
- final boolean fsaPrefixes = metadata.usesPrefixes;
- final boolean fsaInfixes = metadata.usesInfixes;
+ // Determine inflected string's length in bytes, in the same encoding.
+ final byte[] infBytes = inflectedBuffer.array();
+ final int infLen = inflectedBuffer.remaining();
+ final int code0 = bytes[0] - 'A';
- // Increase buffer size, if needed.
- if (bb.capacity() < infLen + len) {
- bb = ByteBuffer.allocate(infLen + len);
- }
+ final boolean fsaPrefixes = metadata.usesPrefixes;
+ final boolean fsaInfixes = metadata.usesInfixes;
- if (code0 >= 0) {
- if (!fsaPrefixes && !fsaInfixes) {
- if (code0 <= infLen) {
- bb.put(infBytes, 0, infLen - code0);
- bb.put(bytes, 1, len - 1);
- return bb;
+ // Increase buffer size, if needed.
+ if (bb.capacity() < infLen + len) {
+ bb = ByteBuffer.allocate(infLen + len);
}
- } else if (fsaPrefixes && !fsaInfixes) {
- if (len > 1) {
- final int stripAtEnd = bytes[1] - 'A' + code0;
- if (stripAtEnd <= infLen) {
- bb.put(infBytes, code0, infLen - stripAtEnd);
- bb.put(bytes, 2, len - 2);
- return bb;
- }
+
+ if (code0 >= 0) {
+ if (!fsaPrefixes && !fsaInfixes) {
+ if (code0 <= infLen) {
+ bb.put(infBytes, 0, infLen - code0);
+ bb.put(bytes, 1, len - 1);
+ return bb;
+ }
+ } else if (fsaPrefixes && !fsaInfixes) {
+ if (len > 1) {
+ final int stripAtEnd = bytes[1] - 'A' + code0;
+ if (stripAtEnd <= infLen) {
+ bb.put(infBytes, code0, infLen - stripAtEnd);
+ bb.put(bytes, 2, len - 2);
+ return bb;
+ }
+ }
+ } else if (fsaInfixes) {
+ // Note: Prefixes are silently assumed here.
+ if (len > 2) {
+ final int stripAtBeginning = bytes[1] - 'A' + code0;
+ final int stripAtEnd = bytes[2] - 'A' + stripAtBeginning;
+ if (stripAtEnd <= infLen) {
+ bb.put(infBytes, 0, code0);
+ bb.put(infBytes, stripAtBeginning, infLen - stripAtEnd);
+ bb.put(bytes, 3, len - 3);
+ return bb;
+ }
+ }
+ }
}
- } else if (fsaInfixes) {
- // Note: Prefixes are silently assumed here.
- if (len > 2) {
- final int stripAtBeginning = bytes[1] - 'A' + code0;
- final int stripAtEnd = bytes[2] - 'A' + stripAtBeginning;
- if (stripAtEnd <= infLen) {
- bb.put(infBytes, 0, code0);
- bb.put(infBytes, stripAtBeginning, infLen - stripAtEnd);
- bb.put(bytes, 3, len - 3);
- return bb;
- }
+
+ /*
+ * This is a fallback in case some junk is detected above. Return the
+ * base form only if this is the case.
+ */
+ bb.clear();
+ bb.put(bytes, 0, len);
+ return bb;
+ }
+
+ /**
+ * Encode a character sequence into a byte buffer, optionally expanding
+ * buffer.
+ */
+ private ByteBuffer charsToBytes(CharBuffer chars, ByteBuffer bytes) {
+ bytes.clear();
+ final int maxCapacity = (int) (chars.remaining() * encoder
+ .maxBytesPerChar());
+ if (bytes.capacity() <= maxCapacity) {
+ bytes = ByteBuffer.allocate(maxCapacity);
}
- }
+
+ chars.mark();
+ encoder.reset();
+ encoder.encode(chars, bytes, true);
+ bytes.flip();
+ chars.reset();
+
+ return bytes;
}
- /*
- * This is a fallback in case some junk is detected above. Return the
- * base form only if this is the case.
+ /**
+ * Return an iterator over all {@link WordData} entries available in the
+ * embedded {@link Dictionary}.
*/
- bb.clear();
- bb.put(bytes, 0, len);
- return bb;
- }
-
- /**
- * Encode a character sequence into a byte buffer, optionally expanding
- * buffer.
- */
- private ByteBuffer charsToBytes(CharBuffer chars, ByteBuffer bytes) {
- bytes.clear();
- final int maxCapacity = (int) (chars.remaining() * encoder.maxBytesPerChar());
- if (bytes.capacity() <= maxCapacity) {
- bytes = ByteBuffer.allocate(maxCapacity);
+ public Iterator<WordData> iterator() {
+ return new DictionaryIterator(dictionary, decoder, true);
}
- chars.mark();
- encoder.reset();
- encoder.encode(chars, bytes, true);
- bytes.flip();
- chars.reset();
-
- return bytes;
- }
-
- /**
- * Return an iterator over all {@link WordData} entries available in
- * the embedded {@link Dictionary}.
- */
- public Iterator<WordData> iterator() {
- return new DictionaryIterator(dictionary, decoder, true);
- }
-
- /**
- * @return Return the {@link Dictionary} used by this object.
- */
- public Dictionary getDictionary() {
- return dictionary;
- }
+ /**
+ * @return Return the {@link Dictionary} used by this object.
+ */
+ public Dictionary getDictionary() {
+ return dictionary;
+ }
}
diff --git a/src/morfologik/stemming/DictionaryMetadata.java b/src/morfologik/stemming/DictionaryMetadata.java
index 6282cf9..ce5e507 100644
--- a/src/morfologik/stemming/DictionaryMetadata.java
+++ b/src/morfologik/stemming/DictionaryMetadata.java
@@ -10,107 +10,113 @@ import java.util.*;
* @see Dictionary
*/
public final class DictionaryMetadata {
- /**
- * Attribute name for {@link #separator}.
- */
- public final static String ATTR_NAME_SEPARATOR = "fsa.dict.separator";
-
- /**
- * Attribute name for {@link #encoding}.
- */
- public final static String ATTR_NAME_ENCODING = "fsa.dict.encoding";
-
- /**
- * Attribute name for {@link #usesPrefixes}.
- */
- public final static String ATTR_NAME_USES_PREFIXES = "fsa.dict.uses-prefixes";
-
- /**
- * Attribute name for {@link #usesInfixes}.
- */
- public final static String ATTR_NAME_USES_INFIXES = "fsa.dict.uses-infixes";
-
- /**
- * A separator character between fields (stem, lemma, form). The character
- * must be within byte range (FSA uses bytes internally).
- */
- public final byte separator;
-
- /**
- * Encoding used for converting bytes to characters and vice versa.
- */
- public final String encoding;
-
- /**
- * True if the dictionary was compiled with prefix compression.
- */
- public final boolean usesPrefixes;
-
- /**
- * True if the dictionary was compiled with infix compression.
- */
- public final boolean usesInfixes;
-
- /**
- * Other meta data not included above.
- */
- public final Map<String, String> metadata;
-
- /**
- * Creates an immutable instance of {@link DictionaryMetadata}.
- */
- public DictionaryMetadata(char separator, String encoding,
- boolean usesPrefixes, boolean usesInfixes, Map<String, String> metadata)
- {
- this.encoding = encoding;
- this.usesPrefixes = usesPrefixes;
- this.usesInfixes = usesInfixes;
-
- try {
- final byte [] separatorBytes = new String(new char [] {separator}).getBytes(encoding);
- if (separatorBytes.length != 1) {
- throw new RuntimeException("Separator character '" + separator
- + "' must be a single byte after transformation with encoding: " + encoding);
- }
- this.separator = separatorBytes[0];
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException("Encoding not supported on this VM: " + encoding);
- }
-
- this.metadata = Collections.unmodifiableMap(new HashMap<String, String>(metadata));
- }
-
- /**
- * Converts attributes in a {@link Map} to an instance of {@link Dictionary},
- * validating attribute values.
- */
- static DictionaryMetadata fromMap(Properties properties)
- throws IOException
- {
- final String separator = properties.getProperty(ATTR_NAME_SEPARATOR);
- if (separator == null || separator.length() != 1) {
- throw new IOException("Attribute " + ATTR_NAME_SEPARATOR + " must be "
- + "a single character.");
- }
-
- final String encoding = properties.getProperty(ATTR_NAME_ENCODING);
- if (encoding == null || encoding.length() == 0) {
- throw new IOException("Attribute " + ATTR_NAME_ENCODING + " must be "
- + "present and non-empty.");
- }
-
- final boolean usesPrefixes = Boolean.valueOf(
- properties.getProperty(ATTR_NAME_USES_PREFIXES, "false")).booleanValue();
-
- final boolean usesInfixes = Boolean.valueOf(
- properties.getProperty(ATTR_NAME_USES_INFIXES, "false")).booleanValue();
-
- final HashMap<String, String> metadata = new HashMap<String, String>();
- for (Map.Entry<Object, Object> e : properties.entrySet()) {
- metadata.put(e.getKey().toString(), e.getValue().toString());
- }
-
- return new DictionaryMetadata(
- separator.charAt(0), encoding, usesPrefixes, usesInfixes, metadata);
- }
+ /**
+ * Attribute name for {@link #separator}.
+ */
+ public final static String ATTR_NAME_SEPARATOR = "fsa.dict.separator";
+
+ /**
+ * Attribute name for {@link #encoding}.
+ */
+ public final static String ATTR_NAME_ENCODING = "fsa.dict.encoding";
+
+ /**
+ * Attribute name for {@link #usesPrefixes}.
+ */
+ public final static String ATTR_NAME_USES_PREFIXES = "fsa.dict.uses-prefixes";
+
+ /**
+ * Attribute name for {@link #usesInfixes}.
+ */
+ public final static String ATTR_NAME_USES_INFIXES = "fsa.dict.uses-infixes";
+
+ /**
+ * A separator character between fields (stem, lemma, form). The character
+ * must be within byte range (FSA uses bytes internally).
+ */
+ public final byte separator;
+
+ /**
+ * Encoding used for converting bytes to characters and vice versa.
+ */
+ public final String encoding;
+
+ /**
+ * True if the dictionary was compiled with prefix compression.
+ */
+ public final boolean usesPrefixes;
+
+ /**
+ * True if the dictionary was compiled with infix compression.
+ */
+ public final boolean usesInfixes;
+
+ /**
+ * Other meta data not included above.
+ */
+ public final Map<String, String> metadata;
+
+ /**
+ * Creates an immutable instance of {@link DictionaryMetadata}.
+ */
+ public DictionaryMetadata(char separator, String encoding,
+ boolean usesPrefixes, boolean usesInfixes,
+ Map<String, String> metadata) {
+ this.encoding = encoding;
+ this.usesPrefixes = usesPrefixes;
+ this.usesInfixes = usesInfixes;
+
+ try {
+ final byte[] separatorBytes = new String(new char[] { separator })
+ .getBytes(encoding);
+ if (separatorBytes.length != 1) {
+ throw new RuntimeException(
+ "Separator character '"
+ + separator
+ + "' must be a single byte after transformation with encoding: "
+ + encoding);
+ }
+ this.separator = separatorBytes[0];
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Encoding not supported on this VM: "
+ + encoding);
+ }
+
+ this.metadata = Collections
+ .unmodifiableMap(new HashMap<String, String>(metadata));
+ }
+
+ /**
+ * Converts attributes in a {@link Map} to an instance of {@link Dictionary}
+ * , validating attribute values.
+ */
+ static DictionaryMetadata fromMap(Properties properties) throws IOException {
+ final String separator = properties.getProperty(ATTR_NAME_SEPARATOR);
+ if (separator == null || separator.length() != 1) {
+ throw new IOException("Attribute " + ATTR_NAME_SEPARATOR
+ + " must be " + "a single character.");
+ }
+
+ final String encoding = properties.getProperty(ATTR_NAME_ENCODING);
+ if (encoding == null || encoding.length() == 0) {
+ throw new IOException("Attribute " + ATTR_NAME_ENCODING
+ + " must be " + "present and non-empty.");
+ }
+
+ final boolean usesPrefixes = Boolean.valueOf(
+ properties.getProperty(ATTR_NAME_USES_PREFIXES, "false"))
+ .booleanValue();
+
+ final boolean usesInfixes = Boolean.valueOf(
+ properties.getProperty(ATTR_NAME_USES_INFIXES, "false"))
+ .booleanValue();
+
+ final HashMap<String, String> metadata = new HashMap<String, String>();
+ for (Map.Entry<Object, Object> e : properties.entrySet()) {
+ metadata.put(e.getKey().toString(), e.getValue().toString());
+ }
+
+ return new DictionaryMetadata(separator.charAt(0), encoding,
+ usesPrefixes, usesInfixes, metadata);
+ }
}
diff --git a/src/morfologik/stemming/IStemmer.java b/src/morfologik/stemming/IStemmer.java
index 904dfbb..6e59526 100644
--- a/src/morfologik/stemming/IStemmer.java
+++ b/src/morfologik/stemming/IStemmer.java
@@ -6,15 +6,15 @@ import java.util.List;
* A generic &quot;stemmer&quot; interface in Morfologik.
*/
public interface IStemmer {
- /**
- * Returns a list of {@link WordData} entries for a given word. The returned
- * list is never <code>null</code>. Depending on the stemmer's
- * implementation the {@link WordData} may carry the stem and additional
- * information (tag) or just the stem.
- * <p>
- * The returned list and any object it contains are not usable after a
- * subsequent call to this method. Any data that should be stored in between
- * must be copied by the caller.
- */
- public List<WordData> lookup(CharSequence word);
+ /**
+ * Returns a list of {@link WordData} entries for a given word. The returned
+ * list is never <code>null</code>. Depending on the stemmer's
+ * implementation the {@link WordData} may carry the stem and additional
+ * information (tag) or just the stem.
+ * <p>
+ * The returned list and any object it contains are not usable after a
+ * subsequent call to this method. Any data that should be stored in between
+ * must be copied by the caller.
+ */
+ public List<WordData> lookup(CharSequence word);
}
diff --git a/src/morfologik/stemming/PolishStemmer.java b/src/morfologik/stemming/PolishStemmer.java
index 5ab3a76..299f76a 100644
--- a/src/morfologik/stemming/PolishStemmer.java
+++ b/src/morfologik/stemming/PolishStemmer.java
@@ -3,7 +3,6 @@ package morfologik.stemming;
import java.util.Iterator;
import java.util.List;
-
/**
* A dictionary-based stemmer for the Polish language. This stemmer requires an
* FSA-compiled dictionary to be present in classpath resources.
@@ -13,32 +12,32 @@ import java.util.List;
* @see morfologik.stemming.DictionaryLookup
*/
public final class PolishStemmer implements IStemmer, Iterable<WordData> {
- /**
- * Dictionary lookup delegate.
- */
- private final DictionaryLookup delegate;
+ /**
+ * Dictionary lookup delegate.
+ */
+ private final DictionaryLookup delegate;
+
+ /**
+ * This constructor is initialized with a built-in dictionary or fails with
+ * a runtime exception if the dictionary is not available.
+ */
+ public PolishStemmer() {
+ final String languageCode = "pl";
- /**
- * This constructor is initialized with a built-in dictionary or fails with
- * a runtime exception if the dictionary is not available.
- */
- public PolishStemmer() {
- final String languageCode = "pl";
- this.delegate = new DictionaryLookup(
- Dictionary.getForLanguage(languageCode));
- }
+ this.delegate = new DictionaryLookup(Dictionary.getForLanguage(languageCode));
+ }
- /**
- * {@inheritDoc}
- */
- public List<WordData> lookup(CharSequence word) {
- return delegate.lookup(word);
- }
+ /**
+ * {@inheritDoc}
+ */
+ public List<WordData> lookup(CharSequence word) {
+ return delegate.lookup(word);
+ }
- /**
- * Iterates over all dictionary forms stored in this stemmer.
- */
- public Iterator<WordData> iterator() {
- return delegate.iterator();
- }
+ /**
+ * Iterates over all dictionary forms stored in this stemmer.
+ */
+ public Iterator<WordData> iterator() {
+ return delegate.iterator();
+ }
}
diff --git a/src/morfologik/stemming/WordData.java b/src/morfologik/stemming/WordData.java
index 7416a7f..4341bc4 100644
--- a/src/morfologik/stemming/WordData.java
+++ b/src/morfologik/stemming/WordData.java
@@ -16,8 +16,8 @@ import morfologik.util.BufferUtils;
* <li>Objects of this class are <i>volatile</i> (their content changes on
* subsequent calls to {@link DictionaryLookup} class. If you need a copy of the
* stem or tag data for a given word, you have to create a custom buffer
- * yourself and copy the associated data, perform {@link #clone()} or create strings (they
- * are immutable) using {@link #getStem()} and then
+ * yourself and copy the associated data, perform {@link #clone()} or create
+ * strings (they are immutable) using {@link #getStem()} and then
* {@link CharSequence#toString()}.</li>
* <li>Objects of this class must not be used in any Java collections. In fact
* both equals and hashCode methods are overridden and throw exceptions to
@@ -25,221 +25,223 @@ import morfologik.util.BufferUtils;
* </ul>
*/
public final class WordData implements Cloneable {
- /**
- * Error information if somebody puts us in a Java collection.
- */
- private static final String COLLECTIONS_ERROR_MESSAGE = "Not suitable for use"
- + " in Java collections framework (volatile content). Refer to documentation.";
-
- /** Character encoding in internal buffers. */
- private final CharsetDecoder decoder;
-
- /**
- * Inflected word form data.
- */
- CharSequence wordCharSequence;
-
- /**
- * Character sequence after converting {@link #stemBuffer} using
- * {@link #decoder}.
- */
- private CharBuffer stemCharSequence;
+ /**
+ * Error information if somebody puts us in a Java collection.
+ */
+ private static final String COLLECTIONS_ERROR_MESSAGE = "Not suitable for use"
+ + " in Java collections framework (volatile content). Refer to documentation.";
+
+ /** Character encoding in internal buffers. */
+ private final CharsetDecoder decoder;
+
+ /**
+ * Inflected word form data.
+ */
+ CharSequence wordCharSequence;
+
+ /**
+ * Character sequence after converting {@link #stemBuffer} using
+ * {@link #decoder}.
+ */
+ private CharBuffer stemCharSequence;
+
+ /**
+ * Character sequence after converting {@link #tagBuffer} using
+ * {@link #decoder}.
+ */
+ private CharBuffer tagCharSequence;
+
+ /** Byte buffer holding the inflected word form data. */
+ ByteBuffer wordBuffer;
+
+ /** Byte buffer holding stem data. */
+ ByteBuffer stemBuffer;
+
+ /** Byte buffer holding tag data. */
+ ByteBuffer tagBuffer;
+
+ /**
+ * Package scope constructor.
+ */
+ WordData(CharsetDecoder decoder) {
+ this.decoder = decoder;
+
+ stemBuffer = ByteBuffer.allocate(0);
+ tagBuffer = ByteBuffer.allocate(0);
+ stemCharSequence = CharBuffer.allocate(0);
+ tagCharSequence = CharBuffer.allocate(0);
+ }
- /**
- * Character sequence after converting {@link #tagBuffer} using
- * {@link #decoder}.
- */
- private CharBuffer tagCharSequence;
+ /**
+ * A constructor for tests only.
+ */
+ WordData(String stem, String tag, String encoding) {
+ this(Charset.forName(encoding).newDecoder());
+
+ try {
+ if (stem != null)
+ stemBuffer.put(stem.getBytes(encoding));
+ if (tag != null)
+ tagBuffer.put(tag.getBytes(encoding));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
- /** Byte buffer holding the inflected word form data. */
- ByteBuffer wordBuffer;
+ /**
+ * Copy the stem's binary data (no charset decoding) to a custom byte
+ * buffer. If the buffer is null or not large enough to hold the result, a
+ * new buffer is allocated.
+ *
+ * @param target
+ * Target byte buffer to copy the stem buffer to or
+ * <code>null</code> if a new buffer should be allocated.
+ *
+ * @return Returns <code>target</code> or the new reallocated buffer.
+ */
+ public ByteBuffer getStemBytes(ByteBuffer target) {
+ target = BufferUtils.ensureCapacity(target, stemBuffer.remaining());
+ stemBuffer.mark();
+ target.put(stemBuffer);
+ stemBuffer.reset();
+ target.flip();
+ return target;
+ }
- /** Byte buffer holding stem data. */
- ByteBuffer stemBuffer;
+ /**
+ * Copy the tag's binary data (no charset decoding) to a custom byte buffer.
+ * If the buffer is null or not large enough to hold the result, a new
+ * buffer is allocated.
+ *
+ * @param target
+ * Target byte buffer to copy the tag buffer to or
+ * <code>null</code> if a new buffer should be allocated.
+ *
+ * @return Returns <code>target</code> or the new reallocated buffer.
+ */
+ public ByteBuffer getTagBytes(ByteBuffer target) {
+ target = BufferUtils.ensureCapacity(target, tagBuffer.remaining());
+ tagBuffer.mark();
+ target.put(tagBuffer);
+ tagBuffer.reset();
+ target.flip();
+ return target;
+ }
- /** Byte buffer holding tag data. */
- ByteBuffer tagBuffer;
+ /**
+ * Copy the inflected word's binary data (no charset decoding) to a custom
+ * byte buffer. If the buffer is null or not large enough to hold the
+ * result, a new buffer is allocated.
+ *
+ * @param target
+ * Target byte buffer to copy the word buffer to or
+ * <code>null</code> if a new buffer should be allocated.
+ *
+ * @return Returns <code>target</code> or the new reallocated buffer.
+ */
+ public ByteBuffer getWordBytes(ByteBuffer target) {
+ target = BufferUtils.ensureCapacity(target, wordBuffer.remaining());
+ wordBuffer.mark();
+ target.put(wordBuffer);
+ wordBuffer.reset();
+ target.flip();
+ return target;
+ }
- /**
- * Package scope constructor.
- */
- WordData(CharsetDecoder decoder) {
- this.decoder = decoder;
+ /**
+ * @return Return tag data decoded to a character sequence or
+ * <code>null</code> if no associated tag data exists.
+ */
+ public CharSequence getTag() {
+ tagCharSequence = decode(tagBuffer, tagCharSequence);
+ return tagCharSequence.remaining() == 0 ? null : tagCharSequence;
+ }
- stemBuffer = ByteBuffer.allocate(0);
- tagBuffer = ByteBuffer.allocate(0);
- stemCharSequence = CharBuffer.allocate(0);
- tagCharSequence = CharBuffer.allocate(0);
- }
+ /**
+ * @return Return stem data decoded to a character sequence or
+ * <code>null</code> if no associated stem data exists.
+ */
+ public CharSequence getStem() {
+ stemCharSequence = decode(stemBuffer, stemCharSequence);
+ return stemCharSequence.remaining() == 0 ? null : stemCharSequence;
+ }
- /**
- * A constructor for tests only.
- */
- WordData(String stem, String tag, String encoding) {
- this(Charset.forName(encoding).newDecoder());
-
- try {
- if (stem != null)
- stemBuffer.put(stem.getBytes(encoding));
- if (tag != null)
- tagBuffer.put(tag.getBytes(encoding));
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
+ /**
+ * @return Return inflected word form data. Usually the parameter passed to
+ * {@link DictionaryLookup#lookup(CharSequence)}.
+ */
+ public CharSequence getWord() {
+ return wordCharSequence;
}
- }
- /**
- * Copy the stem's binary data (no charset decoding) to a custom byte
- * buffer. If the buffer is null or not large enough to hold the result, a
- * new buffer is allocated.
- *
- * @param target
- * Target byte buffer to copy the stem buffer to or
- * <code>null</code> if a new buffer should be allocated.
+ /*
*
- * @return Returns <code>target</code> or the new reallocated buffer.
*/
- public ByteBuffer getStemBytes(ByteBuffer target) {
- target = BufferUtils.ensureCapacity(target, stemBuffer.remaining());
- stemBuffer.mark();
- target.put(stemBuffer);
- stemBuffer.reset();
- target.flip();
- return target;
- }
-
- /**
- * Copy the tag's binary data (no charset decoding) to a custom byte buffer.
- * If the buffer is null or not large enough to hold the result, a new
- * buffer is allocated.
- *
- * @param target
- * Target byte buffer to copy the tag buffer to or
- * <code>null</code> if a new buffer should be allocated.
- *
- * @return Returns <code>target</code> or the new reallocated buffer.
- */
- public ByteBuffer getTagBytes(ByteBuffer target) {
- target = BufferUtils.ensureCapacity(target, tagBuffer.remaining());
- tagBuffer.mark();
- target.put(tagBuffer);
- tagBuffer.reset();
- target.flip();
- return target;
- }
-
- /**
- * Copy the inflected word's binary data (no charset decoding) to a custom
- * byte buffer. If the buffer is null or not large enough to hold the
- * result, a new buffer is allocated.
- *
- * @param target
- * Target byte buffer to copy the word buffer to or
- * <code>null</code> if a new buffer should be allocated.
- *
- * @return Returns <code>target</code> or the new reallocated buffer.
- */
- public ByteBuffer getWordBytes(ByteBuffer target) {
- target = BufferUtils.ensureCapacity(target, wordBuffer.remaining());
- wordBuffer.mark();
- target.put(wordBuffer);
- wordBuffer.reset();
- target.flip();
- return target;
- }
-
- /**
- * @return Return tag data decoded to a character sequence or
- * <code>null</code> if no associated tag data exists.
- */
- public CharSequence getTag() {
- tagCharSequence = decode(tagBuffer, tagCharSequence);
- return tagCharSequence.remaining() == 0 ? null : tagCharSequence;
- }
-
- /**
- * @return Return stem data decoded to a character sequence or
- * <code>null</code> if no associated stem data exists.
- */
- public CharSequence getStem() {
- stemCharSequence = decode(stemBuffer, stemCharSequence);
- return stemCharSequence.remaining() == 0 ? null : stemCharSequence;
- }
-
- /**
- * @return Return inflected word form data. Usually the parameter
- * passed to {@link DictionaryLookup#lookup(CharSequence)}.
- */
- public CharSequence getWord() {
- return wordCharSequence;
- }
+ @Override
+ public boolean equals(Object obj) {
+ throw new UnsupportedOperationException(COLLECTIONS_ERROR_MESSAGE);
+ }
- /*
+ /*
*
*/
- @Override
- public boolean equals(Object obj) {
- throw new UnsupportedOperationException(COLLECTIONS_ERROR_MESSAGE);
- }
+ @Override
+ public int hashCode() {
+ throw new UnsupportedOperationException(COLLECTIONS_ERROR_MESSAGE);
+ }
- /*
- *
- */
- @Override
- public int hashCode() {
- throw new UnsupportedOperationException(COLLECTIONS_ERROR_MESSAGE);
- }
-
- /**
- * Declare a covariant of {@link Object#clone()} that returns a deep copy
- * of this object. The content of all internal buffers is copied.
- */
- @Override
- protected WordData clone() {
- final WordData clone = new WordData(this.decoder);
- clone.wordCharSequence = cloneCharSequence(wordCharSequence);
- clone.wordBuffer = getWordBytes(null);
- clone.stemBuffer = getStemBytes(null);
- clone.tagBuffer = getTagBytes(null);
- return clone;
- }
-
- /**
- * Clone char sequences only if not immutable.
- */
- private CharSequence cloneCharSequence(CharSequence chs) {
- if (chs instanceof String) return chs;
- return chs.toString();
- }
+ /**
+ * Declare a covariant of {@link Object#clone()} that returns a deep copy of
+ * this object. The content of all internal buffers is copied.
+ */
+ @Override
+ protected WordData clone() {
+ final WordData clone = new WordData(this.decoder);
+ clone.wordCharSequence = cloneCharSequence(wordCharSequence);
+ clone.wordBuffer = getWordBytes(null);
+ clone.stemBuffer = getStemBytes(null);
+ clone.tagBuffer = getTagBytes(null);
+ return clone;
+ }
- /**
- * Reset internal structures for storing another word's data.
- */
- void reset() {
- this.wordCharSequence = null;
- this.wordBuffer = null;
- this.stemCharSequence.clear();
- this.tagCharSequence.clear();
- this.stemBuffer.clear();
- this.tagBuffer.clear();
- }
-
- /**
- * Decode byte buffer, optionally expanding the char buffer to.
- */
- private CharBuffer decode(ByteBuffer bytes, CharBuffer chars) {
- chars.clear();
- final int maxCapacity = (int) (bytes.remaining() * decoder.maxCharsPerByte());
- if (chars.capacity() <= maxCapacity) {
- chars = CharBuffer.allocate(maxCapacity);
+ /**
+ * Clone char sequences only if not immutable.
+ */
+ private CharSequence cloneCharSequence(CharSequence chs) {
+ if (chs instanceof String)
+ return chs;
+ return chs.toString();
}
- bytes.mark();
- decoder.reset();
- decoder.decode(bytes, chars, true);
- chars.flip();
- bytes.reset();
+ /**
+ * Reset internal structures for storing another word's data.
+ */
+ void reset() {
+ this.wordCharSequence = null;
+ this.wordBuffer = null;
+ this.stemCharSequence.clear();
+ this.tagCharSequence.clear();
+ this.stemBuffer.clear();
+ this.tagBuffer.clear();
+ }
- return chars;
- }
+ /**
+ * Decode byte buffer, optionally expanding the char buffer to.
+ */
+ private CharBuffer decode(ByteBuffer bytes, CharBuffer chars) {
+ chars.clear();
+ final int maxCapacity = (int) (bytes.remaining() * decoder
+ .maxCharsPerByte());
+ if (chars.capacity() <= maxCapacity) {
+ chars = CharBuffer.allocate(maxCapacity);
+ }
+
+ bytes.mark();
+ decoder.reset();
+ decoder.decode(bytes, chars, true);
+ chars.flip();
+ bytes.reset();
+
+ return chars;
+ }
}
diff --git a/src/morfologik/tools/DumpTool.java b/src/morfologik/tools/DumpTool.java
deleted file mode 100644
index 5a269a7..0000000
--- a/src/morfologik/tools/DumpTool.java
+++ /dev/null
@@ -1,241 +0,0 @@
-package morfologik.tools;
-
-import java.io.*;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.Locale;
-import java.util.Map;
-
-import morfologik.fsa.FSA;
-import morfologik.fsa.FSAHelpers;
-import morfologik.stemming.*;
-import morfologik.util.FileUtils;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Options;
-
-/**
- * This utility will dump the information and contents of a given {@link FSA}
- * dictionary. It can dump dictionaries in the raw form (as fed to the
- * <code>fsa_build</code> program) or decoding compressed stem forms.
- */
-public final class DumpTool extends Tool {
- /**
- * Writer used to print messages and dictionary dump.
- */
- private OutputStream writer;
-
- /**
- * Print raw data only, no headers.
- */
- private boolean dataOnly;
-
- /**
- * Decode encoded forms if present in the dictionary.
- */
- private boolean decode;
-
- /**
- * Command line entry point after parsing arguments.
- */
- protected void go(CommandLine line) throws Exception {
- final File dictionaryFile = (File) line
- .getParsedOptionValue(SharedOptions.fsaDictionaryFileOption
- .getOpt());
-
- dataOnly = line.hasOption(SharedOptions.dataOnly.getOpt());
- decode = line.hasOption(SharedOptions.decode.getOpt());
-
- FileUtils.assertExists(dictionaryFile, true, false);
-
- dump(dictionaryFile, dataOnly);
- }
-
- /**
- * Dumps the content of a dictionary to a file.
- */
- private void dump(File dictionaryFile, boolean dataOnly)
- throws UnsupportedEncodingException, IOException {
- final long start = System.currentTimeMillis();
-
- final Dictionary dictionary;
- final FSA fsa;
-
- if (!dictionaryFile.canRead()) {
- printWarning("Dictionary file does not exist: "
- + dictionaryFile.getAbsolutePath());
- return;
- }
-
- this.writer = new BufferedOutputStream(System.out, 1024 * 32);
-
- if (hasMetadata(dictionaryFile)) {
- dictionary = Dictionary.read(dictionaryFile);
- fsa = dictionary.fsa;
-
- final String encoding = dictionary.metadata.encoding;
- if (!Charset.isSupported(encoding)) {
- printWarning("Dictionary's charset is not supported "
- + "on this JVM: " + encoding);
- return;
- }
- } else {
- dictionary = null;
- fsa = FSA.getInstance(dictionaryFile, "iso-8859-1");
- printWarning("Warning: FSA automaton without metadata file.");
- }
-
- printExtra("FSA properties");
- printExtra("--------------------");
- printExtra("FSA file version : " + fsa.getVersion());
- printExtra("Compiled with flags : "
- + FSAHelpers.flagsToString(fsa.getFlags()));
- printExtra("Number of arcs : " + fsa.getNumberOfArcs());
- printExtra("Number of nodes : " + fsa.getNumberOfNodes());
- printExtra("Annotation separator: " + fsa.getAnnotationSeparator());
- printExtra("Filler character : " + fsa.getFillerCharacter());
- printExtra("");
-
- if (dictionary != null) {
- printExtra("Dictionary metadata");
- printExtra("--------------------");
- printExtra("Encoding : " + dictionary.metadata.encoding);
- printExtra("Separator byte : 0x"
- + Integer.toHexString(dictionary.metadata.separator)
- + " ('" + decodeSeparator(dictionary) + "')");
- printExtra("Uses prefixes : "
- + dictionary.metadata.usesPrefixes);
- printExtra("Uses infixes : "
- + dictionary.metadata.usesInfixes);
- printExtra("");
-
- printExtra("Dictionary metadata (all keys)");
- printExtra("---------------------------------");
-
- for (Map.Entry<String, String> e : dictionary.metadata.metadata
- .entrySet()) {
- printExtra(String
- .format("%-27s : %s", e.getKey(), e.getValue()));
- }
- printExtra("");
- }
-
- int sequences = 0;
- if (decode) {
- if (dictionary == null) {
- printWarning("No dictionary metadata available.");
- return;
- }
-
- printExtra("Decoded FSA data (in the encoding above)");
- printExtra("----------------------------------------");
-
- final DictionaryLookup dl = new DictionaryLookup(dictionary);
- final StringBuilder builder = new StringBuilder();
- final OutputStreamWriter osw = new OutputStreamWriter(writer,
- dictionary.metadata.encoding);
- final char separator = dictionary.fsa.getAnnotationSeparator();
-
- CharSequence t;
- for (WordData wd : dl) {
- builder.setLength(0);
- builder.append(wd.getWord());
- builder.append(separator);
-
- t = wd.getStem();
- if (t == null)
- t = "";
- builder.append(t);
- builder.append(separator);
-
- t = wd.getTag();
- if (t == null)
- t = "";
- builder.append(t);
- builder.append('\n');
-
- osw.write(builder.toString());
- sequences++;
- }
- osw.flush();
- } else {
- printExtra("FSA data (raw bytes in the encoding above)");
- printExtra("------------------------------------------");
-
- for (ByteBuffer bb : fsa) {
- writer.write(bb.array(), 0, bb.remaining());
- writer.write(0x0a);
- sequences++;
- }
- }
-
- printExtra("--------------------");
-
- final long millis = Math.max(1, System.currentTimeMillis() - start);
- printExtra(String
- .format(
- Locale.ENGLISH,
- "Dictionary dumped in %.3f second(s), %d sequences (%d sequences/sec.).",
- millis / 1000.0, sequences,
- (int) (sequences / (millis / 1000.0))));
-
- writer.flush();
- }
-
- /*
- *
- */
- private void printExtra(String msg) throws IOException {
- if (dataOnly)
- return;
- writer.write(msg.getBytes());
- writer.write(0x0a);
- }
-
- /*
- *
- */
- private void printWarning(String msg) throws IOException {
- System.err.println(msg);
- }
-
- /*
- *
- */
- private String decodeSeparator(Dictionary dictionary) {
- try {
- return new String(new byte[] { dictionary.metadata.separator },
- dictionary.metadata.encoding);
- } catch (UnsupportedEncodingException e) {
- return "<unsupported encoding: " + dictionary.metadata.encoding
- + ">";
- }
- }
-
- /**
- * Check if there is a metadata file for the given FSA automaton.
- */
- private static boolean hasMetadata(File fsaFile) {
- final File featuresFile = new File(fsaFile.getParent(), Dictionary
- .getExpectedFeaturesName(fsaFile.getName()));
-
- return featuresFile.canRead();
- }
-
- /**
- * Command line options for the tool.
- */
- protected void initializeOptions(Options options) {
- options.addOption(SharedOptions.fsaDictionaryFileOption);
- options.addOption(SharedOptions.dataOnly);
- options.addOption(SharedOptions.decode);
- }
-
- /**
- * Command line entry point.
- */
- public static void main(String[] args) throws Exception {
- final DumpTool fsaDump = new DumpTool();
- fsaDump.go(args);
- }
-} \ No newline at end of file
diff --git a/src/morfologik/tools/FSABuildTool.java b/src/morfologik/tools/FSABuildTool.java
new file mode 100644
index 0000000..17ff102
--- /dev/null
+++ b/src/morfologik/tools/FSABuildTool.java
@@ -0,0 +1,486 @@
+package morfologik.tools;
+
+import java.io.*;
+import java.util.*;
+
+import morfologik.fsa.*;
+
+import org.apache.commons.cli.*;
+
+import com.carrotsearch.hppc.IntIntOpenHashMap;
+import com.carrotsearch.hppc.cursors.IntIntCursor;
+
+/**
+ * Convert from plain text input to a serialized FSA in any of the
+ * available {@link Format}s.
+ */
+public final class FSABuildTool extends Tool {
+ /**
+ * One megabyte.
+ */
+ private final static int MB = 1024 * 1024;
+
+ /**
+ * The serialization format to use for the binary output.
+ */
+ public enum Format {
+ FSA5,
+ CFSA2;
+
+ public FSASerializer getSerializer() {
+ switch (this) {
+ case FSA5:
+ return new FSA5Serializer();
+
+ case CFSA2:
+ return new CFSA2Serializer();
+
+ default:
+ throw new RuntimeException();
+ }
+ }
+ }
+
+ /**
+ * Be more verbose about progress.
+ */
+ private boolean printProgress;
+
+ /**
+ * Serializer used for emitting the FSA.
+ */
+ private FSASerializer serializer;
+
+ /**
+ * Output format name.
+ */
+ private Format format;
+
+ /**
+ * Warn about CR characters in the input (usually not what you want).
+ */
+ private boolean crWarning = false;
+
+ /**
+ * If <code>true</code>, the input is not buffered and sorted in-memory, but
+ * must be sorted externally (using the "C" convention: unsigned byte values).
+ */
+ private boolean inputSorted;
+
+ /**
+ * Print additional statistics about the output automaton.
+ */
+ private boolean statistics;
+
+ /**
+ * The actual construction of the FSA.
+ */
+ private FSABuilder builder = new FSABuilder();
+
+ /**
+ * Start time.
+ */
+ private long start = System.currentTimeMillis();
+
+ private IMessageLogger logger;
+
+ /**
+ * Gets fed with the lines read from the input.
+ */
+ private static interface LineConsumer {
+ /**
+ * Process the buffer, return the same buffer or a new buffer (for
+ * swapping).
+ */
+ byte[] process(byte[] buffer, int pos);
+ }
+
+ /**
+ * To help break out of the anonymous delegate on error.
+ */
+ @SuppressWarnings("serial")
+ private static class TerminateProgramException extends RuntimeException {
+ public TerminateProgramException(String msg) {
+ super(msg);
+ }
+
+ public synchronized Throwable fillInStackTrace() {
+ return null;
+ }
+ }
+
+ /**
+ * Command line entry point after parsing arguments.
+ */
+ protected void go(CommandLine line) throws Exception {
+ String[] args = line.getArgs();
+ if (args.length != 0) {
+ printUsage();
+ return;
+ }
+
+ // Parse the input options.
+ parseOptions(line);
+
+ logger = new WriterMessageLogger(new PrintWriter(System.err));
+ this.serializer.withLogger(logger);
+
+ try {
+ InputStream inputStream = initializeInput(line);
+
+ if (inputSorted) {
+ logger.log("Assuming input is already sorted");
+ }
+
+ final FSA fsa;
+ if (inputSorted) {
+ fsa = processSortedInput(inputStream);
+ } else {
+ fsa = processUnsortedInput(inputStream);
+ }
+ if (crWarning) logger.log("Warning: input contained carriage returns?");
+
+ if (statistics) {
+ logger.startPart("Statistics");
+ FSAInfo info = new FSAInfo(fsa);
+ TreeMap<Integer, Integer> fanout = FSAUtils.calculateFanOuts(fsa, fsa.getRootNode());
+ logger.endPart();
+
+ final IntIntOpenHashMap numbers = new IntIntOpenHashMap();
+ fsa.visitInPostOrder(new StateVisitor() {
+ public boolean accept(int state) {
+ int thisNodeNumber = 0;
+ for (int arc = fsa.getFirstArc(state); arc != 0; arc = fsa.getNextArc(arc)) {
+ thisNodeNumber +=
+ (fsa.isArcFinal(arc) ? 1 : 0) +
+ (fsa.isArcTerminal(arc) ? 0 : numbers.get(fsa.getEndNode(arc)));
+ }
+ numbers.put(state, thisNodeNumber);
+ return true;
+ }
+ });
+
+ int singleRLC = 0;
+ for (IntIntCursor c : numbers) {
+ if (c.value == 1) singleRLC++;
+ }
+
+ logger.log("Nodes", info.nodeCount);
+ logger.log("Arcs", info.arcsCount);
+ logger.log("Tail nodes", singleRLC);
+
+ logger.log("States with the given # of outgoing arcs:");
+ for (Map.Entry<Integer, Integer> e : fanout.entrySet()) {
+ logger.log(" #" + e.getKey(), e.getValue());
+ }
+
+ logger.log("FSA builder properties:");
+ for (Map.Entry<FSABuilder.InfoEntry, Object> e : builder.getInfo().entrySet()) {
+ logger.log(e.getKey().toString(), e.getValue());
+ }
+ }
+
+ // Save the result.
+ logger.startPart("Serializing " + format);
+ serializer.serialize(fsa, initializeOutput(line)).close();
+ logger.endPart();
+ } catch (OutOfMemoryError e) {
+ logger.log("Error: Out of memory. Pass -Xmx1024m argument (or more) to java.");
+ }
+ }
+
+ /**
+ * Process unsorted input (sort and construct FSA).
+ */
+ private FSA processUnsortedInput(InputStream inputStream)
+ throws IOException {
+ final FSA root;
+ logger.startPart("Reading input");
+ final ArrayList<byte[]> input = readInput(inputStream);
+ logger.endPart();
+
+ logger.log("Input sequences", input.size());
+
+ logger.startPart("Sorting");
+ Collections.sort(input, FSABuilder.LEXICAL_ORDERING);
+ logger.endPart();
+
+ logger.startPart("Building FSA");
+ for (byte [] bb : input)
+ builder.add(bb, 0, bb.length);
+ root = builder.complete();
+ logger.endPart();
+ return root;
+ }
+
+ /**
+ *
+ */
+ private FSA processSortedInput(InputStream inputStream)
+ throws IOException {
+
+ int lines = forAllLines(inputStream, new LineConsumer() {
+ private byte [] current;
+ private byte [] previous = null;
+ private int previousLen;
+ private int line;
+
+ public byte[] process(byte[] current, int currentLen) {
+ line++;
+
+ // Verify the order.
+ if (previous != null) {
+ if (FSABuilder.compare(previous, 0, previousLen, current, 0, currentLen) > 0) {
+ logger.log("\n\nERROR: The input is not sorted: \n" +
+ dumpLine(previous, previousLen) + "\n" +
+ dumpLine(current, currentLen));
+ throw new TerminateProgramException("Input is not sorted.");
+ }
+ }
+
+ // Add to the automaton.
+ builder.add(current, 0, currentLen);
+
+ // Swap buffers.
+ this.current = previous != null ? previous : new byte [current.length];
+ this.previous = current;
+ this.previousLen = currentLen;
+
+ return this.current;
+ }
+ });
+
+ logger.startPart("Building FSA");
+ FSA fsa = builder.complete();
+ logger.endPart();
+ logger.log("Input sequences", lines);
+
+ return fsa;
+ }
+
+ /**
+ * Dump input line, byte-by-byte.
+ */
+ protected String dumpLine(byte[] line, int length) {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < length; i++) {
+ if (i > 0) builder.append(" ");
+ builder.append(String.format("%02x", line[i]));
+ }
+ builder.append(" | ");
+ for (int i = 0; i < length; i++) {
+ if (Character.isLetterOrDigit(line[i]))
+ builder.append((char) line[i]);
+ else
+ builder.append(".");
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Parse input options.
+ */
+ private void parseOptions(CommandLine line) {
+ String opt;
+
+ opt = SharedOptions.outputFormatOption.getOpt();
+ if (line.hasOption(opt)) {
+ String formatValue = line.getOptionValue(opt);
+ try {
+ format = Format.valueOf(formatValue.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ throw new TerminateProgramException("Not a valid format: "
+ + formatValue);
+ }
+ } else {
+ format = Format.FSA5;
+ }
+ serializer = format.getSerializer();
+
+ opt = SharedOptions.fillerCharacterOption.getLongOpt();
+ if (line.hasOption(opt) && requiredCapability(opt, FSAFlags.SEPARATORS)) {
+ String chr = line.getOptionValue(opt);
+ checkSingleByte(chr);
+ serializer.withFiller(chr.getBytes()[0]);
+ }
+
+ opt = SharedOptions.annotationSeparatorCharacterOption.getLongOpt();
+ if (line.hasOption(opt) && requiredCapability(opt, FSAFlags.SEPARATORS)) {
+ String chr = line.getOptionValue(opt);
+ checkSingleByte(chr);
+ serializer.withAnnotationSeparator(chr.getBytes()[0]);
+ }
+
+ opt = SharedOptions.withNumbersOption.getOpt();
+ if (line.hasOption(opt) && requiredCapability(opt, FSAFlags.NUMBERS)) {
+ serializer.withNumbers();
+ }
+
+ opt = SharedOptions.progressOption.getLongOpt();
+ if (line.hasOption(opt)) {
+ printProgress = true;
+ }
+
+ opt = SharedOptions.inputSortedOption.getLongOpt();
+ if (line.hasOption(opt)) {
+ inputSorted = true;
+ }
+
+ opt = SharedOptions.statistics.getLongOpt();
+ if (line.hasOption(opt)) {
+ statistics = true;
+ }
+ }
+
+ private boolean requiredCapability(String opt, FSAFlags flag) {
+ if (!serializer.getFlags().contains(flag)) {
+ throw new RuntimeException("This serializer does not support option: " + opt);
+ }
+ return true;
+ }
+
+ /**
+ * Check if the argument is a single byte after conversion using platform-default
+ * encoding.
+ */
+ public static void checkSingleByte(String chr) {
+ if (chr.getBytes().length == 1)
+ return;
+
+ throw new IllegalArgumentException("Filler and annotation characters must be single" +
+ "-byte values, " + chr + " has " + chr.getBytes().length + " bytes.");
+ }
+
+ /**
+ * Read all the input lines, unsorted.
+ */
+ private ArrayList<byte[]> readInput(InputStream is) throws IOException {
+ final ArrayList<byte[]> result = new ArrayList<byte[]>();
+ forAllLines(is, new LineConsumer() {
+ public byte[] process(byte[] buffer, int pos) {
+ result.add(java.util.Arrays.copyOf(buffer, pos));
+ return buffer;
+ }
+ });
+ return result;
+ }
+
+ /**
+ * Apply line consumer to all non-empty lines.
+ */
+ private int forAllLines(InputStream is, LineConsumer lineConsumer) throws IOException {
+ int lines = 0;
+ byte[] buffer = new byte[0];
+ int line = 0, b, pos = 0;
+ while ((b = is.read()) != -1) {
+ if (b == '\r' && !crWarning) {
+ crWarning = true;
+ }
+
+ if (b == '\n') {
+ if (pos > 0) {
+ buffer = lineConsumer.process(buffer, pos);
+ pos = 0;
+ lines++;
+ }
+
+ if (printProgress && line++ > 0 && (line % 1000000) == 0) {
+ logger.log(String.format(Locale.ENGLISH, "%6.2fs, sequences: %d", elapsedTime(), line));
+ }
+ } else {
+ if (pos >= buffer.length) {
+ buffer = java.util.Arrays.copyOf(buffer, buffer.length + 10);
+ }
+ buffer[pos++] = (byte) b;
+ }
+ }
+
+ if (pos > 0) {
+ lineConsumer.process(buffer, pos);
+ lines++;
+ }
+
+ return lines;
+ }
+
+ private double elapsedTime() {
+ return (System.currentTimeMillis() - start) / 1000.0d;
+ }
+
+ @Override
+ protected void printUsage() {
+ final HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp(this.getClass().getName(), options, true);
+ }
+
+ @Override
+ protected void initializeOptions(Options options) {
+ options.addOption(SharedOptions.inputFileOption);
+ options.addOption(SharedOptions.outputFileOption);
+
+ options.addOption(SharedOptions.outputFormatOption);
+
+ options.addOption(SharedOptions.fillerCharacterOption);
+ options.addOption(SharedOptions.annotationSeparatorCharacterOption);
+
+ options.addOption(SharedOptions.withNumbersOption);
+ options.addOption(SharedOptions.progressOption);
+
+ options.addOption(SharedOptions.inputSortedOption);
+
+ options.addOption(SharedOptions.statistics);
+ }
+
+ /**
+ *
+ */
+ private static OutputStream initializeOutput(CommandLine line)
+ throws IOException, ParseException {
+ final OutputStream output;
+ final String opt = SharedOptions.outputFileOption.getOpt();
+ if (line.hasOption(opt)) {
+ // Use output file.
+ output = new FileOutputStream((File) line.getParsedOptionValue(opt));
+ } else {
+ // Use standard output.
+ output = System.out;
+ }
+ return new BufferedOutputStream(output);
+ }
+
+ /**
+ *
+ */
+ private InputStream initializeInput(CommandLine line)
+ throws IOException, ParseException {
+ final InputStream input;
+ final String opt = SharedOptions.inputFileOption.getOpt();
+
+ if (line.hasOption(opt)) {
+ // Use input file.
+ File inputFile = (File) line.getParsedOptionValue(opt);
+ if (!inputSorted && inputFile.length() > 20 * MB) {
+ logger.log("WARN: The input file is quite large, avoid\n" +
+ " in-memory sorting by piping pre-sorted\n" +
+ " input directly to fsa_build. Linux:\n" +
+ " export LC_ALL=C && \\\n" +
+ " sort input | \\\n" +
+ " java -jar morfologik.jar fsa_build --sorted -o dict.fsa");
+ }
+
+ input = new FileInputStream(inputFile);
+ } else {
+ // Use standard input.
+ input = System.in;
+ }
+ return new BufferedInputStream(input);
+ }
+
+ /**
+ * Command line entry point.
+ */
+ public static void main(String[] args) throws Exception {
+ final FSABuildTool tool = new FSABuildTool();
+ tool.go(args);
+ }
+} \ No newline at end of file
diff --git a/src/morfologik/tools/FSADumpTool.java b/src/morfologik/tools/FSADumpTool.java
new file mode 100644
index 0000000..281d187
--- /dev/null
+++ b/src/morfologik/tools/FSADumpTool.java
@@ -0,0 +1,286 @@
+package morfologik.tools;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.Locale;
+import java.util.Map;
+
+import morfologik.fsa.*;
+import morfologik.stemming.*;
+import morfologik.util.FileUtils;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+
+/**
+ * This utility will dump the information and contents of a given {@link FSA}
+ * dictionary. It can dump dictionaries in the raw form (as fed to the
+ * <code>fsa_build</code> program) or decoding compressed stem forms.
+ */
+public final class FSADumpTool extends Tool {
+ /**
+ * Writer used to print messages and dictionary dump.
+ */
+ private OutputStream os;
+
+ /**
+ * Print raw data only, no headers.
+ */
+ private boolean dataOnly;
+
+ /**
+ * Decode from prefix/infix/suffix encodings.
+ */
+ private boolean decode;
+
+ /**
+ * Dump graphviz DOT file instead of automaton sequences.
+ */
+ private boolean dot;
+
+ /**
+ * Command line entry point after parsing arguments.
+ */
+ protected void go(CommandLine line) throws Exception {
+ final File dictionaryFile = (File) line
+ .getParsedOptionValue(SharedOptions.fsaDictionaryFileOption
+ .getOpt());
+
+ dataOnly = line.hasOption(SharedOptions.dataOnly.getOpt());
+ decode = line.hasOption(SharedOptions.decode.getOpt());
+ dot = line.hasOption(SharedOptions.dot.getLongOpt());
+
+ FileUtils.assertExists(dictionaryFile, true, false);
+
+ dump(dictionaryFile);
+ }
+
+ /**
+ * Dumps the content of a dictionary to a file.
+ */
+ private void dump(File dictionaryFile)
+ throws UnsupportedEncodingException, IOException {
+ final long start = System.currentTimeMillis();
+
+ final Dictionary dictionary;
+ final FSA fsa;
+
+ if (!dictionaryFile.canRead()) {
+ printWarning("Dictionary file does not exist: "
+ + dictionaryFile.getAbsolutePath());
+ return;
+ }
+
+ this.os = new BufferedOutputStream(System.out, 1024 * 32);
+
+ if (hasMetadata(dictionaryFile)) {
+ dictionary = Dictionary.read(dictionaryFile);
+ fsa = dictionary.fsa;
+
+ final String encoding = dictionary.metadata.encoding;
+ if (!Charset.isSupported(encoding)) {
+ printWarning("Dictionary's charset is not supported "
+ + "on this JVM: " + encoding);
+ return;
+ }
+ } else {
+ dictionary = null;
+ fsa = FSA.read(new FileInputStream(dictionaryFile));
+ printWarning("Warning: FSA automaton without metadata file.");
+ }
+
+ printExtra("FSA properties");
+ printExtra("--------------------");
+ printExtra("FSA implementation : " + fsa.getClass().getName());
+ printExtra("Compiled with flags : " + fsa.getFlags().toString());
+
+ if (!dataOnly) {
+ final FSAInfo info = new FSAInfo(fsa);
+ printExtra("Number of arcs : "
+ + info.arcsCount + "/" + info.arcsCountTotal);
+ printExtra("Number of nodes : " + info.nodeCount);
+ printExtra("Number of final st. : " + info.finalStatesCount);
+ printExtra("");
+ }
+
+ // Separator for dumping.
+ char separator = '\t';
+
+ if (fsa instanceof FSA5) {
+ printExtra("FSA5 properties");
+ printExtra("--------------------");
+ printFSA5((FSA5) fsa);
+ printExtra("");
+ }
+
+ if (dictionary != null) {
+ printExtra("Dictionary metadata");
+ printExtra("--------------------");
+ printExtra("Encoding : " + dictionary.metadata.encoding);
+ printExtra("Separator byte : 0x"
+ + Integer.toHexString(dictionary.metadata.separator)
+ + " ('" + decodeSeparator(dictionary) + "')");
+ printExtra("Uses prefixes : "
+ + dictionary.metadata.usesPrefixes);
+ printExtra("Uses infixes : "
+ + dictionary.metadata.usesInfixes);
+ printExtra("");
+
+ printExtra("Dictionary metadata (all keys)");
+ printExtra("---------------------------------");
+
+ for (Map.Entry<String, String> e : dictionary.metadata.metadata
+ .entrySet()) {
+ printExtra(String
+ .format("%-27s : %s", e.getKey(), e.getValue()));
+ }
+ printExtra("");
+ }
+
+ int sequences = 0;
+ if (decode) {
+ if (dictionary == null) {
+ printWarning("No dictionary metadata available.");
+ return;
+ }
+
+ printExtra("Decoded FSA data (in the encoding above)");
+ printExtra("----------------------------------------");
+
+ final DictionaryLookup dl = new DictionaryLookup(dictionary);
+ final StringBuilder builder = new StringBuilder();
+ final OutputStreamWriter osw = new OutputStreamWriter(os,
+ dictionary.metadata.encoding);
+
+ CharSequence t;
+ for (WordData wd : dl) {
+ builder.setLength(0);
+ builder.append(wd.getWord());
+ builder.append(separator);
+
+ t = wd.getStem();
+ if (t == null)
+ t = "";
+ builder.append(t);
+ builder.append(separator);
+
+ t = wd.getTag();
+ if (t == null)
+ t = "";
+ builder.append(t);
+ builder.append('\n');
+
+ osw.write(builder.toString());
+ sequences++;
+ }
+ osw.flush();
+ } else {
+ if (dot) {
+ Writer w = new OutputStreamWriter(os);
+ FSAUtils.toDot(w, fsa, fsa.getRootNode());
+ w.flush();
+ } else {
+ printExtra("FSA data (raw bytes in the encoding above)");
+ printExtra("------------------------------------------");
+
+ for (ByteBuffer bb : fsa) {
+ os.write(bb.array(), 0, bb.remaining());
+ os.write(0x0a);
+ sequences++;
+ }
+ }
+ }
+
+ printExtra("--------------------");
+
+ final long millis = Math.max(1, System.currentTimeMillis() - start);
+ printExtra(String
+ .format(
+ Locale.ENGLISH,
+ "Dictionary dumped in %.3f second(s), %d sequences (%d sequences/sec.).",
+ millis / 1000.0, sequences,
+ (int) (sequences / (millis / 1000.0))));
+
+ os.flush();
+ }
+
+ /**
+ * Print {@link FSA5}-specific stuff.
+ */
+ private void printFSA5(FSA5 fsa) throws IOException {
+ printExtra("GTL : " + fsa.gtl);
+ printExtra("Node extra data : " + fsa.nodeDataLength);
+ printExtra("Annotation separator: " + byteAsChar(fsa.annotation));
+ printExtra("Filler character : " + byteAsChar(fsa.filler));
+ }
+
+ /**
+ * Convert a byte to a character, no charset decoding, simple ASCII range mapping.
+ */
+ private char byteAsChar(byte v) {
+ char chr = (char) (v & 0xff);
+ if (chr < 127)
+ return chr;
+ else
+ return '?';
+ }
+
+ /*
+ *
+ */
+ private void printExtra(String msg) throws IOException {
+ if (dataOnly)
+ return;
+ os.write(msg.getBytes());
+ os.write(0x0a);
+ }
+
+ /*
+ *
+ */
+ private void printWarning(String msg) {
+ System.err.println(msg);
+ }
+
+ /*
+ *
+ */
+ private String decodeSeparator(Dictionary dictionary) {
+ try {
+ return new String(new byte[] { dictionary.metadata.separator },
+ dictionary.metadata.encoding);
+ } catch (UnsupportedEncodingException e) {
+ return "<unsupported encoding: " + dictionary.metadata.encoding
+ + ">";
+ }
+ }
+
+ /**
+ * Check if there is a metadata file for the given FSA automaton.
+ */
+ private static boolean hasMetadata(File fsaFile) {
+ final File featuresFile = new File(fsaFile.getParent(), Dictionary
+ .getExpectedFeaturesName(fsaFile.getName()));
+
+ return featuresFile.canRead();
+ }
+
+ /**
+ * Command line options for the tool.
+ */
+ protected void initializeOptions(Options options) {
+ options.addOption(SharedOptions.fsaDictionaryFileOption);
+ options.addOption(SharedOptions.dataOnly);
+ options.addOption(SharedOptions.decode);
+ options.addOption(SharedOptions.dot);
+ }
+
+ /**
+ * Command line entry point.
+ */
+ public static void main(String[] args) throws Exception {
+ final FSADumpTool fsaDump = new FSADumpTool();
+ fsaDump.go(args);
+ }
+} \ No newline at end of file
diff --git a/src/morfologik/tools/IMessageLogger.java b/src/morfologik/tools/IMessageLogger.java
new file mode 100644
index 0000000..14f9f00
--- /dev/null
+++ b/src/morfologik/tools/IMessageLogger.java
@@ -0,0 +1,25 @@
+package morfologik.tools;
+
+public interface IMessageLogger {
+
+ /**
+ * Log progress to the console.
+ */
+ public void log(String msg);
+
+ /**
+ * Log message header and save current time.
+ */
+ public void startPart(String header);
+
+ /**
+ *
+ */
+ public void endPart();
+
+ /**
+ * Log a two-part message.
+ */
+ public void log(String header, Object v);
+
+} \ No newline at end of file
diff --git a/src/morfologik/tools/InflectionFramesTool.java b/src/morfologik/tools/InflectionFramesTool.java
index a006048..612f62c 100644
--- a/src/morfologik/tools/InflectionFramesTool.java
+++ b/src/morfologik/tools/InflectionFramesTool.java
@@ -12,102 +12,107 @@ import morfologik.stemming.Dictionary;
import org.junit.Test;
/**
- * Calculate inflection frames from the Polish dictionary.
+ * Calculate inflection frames from the Polish dictionary.
*/
public class InflectionFramesTool {
- public static void main(String[] args) throws IOException {
- new InflectionFramesTool().inflectionFrames();
- }
-
- /* */
- @Test
- @SuppressWarnings({ "unused", "unchecked" })
- public void inflectionFrames() throws IOException {
- final Dictionary pl = Dictionary.getForLanguage("pl");
- final DictionaryLookup dict = new DictionaryLookup(pl);
-
- final CharsetDecoder decoder = Charset.forName(pl.metadata.encoding)
- .newDecoder().onMalformedInput(CodingErrorAction.REPORT)
- .onUnmappableCharacter(CodingErrorAction.REPORT);
-
- final HashMap<String, ArrayList<String>> forms = new HashMap();
-
- ByteBuffer stemBuffer = ByteBuffer.allocate(0);
- ByteBuffer inflBuffer = ByteBuffer.allocate(0);
- ByteBuffer stemDecoded = ByteBuffer.allocate(0);
-
- int limit = Integer.MAX_VALUE;
-
- final Iterator<WordData> i = new DictionaryIterator(pl, decoder, false);
- while (i.hasNext() && limit-- > 0) {
- final WordData wd = i.next();
-
- final CharSequence inflected = wd.getWord();
- final CharSequence stemEncoded = wd.getStem();
- final CharSequence tag = wd.getTag();
- if (tag == null)
- continue;
-
- inflBuffer.clear();
- inflBuffer = wd.getWordBytes(inflBuffer);
-
- stemBuffer.clear();
- stemBuffer = wd.getStemBytes(stemBuffer);
-
- stemDecoded = DictionaryLookup.decodeStem(stemDecoded, stemBuffer
- .array(), stemBuffer.remaining(), inflBuffer, pl.metadata);
- stemDecoded.flip();
-
- final String stem = decoder.decode(stemDecoded).toString();
- final String form = tag.toString().intern();
-
- ArrayList<String> frames = forms.get(stem);
- if (frames == null) {
- forms.put(stem, frames = new ArrayList<String>());
- }
-
- if (!frames.contains(form)) {
- frames.add(form);
- }
- }
-
- // Sort the forms so that we get a unique key. Then iteratively add them
- // to another hash (by form this time).
- final HashMap<String, ArrayList<String>> frames = new HashMap();
-
- StringBuilder key = new StringBuilder();
- for (Map.Entry<String, ArrayList<String>> e : forms.entrySet()) {
- Collections.sort(e.getValue());
-
- key.setLength(0);
- for (String s : e.getValue())
- key.append(s).append(" ");
-
- final String k = key.toString();
- ArrayList<String> words = frames.get(k);
- if (words == null) {
- frames.put(k, words = new ArrayList<String>());
- }
- words.add(e.getKey());
-
- e.setValue(null);
+ public static void main(String[] args) throws IOException {
+ new InflectionFramesTool().inflectionFrames();
}
- // Print inflection frames.
- ArrayList<Map.Entry<String, ArrayList<String>>> entries = new ArrayList();
- entries.addAll(frames.entrySet());
- Collections.sort(entries, new Comparator<Map.Entry<String, ArrayList<String>>>() {
- public int compare(Entry<String, ArrayList<String>> o1,
- Entry<String, ArrayList<String>> o2) {
- return o2.getValue().size() - o1.getValue().size();
- }
- });
-
- for (Map.Entry<String, ArrayList<String>> e : entries) {
- System.out.println(String.format("%6d %s %s",
- e.getValue().size(), e.getKey(), e.getValue()));
+ /* */
+ @Test
+ @SuppressWarnings( { "unused" })
+ public void inflectionFrames() throws IOException {
+ final Dictionary pl = Dictionary.getForLanguage("pl");
+ final DictionaryLookup dict = new DictionaryLookup(pl);
+
+ final CharsetDecoder decoder = Charset.forName(pl.metadata.encoding)
+ .newDecoder().onMalformedInput(CodingErrorAction.REPORT)
+ .onUnmappableCharacter(CodingErrorAction.REPORT);
+
+ final HashMap<String, ArrayList<String>> forms =
+ new HashMap<String, ArrayList<String>>();
+
+ ByteBuffer stemBuffer = ByteBuffer.allocate(0);
+ ByteBuffer inflBuffer = ByteBuffer.allocate(0);
+ ByteBuffer stemDecoded = ByteBuffer.allocate(0);
+
+ int limit = Integer.MAX_VALUE;
+
+ final Iterator<WordData> i = new DictionaryIterator(pl, decoder, false);
+ while (i.hasNext() && limit-- > 0) {
+ final WordData wd = i.next();
+
+ final CharSequence inflected = wd.getWord();
+ final CharSequence stemEncoded = wd.getStem();
+ final CharSequence tag = wd.getTag();
+ if (tag == null)
+ continue;
+
+ inflBuffer.clear();
+ inflBuffer = wd.getWordBytes(inflBuffer);
+
+ stemBuffer.clear();
+ stemBuffer = wd.getStemBytes(stemBuffer);
+
+ stemDecoded = DictionaryLookup.decodeStem(stemDecoded, stemBuffer
+ .array(), stemBuffer.remaining(), inflBuffer, pl.metadata);
+ stemDecoded.flip();
+
+ final String stem = decoder.decode(stemDecoded).toString();
+ final String form = tag.toString().intern();
+
+ ArrayList<String> frames = forms.get(stem);
+ if (frames == null) {
+ forms.put(stem, frames = new ArrayList<String>());
+ }
+
+ if (!frames.contains(form)) {
+ frames.add(form);
+ }
+ }
+
+ // Sort the forms so that we get a unique key. Then iteratively add them
+ // to another hash (by form this time).
+ final HashMap<String, ArrayList<String>> frames =
+ new HashMap<String, ArrayList<String>>();
+
+ StringBuilder key = new StringBuilder();
+ for (Map.Entry<String, ArrayList<String>> e : forms.entrySet()) {
+ Collections.sort(e.getValue());
+
+ key.setLength(0);
+ for (String s : e.getValue())
+ key.append(s).append(" ");
+
+ final String k = key.toString();
+ ArrayList<String> words = frames.get(k);
+ if (words == null) {
+ frames.put(k, words = new ArrayList<String>());
+ }
+ words.add(e.getKey());
+
+ e.setValue(null);
+ }
+
+ // Print inflection frames.
+ ArrayList<Map.Entry<String, ArrayList<String>>> entries =
+ new ArrayList<Map.Entry<String, ArrayList<String>>>();
+
+ entries.addAll(frames.entrySet());
+ Collections.sort(entries,
+ new Comparator<Map.Entry<String, ArrayList<String>>>() {
+ public int compare(Entry<String, ArrayList<String>> o1,
+ Entry<String, ArrayList<String>> o2) {
+ return o2.getValue().size() - o1.getValue().size();
+ }
+ });
+
+ for (Map.Entry<String, ArrayList<String>> e : entries) {
+ System.out.println(String.format("%6d %s %s",
+ e.getValue().size(), e.getKey(), e.getValue()));
+ }
+
+ System.out.println("Total frames: " + frames.size());
}
-
- System.out.println("Total frames: " + frames.size());
- }
}
diff --git a/src/morfologik/tools/Launcher.java b/src/morfologik/tools/Launcher.java
index 7332d75..667a6e1 100644
--- a/src/morfologik/tools/Launcher.java
+++ b/src/morfologik/tools/Launcher.java
@@ -1,67 +1,159 @@
package morfologik.tools;
+import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Iterator;
import java.util.TreeMap;
+import java.util.jar.Manifest;
+import morfologik.util.FileUtils;
/**
* A launcher for other command-line tools.
*/
public final class Launcher {
- /**
- * Tool description.
- */
- final static class ToolInfo {
- public final Class<? extends Tool> clazz;
- public final String info;
-
- public ToolInfo(Class<? extends Tool> clazz, String info) {
- this.clazz = clazz;
- this.info = info;
+ /**
+ * Tool description.
+ */
+ final static class ToolInfo {
+ public final Class<? extends Tool> clazz;
+ public final String info;
+
+ public ToolInfo(Class<? extends Tool> clazz, String info) {
+ this.clazz = clazz;
+ this.info = info;
+ }
+
+ public void invoke(String[] subArgs) throws Exception {
+ final Method m = clazz.getMethod("main",
+ new Class[] { String[].class });
+ m.invoke(null, new Object[] { subArgs });
+ }
}
- public void invoke(String[] subArgs) throws Exception {
- final Method m = clazz.getMethod("main",
- new Class[] { String[].class });
- m.invoke(null, new Object[] { subArgs });
+ /**
+ * Command line entry point.
+ */
+ public static void main(String[] args) throws Exception {
+ // If so, tools are unavailable and a classpath error has been logged.
+ final TreeMap<String, ToolInfo> tools = initTools();
+
+ if (tools == null)
+ {
+ return;
+ }
+
+ if (args.length == 0) {
+ System.out
+ .println("Provide tool name and its command-line options. "
+ + "Available tools:");
+ for (String key : tools.keySet()) {
+ final ToolInfo toolInfo = tools.get(key);
+ System.out.println(String.format(" %-10s - %s", key,
+ toolInfo.info));
+ }
+ } else {
+ final String toolName = args[0];
+ if (!tools.containsKey(toolName)) {
+ System.out.println("Unknown tool: " + toolName);
+ return;
+ }
+
+ final String[] subArgs = new String[args.length - 1];
+ System.arraycopy(args, 1, subArgs, 0, subArgs.length);
+
+ final ToolInfo toolInfo = (ToolInfo) tools.get(toolName);
+ toolInfo.invoke(subArgs);
+ }
}
- }
- /**
- * Known tools.
- */
- static TreeMap<String, ToolInfo> tools;
- static {
- tools = new TreeMap<String, ToolInfo>();
- tools.put("dump", new ToolInfo(DumpTool.class,
- "Dump an FSA dictionary."));
- tools.put("plstem", new ToolInfo(PolishStemmingTool.class,
- "Apply Polish stemming to the input."));
- }
+ /**
+ * Initialize and check tools' availability.
+ */
+ static TreeMap<String, ToolInfo> initTools() {
+ TreeMap<String, ToolInfo> tools = new TreeMap<String, ToolInfo>();
- /**
- * Command line entry point.
- */
- public static void main(String[] args) throws Exception {
- if (args.length == 0) {
- System.out.println("Provide tool name and its command-line options. "
- + "Available tools:");
- for (String key : tools.keySet()) {
- final ToolInfo toolInfo = tools.get(key);
- System.out.println(String.format(" %-10s - %s", key, toolInfo.info));
- }
- } else {
- final String toolName = args[0];
- if (!tools.containsKey(toolName)) {
- System.out.println("Unknown tool: " + toolName);
- return;
- }
-
- final String[] subArgs = new String[args.length - 1];
- System.arraycopy(args, 1, subArgs, 0, subArgs.length);
-
- final ToolInfo toolInfo = (ToolInfo) tools.get(toolName);
- toolInfo.invoke(subArgs);
+ tools.put("fsa_build", new ToolInfo(FSABuildTool.class,
+ "Create an automaton from plain text files."));
+
+ tools.put("fsa_dump", new ToolInfo(FSADumpTool.class,
+ "Dump an FSA dictionary."));
+
+ tools.put("tab2morph", new ToolInfo(MorphEncodingTool.class,
+ "Convert tabbed dictionary to fsa encoding format."));
+
+ tools.put("plstem", new ToolInfo(PolishStemmingTool.class,
+ "Apply Polish dictionary stemming to the input."));
+
+ // Prune unavailable tools.
+ for (Iterator<ToolInfo> i = tools.values().iterator(); i.hasNext();) {
+ ToolInfo ti = i.next();
+ try {
+ ti.clazz.newInstance().isAvailable();
+ } catch (NoClassDefFoundError e) {
+ logJarWarning();
+ return null;
+ } catch (Throwable e) {
+ System.out.println("Tools could not be initialized because" +
+ " of an exception during initialization: "
+ + e.getClass().getName() + ", " + e.getMessage());
+ return null;
+ }
+ }
+
+ return tools;
}
+
+ /**
+ * Log a warning about missing JAR dependencies.
+ */
+ private static void logJarWarning() {
+ System.out.println("Tools are unavailable, at least one JAR dependency missing.");
+
+ try {
+ final Class<Launcher> clazz = Launcher.class;
+ final ClassLoader classLoader = clazz.getClassLoader();
+
+ final String clazzName = clazz.getName().replace('.', '/') + ".class";
+ // Figure out our own class path location.
+ final URL launcherLocation = classLoader.getResource(clazzName);
+ if (launcherLocation == null)
+ return;
+
+ String launcherPrefix = launcherLocation.toString()
+ .replace(clazzName, "");
+
+ // Figure our our location's MANIFEST.MF (class loader may be hitting a few).
+ URL manifestResource = null;
+ Enumeration<URL> manifests = classLoader.getResources("META-INF/MANIFEST.MF");
+ while (manifests.hasMoreElements())
+ {
+ URL candidate = manifests.nextElement();
+ if (candidate.toString().startsWith(launcherPrefix))
+ {
+ manifestResource = candidate;
+ break;
+ }
+ }
+
+ if (manifestResource == null)
+ return;
+
+ InputStream stream = null;
+ try {
+ stream = manifestResource.openStream();
+ Manifest manifest = new Manifest(stream);
+
+ System.out.println("Required JARs: "
+ + manifest.getMainAttributes().getValue("Class-Path"));
+ } catch (IOException e) {
+ FileUtils.close(stream);
+ }
+ } catch (IOException e) {
+ // Ignore.
+ }
}
}
diff --git a/src/morfologik/tools/MorphEncoder.java b/src/morfologik/tools/MorphEncoder.java
new file mode 100644
index 0000000..236c1aa
--- /dev/null
+++ b/src/morfologik/tools/MorphEncoder.java
@@ -0,0 +1,399 @@
+package morfologik.tools;
+
+import java.io.UnsupportedEncodingException;
+
+import morfologik.fsa.FSA5;
+
+/**
+ * A class that converts tabular data to fsa morphological format. Three formats
+ * are supported:
+ * <ul>
+ * <li><b>standard</b>, see {@link #standardEncode}</li>
+ * <li><b>prefix</b>, see {@link #prefixEncode}</li>
+ * <li><b>infix</b>, see {@link #infixEncode}</li>
+ * </ul>
+ */
+public final class MorphEncoder {
+ private final byte annotationSeparator;
+
+ private static final int MAX_PREFIX_LEN = 3;
+ private static final int MAX_INFIX_LEN = 3;
+
+ private static final String UTF8 = "UTF-8";
+
+ public MorphEncoder() {
+ this(FSA5.DEFAULT_ANNOTATION);
+ }
+
+ public MorphEncoder(byte annotationSeparator) {
+ this.annotationSeparator = annotationSeparator;
+ }
+
+ public static int commonPrefix(final byte[] s1, final byte[] s2) {
+ final int maxLen = Math.min(s1.length, s2.length);
+ for (int i = 0; i < maxLen; i++) {
+ if (s1[i] != s2[i]) {
+ return i;
+ }
+ }
+ return maxLen;
+ }
+
+ private static byte[] subsequence(final byte[] bytes, final int start) {
+ final byte[] newArray = new byte[bytes.length - start];
+ System.arraycopy(bytes, start, newArray, 0, bytes.length - start);
+ return newArray;
+ }
+
+ private static int copyTo(byte[] dst, final int pos, final byte[] src) {
+ System.arraycopy(src, 0, dst, pos, src.length);
+ return src.length;
+ }
+
+ private static int copyTo(byte[] dst, final int pos, final byte src) {
+ byte[] single = new byte[1];
+ single[0] = src;
+ System.arraycopy(single, 0, dst, pos, 1);
+ return 1;
+ }
+
+ /**
+ * This method converts the wordForm, wordLemma and tag to the form:
+ *
+ * <pre>
+ * wordForm + Kending + tags
+ * </pre>
+ *
+ * where '+' is a separator, K is a character that specifies how many
+ * characters should be deleted from the end of the inflected form to
+ * produce the lexeme by concatenating the stripped string with the ending.
+ *
+ */
+ public byte[] standardEncode(final byte[] wordForm,
+ final byte[] wordLemma, final byte[] wordTag) {
+ final int l1 = wordForm.length;
+ final int prefix = commonPrefix(wordForm, wordLemma);
+ final int len = wordLemma.length - prefix;
+ int pos = 0;
+ // 3 = 2 separators and K character
+ int arrayLen = l1 + len + 3;
+ if (wordTag != null) { //wordTag may be empty for stemming
+ arrayLen += wordTag.length;
+ }
+ final byte[] bytes = new byte[arrayLen];
+ pos += copyTo(bytes, pos, wordForm);
+ pos += copyTo(bytes, pos, annotationSeparator);
+ if (prefix == 0) {
+ pos += copyTo(bytes, pos, (byte) ((l1 + 65) & 0xff));
+ pos += copyTo(bytes, pos, wordLemma);
+ } else {
+ pos += copyTo(bytes, pos, (byte) ((l1 - prefix + 65) & 0xff));
+ pos += copyTo(bytes, pos, subsequence(wordLemma, prefix));
+ }
+ pos += copyTo(bytes, pos, annotationSeparator);
+ if (wordTag != null) {
+ pos += copyTo(bytes, pos, wordTag);
+ }
+ return bytes;
+ }
+
+ /**
+ * This method converts wordform, wordLemma and the tag to the form:
+ * <p>
+ *
+ * <pre>
+ * inflected_form + LKending + tags
+ * </pre>
+ * <p>
+ * where '+' is a separator, L is the number of characters to be deleted
+ * from the beginning of the word ("A" means none, "B" means one, "C" - 2,
+ * etc.), K is a character that specifies how many characters should be
+ * deleted from the end of the inflected form to produce the lexeme by
+ * concatenating the stripped string with the ending ("A" means none,
+ * "B' - 1, "C" - 2, and so on).
+ *
+ * @param wordForm
+ * - inflected word form
+ * @param wordLemma
+ * - canonical form
+ * @param wordTag
+ * - tag
+ * @return the encoded string
+ */
+ public byte[] prefixEncode(final byte[] wordForm,
+ final byte[] wordLemma, final byte[] wordTag) {
+ final int l1 = wordForm.length;
+ final int prefix = commonPrefix(wordForm, wordLemma);
+
+ // 4 = 2 separators + LK characters
+ int arrayLen = l1 + wordLemma.length + 4;
+ if (wordTag != null) {
+ arrayLen += wordTag.length;
+ }
+ final byte[] bytes = new byte[arrayLen];
+ int pos = 0;
+ pos += copyTo(bytes, pos, wordForm);
+ pos += copyTo(bytes, pos, annotationSeparator);
+ if (prefix == 0) {
+ int prefixFound = 0;
+ int prefix1 = 0;
+ final int max = Math.min(wordForm.length, MAX_PREFIX_LEN);
+ for (int i = 1; i <= max; i++) {
+ prefix1 = commonPrefix(subsequence(wordForm, i), wordLemma);
+ if (prefix1 > 2) {
+ prefixFound = i;
+ break;
+ }
+ }
+ if (prefixFound == 0) {
+ pos += copyTo(bytes, pos, (byte) 'A');
+ pos += copyTo(bytes, pos, (byte) ((l1 + 65) & 0xff));
+ pos += copyTo(bytes, pos, wordLemma);
+ } else {
+ pos += copyTo(bytes, pos, (byte) ((prefixFound + 65) & 0xff));
+ pos += copyTo(bytes, pos,
+ (byte) ((l1 - prefixFound - prefix1 + 65) & 0xff));
+ pos += copyTo(bytes, pos, subsequence(wordLemma, prefix1));
+ }
+ } else {
+ pos += copyTo(bytes, pos, (byte) 'A');
+ pos += copyTo(bytes, pos, (byte) ((l1 - prefix + 65) & 0xff));
+ pos += copyTo(bytes, pos, subsequence(wordLemma, prefix));
+ }
+ pos += copyTo(bytes, pos, annotationSeparator);
+ if (wordTag != null) {
+ pos += copyTo(bytes, pos, wordTag);
+ }
+ final byte[] finalArray = new byte[pos];
+ System.arraycopy(bytes, 0, finalArray, 0, pos);
+ return finalArray;
+ }
+
+ /**
+ * This method converts wordform, wordLemma and the tag to the form:
+ * <pre>
+ * inflected_form + MLKending + tags
+ * </pre>
+ * <p>
+ * where '+' is a separator, M is the position of characters to be deleted
+ * towards the beginning of the inflected form ("A" means from the
+ * beginning, "B" from the second character, "C" - from the third one, and
+ * so on), L is the number of characters to be deleted from the position
+ * specified by M ("A" means none, "B" means one, "C" - 2, etc.), K is a
+ * character that specifies how many characters should be deleted from the
+ * end of the inflected form to produce the lexeme by concatenating the
+ * stripped string with the ending ("A" means none, "B' - 1, "C" - 2, and so
+ * on).
+ *
+ * @param wordForm
+ * - inflected word form
+ * @param wordLemma
+ * - canonical form
+ * @param wordTag
+ * - tag
+ * @return the encoded string
+ */
+ public byte[] infixEncode(final byte[] wordForm,
+ final byte[] wordLemma, final byte[] wordTag) {
+ final int l1 = wordForm.length;
+ int prefixFound = 0;
+ int prefix1 = 0;
+ final int prefix = commonPrefix(wordForm, wordLemma);
+ final int max = Math.min(l1, MAX_INFIX_LEN);
+
+ // 5 = 2 separators + MLK characters
+ int arrayLen = l1 + wordLemma.length + 5;
+ if (wordTag != null) {
+ arrayLen += wordTag.length;
+ }
+ final byte[] bytes = new byte[arrayLen];
+ int pos = 0;
+ pos += copyTo(bytes, pos, wordForm);
+ pos += copyTo(bytes, pos, annotationSeparator);
+ if (prefix == 0) {
+ // we may have a prefix
+ for (int i = 1; i <= max; i++) {
+ prefix1 = commonPrefix(subsequence(wordForm, i), wordLemma);
+ if (prefix1 > 2) {
+ prefixFound = i;
+ break;
+ }
+ }
+ if (prefixFound == 0) {
+ pos += copyTo(bytes, pos, (byte) 'A');
+ pos += copyTo(bytes, pos, (byte) 'A');
+ pos += copyTo(bytes, pos, (byte) ((l1 + 65) & 0xff));
+ pos += copyTo(bytes, pos, wordLemma);
+ } else {
+ pos += copyTo(bytes, pos, (byte) 'A');
+ pos += copyTo(bytes, pos, (byte) ((prefixFound + 65) & 0xff));
+ pos += copyTo(bytes, pos,
+ (byte) ((l1 - prefixFound - prefix1 + 65) & 0xff));
+ pos += copyTo(bytes, pos, subsequence(wordLemma, prefix1));
+ }
+ } else { // prefix found but we have to check the infix
+
+ for (int i = 1; i <= max; i++) {
+ prefix1 = commonPrefix(subsequence(wordForm, i), wordLemma);
+ if (prefix1 > 2) {
+ prefixFound = i;
+ break;
+ }
+ }
+ int prefix2 = 0;
+ int infixFound = 0;
+ final int max2 = Math.min(l1 - prefix, MAX_INFIX_LEN);
+ for (int i = 1; i <= max2; i++) {
+ prefix2 = commonPrefix(subsequence(wordForm, prefix + i),
+ subsequence(wordLemma, prefix));
+ if (prefix2 > 2) {
+ infixFound = i;
+ break;
+ }
+ }
+
+ if (prefixFound > infixFound) {
+ if (prefixFound > 0 && (prefix1 > prefix)) {
+ pos += copyTo(bytes, pos, (byte) 'A');
+ pos += copyTo(bytes, pos,
+ (byte) ((prefixFound + 65) & 0xff));
+ pos += copyTo(bytes, pos, (byte) ((l1 - prefixFound
+ - prefix1 + 65) & 0xff));
+ pos += copyTo(bytes, pos, subsequence(wordLemma, prefix1));
+ } else {
+ // infixFound == 0 && prefixFound == 0
+ pos += copyTo(bytes, pos, (byte) 'A');
+ pos += copyTo(bytes, pos, (byte) 'A');
+ pos += copyTo(bytes, pos,
+ (byte) ((l1 - prefix + 65) & 0xff));
+ pos += copyTo(bytes, pos, subsequence(wordLemma, prefix));
+ }
+ } else if (infixFound > 0 && prefix2 > 0) {
+ // we have an infix, , and if there seems to be a prefix,
+ // the infix is longer
+ pos += copyTo(bytes, pos, (byte) ((prefix + 65) & 0xff));
+ pos += copyTo(bytes, pos, (byte) ((infixFound + 65) & 0xff));
+ pos += copyTo(bytes, pos, (byte) ((l1 - prefix - prefix2
+ - infixFound + 65) & 0xff));
+ pos += copyTo(bytes, pos,
+ subsequence(wordLemma, prefix + prefix2));
+ } else {
+ // we have an infix, and if there seems to be a prefix,
+ // the infix is longer
+ // but the common prefix of two words is longer
+ pos += copyTo(bytes, pos, (byte) 'A');
+ pos += copyTo(bytes, pos, (byte) 'A');
+ pos += copyTo(bytes, pos, (byte) ((l1 - prefix + 65) & 0xff));
+ pos += copyTo(bytes, pos, subsequence(wordLemma, prefix));
+ }
+
+ }
+ pos += copyTo(bytes, pos, annotationSeparator);
+ if (wordTag != null) {
+ pos += copyTo(bytes, pos, wordTag);
+ }
+ final byte[] finalArray = new byte[pos];
+ System.arraycopy(bytes, 0, finalArray, 0, pos);
+ return finalArray;
+ }
+
+ /**
+ * Converts a byte array to a given encoding.
+ *
+ * @param str
+ * Byte-array to be converted.
+ * @return Java String. If decoding is unsuccessful, the string is empty.
+ */
+ protected static String asString(final byte[] str, final String encoding) {
+ try {
+ return new String(str, encoding);
+ } catch (UnsupportedEncodingException e) {
+ return "";
+ }
+ }
+
+ /**
+ * A UTF-8 variant of {@link #standardEncode(byte[], byte[], byte[])} This
+ * method converts the wordForm, wordLemma and tag to the form:
+ *
+ * <pre>
+ * wordForm + Kending + tags
+ * </pre>
+ *
+ * where '+' is a separator, K is a character that specifies how many
+ * characters should be deleted from the end of the inflected form to
+ * produce the lexeme by concatenating the stripped string with the ending.
+ *
+ * @throws UnsupportedEncodingException
+ */
+ public String standardEncodeUTF8(final String wordForm,
+ final String wordLemma, final String wordTag)
+ throws UnsupportedEncodingException {
+ return asString(standardEncode(wordForm.getBytes(UTF8), wordLemma
+ .getBytes(UTF8), wordTag.getBytes(UTF8)), UTF8);
+ }
+
+ /**
+ * A UTF-8 variant of {@link #prefixEncode(byte[], byte[], byte[])} This
+ * method converts wordform, wordLemma and the tag to the form:
+ * <pre>
+ * inflected_form + LKending + tags
+ * </pre>
+ * <p>
+ * where '+' is a separator, L is the number of characters to be deleted
+ * from the beginning of the word ("A" means none, "B" means one, "C" - 2,
+ * etc.), K is a character that specifies how many characters should be
+ * deleted from the end of the inflected form to produce the lexeme by
+ * concatenating the stripped string with the ending ("A" means none,
+ * "B' - 1, "C" - 2, and so on).
+ *
+ * @param wordForm
+ * - inflected word form
+ * @param wordLemma
+ * - canonical form
+ * @param wordTag
+ * - tag
+ * @return the encoded string
+ * @throws UnsupportedEncodingException
+ */
+ public String prefixEncodeUTF8(final String wordForm,
+ final String wordLemma, final String wordTag)
+ throws UnsupportedEncodingException {
+ return asString(prefixEncode(wordForm.getBytes(UTF8), wordLemma
+ .getBytes(UTF8), wordTag.getBytes(UTF8)), UTF8);
+ }
+
+ /**
+ * A UTF-8 variant of {@link #infixEncode(byte[], byte[], byte[])}.
+ *
+ * This method converts wordform, wordLemma and the tag to the form:
+ * <pre>
+ * inflected_form + MLKending + tags
+ * </pre>
+ * <p>
+ * where '+' is a separator, M is the position of characters to be deleted
+ * towards the beginning of the inflected form ("A" means from the
+ * beginning, "B" from the second character, "C" - from the third one, and
+ * so on), L is the number of characters to be deleted from the position
+ * specified by M ("A" means none, "B" means one, "C" - 2, etc.), K is a
+ * character that specifies how many characters should be deleted from the
+ * end of the inflected form to produce the lexeme by concatenating the
+ * stripped string with the ending ("A" means none, "B' - 1, "C" - 2, and so
+ * on).
+ *
+ * @param wordForm
+ * - inflected word form
+ * @param wordLemma
+ * - canonical form
+ * @param wordTag
+ * - tag
+ * @return the encoded string
+ * @throws UnsupportedEncodingException
+ */
+ public String infixEncodeUTF8(final String wordForm,
+ final String wordLemma, final String wordTag)
+ throws UnsupportedEncodingException {
+ return asString(infixEncode(wordForm.getBytes(UTF8), wordLemma
+ .getBytes(UTF8), wordTag.getBytes(UTF8)), UTF8);
+ }
+}
diff --git a/src/morfologik/tools/MorphEncodingTool.java b/src/morfologik/tools/MorphEncodingTool.java
new file mode 100644
index 0000000..223a32b
--- /dev/null
+++ b/src/morfologik/tools/MorphEncodingTool.java
@@ -0,0 +1,213 @@
+package morfologik.tools;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import morfologik.fsa.FSA5;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+/**
+ * This utility converts the dictionary in a text (tabbed) format into
+ * the format accepted by the fsa building tools. It is meant to replace
+ * the Perl and AWK scripts from the original FSA package.
+ */
+class MorphEncodingTool extends Tool {
+
+ private boolean prefixes = false;
+ private boolean infixes = false;
+ private boolean noWarn = false;
+
+ private MorphEncoder encoder;
+
+ /**
+ *
+ */
+ protected void go(final CommandLine line) throws Exception {
+
+ noWarn = line.hasOption(SharedOptions.noWarnIfTwoFields.getOpt());
+
+ infixes = line.hasOption(SharedOptions.infixEncoding.getOpt());
+
+ if (!infixes) {
+ prefixes = line.hasOption(SharedOptions.prefixEncoding.getOpt());
+ }
+
+ char separator = FSA5.DEFAULT_ANNOTATION;
+ if (line.hasOption(SharedOptions.annotationSeparatorCharacterOption.getLongOpt())) {
+ String sep = line.getOptionValue(SharedOptions.annotationSeparatorCharacterOption.getLongOpt());
+
+ if (sep.length() == 1) {
+ separator = sep.charAt(0);
+ }
+
+ FSABuildTool.checkSingleByte(Character.toString(separator));
+ }
+ encoder = new MorphEncoder((byte) separator);
+
+ // Determine input and output streams.
+ final DataInputStream input = initializeInput(line);
+ final DataOutputStream output = initializeOutput(line);
+
+ try {
+ process(input, output);
+ output.flush();
+
+ } finally {
+ input.close();
+ output.close();
+ }
+
+ }
+
+ /**
+ * Split fields
+ * @param line
+ * byte input buffer
+ * @param pos
+ * current offset in the file
+ * @return
+ * an array of three byte arrays; if there are less
+ * than three fields, one of byte arrays is null. If the
+ * line contains more than three fields, they are ignored.
+ */
+ private static byte[][] splitFields(final byte[] line, final int pos) {
+ byte[][] outputArray = new byte[3][];
+ int i = 0;
+ int prevPos = 0;
+ int arrayInd = 0;
+ while (i < pos) {
+ if (line[i] == (byte)'\t') { //tab
+ outputArray[arrayInd] = new byte[i - prevPos];
+ System.arraycopy(line, prevPos, outputArray[arrayInd], 0, i - prevPos);
+ prevPos = i + 1;
+ arrayInd++;
+ }
+ i++;
+ }
+ return outputArray;
+ }
+
+ /**
+ * Process input stream, writing to output stream.
+ *
+ */
+ protected void process(final DataInputStream input, final DataOutputStream output)
+ throws IOException {
+ long lnumber = 0;
+ try {
+ int bufPos = 0;
+ byte[] buf = new byte[0xfffff]; // assumed that line is shorter than
+ // 64K chars
+ int dataByte = -1; // not declared within while loop
+ byte[][] words;
+ while ((dataByte = input.read()) != -1) {
+ if (dataByte == (byte) '\n') {
+ lnumber++;
+ buf[bufPos++] = 9;
+ words = splitFields(buf, bufPos);
+ for (int i = 0; i < words.length; i++) {
+ if (i < 1 && words[i] == null) {
+ throw new IllegalArgumentException(
+ "The input file has less than 2 fields in line: "
+ + lnumber);
+ }
+ if (words[i] == null && !noWarn) {
+ System.err.println("Line number: " + lnumber + " has less than three fields.");
+ }
+ }
+
+ if (infixes) {
+ output.write(encoder.infixEncode(words[0], words[1], words[2]));
+ } else if (prefixes) {
+ output.write(encoder.prefixEncode(words[0], words[1], words[2]));
+ } else {
+ output.write(encoder.standardEncode(words[0], words[1], words[2]));
+ }
+
+ output.writeByte('\n'); // Unix line end only.
+ bufPos = 0;
+ } else {
+ if (dataByte != (byte) '\r') {
+ buf[bufPos++] = (byte) dataByte;
+ }
+ }
+ }
+ } finally {
+ input.close();
+ }
+ }
+
+ /**
+ * Command line options for the tool.
+ */
+ protected void initializeOptions(Options options) {
+ options.addOption(SharedOptions.inputFileOption);
+ options.addOption(SharedOptions.outputFileOption);
+ options.addOption(SharedOptions.standardEncoding);
+ options.addOption(SharedOptions.prefixEncoding);
+ options.addOption(SharedOptions.infixEncoding);
+ options.addOption(SharedOptions.noWarnIfTwoFields);
+ options.addOption(SharedOptions.annotationSeparatorCharacterOption);
+ }
+
+ /**
+ *
+ */
+ private static DataOutputStream initializeOutput(CommandLine line)
+ throws IOException, ParseException {
+ final DataOutputStream output;
+ final String opt = SharedOptions.outputFileOption.getOpt();
+ if (line.hasOption(opt)) {
+ // Use output file.
+ output = new DataOutputStream(
+ new BufferedOutputStream(
+ new FileOutputStream((File) line
+ .getParsedOptionValue(opt))));
+ } else {
+ // Use standard output.
+ output = new DataOutputStream(
+ new BufferedOutputStream(
+ System.out));
+ }
+ return output;
+ }
+
+ /**
+ *
+ */
+ private static DataInputStream initializeInput(CommandLine line)
+ throws IOException, ParseException {
+ final DataInputStream input;
+ final String opt = SharedOptions.inputFileOption.getOpt();
+ if (line.hasOption(opt)) {
+ // Use input file.
+ input = new DataInputStream (
+ new BufferedInputStream(
+ new FileInputStream((File) line
+ .getParsedOptionValue(opt))));
+ } else {
+ // Use standard input.
+ input = new DataInputStream(
+ new BufferedInputStream(
+ System.in));
+ }
+ return input;
+ }
+
+ /**
+ * Command line entry point.
+ */
+ public static void main(String[] args) throws Exception {
+ final MorphEncodingTool tool = new MorphEncodingTool();
+ tool.go(args);
+ }
+} \ No newline at end of file
diff --git a/src/morfologik/tools/PolishStemmingTool.java b/src/morfologik/tools/PolishStemmingTool.java
index 715e991..0abd897 100644
--- a/src/morfologik/tools/PolishStemmingTool.java
+++ b/src/morfologik/tools/PolishStemmingTool.java
@@ -22,167 +22,170 @@ import org.apache.commons.cli.*;
* respective column. Columns are tab-delimited.
*/
class PolishStemmingTool extends Tool {
- /**
- * The stemmer to use.
- */
- private final IStemmer stemmer;
-
- /**
+ /**
*
*/
- public PolishStemmingTool() {
- this.stemmer = new PolishStemmer();
- }
+ protected void go(CommandLine line) throws Exception {
+ // Determine input/ output encoding.
+ final String inputEncoding = getEncodingOption(line,
+ SharedOptions.inputEncodingOption.getOpt());
+
+ final String outputEncoding = getEncodingOption(line,
+ SharedOptions.outputEncodingOption.getOpt());
+
+ System.out.println("Input encoding: " + inputEncoding);
+ System.out.println("Output encoding: " + outputEncoding);
+
+ // Determine input and output streams.
+ final Reader input = initializeInput(line, inputEncoding);
+ final Writer output = initializeOutput(line, outputEncoding);
+
+ final long start = System.currentTimeMillis();
+ try {
+ final long count = process(input, output);
+
+ output.flush();
+
+ final long millis = System.currentTimeMillis() - start;
+ final double time = millis / 1000.0;
+ final double wordsPerSec = time > 0 ? (count / time)
+ : Double.POSITIVE_INFINITY;
+ System.out
+ .println(new MessageFormat(
+ "Processed {0} words in {1,number,#.###} seconds ({2,number,#} words per second).",
+ Locale.ENGLISH).format(new Object[] {
+ new Long(count), new Double(millis / 1000.0),
+ new Double(wordsPerSec) }));
+ } finally {
+ input.close();
+ output.close();
+ }
- /**
- *
- */
- protected void go(CommandLine line) throws Exception {
- // Determine input/ output encoding.
- final String inputEncoding = getEncodingOption(line,
- SharedOptions.inputEncodingOption.getOpt());
-
- final String outputEncoding = getEncodingOption(line,
- SharedOptions.outputEncodingOption.getOpt());
-
- System.out.println("Input encoding: " + inputEncoding);
- System.out.println("Output encoding: " + outputEncoding);
-
- // Determine input and output streams.
- final Reader input = initializeInput(line, inputEncoding);
- final Writer output = initializeOutput(line, outputEncoding);
-
- final long start = System.currentTimeMillis();
- try {
- final long count = process(input, output);
-
- output.flush();
-
- final long millis = System.currentTimeMillis() - start;
- final double time = millis / 1000.0;
- final double wordsPerSec = time > 0 ? (count / time)
- : Double.POSITIVE_INFINITY;
- System.out
- .println(new MessageFormat(
- "Processed {0} words in {1,number,#.###} seconds ({2,number,#} words per second).",
- Locale.ENGLISH).format(new Object[] {
- new Long(count), new Double(millis / 1000.0),
- new Double(wordsPerSec) }));
- } finally {
- input.close();
- output.close();
}
- }
-
- /**
- * Process input stream, writing to output stream.
- *
- * @return Returns the number of processed words.
- */
- protected long process(Reader input, Writer output) throws IOException {
- final StreamTokenizer st = new StreamTokenizer(input);
- st.eolIsSignificant(false);
- st.wordChars('+', '+');
-
- long count = 0;
- int token;
- while ((token = st.nextToken()) != StreamTokenizer.TT_EOF) {
- if (token == StreamTokenizer.TT_WORD) {
- final String word = st.sval;
-
- count++;
- final List<WordData> stems = stemmer.lookup(word);
- if (stems.size() == 0) {
- output.write(word);
- output.write("\t-\t-\n");
- } else {
- for (WordData wd : stems) {
- output.write(word);
- output.write("\t");
- output.write(asString(wd.getStem()));
- output.write("\t");
- output.write(asString(wd.getTag()));
- output.write("\n");
- }
+ /**
+ * Process input stream, writing to output stream.
+ *
+ * @return Returns the number of processed words.
+ */
+ protected long process(Reader input, Writer output) throws IOException {
+ final IStemmer stemmer = new PolishStemmer();
+ final StreamTokenizer st = new StreamTokenizer(input);
+ st.eolIsSignificant(false);
+ st.wordChars('+', '+');
+
+ long count = 0;
+ int token;
+ while ((token = st.nextToken()) != StreamTokenizer.TT_EOF) {
+ if (token == StreamTokenizer.TT_WORD) {
+ final String word = st.sval;
+
+ count++;
+ final List<WordData> stems = stemmer.lookup(word);
+ if (stems.size() == 0) {
+ output.write(word);
+ output.write("\t-\t-\n");
+ } else {
+ for (WordData wd : stems) {
+ output.write(word);
+ output.write("\t");
+ output.write(asString(wd.getStem()));
+ output.write("\t");
+ output.write(asString(wd.getTag()));
+ output.write("\n");
+ }
+ }
+ }
}
- }
+
+ return count;
}
- return count;
- }
+ private String asString(CharSequence stem) {
+ if (stem == null)
+ return "-";
+ return stem.toString();
+ }
- private String asString(CharSequence stem) {
- if (stem == null)
- return "-";
- return stem.toString();
- }
+ /**
+ * Command line options for the tool.
+ */
+ protected void initializeOptions(Options options) {
+ options.addOption(SharedOptions.inputFileOption);
+ options.addOption(SharedOptions.inputEncodingOption);
+ options.addOption(SharedOptions.outputFileOption);
+ options.addOption(SharedOptions.outputEncodingOption);
+ }
- /**
- * Command line options for the tool.
- */
- protected void initializeOptions(Options options) {
- options.addOption(SharedOptions.inputFileOption);
- options.addOption(SharedOptions.inputEncodingOption);
- options.addOption(SharedOptions.outputFileOption);
- options.addOption(SharedOptions.outputEncodingOption);
- }
-
- /**
+ /**
*
*/
- private Writer initializeOutput(CommandLine line, String outputEncoding)
- throws IOException, ParseException {
- final Writer output;
- final String opt = SharedOptions.outputFileOption.getOpt();
- if (line.hasOption(opt)) {
- // Use output file.
- output = new OutputStreamWriter(
- new BufferedOutputStream(new FileOutputStream((File) line
- .getParsedOptionValue(opt))), outputEncoding);
- } else {
- // Use standard output.
- output = new OutputStreamWriter(System.out, outputEncoding);
+ private Writer initializeOutput(CommandLine line, String outputEncoding)
+ throws IOException, ParseException {
+ final Writer output;
+ final String opt = SharedOptions.outputFileOption.getOpt();
+ if (line.hasOption(opt)) {
+ // Use output file.
+ output = new OutputStreamWriter(
+ new BufferedOutputStream(new FileOutputStream((File) line
+ .getParsedOptionValue(opt))), outputEncoding);
+ } else {
+ // Use standard output.
+ output = new OutputStreamWriter(System.out, outputEncoding);
+ }
+ return output;
}
- return output;
- }
- /**
+ /**
*
*/
- private Reader initializeInput(CommandLine line, String inputEncoding)
- throws IOException, ParseException {
- final Reader input;
- final String opt = SharedOptions.inputFileOption.getOpt();
-
- if (line.hasOption(opt)) {
- // Use input file.
- input = new InputStreamReader(
- new BufferedInputStream(new FileInputStream((File) line
- .getParsedOptionValue(opt))), inputEncoding);
- } else {
- // Use standard input.
- input = new InputStreamReader(System.in, inputEncoding);
+ private Reader initializeInput(CommandLine line, String inputEncoding)
+ throws IOException, ParseException {
+ final Reader input;
+ final String opt = SharedOptions.inputFileOption.getOpt();
+
+ if (line.hasOption(opt)) {
+ // Use input file.
+ input = new InputStreamReader(
+ new BufferedInputStream(new FileInputStream((File) line
+ .getParsedOptionValue(opt))), inputEncoding);
+ } else {
+ // Use standard input.
+ input = new InputStreamReader(System.in, inputEncoding);
+ }
+ return input;
}
- return input;
- }
- /**
+ /**
*
*/
- private String getEncodingOption(CommandLine line, String opt) {
- String encoding = System.getProperty("file.encoding", "iso-8859-1");
- if (line.hasOption(opt)) {
- encoding = line.getOptionValue(opt);
+ private String getEncodingOption(CommandLine line, String opt) {
+ String encoding = System.getProperty("file.encoding", "iso-8859-1");
+ if (line.hasOption(opt)) {
+ encoding = line.getOptionValue(opt);
+ }
+ return encoding;
+ }
+
+ /*
+ * Check if the dictionary is available.
+ */
+ @Override
+ protected boolean isAvailable() {
+ boolean available = true;
+ try {
+ new PolishStemmer();
+ } catch (Throwable t) {
+ available = false;
+ }
+ return available;
+ }
+
+ /**
+ * Command line entry point.
+ */
+ public static void main(String[] args) throws Exception {
+ final PolishStemmingTool tool = new PolishStemmingTool();
+ tool.go(args);
}
- return encoding;
- }
-
- /**
- * Command line entry point.
- */
- public static void main(String[] args) throws Exception {
- final PolishStemmingTool tool = new PolishStemmingTool();
- tool.go(args);
- }
} \ No newline at end of file
diff --git a/src/morfologik/tools/SharedOptions.java b/src/morfologik/tools/SharedOptions.java
index 3be87c0..e047d7f 100644
--- a/src/morfologik/tools/SharedOptions.java
+++ b/src/morfologik/tools/SharedOptions.java
@@ -1,6 +1,7 @@
package morfologik.tools;
import java.io.File;
+import java.util.Arrays;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
@@ -10,67 +11,143 @@ import org.apache.commons.cli.OptionBuilder;
*/
@SuppressWarnings("static-access")
final class SharedOptions {
- public final static Option fsaDictionaryFileOption =
- OptionBuilder
- .hasArg().withArgName("file")
- .withDescription("Path to the FSA dictionary.")
- .withLongOpt("dictionary")
- .withType(File.class)
- .isRequired(true)
- .create("d");
-
- public final static Option decode =
- OptionBuilder
- .withDescription("Decode prefix/ infix/ suffix forms (if available).")
- .withLongOpt("decode")
- .isRequired(false)
- .create("x");
-
- public final static Option dataOnly =
- OptionBuilder
- .withDescription("Dump only raw FSA data.")
- .withLongOpt("raw-data")
- .isRequired(false)
- .create("r");
-
- public final static Option inputEncodingOption =
- OptionBuilder
- .hasArg().withArgName("codepage")
- .withDescription("Input stream encoding.")
- .withLongOpt("input-encoding")
- .isRequired(false)
- .create("ie");
-
- public final static Option outputEncodingOption =
- OptionBuilder
- .hasArg().withArgName("codepage")
- .withDescription("Output stream encoding.")
- .withLongOpt("output-encoding")
- .isRequired(false)
- .create("oe");
-
- public final static Option inputFileOption =
- OptionBuilder
- .hasArg().withArgName("file")
- .withDescription("Input file. If missing, standard input is used.")
- .withLongOpt("input")
- .withType(File.class)
- .isRequired(false)
- .create("i");
-
- public final static Option outputFileOption =
- OptionBuilder
- .hasArg().withArgName("file")
- .withDescription("Output file. If missing, standard output is used.")
- .withLongOpt("output")
- .withType(File.class)
- .isRequired(false)
- .create("o");
-
- /**
- * No instances. Use static fields.
- */
- private SharedOptions() {
- // empty
- }
+ public final static Option fsaDictionaryFileOption = OptionBuilder
+ .hasArg()
+ .withArgName("file")
+ .withDescription("Path to the FSA dictionary.")
+ .withLongOpt("dictionary")
+ .withType(File.class)
+ .isRequired(true)
+ .create("d");
+
+ public final static Option decode = OptionBuilder
+ .withDescription("Decode prefix/ infix/ suffix forms (if available).")
+ .withLongOpt("decode")
+ .isRequired(false)
+ .create("x");
+
+ public final static Option dataOnly = OptionBuilder
+ .withDescription("Dump only raw FSA data.")
+ .withLongOpt("raw-data")
+ .isRequired(false)
+ .create("r");
+
+ public final static Option dot = OptionBuilder
+ .withDescription("Dump the automaton as graphviz DOT file.")
+ .withLongOpt("dot")
+ .isRequired(false)
+ .create();
+
+ public final static Option inputEncodingOption = OptionBuilder
+ .hasArg()
+ .withArgName("codepage")
+ .withDescription("Input stream encoding.")
+ .withLongOpt("input-encoding")
+ .isRequired(false)
+ .create("ie");
+
+ public final static Option outputEncodingOption = OptionBuilder
+ .hasArg()
+ .withArgName("codepage")
+ .withDescription("Output stream encoding.")
+ .withLongOpt("output-encoding")
+ .isRequired(false)
+ .create("oe");
+
+ public final static Option inputFileOption = OptionBuilder
+ .hasArg()
+ .withArgName("file")
+ .withDescription("Input file. If missing, standard input is used.")
+ .withLongOpt("input")
+ .withType(File.class)
+ .isRequired(false)
+ .create("i");
+
+ public final static Option outputFileOption = OptionBuilder
+ .hasArg()
+ .withArgName("file")
+ .withDescription("Output file. If missing, standard output is used.")
+ .withLongOpt("output")
+ .withType(File.class)
+ .isRequired(false)
+ .create("o");
+
+ public final static Option outputFormatOption = OptionBuilder
+ .hasArg()
+ .withArgName("format")
+ .withDescription("Name of the binary output format. Allowed values: " + Arrays.toString(FSABuildTool.Format.values()))
+ .withLongOpt("format")
+ .isRequired(false)
+ .create("f");
+
+ public final static Option fillerCharacterOption = OptionBuilder
+ .hasArg()
+ .withArgName("char")
+ .withDescription("Custom filler character")
+ .isRequired(false)
+ .withLongOpt("filler")
+ .create();
+
+ public final static Option annotationSeparatorCharacterOption = OptionBuilder
+ .hasArg()
+ .withArgName("char")
+ .withDescription("Custom annotation separator character")
+ .isRequired(false)
+ .withLongOpt("annotation")
+ .create();
+
+ public final static Option withNumbersOption = OptionBuilder
+ .withDescription("Include numbers required for perfect hashing (larger automaton)")
+ .isRequired(false)
+ .withLongOpt("with-numbers")
+ .create("n");
+
+ public final static Option progressOption = OptionBuilder
+ .withDescription("Print more verbose progress information")
+ .isRequired(false)
+ .withLongOpt("progress")
+ .create();
+
+ public final static Option inputSortedOption = OptionBuilder
+ .withDescription("Assume the input is already sorted using C-sort (builds FSA directly, no in-memory sorting)")
+ .isRequired(false)
+ .withLongOpt("sorted")
+ .create();
+
+ public final static Option standardEncoding = OptionBuilder
+ .withDescription("Encode suffix forms in a standard way")
+ .withLongOpt("suffix")
+ .isRequired(false)
+ .create("suf");
+
+ public final static Option prefixEncoding = OptionBuilder
+ .withDescription("Encode suffix forms in a prefix way")
+ .withLongOpt("prefix")
+ .isRequired(false)
+ .create("pre");
+
+ public final static Option infixEncoding = OptionBuilder
+ .withDescription("Encode suffix forms in an infix way")
+ .withLongOpt("infix")
+ .isRequired(false)
+ .create("inf");
+
+ public final static Option noWarnIfTwoFields = OptionBuilder
+ .withDescription("Suppress warning for lines with only two fields (for stemming dictionaries)")
+ .withLongOpt("nowarn")
+ .isRequired(false)
+ .create("nw");
+
+ public final static Option statistics = OptionBuilder
+ .withDescription("Print extra statistics.")
+ .isRequired(false)
+ .withLongOpt("stats")
+ .create();
+
+ /**
+ * No instances. Use static fields.
+ */
+ private SharedOptions() {
+ // empty
+ }
}
diff --git a/src/morfologik/tools/Tool.java b/src/morfologik/tools/Tool.java
index bd60538..ebc1daf 100644
--- a/src/morfologik/tools/Tool.java
+++ b/src/morfologik/tools/Tool.java
@@ -6,71 +6,79 @@ import org.apache.commons.cli.*;
* Base class for command-line applications.
*/
abstract class Tool {
- /** Command line options. */
- protected final Options options = new Options();
+ /** Command line options. */
+ protected final Options options = new Options();
- /**
- * Initializes application context.
- */
- protected final void go(String[] args) {
- initializeOptions(options);
+ /**
+ * Initializes application context.
+ */
+ protected final void go(String[] args) {
+ initializeOptions(options);
- if (args.length == 0) {
- printUsage();
- return;
+ if (args.length == 0) {
+ printUsage();
+ return;
+ }
+
+ final Parser parser = new GnuParser();
+ final CommandLine line;
+ try {
+ line = parser.parse(options, args);
+ try {
+ go(line);
+ } catch (Throwable e) {
+ printError("Unhandled program error occurred.", e);
+ }
+ } catch (MissingArgumentException e) {
+ printError("Provide the required argument for option: "
+ + e.getMessage());
+ } catch (MissingOptionException e) {
+ printError("Provide the required option: " + e.getMessage());
+ } catch (UnrecognizedOptionException e) {
+ printError(e.getMessage());
+ } catch (ParseException e) {
+ printError("Could not parse command line: " + e.getMessage());
+ }
}
- final Parser parser = new GnuParser();
- final CommandLine line;
- try {
- line = parser.parse(options, args);
- try {
- go(line);
- } catch (Throwable e) {
- printError("Unhandled program error occurred.", e);
- }
- } catch (MissingArgumentException e) {
- printError("Provide the required argument for option: " + e.getMessage());
- } catch (MissingOptionException e) {
- printError("Provide the required option: " + e.getMessage());
- } catch (UnrecognizedOptionException e) {
- printError(e.getMessage());
- } catch (ParseException e) {
- printError("Could not parse command line: " + e.getMessage());
+ /**
+ * Print an error and an associated exception.
+ */
+ protected void printError(String msg, Throwable t) {
+ printError(msg);
+ t.printStackTrace(System.err);
}
- }
- /**
- * Print an error and an associated exception.
- */
- protected void printError(String msg, Throwable t) {
- printError(msg);
- t.printStackTrace(System.err);
- }
+ /**
+ * Print an error without an exception.
+ */
+ protected void printError(String msg) {
+ System.err.println();
+ System.err.println(msg);
+ }
- /**
- * Print an error without an exception.
- */
- protected void printError(String msg) {
- System.err.println();
- System.err.println(msg);
- }
+ /**
+ * Prints usage (options).
+ */
+ protected void printUsage() {
+ final HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp(this.getClass().getName(), options, true);
+ }
- /**
- * Prints usage (options).
- */
- protected void printUsage() {
- final HelpFormatter formatter = new HelpFormatter();
- formatter.printHelp(this.getClass().getName(), options, true);
- }
+ /**
+ * Override and write your stuff using command line options.
+ */
+ protected abstract void go(CommandLine line) throws Exception;
- /**
- * Override and write your stuff using command line options.
- */
- protected abstract void go(CommandLine line) throws Exception;
+ /**
+ * Override and initialize options.
+ */
+ protected abstract void initializeOptions(Options options);
- /**
- * Override and initialize options.
- */
- protected abstract void initializeOptions(Options options);
+ /**
+ * Is the tool available? <code>true</code> by default.
+ */
+ protected boolean isAvailable() {
+ return true;
+ }
}
diff --git a/src/morfologik/tools/WriterMessageLogger.java b/src/morfologik/tools/WriterMessageLogger.java
new file mode 100644
index 0000000..fceb698
--- /dev/null
+++ b/src/morfologik/tools/WriterMessageLogger.java
@@ -0,0 +1,123 @@
+package morfologik.tools;
+
+import java.io.PrintWriter;
+import java.util.*;
+
+/**
+ * A logger dumping info to <code>System.err</code>.
+ */
+public class WriterMessageLogger implements IMessageLogger {
+ /**
+ * Start of the world timestamp.
+ */
+ private final static long world = System.currentTimeMillis();
+
+ /**
+ * A single part: name, start timestamp.
+ */
+ private static class Part {
+ final String name;
+ final long start;
+
+ Part(String name, long start) {
+ this.name = name;
+ this.start = start;
+ }
+ }
+
+ /**
+ * Is the output currently indented?
+ */
+ private boolean indent;
+
+ /**
+ * Active parts.
+ */
+ private ArrayDeque<Part> parts = new ArrayDeque<Part>();
+
+ /**
+ * Output writer.
+ */
+ private final PrintWriter writer;
+
+ /**
+ *
+ */
+ public WriterMessageLogger(PrintWriter w) {
+ this.writer = w;
+ }
+
+ /*
+ *
+ */
+ @Override
+ public void log(String msg) {
+ cancelIndent();
+
+ writer.println(msg);
+ writer.flush();
+ }
+
+ /*
+ *
+ */
+ @Override
+ public void log(String header, Object v) {
+ cancelIndent();
+
+ if (v instanceof Integer || v instanceof Long) {
+ writer.println(String.format(Locale.ENGLISH, "%-30s %,11d", header, v));
+ } else {
+ writer.println(String.format(Locale.ENGLISH, "%-30s %11s", header, v.toString()));
+ }
+ writer.flush();
+ }
+
+ /*
+ *
+ */
+ @Override
+ public void startPart(String header) {
+ cancelIndent();
+
+ Part p = new Part(header, System.currentTimeMillis());
+ parts.addLast(p);
+
+ writer.print(String.format(Locale.ENGLISH, "%-30s", p.name + "..."));
+ writer.flush();
+
+ indent = true;
+ }
+
+ /*
+ *
+ */
+ @Override
+ public void endPart() {
+ long now = System.currentTimeMillis();
+ Part p = parts.removeLast();
+
+ if (!indent) {
+ writer.print(String.format(Locale.ENGLISH, "%-30s", p.name + "..."));
+ }
+
+ writer.println(
+ String.format(Locale.ENGLISH, "%13.2f sec. [%6.2f sec.]",
+ (now - p.start) / 1000.0,
+ (now - world) / 1000.0));
+ writer.flush();
+
+ indent = false;
+ }
+
+ /*
+ *
+ */
+ private void cancelIndent() {
+ if (indent) {
+ System.err.println();
+ }
+
+ indent = false;
+ }
+}
diff --git a/src/morfologik/util/Arrays.java b/src/morfologik/util/Arrays.java
index 624ad27..4d1d840 100644
--- a/src/morfologik/util/Arrays.java
+++ b/src/morfologik/util/Arrays.java
@@ -1,41 +1,68 @@
package morfologik.util;
-import java.lang.reflect.Array;
-
/**
* Compatibility layer for JVM 1.5.
*/
public final class Arrays {
- private Arrays() {
- // No instances.
- }
+ private Arrays() {
+ // No instances.
+ }
+
+ /**
+ * Compare two lists of objects for reference-equality.
+ */
+ public static boolean referenceEquals(Object[] a1, int a1s, Object[] a2, int a2s, int length) {
+ for (int i = 0; i < length; i++)
+ if (a1[a1s++] != a2[a2s++])
+ return false;
+
+ return true;
+ }
- public static byte[] copyOf(byte[] original, int newLength) {
- byte[] copy = new byte[newLength];
- System.arraycopy(original, 0, copy, 0,
- Math.min(original.length, newLength));
- return copy;
+ /**
+ * Compare two arrays for equality.
+ */
+ public static boolean equals(byte[] a1, int a1s, byte [] a2, int a2s, int length) {
+ for (int i = 0; i < length; i++)
+ if (a1[a1s++] != a2[a2s++])
+ return false;
+
+ return true;
}
- public static int[] copyOf(int[] original, int newLength) {
- int[] copy = new int[newLength];
- System.arraycopy(original, 0, copy, 0,
- Math.min(original.length, newLength));
- return copy;
+ /**
+ * Compare two arrays for equality.
+ */
+ public static boolean equals(boolean[] a1, int a1s, boolean[] a2, int a2s, int length) {
+ for (int i = 0; i < length; i++)
+ if (a1[a1s++] != a2[a2s++])
+ return false;
+
+ return true;
}
- @SuppressWarnings("unchecked")
- public static <T> T[] copyOf(T[] original, int newLength) {
- return (T[]) copyOf(original, newLength, original.getClass());
+ /**
+ * Compare two arrays for equality.
+ */
+ public static boolean equals(int[] a1, int a1s, int[] a2, int a2s, int length) {
+ for (int i = 0; i < length; i++)
+ if (a1[a1s++] != a2[a2s++])
+ return false;
+
+ return true;
}
- @SuppressWarnings("unchecked")
- public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
- T[] copy = ((Object)newType == (Object)Object[].class)
- ? (T[]) new Object[newLength]
- : (T[]) Array.newInstance(newType.getComponentType(), newLength);
- System.arraycopy(original, 0, copy, 0,
- Math.min(original.length, newLength));
- return copy;
- }
+ /**
+ * Convert an array of strings to bytes.
+ */
+ public static String toString(byte [] bytes, int start, int length)
+ {
+ if (bytes.length != length)
+ {
+ final byte [] sub = new byte [length];
+ System.arraycopy(bytes, start, sub, 0, length);
+ bytes = sub;
+ }
+ return java.util.Arrays.toString(bytes);
+ }
}
diff --git a/src/morfologik/util/BufferUtils.java b/src/morfologik/util/BufferUtils.java
index c4e4cb0..6ccfbc6 100644
--- a/src/morfologik/util/BufferUtils.java
+++ b/src/morfologik/util/BufferUtils.java
@@ -8,40 +8,47 @@ import java.nio.CharBuffer;
*/
public final class BufferUtils {
- /**
- * No instances.
- */
- private BufferUtils() {
- // empty
- }
+ /**
+ * No instances.
+ */
+ private BufferUtils() {
+ // empty
+ }
- /**
- * Ensure the byte buffer's capacity. If a new buffer is allocated, its
- * content is empty (the old buffer's contents is not copied).
- *
- * @param buffer
- * The buffer to check or <code>null</code> if a new buffer
- * should be allocated.
- */
- public static ByteBuffer ensureCapacity(ByteBuffer buffer, int capacity) {
- if (buffer == null || buffer.capacity() < capacity) {
- buffer = ByteBuffer.allocate(capacity);
+ /**
+ * Ensure the byte buffer's capacity. If a new buffer is allocated, its
+ * content is empty (the old buffer's contents is not copied).
+ *
+ * @param buffer
+ * The buffer to check or <code>null</code> if a new buffer
+ * should be allocated.
+ */
+ public static ByteBuffer ensureCapacity(ByteBuffer buffer, int capacity) {
+ if (buffer == null || buffer.capacity() < capacity) {
+ buffer = ByteBuffer.allocate(capacity);
+ }
+ return buffer;
}
- return buffer;
- }
-
- /**
- * Ensure the char buffer's capacity. If a new buffer is allocated, its
- * content is empty (the old buffer's contents is not copied).
- *
- * @param buffer
- * The buffer to check or <code>null</code> if a new buffer
- * should be allocated.
- */
- public static CharBuffer ensureCapacity(CharBuffer buffer, int capacity) {
- if (buffer == null || buffer.capacity() < capacity) {
- buffer = CharBuffer.allocate(capacity);
+
+ /**
+ * Ensure the char buffer's capacity. If a new buffer is allocated, its
+ * content is empty (the old buffer's contents is not copied).
+ *
+ * @param buffer
+ * The buffer to check or <code>null</code> if a new buffer
+ * should be allocated.
+ */
+ public static CharBuffer ensureCapacity(CharBuffer buffer, int capacity) {
+ if (buffer == null || buffer.capacity() < capacity) {
+ buffer = CharBuffer.allocate(capacity);
+ }
+ return buffer;
}
- return buffer;
- }
+
+ /**
+ * Convert a byte buffer to a string in platform default encoding.
+ */
+ public static String toString(ByteBuffer sequence) {
+ return new String(sequence.array(), sequence.position(), sequence.remaining());
+ }
} \ No newline at end of file
diff --git a/src/morfologik/util/FileUtils.java b/src/morfologik/util/FileUtils.java
index e068340..5d62212 100644
--- a/src/morfologik/util/FileUtils.java
+++ b/src/morfologik/util/FileUtils.java
@@ -7,50 +7,131 @@ import java.io.*;
*/
public final class FileUtils {
- /**
- * No instances.
- */
- private FileUtils() {
- // empty
- }
+ /**
+ * No instances.
+ */
+ private FileUtils() {
+ // empty
+ }
- /**
- * Checks if the given file exists.
- */
- public static void assertExists(File fsaFile, boolean requireFile,
- boolean requireDirectory) throws IOException {
- if (!fsaFile.exists()) {
- throw new IOException("File does not exist: "
- + fsaFile.getAbsolutePath());
+ /**
+ * Checks if the given file exists.
+ */
+ public static void assertExists(File fsaFile, boolean requireFile,
+ boolean requireDirectory) throws IOException {
+ if (!fsaFile.exists()) {
+ throw new IOException("File does not exist: "
+ + fsaFile.getAbsolutePath());
+ }
+
+ if (requireFile) {
+ if (!fsaFile.isFile() || !fsaFile.canRead()) {
+ throw new IOException("File cannot be read: "
+ + fsaFile.getAbsolutePath());
+ }
+ }
+
+ if (requireDirectory) {
+ if (!fsaFile.isDirectory()) {
+ throw new IOException("Not a directory: "
+ + fsaFile.getAbsolutePath());
+ }
+ }
+ }
+
+ /**
+ * Force any non-null closeables.
+ */
+ public static void close(Closeable... closeables) {
+ for (Closeable c : closeables) {
+ if (c != null) {
+ try {
+ c.close();
+ } catch (IOException e) {
+ // too bad
+ }
+ }
+ }
}
- if (requireFile) {
- if (!fsaFile.isFile() || !fsaFile.canRead()) {
- throw new IOException("File cannot be read: "
- + fsaFile.getAbsolutePath());
- }
+ /**
+ * Reads all bytes from an input stream (until EOF).
+ */
+ public static byte[] readFully(InputStream stream) throws IOException {
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream(1024 * 16);
+ final byte[] buffer = new byte[1024 * 8];
+ int bytesCount;
+ while ((bytesCount = stream.read(buffer)) > 0) {
+ baos.write(buffer, 0, bytesCount);
+ }
+ return baos.toByteArray();
}
- if (requireDirectory) {
- if (!fsaFile.isDirectory()) {
- throw new IOException("Not a directory: "
- + fsaFile.getAbsolutePath());
- }
+ /**
+ * Read enough bytes to fill <code>array</code> If there are not enough
+ * bytes, throw an exception.
+ */
+ public static void readFully(InputStream in, byte[] array)
+ throws IOException {
+ int offset = 0;
+ int cnt;
+ while ((cnt = in.read(array, offset, array.length - offset)) > 0) {
+ offset += cnt;
+
+ if (offset == array.length)
+ break;
+ }
+
+ if (cnt < 0)
+ throw new EOFException();
}
+
+ /**
+ * Read exactly 4 bytes from the input stream.
+ */
+ public static int readInt(InputStream in) throws IOException {
+ int v = 0;
+ for (int i = 0; i < 4; i++) {
+ v = (v << 8) | (readByte(in) & 0xff);
+ }
+ return v;
}
/**
- * Force any non-null closeables.
+ *
*/
- public static void close(Closeable... closeables) {
- for (Closeable c : closeables) {
- if (c != null) {
- try {
- c.close();
- } catch (IOException e) {
- // too bad
- }
- }
+ public static void writeInt(OutputStream os, int v) throws IOException {
+ os.write( v >>> 24);
+ os.write((v >>> 16) & 0xff);
+ os.write((v >>> 8) & 0xff);
+ os.write( v & 0xff);
+ }
+
+ /**
+ * Read exactly 2 bytes from the input stream.
+ */
+ public static short readShort(InputStream in) throws IOException {
+ return (short) (readByte(in) << 8 |
+ readByte(in) & 0xff);
+ }
+
+ /**
+ * Read exactly one byte from the input stream.
+ *
+ * @throws EOFException if EOF is reached.
+ */
+ public static byte readByte(InputStream in) throws IOException {
+ int b = in.read();
+ if (b == -1)
+ throw new EOFException();
+ return (byte) b;
}
+
+ /**
+ *
+ */
+ public static void writeShort(OutputStream os, short v) throws IOException {
+ os.write((v >>> 8) & 0xff);
+ os.write( v & 0xff);
}
} \ No newline at end of file
diff --git a/src/morfologik/util/PerformanceTimer.java b/src/morfologik/util/PerformanceTimer.java
deleted file mode 100644
index 551c71b..0000000
--- a/src/morfologik/util/PerformanceTimer.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package morfologik.util;
-
-import java.util.Locale;
-import java.util.concurrent.Callable;
-
-/**
- * Simple, simple performance checking.
- */
-public final class PerformanceTimer {
- private int rounds;
-
- private long startTime;
- private long stopTime;
-
- private double totalTime;
-
- private double perRoundTime;
-
- /**
- * Run the task with a given number of warm-up rounds and the given number
- * of cycles.
- */
- public static PerformanceTimer run(final Callable<Void> task,
- int warmupRounds, int cycles) {
- final PerformanceTimer t = new PerformanceTimer();
-
- try {
- while (warmupRounds-- > 0) {
- task.call();
- }
-
- t.start();
- t.rounds = cycles;
- while (cycles-- > 0) {
- task.call();
- }
- t.stop();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- return t;
- }
-
- /*
- *
- */
- private void start() {
- startTime = System.currentTimeMillis();
- }
-
- /*
- *
- */
- private void stop() {
- stopTime = System.currentTimeMillis();
-
- totalTime = (stopTime - startTime) / 1000.0d;
- perRoundTime = totalTime / rounds;
- }
-
- /*
- *
- */
- @Override
- public String toString() {
- return String.format(Locale.ENGLISH, "Rounds: %d, Time: %.3f, Time/round: %.3f",
- rounds, totalTime, perRoundTime);
- }
-
- /*
- *
- */
- public long elemsPerSecond(int sequences) {
- return (long) (sequences / perRoundTime);
- }
-}
diff --git a/src/morfologik/util/ResourceUtils.java b/src/morfologik/util/ResourceUtils.java
index 41ffcad..2c7bd23 100644
--- a/src/morfologik/util/ResourceUtils.java
+++ b/src/morfologik/util/ResourceUtils.java
@@ -7,49 +7,52 @@ import java.net.*;
* Resource management utilities.
*/
public final class ResourceUtils {
- /**
- * No instances.
- */
- private ResourceUtils() {
- }
+ /**
+ * No instances.
+ */
+ private ResourceUtils() {
+ }
- /**
- * Returns an input stream to the resource.
- *
- * @param resource The path leading to the resource. Can be an URL, a path
- * leading to a class resource or a {@link File}.
- *
- * @return InputStream instance.
- * @throws IOException If the resource could not be found or opened.
- */
- public static InputStream openInputStream(String resource) throws IOException {
- try {
- // See if the resource is an URL first.
- final URL url = new URL(resource);
- // success, load the resource.
- return url.openStream();
- } catch (MalformedURLException e) {
- // No luck. Fallback to class loader paths.
- }
+ /**
+ * Returns an input stream to the resource.
+ *
+ * @param resource
+ * The path leading to the resource. Can be an URL, a path
+ * leading to a class resource or a {@link File}.
+ *
+ * @return InputStream instance.
+ * @throws IOException
+ * If the resource could not be found or opened.
+ */
+ public static InputStream openInputStream(String resource)
+ throws IOException {
+ try {
+ // See if the resource is an URL first.
+ final URL url = new URL(resource);
+ // success, load the resource.
+ return url.openStream();
+ } catch (MalformedURLException e) {
+ // No luck. Fallback to class loader paths.
+ }
- // Try current thread's class loader first.
- final ClassLoader ldr = Thread.currentThread().getContextClassLoader();
+ // Try current thread's class loader first.
+ final ClassLoader ldr = Thread.currentThread().getContextClassLoader();
- InputStream is;
- if (ldr != null && (is = ldr.getResourceAsStream(resource)) != null) {
- return is;
- } else if ((is = ResourceUtils.class.getResourceAsStream(resource)) != null) {
- return is;
- } else if ((is = ClassLoader.getSystemResourceAsStream(resource)) != null) {
- return is;
- }
+ InputStream is;
+ if (ldr != null && (is = ldr.getResourceAsStream(resource)) != null) {
+ return is;
+ } else if ((is = ResourceUtils.class.getResourceAsStream(resource)) != null) {
+ return is;
+ } else if ((is = ClassLoader.getSystemResourceAsStream(resource)) != null) {
+ return is;
+ }
- // Try file path
- final File f = new File(resource);
- if (f.exists() && f.isFile() && f.canRead()) {
- return new FileInputStream(f);
- }
+ // Try file path
+ final File f = new File(resource);
+ if (f.exists() && f.isFile() && f.canRead()) {
+ return new FileInputStream(f);
+ }
- throw new IOException("Could not locate resource: " + resource);
- }
+ throw new IOException("Could not locate resource: " + resource);
+ }
}