From 34104b709aaa6edf5c44dc18292de75f15ca4a92 Mon Sep 17 00:00:00 2001
From: Jonathan Hsieh <jon@cloudera.com>
Date: Tue, 1 Feb 2011 07:18:49 -0800
Subject: [PATCH] FLUME-415: Properly handle license for aho-corasick code

---
 build.xml                                          |   22 +--
 lib/org.arabidopsis.ahocorasick-2.x.jar            |  Bin 0 -> 17497 bytes
 lib/org.arabidopsis.ahocorasick.LICENSE            |   31 +++
 .../org/arabidopsis/ahocorasick/AhoCorasick.java   |  174 ---------------
 .../org/arabidopsis/ahocorasick/DenseEdgeList.java |   72 ------
 .../org/arabidopsis/ahocorasick/EdgeList.java      |   29 ---
 .../org/arabidopsis/ahocorasick/Queue.java         |   53 -----
 .../org/arabidopsis/ahocorasick/SearchResult.java  |   58 -----
 .../org/arabidopsis/ahocorasick/Searcher.java      |   52 -----
 .../arabidopsis/ahocorasick/SparseEdgeList.java    |   77 -------
 .../org/arabidopsis/ahocorasick/State.java         |  110 ---------
 .../arabidopsis/ahocorasick/TestAhoCorasick.java   |  233 --------------------
 .../org/arabidopsis/ahocorasick/TestAll.java       |   32 ---
 .../org/arabidopsis/ahocorasick/TestQueue.java     |   46 ----
 .../org/arabidopsis/ahocorasick/TestState.java     |   84 -------
 .../org/arabidopsis/ahocorasick/TimeTrial.java     |   46 ----
 16 files changed, 32 insertions(+), 1087 deletions(-)
 create mode 100644 lib/org.arabidopsis.ahocorasick-2.x.jar
 create mode 100644 lib/org.arabidopsis.ahocorasick.LICENSE
 delete mode 100644 src/ahocorasick/org/arabidopsis/ahocorasick/AhoCorasick.java
 delete mode 100644 src/ahocorasick/org/arabidopsis/ahocorasick/DenseEdgeList.java
 delete mode 100644 src/ahocorasick/org/arabidopsis/ahocorasick/EdgeList.java
 delete mode 100644 src/ahocorasick/org/arabidopsis/ahocorasick/Queue.java
 delete mode 100644 src/ahocorasick/org/arabidopsis/ahocorasick/SearchResult.java
 delete mode 100644 src/ahocorasick/org/arabidopsis/ahocorasick/Searcher.java
 delete mode 100644 src/ahocorasick/org/arabidopsis/ahocorasick/SparseEdgeList.java
 delete mode 100644 src/ahocorasick/org/arabidopsis/ahocorasick/State.java
 delete mode 100644 src/ahocorasick/org/arabidopsis/ahocorasick/TestAhoCorasick.java
 delete mode 100644 src/ahocorasick/org/arabidopsis/ahocorasick/TestAll.java
 delete mode 100644 src/ahocorasick/org/arabidopsis/ahocorasick/TestQueue.java
 delete mode 100644 src/ahocorasick/org/arabidopsis/ahocorasick/TestState.java
 delete mode 100644 src/ahocorasick/org/arabidopsis/ahocorasick/TimeTrial.java

diff --git a/build.xml b/build.xml
index 02a3b51..ac49caa 100644
--- a/build.xml
+++ b/build.xml
@@ -53,7 +53,6 @@ to call at top-level: ant deploy-contrib compile-core-test
   <property name="src.dir" value="${basedir}/src/"/>  	
   <property name="core.src.dir" value="${src.dir}/java"/>
   <property name="antlr.src.dir" value="${src.dir}/antlr"/>
-  <property name="aho.src.dir" value="${src.dir}/ahocorasick"/>
   <property name="test.src.dir" value="${src.dir}/javatest"/>
   <property name="perf.src.dir" value="${src.dir}/javaperf"/>
   <property name="docs.dir" value="${basedir}/docs/"/>
@@ -255,22 +254,6 @@ to call at top-level: ant deploy-contrib compile-core-test
   <target name="ivy-retrieve-all"
           depends="ivy-retrieve,ivy-retrieve-test,ivy-retrieve-findbugs,ivy-retrieve-pmd,ivy-retrieve-coverage,ivy-retrieve-releaseaudit" />
 
-  <target name="compile-aho" depends="init,ivy-retrieve-test">
-    <javac 
-     encoding="${build.encoding}" 
-     srcdir="${aho.src.dir}"
-     includes="org/**/*.java"
-     destdir="${build.classes}"
-     debug="${javac.debug}"
-     optimize="${javac.optimize}"
-     target="${javac.version}"
-     source="${javac.version}"
-     deprecation="${javac.deprecation}">
-      <compilerarg line="${javac.args} ${javac.args.warnings}" />
-      <classpath refid="test.classpath"/>
-    </javac>   
-  	
-  </target>
 
 
   <!-- ================================================================== -->
@@ -463,7 +446,7 @@ to call at top-level: ant deploy-contrib compile-core-test
 
   </target>
 
-  <target name="compile-core" depends="init,version,ivy-retrieve,compile-aho,compile-gen">
+  <target name="compile-core" depends="init,version,ivy-retrieve,compile-gen">
 
     <!-- Compile Java files (excluding JSPs) checking warnings -->
     <javac 
@@ -1111,8 +1094,6 @@ to call at top-level: ant deploy-contrib compile-core-test
       <classpath>
         <source path="${core.src.dir}"
                 output="${build.dir.eclipse-main-classes}" />
-        <source path="${aho.src.dir}"
-                output="${build.dir.eclipse-main-classes}" />
         <source path="${avro.gen.dir}"
                 output="${build.dir.eclipse-main-classes}" />
         <source path="${thrift.gen.dir}"
@@ -1164,7 +1145,6 @@ to call at top-level: ant deploy-contrib compile-core-test
 	 version="true" use="true" windowtitle="${name} ${version} API" 
 	 doctitle="${final.name} API" bottom="Copyright &amp;copy; ${year} Cloudera, Inc.">
       <packageset dir="${core.src.dir}" />
-      <packageset dir="${aho.src.dir}" />
       <packageset dir="${test.src.dir}" />
       <packageset dir="${perf.src.dir}" />
       <link href="${javadoc.link.java}" />
diff --git a/lib/org.arabidopsis.ahocorasick-2.x.jar b/lib/org.arabidopsis.ahocorasick-2.x.jar
new file mode 100644
index 0000000000000000000000000000000000000000..5dc624e6b36738ea4d915be3de5a7ed0e846a34f
GIT binary patch
diff --git a/lib/org.arabidopsis.ahocorasick.LICENSE b/lib/org.arabidopsis.ahocorasick.LICENSE
new file mode 100644
index 0000000..a758aa4
--- /dev/null
+++ b/lib/org.arabidopsis.ahocorasick.LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2005, 2008 Danny Yoo
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+
+    * Neither the name of the Carnegie Institution of Washington nor
+the names of its contributors may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/ahocorasick/org/arabidopsis/ahocorasick/AhoCorasick.java b/src/ahocorasick/org/arabidopsis/ahocorasick/AhoCorasick.java
deleted file mode 100644
index 88ede16..0000000
--- a/src/ahocorasick/org/arabidopsis/ahocorasick/AhoCorasick.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/**
- * Licensed to Cloudera, Inc. under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  Cloudera, Inc. licenses this file
- * to you 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.
- */
-package org.arabidopsis.ahocorasick;
-
-import java.util.Iterator;
-
-/**
- * jon:
- * 
- * The main modifications from the original is to make this fully type-parameterized. 
- */
-
-/**
- * <p>
- * An implementation of the Aho-Corasick string searching automaton. This
- * implementation of the <a
- * href="http://portal.acm.org/citation.cfm?id=360855&dl=ACM&coll=GUIDE"
- * target="_blank">Aho-Corasick</a> algorithm is optimized to work with bytes.
- * </p>
- * 
- * <p>
- * Example usage: <code><pre>
-       AhoCorasick tree = new AhoCorasick();
-       tree.add("hello".getBytes(), "hello");
-       tree.add("world".getBytes(), "world");
-       tree.prepare();
-
-       Iterator searcher = tree.search("hello world".getBytes());
-       while (searcher.hasNext()) {
-           SearchResult result = searcher.next();
-           System.out.println(result.getOutputs());
-           System.out.println("Found at index: " + result.getLastIndex());
-       }
-   </pre></code>
- * </p>
- * 
- * <h2>Recent changes</h2>
- * <ul>
- * 
- * <li>Per user request from Carsten Kruege, I've changed the signature of
- * State.getOutputs() and SearchResults.getOutputs() to Sets rather than Lists.</li>
- * 
- * </ul>
- * 
- * jon: tweaked to be type generic
- */
-public class AhoCorasick<T> {
-  private State<T> root;
-  private boolean prepared;
-
-  public AhoCorasick() {
-    this.root = new State<T>(0);
-    this.prepared = false;
-  }
-
-  /**
-   * Adds a new keyword with the given output. During search, if the keyword is
-   * matched, output will be one of the yielded elements in
-   * SearchResults.getOutputs().
-   */
-  public void add(byte[] keyword, T output) {
-    if (this.prepared)
-      throw new IllegalStateException(
-          "can't add keywords after prepare() is called");
-    State<T> lastState = this.root.extendAll(keyword);
-    lastState.addOutput(output);
-  }
-
-  /**
-   * Prepares the automaton for searching. This must be called before any
-   * searching().
-   */
-  public void prepare() {
-    this.prepareFailTransitions();
-    this.prepared = true;
-  }
-
-  /**
-   * Starts a new search, and returns an Iterator of SearchResults.
-   */
-  public Iterator<SearchResult<T>> search(byte[] bytes) {
-    return new Searcher<T>(this, this.startSearch(bytes));
-  }
-
-  /**
-   * DANGER DANGER: dense algorithm code ahead. Very order dependent.
-   * Initializes the fail transitions of all states except for the root.
-   */
-  private void prepareFailTransitions() {
-    Queue<T> q = new Queue<T>();
-    for (int i = 0; i < 256; i++)
-      if (this.root.get((byte) i) != null) {
-        this.root.get((byte) i).setFail(this.root);
-        q.add(this.root.get((byte) i));
-      }
-    this.prepareRoot();
-    while (!q.isEmpty()) {
-      State<T> state = q.pop();
-      byte[] keys = state.keys();
-      for (int i = 0; i < keys.length; i++) {
-        State<T> r = state;
-        byte a = keys[i];
-        State<T> s = r.get(a);
-        q.add(s);
-        r = r.getFail();
-        while (r.get(a) == null)
-          r = r.getFail();
-        s.setFail(r.get(a));
-        s.getOutputs().addAll(r.get(a).getOutputs());
-      }
-    }
-  }
-
-  /**
-   * Sets all the out transitions of the root to itself, if no transition yet
-   * exists at this point.
-   */
-  private void prepareRoot() {
-    for (int i = 0; i < 256; i++)
-      if (this.root.get((byte) i) == null)
-        this.root.put((byte) i, this.root);
-  }
-
-  /**
-   * Returns the root of the tree. Package protected, since the user probably
-   * shouldn't touch this.
-   */
-  State<T> getRoot() {
-    return this.root;
-  }
-
-  /**
-   * Begins a new search using the raw interface. Package protected.
-   */
-  SearchResult<T> startSearch(byte[] bytes) {
-    if (!this.prepared)
-      throw new IllegalStateException("can't start search until prepare()");
-    return continueSearch(new SearchResult<T>(this.root, bytes, 0));
-  }
-
-  /**
-   * Continues the search, given the initial state described by the lastResult.
-   * Package protected.
-   */
-  SearchResult<T> continueSearch(SearchResult<T> lastResult) {
-    byte[] bytes = lastResult.bytes;
-    State<T> state = lastResult.lastMatchedState;
-    for (int i = lastResult.lastIndex; i < bytes.length; i++) {
-      byte b = bytes[i];
-      while (state.get(b) == null)
-        state = state.getFail();
-      state = state.get(b);
-      if (state.getOutputs().size() > 0)
-        return new SearchResult<T>(state, bytes, i + 1);
-    }
-    return null;
-  }
-
-}
diff --git a/src/ahocorasick/org/arabidopsis/ahocorasick/DenseEdgeList.java b/src/ahocorasick/org/arabidopsis/ahocorasick/DenseEdgeList.java
deleted file mode 100644
index 15f8064..0000000
--- a/src/ahocorasick/org/arabidopsis/ahocorasick/DenseEdgeList.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Licensed to Cloudera, Inc. under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  Cloudera, Inc. licenses this file
- * to you 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.
- */
-package org.arabidopsis.ahocorasick;
-
-/**
- * Represents an EdgeList by using a single array. Very fast lookup (just an
- * array access), but expensive in terms of memory.
- */
-
-class DenseEdgeList<T> implements EdgeList<T> {
-  private State<T>[] array;
-
-  @SuppressWarnings("unchecked")
-  public DenseEdgeList() {
-    this.array = new State[256];
-    for (int i = 0; i < array.length; i++)
-      this.array[i] = null;
-  }
-
-  /**
-   * Helps in converting to dense representation.
-   */
-  public static <T> DenseEdgeList<T> fromSparse(SparseEdgeList<T> list) {
-    byte[] keys = list.keys();
-    DenseEdgeList<T> newInstance = new DenseEdgeList<T>();
-    for (int i = 0; i < keys.length; i++) {
-      newInstance.put(keys[i], list.get(keys[i]));
-    }
-    return newInstance;
-  }
-
-  public State<T> get(byte b) {
-    return this.array[(int) b & 0xFF];
-  }
-
-  public void put(byte b, State<T> s) {
-    this.array[(int) b & 0xFF] = s;
-  }
-
-  public byte[] keys() {
-    int length = 0;
-    for (int i = 0; i < array.length; i++) {
-      if (array[i] != null)
-        length++;
-    }
-    byte[] result = new byte[length];
-    int j = 0;
-    for (int i = 0; i < array.length; i++) {
-      if (array[i] != null) {
-        result[j] = (byte) i;
-        j++;
-      }
-    }
-    return result;
-  }
-
-}
diff --git a/src/ahocorasick/org/arabidopsis/ahocorasick/EdgeList.java b/src/ahocorasick/org/arabidopsis/ahocorasick/EdgeList.java
deleted file mode 100644
index 2db1e8f..0000000
--- a/src/ahocorasick/org/arabidopsis/ahocorasick/EdgeList.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Licensed to Cloudera, Inc. under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  Cloudera, Inc. licenses this file
- * to you 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.
- */
-package org.arabidopsis.ahocorasick;
-
-/**
- * Simple interface for mapping bytes to States.
- */
-interface EdgeList<T> {
-  State<T> get(byte ch);
-
-  void put(byte ch, State<T> state);
-
-  byte[] keys();
-}
diff --git a/src/ahocorasick/org/arabidopsis/ahocorasick/Queue.java b/src/ahocorasick/org/arabidopsis/ahocorasick/Queue.java
deleted file mode 100644
index df4a4b6..0000000
--- a/src/ahocorasick/org/arabidopsis/ahocorasick/Queue.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Licensed to Cloudera, Inc. under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  Cloudera, Inc. licenses this file
- * to you 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.
- */
-package org.arabidopsis.ahocorasick;
-
-import java.util.ArrayList;
-
-/**
- * Quick-and-dirty queue class. Essentially uses two lists to represent a queue.
- */
-class Queue<T> {
-  ArrayList<State<T>> l1;
-  ArrayList<State<T>> l2;
-
-  public Queue() {
-    l1 = new ArrayList<State<T>>();
-    l2 = new ArrayList<State<T>>();
-  }
-
-  public void add(State<T> s) {
-    l2.add(s);
-  }
-
-  public boolean isEmpty() {
-    return l1.isEmpty() && l2.isEmpty();
-  }
-
-  public State<T> pop() {
-    if (isEmpty())
-      throw new IllegalStateException();
-    if (l1.isEmpty()) {
-      for (int i = l2.size() - 1; i >= 0; i--)
-        l1.add(l2.remove(i));
-      assert l2.isEmpty();
-      assert !l1.isEmpty();
-    }
-    return l1.remove(l1.size() - 1);
-  }
-}
diff --git a/src/ahocorasick/org/arabidopsis/ahocorasick/SearchResult.java b/src/ahocorasick/org/arabidopsis/ahocorasick/SearchResult.java
deleted file mode 100644
index 198088a..0000000
--- a/src/ahocorasick/org/arabidopsis/ahocorasick/SearchResult.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Licensed to Cloudera, Inc. under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  Cloudera, Inc. licenses this file
- * to you 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.
- */
-package org.arabidopsis.ahocorasick;
-
-import java.util.Set;
-
-/**
- * <p>
- * Holds the result of the search so far. Includes the outputs where the search
- * finished as well as the last index of the matching.
- * </p>
- * 
- * <p>
- * (Internally, it also holds enough state to continue a running search, though
- * this is not exposed for public use.)
- * </p>
- */
-public class SearchResult<T> {
-  State<T> lastMatchedState;
-  byte[] bytes;
-  int lastIndex;
-
-  SearchResult(State<T> s, byte[] bs, int i) {
-    this.lastMatchedState = s;
-    this.bytes = bs;
-    this.lastIndex = i;
-  }
-
-  /**
-   * Returns a list of the outputs of this match.
-   */
-  public Set<T> getOutputs() {
-    return lastMatchedState.getOutputs();
-  }
-
-  /**
-   * Returns the index where the search terminates. Note that this is one byte
-   * after the last matching character.
-   */
-  public int getLastIndex() {
-    return lastIndex;
-  }
-}
diff --git a/src/ahocorasick/org/arabidopsis/ahocorasick/Searcher.java b/src/ahocorasick/org/arabidopsis/ahocorasick/Searcher.java
deleted file mode 100644
index c3af8be..0000000
--- a/src/ahocorasick/org/arabidopsis/ahocorasick/Searcher.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Licensed to Cloudera, Inc. under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  Cloudera, Inc. licenses this file
- * to you 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.
- */
-package org.arabidopsis.ahocorasick;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * Iterator returns a list of Search matches.
- */
-
-class Searcher<T> implements Iterator<SearchResult<T>> {
-  private SearchResult<T> currentResult;
-  private AhoCorasick<T> tree;
-
-  Searcher(AhoCorasick<T> tree, SearchResult<T> result) {
-    this.tree = tree;
-    this.currentResult = result;
-  }
-
-  public boolean hasNext() {
-    return (this.currentResult != null);
-  }
-
-  public SearchResult<T> next() {
-    if (!hasNext())
-      throw new NoSuchElementException();
-    SearchResult<T> result = currentResult;
-    currentResult = tree.continueSearch(currentResult);
-    return result;
-  }
-
-  public void remove() {
-    throw new UnsupportedOperationException();
-  }
-
-}
diff --git a/src/ahocorasick/org/arabidopsis/ahocorasick/SparseEdgeList.java b/src/ahocorasick/org/arabidopsis/ahocorasick/SparseEdgeList.java
deleted file mode 100644
index fd2eb20..0000000
--- a/src/ahocorasick/org/arabidopsis/ahocorasick/SparseEdgeList.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * Licensed to Cloudera, Inc. under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  Cloudera, Inc. licenses this file
- * to you 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.
- */
-package org.arabidopsis.ahocorasick;
-
-/**
- * Linked list implementation of the EdgeList should be less memory-intensive.
- * 
- * jon: tweaked to be type generic
- */
-
-class SparseEdgeList<T> implements EdgeList<T> {
-  private Cons<T> head;
-
-  public SparseEdgeList() {
-    head = null;
-  }
-
-  public State<T> get(byte b) {
-    Cons<T> c = head;
-    while (c != null) {
-      if (c.b == b)
-        return c.s;
-      c = c.next;
-    }
-    return null;
-  }
-
-  public void put(byte b, State<T> s) {
-    this.head = new Cons<T>(b, s, head);
-  }
-
-  public byte[] keys() {
-    int length = 0;
-    Cons<T> c = head;
-    while (c != null) {
-      length++;
-      c = c.next;
-    }
-    byte[] result = new byte[length];
-    c = head;
-    int j = 0;
-    while (c != null) {
-      result[j] = c.b;
-      j++;
-      c = c.next;
-    }
-    return result;
-  }
-
-  static private class Cons<T> {
-    byte b;
-    State<T> s;
-    Cons<T> next;
-
-    public Cons(byte b, State<T> s, Cons<T> next) {
-      this.b = b;
-      this.s = s;
-      this.next = next;
-    }
-  }
-
-}
diff --git a/src/ahocorasick/org/arabidopsis/ahocorasick/State.java b/src/ahocorasick/org/arabidopsis/ahocorasick/State.java
deleted file mode 100644
index e649aa2..0000000
--- a/src/ahocorasick/org/arabidopsis/ahocorasick/State.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * Licensed to Cloudera, Inc. under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  Cloudera, Inc. licenses this file
- * to you 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.
- */
-package org.arabidopsis.ahocorasick;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A state represents an element in the Aho-Corasick tree.
- */
-
-class State<T> {
-
-  // Arbitrarily chosen constant. If this state ends up getting
-  // deeper than THRESHOLD_TO_USE_SPARSE, then we switch over to a
-  // sparse edge representation. I did a few tests, and there's a
-  // local minima here. We may want to choose a more sophisticated
-  // strategy.
-  private static final int THRESHOLD_TO_USE_SPARSE = 3;
-
-  private int depth;
-  private EdgeList<T> edgeList;
-  private State<T> fail;
-  private Set<T> outputs;
-
-  public State(int depth) {
-    this.depth = depth;
-    if (depth > THRESHOLD_TO_USE_SPARSE)
-      this.edgeList = new SparseEdgeList<T>();
-    else
-      this.edgeList = new DenseEdgeList<T>();
-    this.fail = null;
-    this.outputs = new HashSet<T>();
-  }
-
-  public State<T> extend(byte b) {
-    if (this.edgeList.get(b) != null)
-      return this.edgeList.get(b);
-    State<T> nextState = new State<T>(this.depth + 1);
-    this.edgeList.put(b, nextState);
-    return nextState;
-  }
-
-  public State<T> extendAll(byte[] bytes) {
-    State<T> state = this;
-    for (int i = 0; i < bytes.length; i++) {
-      if (state.edgeList.get(bytes[i]) != null)
-        state = state.edgeList.get(bytes[i]);
-      else
-        state = state.extend(bytes[i]);
-    }
-    return state;
-  }
-
-  /**
-   * Returns the size of the tree rooted at this State. Note: do not call this
-   * if there are loops in the edgelist graph, such as those introduced by
-   * AhoCorasick.prepare().
-   */
-  public int size() {
-    byte[] keys = edgeList.keys();
-    int result = 1;
-    for (int i = 0; i < keys.length; i++)
-      result += edgeList.get(keys[i]).size();
-    return result;
-  }
-
-  public State<T> get(byte b) {
-    return this.edgeList.get(b);
-  }
-
-  public void put(byte b, State<T> s) {
-    this.edgeList.put(b, s);
-  }
-
-  public byte[] keys() {
-    return this.edgeList.keys();
-  }
-
-  public State<T> getFail() {
-    return this.fail;
-  }
-
-  public void setFail(State<T> f) {
-    this.fail = f;
-  }
-
-  public void addOutput(T o) {
-    this.outputs.add(o);
-  }
-
-  public Set<T> getOutputs() {
-    return this.outputs;
-  }
-}
diff --git a/src/ahocorasick/org/arabidopsis/ahocorasick/TestAhoCorasick.java b/src/ahocorasick/org/arabidopsis/ahocorasick/TestAhoCorasick.java
deleted file mode 100644
index 30887d6..0000000
--- a/src/ahocorasick/org/arabidopsis/ahocorasick/TestAhoCorasick.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/**
- * Licensed to Cloudera, Inc. under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  Cloudera, Inc. licenses this file
- * to you 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.
- */
-package org.arabidopsis.ahocorasick;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import junit.framework.TestCase;
-
-/**
- * Junit test cases for AhoCorasick.
- */
-@SuppressWarnings("unchecked")
-public class TestAhoCorasick extends TestCase {
-
-  private AhoCorasick tree;
-
-  public void setUp() {
-    this.tree = new AhoCorasick();
-  }
-
-  public void testConstruction() {
-    tree.add("hello".getBytes(), "hello".getBytes());
-    tree.add("hi".getBytes(), "hi".getBytes());
-    tree.prepare();
-
-    State s0 = tree.getRoot();
-    State s1 = s0.get((byte) 'h');
-    State s2 = s1.get((byte) 'e');
-    State s3 = s2.get((byte) 'l');
-    State s4 = s3.get((byte) 'l');
-    State s5 = s4.get((byte) 'o');
-    State s6 = s1.get((byte) 'i');
-    
-    assertTrue(s6 != null);
-
-    assertEquals(s0, s1.getFail());
-    assertEquals(s0, s2.getFail());
-    assertEquals(s0, s3.getFail());
-    assertEquals(s0, s4.getFail());
-    assertEquals(s0, s5.getFail());
-    assertEquals(s0, s6.getFail());
-
-    assertEquals(0, s0.getOutputs().size());
-    assertEquals(0, s1.getOutputs().size());
-    assertEquals(0, s2.getOutputs().size());
-    assertEquals(0, s3.getOutputs().size());
-    assertEquals(0, s4.getOutputs().size());
-    assertEquals(1, s5.getOutputs().size());
-    assertEquals(1, s6.getOutputs().size());    
-  }
-
-  public void testExample() {
-    tree.add("he".getBytes(), "he".getBytes());
-    tree.add("she".getBytes(), "she".getBytes());
-    tree.add("his".getBytes(), "his".getBytes());
-    tree.add("hers".getBytes(), "hers".getBytes());
-    assertEquals(10, tree.getRoot().size());
-    tree.prepare(); // after prepare, we can't call size()
-    State s0 = tree.getRoot();
-    State s1 = s0.get((byte) 'h');
-    State s2 = s1.get((byte) 'e');
-
-    State s3 = s0.get((byte) 's');
-    State s4 = s3.get((byte) 'h');
-    State s5 = s4.get((byte) 'e');
-
-    State s6 = s1.get((byte) 'i');
-    State s7 = s6.get((byte) 's');
-
-    State s8 = s2.get((byte) 'r');
-    State s9 = s8.get((byte) 's');
-
-    assertEquals(s0, s1.getFail());
-    assertEquals(s0, s2.getFail());
-    assertEquals(s0, s3.getFail());
-    assertEquals(s0, s6.getFail());
-    assertEquals(s0, s8.getFail());
-
-    assertEquals(s1, s4.getFail());
-    assertEquals(s2, s5.getFail());
-    assertEquals(s3, s7.getFail());
-    assertEquals(s3, s9.getFail());
-
-    assertEquals(0, s1.getOutputs().size());
-    assertEquals(0, s3.getOutputs().size());
-    assertEquals(0, s4.getOutputs().size());
-    assertEquals(0, s6.getOutputs().size());
-    assertEquals(0, s8.getOutputs().size());
-    assertEquals(1, s2.getOutputs().size());
-    assertEquals(1, s7.getOutputs().size());
-    assertEquals(1, s9.getOutputs().size());
-    assertEquals(2, s5.getOutputs().size());
-  }
-
-  public void testStartSearchWithSingleResult() {
-    tree.add("apple".getBytes(), "apple".getBytes());
-    tree.prepare();
-    SearchResult result = tree.startSearch("washington cut the apple tree"
-        .getBytes());
-    assertEquals(1, result.getOutputs().size());
-    assertEquals("apple", new String((byte[]) result.getOutputs().iterator()
-        .next()));
-    assertEquals(24, result.getLastIndex());
-    assertEquals(null, tree.continueSearch(result));
-  }
-
-  public void testStartSearchWithAdjacentResults() {
-    tree.add("john".getBytes(), "john".getBytes());
-    tree.add("jane".getBytes(), "jane".getBytes());
-    tree.prepare();
-    SearchResult firstResult = tree.startSearch("johnjane".getBytes());
-    SearchResult secondResult = tree.continueSearch(firstResult);
-    assertEquals(null, tree.continueSearch(secondResult));
-  }
-
-  public void testStartSearchOnEmpty() {
-    tree.add("cipher".getBytes(), Integer.valueOf(0));
-    tree.add("zip".getBytes(), Integer.valueOf(1));
-    tree.add("nought".getBytes(), Integer.valueOf(2));
-    tree.prepare();
-    SearchResult result = tree.startSearch("".getBytes());
-    assertEquals(null, result);
-  }
-
-  public void testMultipleOutputs() {
-    tree.add("x".getBytes(), "x");
-    tree.add("xx".getBytes(), "xx");
-    tree.add("xxx".getBytes(), "xxx");
-    tree.prepare();
-
-    SearchResult result = tree.startSearch("xxx".getBytes());
-    assertEquals(1, result.getLastIndex());
-    assertEquals(new HashSet(Arrays.asList(new String[] { "x" })), result
-        .getOutputs());
-
-    result = tree.continueSearch(result);
-    assertEquals(2, result.getLastIndex());
-    assertEquals(new HashSet(Arrays.asList(new String[] { "xx", "x" })), result
-        .getOutputs());
-
-    result = tree.continueSearch(result);
-    assertEquals(3, result.getLastIndex());
-    assertEquals(new HashSet(Arrays.asList(new String[] { "xxx", "xx", "x" })),
-        result.getOutputs());
-
-    assertEquals(null, tree.continueSearch(result));
-  }
-
-  public void testIteratorInterface() {
-    tree.add("moo".getBytes(), "moo");
-    tree.add("one".getBytes(), "one");
-    tree.add("on".getBytes(), "on");
-    tree.add("ne".getBytes(), "ne");
-    tree.prepare();
-    Iterator iter = tree.search("one moon ago".getBytes());
-
-    assertTrue(iter.hasNext());
-    SearchResult r = (SearchResult) iter.next();
-    assertEquals(new HashSet(Arrays.asList(new String[] { "on" })), r
-        .getOutputs());
-    assertEquals(2, r.getLastIndex());
-
-    assertTrue(iter.hasNext());
-    r = (SearchResult) iter.next();
-    assertEquals(new HashSet(Arrays.asList(new String[] { "one", "ne" })), r
-        .getOutputs());
-    assertEquals(3, r.getLastIndex());
-
-    assertTrue(iter.hasNext());
-    r = (SearchResult) iter.next();
-    assertEquals(new HashSet(Arrays.asList(new String[] { "moo" })), r
-        .getOutputs());
-    assertEquals(7, r.getLastIndex());
-
-    assertTrue(iter.hasNext());
-    r = (SearchResult) iter.next();
-    assertEquals(new HashSet(Arrays.asList(new String[] { "on" })), r
-        .getOutputs());
-    assertEquals(8, r.getLastIndex());
-
-    assertFalse(iter.hasNext());
-
-    try {
-      iter.next();
-      fail();
-    } catch (NoSuchElementException e) {
-    }
-
-  }
-
-  public void largerTextExample() {
-    String text = "The ga3 mutant of Arabidopsis is a gibberellin-responsive dwarf. We present data showing that the ga3-1 mutant is deficient in ent-kaurene oxidase activity, the first cytochrome P450-mediated step in the gibberellin biosynthetic pathway. By using a combination of conventional map-based cloning and random sequencing we identified a putative cytochrome P450 gene mapping to the same location as GA3. Relative to the progenitor line, two ga3 mutant alleles contained single base changes generating in-frame stop codons in the predicted amino acid sequence of the P450. A genomic clone spanning the P450 locus complemented the ga3-2 mutant. The deduced GA3 protein defines an additional class of cytochrome P450 enzymes. The GA3 gene was expressed in all tissues examined, RNA abundance being highest in inflorescence tissue.";
-    String[] terms = { "microsome", "cytochrome", "cytochrome P450 activity",
-        "gibberellic acid biosynthesis", "GA3", "cytochrome P450",
-        "oxygen binding", "AT5G25900.1", "protein", "RNA", "gibberellin",
-        "Arabidopsis", "ent-kaurene oxidase activity", "inflorescence",
-        "tissue", };
-    for (int i = 0; i < terms.length; i++) {
-      tree.add(terms[i].getBytes(), terms[i]);
-    }
-    tree.prepare();
-
-    Set termsThatHit = new HashSet();
-    for (Iterator iter = tree.search(text.getBytes()); iter.hasNext();) {
-      SearchResult result = (SearchResult) iter.next();
-      termsThatHit.addAll(result.getOutputs());
-    }
-    assertEquals(new HashSet(Arrays.asList(new String[] { "cytochrome", "GA3",
-        "cytochrome P450", "protein", "RNA", "gibberellin", "Arabidopsis",
-        "ent-kaurene oxidase activity", "inflorescence", "tissue", })),
-        termsThatHit);
-
-  }
-}
diff --git a/src/ahocorasick/org/arabidopsis/ahocorasick/TestAll.java b/src/ahocorasick/org/arabidopsis/ahocorasick/TestAll.java
deleted file mode 100644
index 179ba6f..0000000
--- a/src/ahocorasick/org/arabidopsis/ahocorasick/TestAll.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Licensed to Cloudera, Inc. under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  Cloudera, Inc. licenses this file
- * to you 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.
- */
-package org.arabidopsis.ahocorasick;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-public class TestAll extends TestCase {
-    public static Test suite() {
-	TestSuite suite = new TestSuite();
-	suite.addTestSuite(TestState.class);
-	suite.addTestSuite(TestAhoCorasick.class);
-	suite.addTestSuite(TestQueue.class);
-	return suite;
-    }
-}
diff --git a/src/ahocorasick/org/arabidopsis/ahocorasick/TestQueue.java b/src/ahocorasick/org/arabidopsis/ahocorasick/TestQueue.java
deleted file mode 100644
index 891bcde..0000000
--- a/src/ahocorasick/org/arabidopsis/ahocorasick/TestQueue.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Licensed to Cloudera, Inc. under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  Cloudera, Inc. licenses this file
- * to you 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.
- */
-package org.arabidopsis.ahocorasick;
-
-import junit.framework.TestCase;
-
-@SuppressWarnings("unchecked")
-public class TestQueue extends TestCase {
-    public void testSimple() {
-	Queue q = new Queue();
-	State s1 = new State(0);
-	State s2 = new State(0);
-	State s3 = new State(0);
-	State s4 = new State(0);
-	State s5 = new State(0);
-	assertTrue(q.isEmpty());
-	q.add(s1);
-	assertFalse(q.isEmpty());
-	assertEquals(s1, q.pop());
-
-	q.add(s2);
-	q.add(s3);
-	assertEquals(s2, q.pop());
-	q.add(s4);
-	q.add(s5);
-	assertEquals(s3, q.pop());
-	assertEquals(s4, q.pop());
-	assertEquals(s5, q.pop());
-	assertTrue(q.isEmpty());
-    }
-}
diff --git a/src/ahocorasick/org/arabidopsis/ahocorasick/TestState.java b/src/ahocorasick/org/arabidopsis/ahocorasick/TestState.java
deleted file mode 100644
index 1b2b86c..0000000
--- a/src/ahocorasick/org/arabidopsis/ahocorasick/TestState.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * Licensed to Cloudera, Inc. under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  Cloudera, Inc. licenses this file
- * to you 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.
- */
-package org.arabidopsis.ahocorasick;
-
-import junit.framework.TestCase;
-
-@SuppressWarnings("unchecked")
-public class TestState extends TestCase {
-  public void testSimpleExtension() {
-    State s = new State(0);
-    State s2 = s.extend("a".getBytes()[0]);
-    assertTrue(s2 != s && s2 != null);
-    assertEquals(2, s.size());
-  }
-
-  public void testSimpleExtensionSparse() {
-    State s = new State(50);
-    State s2 = s.extend((byte) 3);
-    assertTrue(s2 != s && s2 != null);
-    assertEquals(2, s.size());
-  }
-
-  public void testSingleState() {
-    State s = new State(0);
-    assertEquals(1, s.size());
-  }
-
-  public void testSingleStateSparse() {
-    State s = new State(50);
-    assertEquals(1, s.size());
-  }
-
-  public void testExtendAll() {
-    State s = new State(0);
-    s.extendAll("hello world".getBytes());
-    assertEquals(12, s.size());
-  }
-
-  public void testExtendAllTwiceDoesntAddMoreStates() {
-    State s = new State(0);
-    State s2 = s.extendAll("hello world".getBytes());
-    State s3 = s.extendAll("hello world".getBytes());
-    assertEquals(12, s.size());
-    assertTrue(s2 == s3);
-  }
-
-  public void testExtendAllTwiceDoesntAddMoreStatesSparse() {
-    State s = new State(50);
-    State s2 = s.extendAll("hello world".getBytes());
-    State s3 = s.extendAll("hello world".getBytes());
-    assertEquals(12, s.size());
-    assertTrue(s2 == s3);
-  }
-
-  public void testAddingALotOfStatesIsOk() {
-    State s = new State(0);
-    for (int i = 0; i < 256; i++)
-      s.extend((byte) i);
-    assertEquals(257, s.size());
-  }
-
-  public void testAddingALotOfStatesIsOkOnSparseRep() {
-    State s = new State(50);
-    for (int i = 0; i < 256; i++)
-      s.extend((byte) i);
-    assertEquals(257, s.size());
-  }
-
-}
diff --git a/src/ahocorasick/org/arabidopsis/ahocorasick/TimeTrial.java b/src/ahocorasick/org/arabidopsis/ahocorasick/TimeTrial.java
deleted file mode 100644
index 59c4e4a..0000000
--- a/src/ahocorasick/org/arabidopsis/ahocorasick/TimeTrial.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Licensed to Cloudera, Inc. under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  Cloudera, Inc. licenses this file
- * to you 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.
- */
-package org.arabidopsis.ahocorasick;
-
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-/**
- * Quick and dirty code: measures the amount of time it takes to construct an
- * AhoCorasick tree out of all the words in <tt>/usr/share/dict/words</tt>.
- */
-
-@SuppressWarnings("unchecked")
-public class TimeTrial {
-  static public void main(String[] args) throws IOException {
-    long startTime = System.currentTimeMillis();
-    AhoCorasick tree = new AhoCorasick();
-    BufferedReader reader = new BufferedReader(new InputStreamReader(
-        new FileInputStream("/usr/share/dict/words")));
-    String line;
-    while ((line = reader.readLine()) != null) {
-      tree.add(line.getBytes(), null);
-    }
-    tree.prepare();
-    long endTime = System.currentTimeMillis();
-    System.out.println("endTime - startTime = " + (endTime - startTime)
-        + " milliseconds");
-  }
-}
-- 
1.7.1

